Exported from Notepad++
1 /*
2 Authors: abde
3 File: SpriteFacadeREST.java
4 Description: Routes and handles all the http REST requests implementing AbstractFacade interface
5 */
6
7 package service;
8
9 import cst.entities.Sprite;
10 import java.awt.Color;
11 import java.util.ArrayList;
12 import java.util.HashSet;
13 import java.util.List;
14 import java.util.Objects;
15 import javax.persistence.EntityManager;
16 import javax.persistence.PersistenceContext;
17 import javax.ws.rs.core.Response;
18 import cst.entities.AbstractFacade;
19 import javax.annotation.security.DeclareRoles;
20 import javax.annotation.security.RolesAllowed;
21
22 /**
23 * Defines our RESTful API endpoints
24 * @author abde
25 */
26 @javax.ejb.Stateless
27 @javax.ws.rs.Path("sprites")
28 @DeclareRoles({"Admin", "RestGroup"})
29 public class SpriteFacadeREST extends AbstractFacade<Sprite> {
30
31 @PersistenceContext(unitName = "SpriteUsersPU")
32 private EntityManager em;
33
34 public SpriteFacadeREST() {
35 super(Sprite.class);
36 }
37
38 /**
39 * POST on root resource Without an id - Creates a new sprite without an id
40 * provided With an id - Checks there is a sprite to update, non-existent id
41 * returns error
42 *
43 * @param entity Sprite entity provided sprite values
44 * @return response code with requested information
45 */
46 @javax.ws.rs.POST
47 @javax.ws.rs.Consumes({javax.ws.rs.core.MediaType.APPLICATION_XML, javax.ws.rs.core.MediaType.APPLICATION_JSON})
48 @RolesAllowed({"Admin", "RestGroup"})
49 public Response createUpdate(Sprite entity) {
50 // check if id exists
51 Long id = entity.getId();
52 if (id == null) {
53 // verify the attributes
54 String verification = validateSprite(entity, false, null);
55 if (verification.compareTo("") == 0) {
56 // create new sprite
57 super.create(entity);
58 return Response.status(Response.Status.CREATED).entity("New sprite created").build();
59 } else {
60 // invalid attribute(s)
61 return Response.status(Response.Status.NOT_ACCEPTABLE).entity(verification).build();
62 }
63 } else {
64 // check if id exists
65 Sprite sprite = findId(id);
66 if (sprite == null) {
67 // error if no sprite with this ID exists
68 return Response.status(Response.Status.NOT_ACCEPTABLE).entity("Sprite ID cannot be manually set").build();
69 } else {
70 // verify the attributes
71 String verification = validateSprite(entity, true, sprite);
72 if (verification.compareTo("") == 0) {
73 // update existing sprite
74 updateSprite(entity, sprite);
75 return Response.ok("Sprite with id " + id + " updated").build();
76 } else {
77 // invalid attribute(s)
78 return Response.status(Response.Status.NOT_ACCEPTABLE).entity(verification).build();
79 }
80 }
81 }
82 }
83
84 /**
85 * PUT on root resource Unsupported - return error
86 *
87 * @param entity Sprite entity provided sprite values
88 * @return response code with requested information
89 */
90 @javax.ws.rs.PUT
91 @javax.ws.rs.Consumes({javax.ws.rs.core.MediaType.APPLICATION_XML, javax.ws.rs.core.MediaType.APPLICATION_JSON})
92 @RolesAllowed({"Admin", "RestGroup"})
93 public Response invCreate(Sprite entity) {
94 return Response.status(Response.Status.NOT_IMPLEMENTED).entity("Can not PUT on the root resource").build();
95 }
96
97 /**
98 * PUT request with an id Replaces a sprite with the matching id
99 *
100 * @param id provided sprite id
101 * @param entity sprite entity provided sprite values
102 * @return response code with requested information
103 */
104 @javax.ws.rs.PUT
105 @javax.ws.rs.Path("{id}")
106 @javax.ws.rs.Consumes({javax.ws.rs.core.MediaType.APPLICATION_XML, javax.ws.rs.core.MediaType.APPLICATION_JSON})
107 @RolesAllowed({"Admin", "RestGroup"})
108 public Response replace(@javax.ws.rs.PathParam("id") Long id, Sprite entity) {
109 // make sure IDs are not contradictory
110 if (entity.getId() != null && !Objects.equals(entity.getId(), id)){
111 return Response.status(Response.Status.NOT_ACCEPTABLE).entity("Body ID " + entity.getId() + " must be null or match provided ID " + id).build();
112 }
113
114 // check if id exists
115 Sprite sprite = findId(id);
116 if (sprite == null) {
117 // error if no sprite with this ID exists
118 return Response.status(Response.Status.NOT_ACCEPTABLE).entity("Sprite with ID " + id + " cannot be found").build();
119 } else {
120 // verify the attributes
121 String verification = validateSprite(entity, false, null);
122 if (verification.compareTo("") == 0) {
123 // replace the sprite
124 entity.setId(id);
125 super.edit(entity);
126 return Response.status(Response.Status.OK).entity("Sprite with id " + id + " replaced").build();
127 } else {
128 // invalid attribute(s)
129 return Response.status(Response.Status.NOT_ACCEPTABLE).entity(verification).build();
130 }
131 }
132 }
133
134 /**
135 * POST request with an id Updates a sprite with the matching id with the
136 * non-null values
137 *
138 * @param id provided sprite id
139 * @param entity sprite entity provided sprite values
140 * @return response code with requested information
141 */
142 @javax.ws.rs.POST
143 @javax.ws.rs.Path("{id}")
144 @javax.ws.rs.Consumes({javax.ws.rs.core.MediaType.APPLICATION_XML, javax.ws.rs.core.MediaType.APPLICATION_JSON})
145 @RolesAllowed({"Admin", "RestGroup"})
146 public Response update(@javax.ws.rs.PathParam("id") Long id, Sprite entity) {
147 // make sure IDs are not contradictory
148 if (entity.getId() != null && !Objects.equals(entity.getId(), id)){
149 return Response.status(Response.Status.NOT_ACCEPTABLE).entity("Body ID " + entity.getId() + " must be null or match provided ID " + id).build();
150 }
151
152 // check if id exists
153 Sprite sprite = findId(id);
154 if (sprite == null) {
155 // error if no sprite with this ID exists
156 return Response.status(Response.Status.NOT_ACCEPTABLE).entity("Sprite with ID " + id + " cannot be found").build();
157 } else {
158 // verify the attributes
159 String verification = validateSprite(entity, true, sprite);
160 if (verification.compareTo("") == 0) {
161 // update existing sprite
162 updateSprite(entity, sprite);
163 return Response.ok("Sprite with id " + id + " updated").build();
164 } else {
165 // invalid attribute(s)
166 return Response.status(Response.Status.NOT_ACCEPTABLE).entity(verification).build();
167 }
168 }
169 }
170
171 /**
172 * DELETE with an id Delete the selected sprite if it exists
173 *
174 * @param id provided sprite id
175 * @return response code with requested information
176 */
177 @javax.ws.rs.DELETE
178 @javax.ws.rs.Path("{id}")
179 @RolesAllowed({"Admin", "RestGroup"})
180 public Response remove(@javax.ws.rs.PathParam("id") Long id) {
181 // check if id exists
182 Sprite sprite = findId(id);
183 if (sprite == null) {
184 return Response.status(Response.Status.NOT_ACCEPTABLE).entity("Sprite with ID " + id + " cannot be found").build();
185 } else {
186 super.remove(super.find(id));
187 return Response.status(Response.Status.OK).entity("Sprite with id " + id + " removed").build();
188 }
189 }
190
191 /**
192 * GET with an id Returns found sprite if any
193 *
194 * @param id provided sprite id
195 * @return response code with requested information
196 */
197 @javax.ws.rs.GET
198 @javax.ws.rs.Path("{id}")
199 @javax.ws.rs.Produces({javax.ws.rs.core.MediaType.APPLICATION_XML, javax.ws.rs.core.MediaType.APPLICATION_JSON})
200 @RolesAllowed({"Admin", "RestGroup"})
201 public Response find(@javax.ws.rs.PathParam("id") Long id) {
202 // check if id exists
203 Sprite sprite = findId(id);
204 if (sprite == null) {
205 return Response.status(Response.Status.NO_CONTENT).entity("Sprite with ID " + id + " does not exist").build();
206 } else {
207 return Response.status(Response.Status.OK).entity(sprite).build();
208 }
209 }
210
211 /**
212 * GET root resource Returns all sprites if any
213 *
214 * @return response code with requested information
215 */
216 @javax.ws.rs.GET
217 @javax.ws.rs.Produces({javax.ws.rs.core.MediaType.APPLICATION_XML, javax.ws.rs.core.MediaType.APPLICATION_JSON})
218 @RolesAllowed({"Admin", "RestGroup"})
219 public Response getAll() {
220 List<Sprite> sprites = super.findAll();
221 if (sprites.isEmpty()) {
222 return Response.status(Response.Status.NO_CONTENT).entity("No sprites exist").build();
223 } else {
224 return Response.status(Response.Status.OK).entity(sprites).build();
225 }
226 }
227
228 /**
229 * GET with id range Returns the sprites with applicable ids if any
230 *
231 * @param from beginning id range
232 * @param to end id range
233 * @return response code with requested information
234 */
235 @javax.ws.rs.GET
236 @javax.ws.rs.Path("{from}/{to}")
237 @javax.ws.rs.Produces({javax.ws.rs.core.MediaType.APPLICATION_XML, javax.ws.rs.core.MediaType.APPLICATION_JSON})
238 @RolesAllowed({"Admin", "RestGroup"})
239 public Response findRange(@javax.ws.rs.PathParam("from") Integer from, @javax.ws.rs.PathParam("to") Integer to) {
240 //return super.findRange(new int[]{from, to});
241 List<Sprite> sprites = super.findRange(new int[]{from, to});
242 if (sprites.isEmpty()) {
243 return Response.status(Response.Status.NO_CONTENT).entity("No sprites exist").build();
244 } else {
245 return Response.status(Response.Status.OK).entity(sprites).build();
246 }
247 }
248
249 /**
250 * GET with count Returns the how many sprites there are
251 *
252 * @return response code with requested information
253 */
254 @javax.ws.rs.GET
255 @javax.ws.rs.Path("count")
256 @javax.ws.rs.Produces({javax.ws.rs.core.MediaType.APPLICATION_XML, javax.ws.rs.core.MediaType.APPLICATION_JSON,
257 javax.ws.rs.core.MediaType.TEXT_PLAIN})
258 @RolesAllowed({"Admin", "RestGroup"})
259 public Response countREST() {
260 return Response.status(Response.Status.OK).entity(super.count()).build();
261 }
262
263 /**
264 * Returns an entity manager
265 *
266 * @return entity manager
267 */
268 @Override
269 protected EntityManager getEntityManager() {
270 return em;
271 // return Response.ok(em).build();
272 }
273
274 /**
275 * Validates the sprites attributes and returns a string of errors if any
276 *
277 * @param sprite the sprite to validate
278 * @param Boolean whether we are validating for an update or a replace
279 * @param ogSprite sprite being updated for extra validation
280 * @return string of errors if any
281 */
282 private String validateSprite(Sprite sprite, Boolean update, Sprite ogSprite) {
283 String response = "";
284 int maxSpeed = Sprite.MAX_SPEED;
285 int size = Sprite.SIZE;
286 List<String> invalidVals = new ArrayList<>();
287
288 if (((update && sprite.getPanelWidth() != null) || !update) && (sprite.getPanelWidth() == null || sprite.getPanelWidth() <= size)) {
289 invalidVals.add(String.format("PanelWidth (must be whole number greater than sprite size of %d)", size));
290 }
291
292 if (((update && sprite.getPanelHeight() != null) || !update) && (sprite.getPanelHeight() == null || sprite.getPanelHeight() <= size)) {
293 invalidVals.add(String.format("PanelHeight (must be whole number greater than sprite size of %d)", size));
294 }
295
296 if ((!update) && (sprite.getX() == null || sprite.getX() < 0 || sprite.getX() > (sprite.getPanelWidth() - size))) {
297 invalidVals.add(String.format("X (must be %d or under, less than PanelWidth (%d) minus size of sprite (%d))",
298 (sprite.getPanelHeight() - size),sprite.getPanelHeight(), size));
299 }
300
301 if ((!update) && (sprite.getY() == null || sprite.getY() < 0 || sprite.getY() > (sprite.getPanelHeight() - size))) {
302 invalidVals.add(String.format("Y (must be %d or under, less than PanelHeight (%d) minus size of sprite (%d))",
303 (sprite.getPanelHeight() - size), sprite.getPanelHeight(), size));
304 }
305
306 // validate x and y coordinates for updates
307 if (update){
308 Integer panelWidth = sprite.getPanelWidth();
309 Integer x = sprite.getX();
310 if (panelWidth == null){
311 panelWidth = ogSprite.getPanelWidth();
312 }
313 if (x == null){
314 x = ogSprite.getX();
315 }
316 if (x < 0 || x > (panelWidth - size)) {
317 invalidVals.add(String.format("X (must be %d or under, less than PanelWidth (%d) minus size of sprite (%d))",
318 (panelWidth - size), panelWidth, size));
319 }
320
321 Integer panelHeight = sprite.getPanelHeight();
322 Integer y = sprite.getY();
323 if (panelHeight == null){
324 panelHeight = ogSprite.getPanelHeight();
325 }
326 if (y == null){
327 y = ogSprite.getY();
328 }
329 if (y < 0 || y > (panelHeight - size)) {
330 invalidVals.add(String.format("Y (must be %d or under, less than PanelHeight (%d) minus size of sprite (%d))", (panelHeight - size), panelHeight, size));
331 }
332 }
333
334
335 if (((update && sprite.getDx() != null) || !update) && (sprite.getDx() == null ||
336 sprite.getDx() < -1 * (maxSpeed) || sprite.getDx() > maxSpeed)) {
337 invalidVals.add(String.format("dX (must be whole number between -%d to %d)", maxSpeed, maxSpeed));
338 }
339
340 if (((update && sprite.getDy() != null) || !update) && (sprite.getDy() == null ||
341 sprite.getDy() < -1 * (maxSpeed) || sprite.getDy() > maxSpeed)) {
342 invalidVals.add(String.format("dY (must be whole number between -%d to %d)", maxSpeed, maxSpeed));
343 }
344
345 for (int i = 0; i < invalidVals.size(); i++) {
346 response += invalidVals.get(i);
347 if (i < invalidVals.size()) {
348 response += ", ";
349 }
350 }
351
352 return response;
353 }
354
355 /**
356 * Updates a sprite with received non-null values
357 *
358 * @param entity the updated values
359 * @param sprite the original sprite
360 */
361 private void updateSprite(Sprite entity, Sprite sprite) {
362 Color color = entity.getColor();
363
364 if (color != null) {
365 sprite.setColor(color);
366 }
367
368 if (entity.getX() != null) {
369 sprite.setX(entity.getX());
370 }
371
372 if (entity.getY() != null) {
373 sprite.setY(entity.getY());
374 }
375
376 if (entity.getDx() != null) {
377 sprite.setDx(entity.getDx());
378 }
379
380 if (entity.getDy() != null) {
381 sprite.setDy(entity.getDy());
382 }
383
384 if (entity.getPanelWidth() != null) {
385 sprite.setPanelWidth(entity.getPanelWidth());
386 }
387
388 if (entity.getPanelHeight() != null) {
389 sprite.setPanelHeight(entity.getPanelHeight());
390 }
391
392 super.edit(sprite);
393 }
394
395 /**
396 * Find the sprite with a specified id or null
397 *
398 * @param id provided sprite id
399 * @return the sprite with the selected id or null
400 */
401 private Sprite findId(Long id) {
402 List<Sprite> sprites = super.findAll();
403 Sprite found = null;
404 for (Sprite sprite : sprites) {
405 if (Objects.equals(sprite.getId(), id)) {
406 found = sprite;
407 return found;
408 }
409 }
410 return found;
411 }
412
413 }
414