/* * Copyright 2013- Yan Bonnel * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package fr.ybonnel.simpleweb4j.handlers.resource; import fr.ybonnel.simpleweb4j.exception.HttpErrorException; import fr.ybonnel.simpleweb4j.handlers.Response; import fr.ybonnel.simpleweb4j.handlers.Route; import fr.ybonnel.simpleweb4j.handlers.RouteParameters; import javax.servlet.http.HttpServletResponse; import java.util.Collection; /** * Class to represent a REST Resource. * @see fr.ybonnel.simpleweb4j.SimpleWeb4j#resource(RestResource) * @param <T> Type of the resource. */ public abstract class RestResource<T> { /** * Class of the resource. */ private Class<T> resourceType; /** * Route of the resource. */ private String resourceRoute; /** * Constructor. * @param resourceRoute route of the resource. * @param resourceType class of the resource. */ protected RestResource(String resourceRoute, Class<T> resourceType) { this.resourceType = resourceType; this.resourceRoute = resourceRoute; initRoutes(); } /** * Method to implement for the get by id. * This method will be invoked when a GET on <code>/<resourceRoute>/<id></code> is detected. * @param id id of the resource. * @return the resource. * @throws HttpErrorException any error you want to throw, for example, you can throw a new HttpErrorException(404) if resource is not found. */ public abstract T getById(String id) throws HttpErrorException; /** * Method to implement for the get all. * This method will be invoked when a GET on <code>/<resourceRoute></code> is detected. * @return the list of all resources. * @throws HttpErrorException any error you want to throw, for example, * you can throw a new HttpErrorException(204) if there is no resources (no content). */ public abstract Collection<T> getAll() throws HttpErrorException; /** * Method to implement for the update method. * This method will be invoked when a PUT on <code>/<resourceRoute>/<id></code> is detected. * @param id the id of the resource to update. * @param resource the resource. * @throws HttpErrorException any error you want to throw, for example, you can throw a new HttpErrorException(404) if resource is not found. */ public abstract void update(String id, T resource) throws HttpErrorException; /** * Method to implement to create of a resource. * This method will be invoked when a POST on <code>/<resourceRoute></code> is detected. * @param resource resource to create. * @return result of creation. * @throws HttpErrorException any error you want to throw, for example, * you can throw a new HttpErrorException(400) if a required attribute is missing (bad request). */ public abstract T create(T resource) throws HttpErrorException; /** * Method to implement to delete a resource. * This method will be invoked when a DELETE on <code>/<resourceRoute>/<id></code> is detected. * @param id id of the resource to delete. * @throws HttpErrorException any error you want to throw, for example, you can throw a new HttpErrorException(404) if resource is not found. */ public abstract void delete(String id) throws HttpErrorException; /** * Route for getById. */ private Route<String, T> routeGetById; /** * Route for getAll. */ private Route<Void, Collection<T>> routeGetAll; /** * Route for create. */ private Route<T, T> routeCreate; /** * Route for delete. */ private Route<Void, Void> routeDelete; /** * Route for update. */ private Route<T, Void> routeUpdate; /** * Initialise the routes. */ private void initRoutes() { routeGetById = new Route<String, T>(resourceRoute + "/:id", String.class) { @Override public Response<T> handle(String param, RouteParameters routeParams) throws HttpErrorException { String id = routeParams.getParam("id"); return new Response<>(getById(id)); } }; routeCreate = new Route<T, T>(resourceRoute, resourceType) { @Override public Response<T> handle(T param, RouteParameters routeParams) throws HttpErrorException { return new Response<>(create(param), HttpServletResponse.SC_CREATED); } }; routeDelete = new Route<Void, Void>(resourceRoute + "/:id", Void.class) { @Override public Response<Void> handle(Void param, RouteParameters routeParams) throws HttpErrorException { delete(routeParams.getParam("id")); return new Response<>(null); } }; routeUpdate = new Route<T, Void>(resourceRoute + "/:id", resourceType) { @Override public Response<Void> handle(T param, RouteParameters routeParams) throws HttpErrorException { update(routeParams.getParam("id"), param); return new Response<>(null); } }; routeGetAll = new Route<Void, Collection<T>>(resourceRoute, Void.class) { @Override public Response<Collection<T>> handle(Void param, RouteParameters routeParams) throws HttpErrorException { return new Response<>(getAll()); } }; } /** * Get the route of getById (don't use it directly). * @return the route of getById. */ public Route<String, T> routeGetById() { return routeGetById; } /** * Get the route of create (don't use it directly). * @return the route of create. */ public Route<T, T> routeCreate() { return routeCreate; } /** * Get the route of delete (don't use it directly). * @return the route of delete. */ public Route<Void, Void> routeDelete() { return routeDelete; } /** * Get the route of update (don't use it directly). * @return the route of update. */ public Route<T, Void> routeUpdate() { return routeUpdate; } /** * Get the route of getAll (don't use it directly). * @return the route of getAll. */ public Route<Void, Collection<T>> routeGetAll() { return routeGetAll; } }