001package org.maxur.perfmodel.backend.rest.resources; 002 003 004import org.jsondoc.core.annotation.*; 005import org.jsondoc.core.pojo.ApiVerb; 006import org.maxur.perfmodel.backend.domain.ConflictException; 007import org.maxur.perfmodel.backend.domain.Project; 008import org.maxur.perfmodel.backend.domain.Repository; 009import org.maxur.perfmodel.backend.rest.dto.ProjectDto; 010import org.slf4j.Logger; 011import org.slf4j.LoggerFactory; 012 013import javax.inject.Inject; 014import javax.ws.rs.*; 015import javax.ws.rs.core.MediaType; 016import javax.ws.rs.core.Response; 017import java.util.Collection; 018import java.util.Optional; 019 020import static com.google.common.base.Strings.isNullOrEmpty; 021import static java.lang.String.format; 022import static org.maxur.perfmodel.backend.rest.WebException.*; 023import static org.maxur.perfmodel.backend.rest.dto.ProjectDto.dto; 024import static org.maxur.perfmodel.backend.rest.dto.ProjectDto.dtoList; 025 026 027/** 028 * @author Maxim Yunusov 029 * @version 1.0 01.09.13 030 */ 031@Path("/{a:project}") 032@Api(name = "Project Resource", description = "Methods for managing Project") 033@ApiVersion(since = "1.0") 034public class ProjectResource { 035 036 private static final String PROJECT_IS_NOT_SAVED = "Project is not saved"; 037 038 private static final Logger LOGGER = LoggerFactory.getLogger(ProjectResource.class); 039 040 @Inject 041 private Repository<Project> repository; 042 043 @GET 044 @Produces(MediaType.APPLICATION_JSON) 045 @ApiMethod( 046 path = "/project", 047 verb = ApiVerb.GET, 048 description = "Gets all projects", 049 produces = { MediaType.APPLICATION_JSON }, 050 responsestatuscode = "200 - OK" 051 ) 052 @ApiErrors(apierrors={ 053 @ApiError(code="500", description="Application critical error") 054 }) 055 @ApiResponseObject 056 public Collection<ProjectDto> findAll() { 057 return dtoList(repository.findAll()); 058 } 059 060 @GET 061 @Path("/{id}") 062 @Produces(MediaType.APPLICATION_JSON) 063 @ApiMethod( 064 path = "/project/{id}", 065 verb = ApiVerb.GET, 066 description = "Get the project by it's identifier", 067 produces = { MediaType.APPLICATION_JSON }, 068 responsestatuscode = "200 - OK" 069 ) 070 @ApiErrors(apierrors={ 071 @ApiError(code="400", description="Bad request"), 072 @ApiError(code="404", description="Project not found"), 073 @ApiError(code="500", description="Application critical error") 074 }) 075 @ApiResponseObject 076 public ProjectDto load( 077 @ApiPathParam(name = "id", description = "The project identifier") 078 @PathParam("id") String id 079 ) { 080 checkIdIsNotNull(id); 081 final Optional<Project> result = repository.get(id); 082 checkResult(id, result); 083 return dto(result.get()); 084 } 085 086 @DELETE 087 @Path("/{id}") 088 @Produces(MediaType.APPLICATION_JSON) 089 @ApiMethod( 090 path = "/project/{id}", 091 verb = ApiVerb.DELETE, 092 description = "Delete the project by it's identifier", 093 produces = { MediaType.APPLICATION_JSON }, 094 responsestatuscode = "200 - OK" 095 ) 096 @ApiErrors(apierrors={ 097 @ApiError(code="400", description="Bad request"), 098 @ApiError(code="404", description="Project not found"), 099 @ApiError(code="500", description="Application critical error") 100 }) 101 @ApiResponseObject 102 public ProjectDto delete( 103 @ApiPathParam(name = "id", description = "The project identifier") 104 @PathParam("id") String id 105 ) { 106 checkIdIsNotNull(id); 107 final Optional<Project> result = repository.remove(id); 108 checkResult(id, result); 109 return dto(result.get()); 110 } 111 112 @POST 113 @Consumes(MediaType.APPLICATION_JSON) 114 @Produces(MediaType.APPLICATION_JSON) 115 @ApiMethod( 116 path = "/project", 117 verb = ApiVerb.POST, 118 description = "Create new project version by project's identifier", 119 produces = { MediaType.APPLICATION_JSON }, 120 consumes = { MediaType.APPLICATION_JSON }, 121 responsestatuscode = "201 - Created" 122 ) 123 @ApiErrors(apierrors={ 124 @ApiError(code="400", description="Bad request"), 125 @ApiError(code="404", description="Project not found"), 126 @ApiError(code="500", description="Application critical error") 127 }) 128 @ApiResponseObject 129 public Response create( 130 @ApiBodyObject final ProjectDto dto 131 ) { 132 try { 133 final Project project = dto.assemble(); 134 checkIdIsNotNull(dto.getId()); 135 final Optional<Project> result = repository.add(project); 136 return created(result.get()); 137 } catch (NumberFormatException e) { 138 LOGGER.error(PROJECT_IS_NOT_SAVED, e); 139 throw badRequestException(PROJECT_IS_NOT_SAVED, e.getMessage()); 140 } catch (ConflictException e) { 141 LOGGER.error(format("%s: %s", PROJECT_IS_NOT_SAVED, e.getMessage())); 142 throw conflictException(PROJECT_IS_NOT_SAVED, e.getMessage()); 143 } 144 } 145 146 @PUT 147 @Path("/{id}") 148 @Consumes(MediaType.APPLICATION_JSON) 149 @Produces(MediaType.APPLICATION_JSON) 150 @ApiMethod( 151 path = "/project/{id}", 152 verb = ApiVerb.PUT, 153 description = "Create new project version by project's identifier", 154 produces = { MediaType.APPLICATION_JSON }, 155 consumes = { MediaType.APPLICATION_JSON }, 156 responsestatuscode = "200 - OK" 157 ) 158 @ApiErrors(apierrors={ 159 @ApiError(code="400", description="Bad request"), 160 @ApiError(code="404", description="Project not found"), 161 @ApiError(code="500", description="Application critical error") 162 }) 163 @ApiResponseObject 164 public ProjectDto update( 165 @ApiPathParam(name = "id", description = "The project identifier") 166 @PathParam("id") String id, 167 @ApiBodyObject final ProjectDto dto 168 ) { 169 try { 170 checkIdIsNotNull(id); 171 final Project project = dto.assemble(); 172 final Optional<Project> result = repository.amend(project); 173 checkResult(id, result); 174 return dto(result.get()); 175 } catch (NumberFormatException e) { 176 LOGGER.error(PROJECT_IS_NOT_SAVED, e); 177 throw badRequestException(PROJECT_IS_NOT_SAVED, e.getMessage()); 178 } catch (ConflictException e) { 179 LOGGER.error(format("%s: %s", PROJECT_IS_NOT_SAVED, e.getMessage())); 180 throw conflictException(PROJECT_IS_NOT_SAVED, e.getMessage()); 181 } 182 } 183 184 private Response created(final Project result) { 185 return Response.status(Response.Status.CREATED).entity(dto(result)).build(); 186 } 187 188 private void checkIdIsNotNull(final String id) { 189 if (isNullOrEmpty(id)) { 190 final String msg = "Bad get request. 'Id' must not be null"; 191 LOGGER.error(msg); 192 throw notFoundException(msg); 193 } 194 } 195 196 private void checkResult(final String id, final Optional<Project> result) { 197 if (!result.isPresent()) { 198 final String msg = format("Project '%s' is not founded", id); 199 LOGGER.error(msg); 200 throw notFoundException(msg); 201 } 202 } 203 204}