1
2
3
4
5 package com.jcabi.github;
6
7 import com.jcabi.aspects.Immutable;
8 import com.jcabi.aspects.Loggable;
9 import com.jcabi.http.Request;
10 import com.jcabi.http.response.JsonResponse;
11 import com.jcabi.http.response.RestResponse;
12 import jakarta.json.Json;
13 import jakarta.json.JsonObject;
14 import jakarta.json.JsonStructure;
15 import jakarta.json.JsonValue;
16 import java.io.IOException;
17 import java.net.HttpURLConnection;
18 import lombok.EqualsAndHashCode;
19
20
21
22
23
24
25 @Immutable
26 @Loggable(Loggable.DEBUG)
27 @EqualsAndHashCode(of = { "entry", "request", "owner" })
28 @SuppressWarnings("PMD.AvoidDuplicateLiterals")
29 final class RtContents implements Contents {
30
31
32
33
34 private final transient Request entry;
35
36
37
38
39 private final transient Repo owner;
40
41
42
43
44 private final transient Request request;
45
46
47
48
49
50
51 RtContents(final Request req, final Repo repo) {
52 this.entry = req;
53 this.owner = repo;
54 this.request = req.uri()
55 .path("/repos")
56 .path(repo.coordinates().user())
57 .path(repo.coordinates().repo())
58 .path("/contents")
59 .back();
60 }
61
62 @Override
63 public Repo repo() {
64 return this.owner;
65 }
66
67 @Override
68 public Content readme() throws IOException {
69 return new RtContent(
70 this.entry, this.owner,
71 this.entry.uri()
72 .path("/repos")
73 .path(this.owner.coordinates().user())
74 .path(this.owner.coordinates().repo())
75 .path("/readme")
76 .back()
77 .method(Request.GET)
78 .fetch()
79 .as(RestResponse.class)
80 .assertStatus(HttpURLConnection.HTTP_OK)
81 .as(JsonResponse.class)
82 .json().readObject().getString("path")
83 );
84 }
85
86 @Override
87 public Content readme(
88 final String branch
89 ) throws IOException {
90 final JsonStructure json = Json.createObjectBuilder()
91 .add("ref", branch)
92 .build();
93 return new RtContent(
94 this.entry, this.owner,
95 this.entry.uri()
96 .path("/repos")
97 .path(this.owner.coordinates().user())
98 .path(this.owner.coordinates().repo())
99 .path("/readme")
100 .back()
101 .method(Request.GET)
102 .body().set(json).back()
103 .fetch()
104 .as(RestResponse.class)
105 .assertStatus(HttpURLConnection.HTTP_OK)
106 .as(JsonResponse.class)
107 .json().readObject().getString("path")
108 );
109 }
110
111 @Override
112 public Content create(
113 final JsonObject content
114 )
115 throws IOException {
116 if (!content.containsKey("path")) {
117 throw new IllegalStateException(
118 "Content should have path parameter"
119 );
120 }
121 final String path = content.getString("path");
122 return new RtContent(
123 this.entry, this.owner,
124 this.request.method(Request.PUT)
125 .uri().path(path).back()
126 .body().set(content).back()
127 .fetch()
128 .as(RestResponse.class)
129 .assertStatus(HttpURLConnection.HTTP_CREATED)
130 .as(JsonResponse.class)
131 .json().readObject().getJsonObject("content").getString("path")
132 );
133 }
134
135 @Override
136 public Content get(
137 final String path,
138 final String ref
139 ) throws IOException {
140 return this.content(path, ref);
141 }
142
143 @Override
144 public Content get(
145 final String path
146 ) throws IOException {
147 return this.content(path, this.repo().defaultBranch().name());
148 }
149
150 @Override
151 public Iterable<Content> iterate(
152 final String path,
153 final String ref
154 ) {
155 return new RtPagination<>(
156 this.request.method(Request.GET)
157 .uri().path(path).queryParam("ref", ref).back(),
158 object -> new RtContent(
159 this.entry, this.owner,
160 object.getString("path")
161 )
162 );
163 }
164
165 @Override
166 public RepoCommit remove(final JsonObject content
167 )
168 throws IOException {
169 if (!content.containsKey("path")) {
170 throw new IllegalStateException(
171 "Content should have path parameter"
172 );
173 }
174 final String path = content.getString("path");
175 return new RtRepoCommit(
176 this.entry,
177 this.owner,
178 this.request.method(Request.DELETE)
179 .uri().path(path).back()
180 .body().set(content).back().fetch()
181 .as(RestResponse.class)
182 .assertStatus(HttpURLConnection.HTTP_OK)
183 .as(JsonResponse.class).json()
184 .readObject().getJsonObject("commit").getString("sha")
185 );
186 }
187
188 @Override
189 public RepoCommit update(
190 final String path,
191 final JsonObject json)
192 throws IOException {
193 return new RtRepoCommit(
194 this.entry,
195 this.owner,
196 this.request.uri().path(path).back()
197 .method(Request.PUT)
198 .body().set(json).back()
199 .fetch()
200 .as(RestResponse.class)
201 .assertStatus(HttpURLConnection.HTTP_OK)
202 .as(JsonResponse.class).json()
203 .readObject().getJsonObject("commit").getString("sha")
204 );
205 }
206
207 @Override
208 public boolean exists(final String path, final String ref)
209 throws IOException {
210 final RestResponse response = this.request.method(Request.GET)
211 .uri().path(path).queryParam("ref", ref).back()
212 .fetch().as(RestResponse.class);
213 return response.status() == HttpURLConnection.HTTP_OK;
214 }
215
216
217
218
219
220
221
222
223
224 private Content content(
225 final String path, final String ref
226 ) throws IOException {
227 final String name = "ref";
228 RtContent content = null;
229 final JsonStructure structure = this.request.method(Request.GET)
230 .uri().path(path).queryParam(name, ref).back()
231 .fetch()
232 .as(RestResponse.class)
233 .assertStatus(HttpURLConnection.HTTP_OK)
234 .as(JsonResponse.class)
235 .json().read();
236 if (JsonValue.ValueType.OBJECT.equals(structure.getValueType())) {
237 content = new RtContent(
238 this.entry.uri().queryParam(name, ref).back(), this.owner,
239 ((JsonObject) structure).getString("path")
240 );
241 }
242 return content;
243 }
244
245 }