View Javadoc
1   package ejava.examples.ejbwar.inventory.rs;
2   
3   import java.net.URI;
4   
5   import javax.inject.Inject;
6   import javax.json.bind.annotation.JsonbAnnotation;
7   import javax.json.bind.annotation.JsonbProperty;
8   import javax.ws.rs.Consumes;
9   import javax.ws.rs.DELETE;
10  import javax.ws.rs.DefaultValue;
11  import javax.ws.rs.FormParam;
12  import javax.ws.rs.GET;
13  import javax.ws.rs.POST;
14  import javax.ws.rs.PUT;
15  import javax.ws.rs.Path;
16  import javax.ws.rs.PathParam;
17  import javax.ws.rs.Produces;
18  import javax.ws.rs.QueryParam;
19  import javax.ws.rs.core.Context;
20  import javax.ws.rs.core.MediaType;
21  import javax.ws.rs.core.Request;
22  import javax.ws.rs.core.Response;
23  import javax.ws.rs.core.UriBuilder;
24  import javax.ws.rs.core.UriInfo;
25  
26  import org.slf4j.Logger;
27  import org.slf4j.LoggerFactory;
28  
29  import ejava.examples.ejbwar.inventory.bo.Product;
30  import ejava.examples.ejbwar.inventory.bo.Products;
31  import ejava.examples.ejbwar.inventory.ejb.InventoryMgmtEJB;
32  
33  /**
34   * This class implements the JAX-RS interface for the injected inventory 
35   * management EJB logic.
36   */
37  @Path("/products")
38  public class ProductsResource {
39  	private static final Logger logger = LoggerFactory.getLogger(ProductsResource.class);
40  	@Inject
41  	private InventoryMgmtEJB ejb;
42  	@Context
43  	private Request request;
44  	@Context 
45  	private UriInfo uriInfo;
46  
47  	/**
48  	 * Creates a product
49  	 * @param product
50  	 * @param category
51  	 * @return
52  	 */
53  	@POST @Path("")
54  	@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
55  	@Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
56  	@JsonbAnnotation  //helps trigger JSON-B response marshaling when class also JAXB
57  	public Response createProduct(
58  			@FormParam("name") String name,
59  			@FormParam("quantity") Integer quantity,
60  			@FormParam("price") Double price,
61  			@FormParam("category") String category) {
62  		logger.debug("{} {}", request.getMethod(), uriInfo.getAbsolutePath());
63  
64  		try {
65  			Product product = new Product(name, quantity, price);
66  			Product p = ejb.addProduct(product, category);
67              logger.info("returning created pojo product={}", p);
68  			//build URI that can be used to get this product
69  			URI uri = UriBuilder.fromUri(uriInfo.getAbsolutePath())
70  						.path(ProductsResource.class, "getProduct")
71  						.build(p.getId());
72  			return Response.created(uri)
73  					.entity(p)
74    				    .tag("" + p.getVersion())
75  				    .build();
76  		} catch (Exception ex) {
77  			return ResourceHelper.serverError(logger, "creating product", ex).build();
78  		}
79  	}
80  	
81  	/**
82  	 * Returns a specific product
83  	 * @param id
84  	 * @return
85  	 */
86  	@GET @Path("{id}")
87      @Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
88  	@JsonbAnnotation  //helps trigger JSON-B response marshaling when class also JAXB
89  	public Response getProduct(@PathParam("id")int id) {
90  		logger.debug("{} {}", request.getMethod(), uriInfo.getAbsolutePath());
91  
92  		try {
93  			Product product = ejb.getProduct(id);
94  			if (product != null) {
95  				return Response.ok(product)
96  						.tag("" + product.getVersion())
97  						.build();
98  			}
99  			else {
100 				return Response.status(Response.Status.NOT_FOUND)
101 						.entity(String.format("unable to locate product %d", id))
102 						.type(MediaType.TEXT_PLAIN)
103 						.build();
104 			}
105 		} catch (Exception ex) {
106 			return ResourceHelper.serverError(logger, "getting product", ex).build();
107 		}
108 	}
109 
110 	/**
111 	 * Updates a product with the values of the object passed in
112 	 * @param id
113 	 * @param product
114 	 * @return updated product if successful
115 	 */
116 	@PUT @Path("{id}")
117     @Consumes({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
118     @Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
119 	@JsonbAnnotation  //helps trigger JSON-B response marshaling when DTO also JAXB
120 	public Response updateProduct(@PathParam("id") int id, 
121 	        @JsonbProperty Product product  //annotation helps trigger JSON-B request demarshaling when DTO also JAXB
122 	     ) {
123 		logger.debug("{} {}", request.getMethod(), uriInfo.getAbsolutePath());
124 
125 		try {
126 			Product p = ejb.updateProduct(product);
127 			logger.info("updated pojo product={}", p);
128 			return Response.ok(p)
129 					.tag("" + p.getVersion())
130 					.build();
131 		} catch (Exception ex) {
132 			return ResourceHelper.serverError(logger, "update product", ex).build();
133 		}
134 	}
135 
136 	/* for debugging
137 	@PUT @Path("{id}")
138     @Consumes({MediaType.APPLICATION_JSON})
139     @Produces({MediaType.APPLICATION_JSON})
140     public Response updateProductJSON(@PathParam("id") int id, String payload) {
141         logger.debug("{} {}", request.getMethod(), uriInfo.getAbsolutePath());
142 
143         try {
144             Product product = JSONUtils.unmarshal(payload, Product.class);
145             Product p = ejb.updateProduct(product);
146             String result = JSONUtils.marshal(p);
147             return Response.ok(result)
148                     .tag("" + p.getVersion())
149                     .build();
150         } catch (Exception ex) {
151             return ResourceHelper.serverError(logger, "update product", ex).build();
152         }
153     }
154     */
155 
156 	/**
157 	 * Deletes the product identified.
158 	 * @param id
159 	 * @return
160 	 */
161 	@DELETE @Path("{id}")
162 	public Response deleteProduct(@PathParam("id")int id) {
163 		logger.debug("{} {}", request.getMethod(), uriInfo.getAbsolutePath());
164 
165 		try {
166 			Product product = ejb.getProduct(id);
167 			if (product != null) {
168 				try {
169 					ejb.deleteProduct(product);
170 					return Response.noContent().build();
171 				} catch (Exception ex) {
172 					return ResourceHelper.serverError(logger, "deleting product", ex).build();
173 				}
174 			}
175 			else {
176 				return Response.status(Response.Status.NOT_FOUND)
177 						.entity(String.format("unable to locate product %d", id))
178 						.type(MediaType.TEXT_PLAIN)
179 						.build();
180 			}
181 		} catch (Exception ex) {
182 			return ResourceHelper.serverError(logger, "getting product", ex).build();
183 		}
184 	}
185 
186 	/**
187 	 * Returns a simple list of products that match provided name
188 	 * @param name
189 	 * @return
190 	 */
191 	@GET @Path("")
192     @Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
193 	@JsonbAnnotation  //helps trigger JSON-B response marshaling when class also JAXB
194 	public Response findProductsByName(
195 			@QueryParam("name")String name,
196 			@QueryParam("offset") @DefaultValue("0") int offset,
197 			@QueryParam("limit") @DefaultValue("0") int limit) {
198 		logger.debug("{} {}", request.getMethod(), uriInfo.getAbsolutePath());
199 
200 		try {
201 			Products products = ejb.findProductByName(name, offset, limit);
202 			return Response.ok(products)
203 					.build();
204 		} catch (Exception ex) {
205 			return ResourceHelper.serverError(logger, "getting products", ex).build();
206 		}
207 	}	
208 }