1 package com.atlassian.plugins.rest.common;
2
3 import com.google.common.base.Preconditions;
4 import com.google.common.collect.Lists;
5 import org.apache.commons.lang.builder.EqualsBuilder;
6 import org.apache.commons.lang.builder.HashCodeBuilder;
7
8 import javax.ws.rs.core.CacheControl;
9 import javax.ws.rs.core.Response;
10 import javax.xml.bind.annotation.XmlAttribute;
11 import javax.xml.bind.annotation.XmlElement;
12 import javax.xml.bind.annotation.XmlElementWrapper;
13 import javax.xml.bind.annotation.XmlRootElement;
14 import java.util.Collection;
15 import java.util.Collections;
16 import java.util.List;
17
18
19
20
21 @XmlRootElement
22 public class Status
23 {
24
25
26
27 @XmlElement
28 private final Plugin plugin;
29
30
31
32
33
34 @XmlElement(name = "status-code")
35 private final Integer code;
36
37
38
39
40 @XmlElement(name = "sub-code")
41 private final Integer subCode;
42
43
44
45
46 @XmlElement
47 private final String message;
48
49
50
51
52
53 @XmlElement(name = "etag")
54 private final String eTag;
55
56
57
58
59 @XmlElementWrapper(name = "resources-created")
60 @XmlElement(name = "link")
61 private final Collection<Link> resourcesCreated;
62
63
64
65
66 @XmlElementWrapper(name = "resources-updated")
67 @XmlElement(name = "link")
68 private final Collection<Link> resourcesUpdated;
69
70
71 private Status()
72 {
73 this.plugin = null;
74 this.code = -1;
75 this.subCode = -1;
76 this.message = null;
77 this.eTag = null;
78 this.resourcesCreated = null;
79 this.resourcesUpdated = null;
80 }
81
82 private Status(Plugin plugin, Integer code, Integer subCode, String message, String eTag, Collection<Link> resourcesCreated, Collection<Link> resourcesUpdated)
83 {
84 this.plugin = plugin;
85 this.code = code;
86 this.subCode = subCode;
87 this.message = message;
88 this.eTag = eTag;
89 this.resourcesCreated = resourcesCreated;
90 this.resourcesUpdated = resourcesUpdated;
91 }
92
93 public static StatusResponseBuilder ok()
94 {
95 return new StatusResponseBuilder(Response.Status.OK);
96 }
97
98 public static StatusResponseBuilder notFound()
99 {
100 return new StatusResponseBuilder(Response.Status.NOT_FOUND);
101 }
102
103 public static StatusResponseBuilder error()
104 {
105
106 return new StatusResponseBuilder(Response.Status.INTERNAL_SERVER_ERROR).noCache().noStore();
107 }
108
109 public static StatusResponseBuilder forbidden()
110 {
111 return new StatusResponseBuilder(Response.Status.FORBIDDEN);
112 }
113
114 public static StatusResponseBuilder unauthorized()
115 {
116 return new StatusResponseBuilder(Response.Status.UNAUTHORIZED);
117 }
118
119 public static StatusResponseBuilder created(Link link)
120 {
121 return new StatusResponseBuilder(Response.Status.CREATED).created(Preconditions.checkNotNull(link));
122 }
123
124 public Plugin getPlugin()
125 {
126 return plugin;
127 }
128
129 public int getCode()
130 {
131 return code;
132 }
133
134 public int getSubCode()
135 {
136 return subCode;
137 }
138
139 public String getMessage()
140 {
141 return message;
142 }
143
144 public String getETag()
145 {
146 return eTag;
147 }
148
149 public Collection<Link> getResourcesCreated()
150 {
151 return Collections.unmodifiableCollection(resourcesCreated);
152 }
153
154 public Collection<Link> getResourcesUpdated()
155 {
156 return Collections.unmodifiableCollection(resourcesUpdated);
157 }
158
159 @XmlRootElement
160 public static class Plugin
161 {
162 @XmlAttribute
163 private final String key;
164
165 @XmlAttribute
166 private final String version;
167
168
169 private Plugin()
170 {
171 this.key = null;
172 this.version = null;
173 }
174
175 public Plugin(String key, String version)
176 {
177 this.key = Preconditions.checkNotNull(key);
178 this.version = Preconditions.checkNotNull(version);
179 }
180
181 public String getKey()
182 {
183 return key;
184 }
185
186 public String getVersion()
187 {
188 return version;
189 }
190
191 @Override
192 public int hashCode()
193 {
194 return new HashCodeBuilder(3, 5).append(key).append(version).toHashCode();
195 }
196
197 @Override
198 public boolean equals(Object obj)
199 {
200 if (obj == null)
201 {
202 return false;
203 }
204 if (obj == this)
205 {
206 return true;
207 }
208 if (obj.getClass() != getClass())
209 {
210 return false;
211 }
212 final Plugin plugin = (Plugin) obj;
213 return new EqualsBuilder().append(key, plugin.key).append(version, plugin.version).isEquals();
214 }
215 }
216
217 public static class StatusResponseBuilder
218 {
219 private final CacheControl cacheControl;
220 private final Response.Status status;
221 private String eTag;
222 private Plugin plugin;
223 private String message;
224 private List<Link> created;
225 private List<Link> updated;
226
227 private StatusResponseBuilder(Response.Status status)
228 {
229 this(status, new CacheControl());
230 }
231
232 private StatusResponseBuilder(Response.Status status, CacheControl cacheControl)
233 {
234 this.status = Preconditions.checkNotNull(status);
235 this.cacheControl = Preconditions.checkNotNull(cacheControl);
236 }
237
238 public StatusResponseBuilder plugin(String key, String version)
239 {
240 plugin = new Plugin(key, version);
241 return this;
242 }
243
244 public StatusResponseBuilder message(String message)
245 {
246 this.message = message;
247 return this;
248 }
249
250 public StatusResponseBuilder tag(String eTag)
251 {
252 this.eTag = eTag;
253 return this;
254 }
255
256 public StatusResponseBuilder noCache()
257 {
258 cacheControl.setNoCache(true);
259 return this;
260 }
261
262 public StatusResponseBuilder noStore()
263 {
264 cacheControl.setNoStore(true);
265 return this;
266 }
267
268 public Status build()
269 {
270 return new Status(plugin, status.getStatusCode(), null, message, eTag, created, updated);
271 }
272
273 public Response response()
274 {
275 return responseBuilder().build();
276 }
277
278 public Response.ResponseBuilder responseBuilder()
279 {
280 final Response.ResponseBuilder builder = Response.status(status).cacheControl(cacheControl).tag(eTag).entity(build());
281
282 final List<Link> c = getCreated();
283 final List<Link> u = getUpdated();
284 if (c.size() == 1 && u.isEmpty())
285 {
286 builder.location(c.get(0).getHref());
287 }
288 else if (u.size() == 1 && c.isEmpty())
289 {
290 builder.location(u.get(0).getHref());
291 }
292 return builder;
293 }
294
295 public StatusResponseBuilder created(final Link link)
296 {
297 getCreated().add(link);
298 return this;
299 }
300
301 public StatusResponseBuilder updated(final Link link)
302 {
303 getUpdated().add(link);
304 return this;
305 }
306
307 private List<Link> getCreated()
308 {
309 if (created == null)
310 {
311 created = Lists.newLinkedList();
312 }
313 return created;
314 }
315
316 private List<Link> getUpdated()
317 {
318 if (updated == null)
319 {
320 updated = Lists.newLinkedList();
321 }
322 return updated;
323 }
324 }
325 }