Skip to content

Commit 773ea55

Browse files
committed
Refactor code into a utility class. Set list hard limit to 100 records.
1 parent 696988c commit 773ea55

File tree

5 files changed

+274
-92
lines changed

5 files changed

+274
-92
lines changed

src/main/java/com/parallax/server/blocklyprop/db/dao/impl/ProjectDaoImpl.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -571,6 +571,13 @@ public boolean deleteProject(Long idProject) {
571571
* @param code
572572
*
573573
* @return
574+
* Returns the specified project record, otherwise it returns a null if
575+
* the current user does not own the project and the project is not shared
576+
* or public, or the requested project record was not found.
577+
*
578+
* @implNote This method will actually create a new project record based on the
579+
* existing project under specific conditions. Since this is an update record method,
580+
* the creation of a new project my be unexpected at higher layers of the application.
574581
*/
575582
@Override
576583
public ProjectRecord updateProjectCode(Long idProject, String code) {

src/main/java/com/parallax/server/blocklyprop/rest/RestProject.java

Lines changed: 143 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,24 @@
11
/*
2-
* To change this license header, choose License Headers in Project Properties.
3-
* To change this template file, choose Tools | Templates
4-
* and open the template in the editor.
2+
* Copyright (c) 2019 Parallax Inc.
3+
*
4+
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software
5+
* and associated documentation files (the “Software”), to deal in the Software without
6+
* restriction, including without limitation the rights to use, copy, modify, merge, publish,
7+
* distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the
8+
* Software is furnished to do so, subject to the following conditions:
9+
*
10+
* The above copyright notice and this permission notice shall be included in all copies or
11+
* substantial portions of the Software.
12+
*
13+
* THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
19+
* SOFTWARE.
520
*/
21+
622
package com.parallax.server.blocklyprop.rest;
723

824
import com.cuubez.visualizer.annotation.Detail;
@@ -16,6 +32,7 @@
1632
import com.google.inject.Inject;
1733
import com.parallax.server.blocklyprop.TableOrder;
1834
import com.parallax.server.blocklyprop.TableSort;
35+
import com.parallax.server.blocklyprop.utils.RestProjectUtils;
1936
import com.parallax.server.blocklyprop.converter.ProjectConverter;
2037
import com.parallax.server.blocklyprop.db.enums.ProjectType;
2138
import com.parallax.server.blocklyprop.db.generated.tables.records.ProjectRecord;
@@ -31,6 +48,7 @@
3148
import javax.ws.rs.QueryParam;
3249
import javax.ws.rs.core.Response;
3350
import org.apache.shiro.authz.AuthorizationException;
51+
import org.jetbrains.annotations.NotNull;
3452
import org.slf4j.Logger;
3553
import org.slf4j.LoggerFactory;
3654

@@ -45,19 +63,36 @@
4563
@Group(name = "/project", title = "Project management")
4664
@HttpCode("500>Internal Server Error,200>Success Response")
4765
public class RestProject {
48-
// Get a logger instance
66+
67+
/**
68+
* Get a logger instance
69+
*/
4970
private static final Logger LOG = LoggerFactory.getLogger(RestProject.class);
5071

51-
// Connector to project services object
72+
73+
/**
74+
* Connector to project services object
75+
*/
5276
private ProjectService projectService;
5377

54-
// Connector to project converter object
78+
79+
/**
80+
* Connector to project converter object
81+
*/
5582
private ProjectConverter projectConverter;
5683

5784

85+
/**
86+
* Limit the number of records that can be returned in list functions
87+
*/
88+
final int REQUEST_LIMIT = 100;
89+
90+
5891
/**
5992
* Connect to the project service object
60-
* @param projectService
93+
*
94+
* @param projectService
95+
* An instance of the ProjectService object
6196
*/
6297
@Inject
6398
public void setProjectService(ProjectService projectService) {
@@ -67,7 +102,9 @@ public void setProjectService(ProjectService projectService) {
67102

68103
/**
69104
* Connect to the project converter object
70-
* @param projectConverter
105+
*
106+
* @param projectConverter
107+
* An instance of the ProjectConverter object
71108
*/
72109
@Inject
73110
public void setProjectConverter(ProjectConverter projectConverter) {
@@ -77,13 +114,22 @@ public void setProjectConverter(ProjectConverter projectConverter) {
77114

78115
/**
79116
* Return a list of projects owned by the currently authenticated user.
80-
*
117+
*
81118
* @param sort
119+
* The project field used to evaluate the sort
120+
*
82121
* @param order
122+
* Specify the sort order - ascending or descending
123+
*
83124
* @param limit
125+
* Specify the maximum number of rows to return
126+
*
84127
* @param offset
85-
*
86-
* @return JSON formatted list of project details
128+
* Specify the beginning row to return
129+
*
130+
* @return
131+
* Return a response object that contains either the data requested
132+
* or a JSON string containing the error details
87133
*/
88134
@GET
89135
@Path("/list")
@@ -95,49 +141,62 @@ public Response get(
95141
@QueryParam("order") @ParameterDetail("Sort order") @M() TableOrder order,
96142
@QueryParam("limit") @ParameterDetail("Number of rows to return") @M() Integer limit,
97143
@QueryParam("offset") @ParameterDetail("Offset to next row returned") @M() Integer offset) {
98-
99-
LOG.info("REST:/rest/project/list/ Get request received");
100-
144+
145+
String endPoint = "REST:/rest/project/list/";
146+
147+
LOG.info("{} Get request received", endPoint);
148+
RestProjectUtils restProjectUtils = new RestProjectUtils();
149+
101150
try {
102151
// Get the logged in user id for the current session
103152
Long idUser = BlocklyPropSecurityUtils.getCurrentUserId();
104-
153+
154+
// Return FORBIDDEN if we cannot identify the current user. This could
155+
// mean that the user is not logged in or that some underlying issue
156+
// is causing the authentication system to fail.
105157
if (idUser == 0) {
106158
// Current session is not logged in.
107-
return Response.status(Response.Status.NOT_FOUND).build();
159+
return Response.status(Response.Status.FORBIDDEN).build();
108160
}
109161

110162
//Sanity checks - is the request reasonable
111-
if (sort == null)
112-
sort = TableSort.modified;
113-
114-
if (order == null)
115-
order = TableOrder.asc;
116-
117-
if (limit == null)
118-
limit = 20;
119-
120-
if (offset == null)
121-
offset = 0;
122163

123-
List<ProjectRecord> userProjects =
124-
projectService.getUserProjects(idUser, sort, order, limit, offset);
125-
126-
int projectCount = projectService.countUserProjects(idUser);
164+
// Sort flag evaluation
165+
if (!restProjectUtils.ValidateSortType(sort)) {
166+
LOG.warn("{} Sort parameter failed", endPoint);
167+
return Response.status(Response.Status.NOT_ACCEPTABLE).build();
168+
}
169+
170+
// Sort order evaluation
171+
if (!restProjectUtils.ValidateSortOrder(order)) {
172+
LOG.warn("{} Sort order parameter failed", endPoint);
173+
return Response.status(Response.Status.NOT_ACCEPTABLE).build();
174+
}
127175

128-
JsonObject result = new JsonObject();
129-
JsonArray jsonProjects = new JsonArray();
176+
// Limit result set value
177+
if ( (limit == null) || (limit > REQUEST_LIMIT)) {
178+
LOG.info("{} Limit throttle to {} entries", endPoint, REQUEST_LIMIT);
179+
limit = REQUEST_LIMIT;
180+
}
130181

131-
// Loop through user projects and build a Json array
132-
for (ProjectRecord project : userProjects) {
133-
jsonProjects.add(projectConverter.toListJson(project));
182+
// Check ofset from the beginning of the record set
183+
if ((offset == null) || (offset < 0)) {
184+
offset = 0;
134185
}
135186

136-
// Add payload details
137-
result.add("rows", jsonProjects);
138-
result.addProperty("total", projectCount);
187+
// Obtain a list of the user's projects
188+
List<ProjectRecord> userProjects = projectService.getUserProjects(idUser, sort, order, limit, offset);
139189

140-
return Response.ok(result.toString()).build();
190+
// Tell the caller that there is nothing to see here
191+
if (userProjects == null) {
192+
return Response.status(Response.Status.NOT_FOUND).build();
193+
}
194+
195+
return Response.ok(
196+
returnProjectsJson(
197+
userProjects,
198+
projectService.countUserProjects(idUser)))
199+
.build();
141200
}
142201

143202
catch(Exception ex) {
@@ -152,7 +211,11 @@ public Response get(
152211
* Retreive a project based on the supplied project ID
153212
*
154213
* @param idProject
214+
* The project key ID
215+
*
155216
* @return
217+
* Return a string representation of the project in Json format if successful, otherwise
218+
* return a Json string containing an error status message
156219
*/
157220
@GET
158221
@Path("/get/{id}")
@@ -197,7 +260,10 @@ public Response get(@PathParam("id") @ParameterDetail("Project identifier") Long
197260
*
198261
* @param idProject
199262
* @param code
200-
* @return
263+
* @return
264+
* Returns a Json string containing the project details if the update was successful
265+
* or an error message upon failure
266+
*
201267
*/
202268
@POST
203269
@Path("/code")
@@ -211,12 +277,19 @@ public Response saveProjectCode(
211277
LOG.info("REST:/rest/project/code/ POST request received for project '{}'", idProject);
212278

213279
try {
280+
281+
/* WARNING:
282+
* =================================================================================
283+
* This call can create a new project record under specific circumstances and does
284+
* not appear to provide any notification that this has occurred.
285+
* =================================================================================
286+
*/
214287
ProjectRecord savedProject = projectService.saveProjectCode(idProject, code);
288+
215289
LOG.debug("Code for project {} has been saved", idProject);
216290

217291
JsonObject result = projectConverter.toJson(savedProject,false);
218292

219-
LOG.debug("Returning JSON: {}", result);
220293

221294
result.addProperty("success", true);
222295

@@ -332,4 +405,32 @@ public Response saveProject(
332405
return Response.status(Response.Status.INTERNAL_SERVER_ERROR).build();
333406
}
334407
}
408+
409+
/**
410+
* Iterate a list of projects into an array of Json objects
411+
*
412+
* @param projects
413+
* A List of ProjectRecord objects
414+
*
415+
* @param projectCount
416+
* The number of projects available. This may not be the same value as
417+
* the number of records contained in the passed list of ProjectRecords.
418+
*
419+
* @return
420+
* A String containing the array of the converted Json objects
421+
*/
422+
private String returnProjectsJson(@NotNull List<ProjectRecord> projects, int projectCount) {
423+
JsonObject result = new JsonObject();
424+
JsonArray jsonProjects = new JsonArray();
425+
426+
for (ProjectRecord project : projects) {
427+
jsonProjects.add(projectConverter.toListJson(project));
428+
}
429+
430+
result.add("rows", jsonProjects);
431+
result.addProperty("total", projectCount);
432+
433+
return result.toString();
434+
}
435+
335436
}

0 commit comments

Comments
 (0)