1 package org.kuali.kpme.edo.item.web;
2
3 import java.io.File;
4 import java.io.FileOutputStream;
5 import java.math.BigDecimal;
6 import java.util.ArrayList;
7 import java.util.Collection;
8 import java.util.Collections;
9 import java.util.List;
10 import java.util.Map;
11
12 import javax.servlet.http.HttpServletRequest;
13 import javax.servlet.http.HttpServletResponse;
14 import javax.servlet.http.HttpSession;
15
16 import org.apache.commons.collections.CollectionUtils;
17 import org.apache.commons.fileupload.disk.DiskFileItemFactory;
18 import org.apache.commons.fileupload.servlet.ServletFileUpload;
19 import org.apache.commons.lang.StringUtils;
20 import org.apache.log4j.Logger;
21 import org.apache.struts.action.ActionForm;
22 import org.apache.struts.action.ActionForward;
23 import org.apache.struts.action.ActionMapping;
24 import org.apache.struts.upload.FormFile;
25 import org.joda.time.DateTime;
26 import org.joda.time.LocalDate;
27 import org.kuali.kpme.edo.api.dossier.EdoDossierDocumentInfo;
28 import org.kuali.kpme.edo.api.item.EdoItem;
29 import org.kuali.kpme.edo.api.reviewlayerdef.EdoReviewLayerDefinition;
30 import org.kuali.kpme.edo.base.web.EdoAction;
31 import org.kuali.kpme.edo.candidate.EdoSelectedCandidate;
32 import org.kuali.kpme.edo.item.EdoItemTracker;
33 import org.kuali.kpme.edo.service.EdoServiceLocator;
34 import org.kuali.kpme.edo.util.EdoConstants;
35 import org.kuali.kpme.edo.util.EdoContext;
36 import org.kuali.kpme.edo.util.EdoRule;
37 import org.kuali.kpme.edo.util.EdoUtils;
38 import org.kuali.kpme.edo.util.QueryParams;
39 import org.kuali.rice.core.api.config.property.Config;
40 import org.kuali.rice.core.api.config.property.ConfigContext;
41 import org.kuali.rice.krad.util.GlobalVariables;
42 import org.kuali.rice.krad.util.MessageMap;
43
44
45
46
47
48
49
50
51
52 public class EdoSecondUnitAction extends EdoAction {
53 protected Config config;
54 static final Logger LOG = Logger.getLogger(EdoSecondUnitAction.class);
55
56 @Override
57 public ActionForward execute(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
58
59 int currentTreeNodeID;
60 List<EdoItem> itemList;
61 String itemListJSON = "";
62 EdoSecondUnitForm reviewLetterForm = (EdoSecondUnitForm) form;
63
64 EdoSelectedCandidate selectedCandidate = (EdoSelectedCandidate) request.getSession().getAttribute("selectedCandidate");
65 String workflowId = selectedCandidate.getDossierWorkflowId();
66 Map<String, EdoReviewLayerDefinition> lvlMap = EdoServiceLocator.getEdoReviewLayerDefinitionService().buildReviewLevelMap( EdoServiceLocator.getEdoReviewLayerDefinitionService().getReviewLayerDefinitions(workflowId) );
67
68
69
70 String dossierCurrentRouteLevelName = EdoServiceLocator.getEdoDossierDocumentInfoService().getCurrentRouteLevelName(selectedCandidate.getCandidateDossierID().toString());
71
72
73 String dossierCurrentReviewLevel = EdoServiceLocator.getEdoReviewLayerDefinitionService().buildReviewLevelByRouteMap(EdoServiceLocator.getEdoReviewLayerDefinitionService().getReviewLayerDefinitions(workflowId)).get(dossierCurrentRouteLevelName);
74
75
76
77 BigDecimal highestAuthorizedViewReviewLevel = BigDecimal.ZERO;
78 List<BigDecimal> authorizedViewReviewLetterLevels = EdoContext.getAuthorizedViewReviewLetterLevels();
79
80 if (CollectionUtils.isNotEmpty(authorizedViewReviewLetterLevels)) {
81 highestAuthorizedViewReviewLevel = Collections.max(authorizedViewReviewLetterLevels);
82 }
83
84
85 BigDecimal highestAuthorizedUploadReviewLevel = BigDecimal.ZERO;
86 Collection<EdoReviewLayerDefinition> authorizedUploadLevelDefs = reviewLetterForm.getLayerList();
87 List<BigDecimal> authorizedUploadReviewLetterLevels = EdoContext.getAuthorizedUploadReviewLetterLevels();
88
89 for ( BigDecimal lvl : authorizedUploadReviewLetterLevels ) {
90 authorizedUploadLevelDefs.add(lvlMap.get(lvl));
91 }
92 if (CollectionUtils.isNotEmpty(authorizedUploadReviewLetterLevels)) {
93 highestAuthorizedUploadReviewLevel = Collections.max(authorizedUploadReviewLetterLevels);
94 }
95
96 request.setAttribute("authorizedUploadReviewLevels", authorizedUploadLevelDefs);
97 request.setAttribute("authorizedEditReviewLevels", authorizedUploadReviewLetterLevels.toString());
98 request.setAttribute("highestAuthorizedUploadLevel", highestAuthorizedUploadReviewLevel);
99 request.setAttribute("currentDossierLevel", 0);
100 if (dossierCurrentReviewLevel != null) {
101 request.setAttribute("currentDossierLevel", dossierCurrentReviewLevel);
102 }
103
104
105 HttpSession ssn = request.getSession();
106
107 if (request.getParameterMap().containsKey("nid")) {
108 ssn.setAttribute("nid", request.getParameter("nid"));
109 } else if (request.getParameterMap().containsKey("nidFwd")) {
110 ssn.setAttribute("nid", request.getParameter("nidFwd"));
111 }
112 request.setAttribute("nidFwd", ssn.getAttribute("nid"));
113
114 ssn.setAttribute("currentNodeID", Integer.parseInt(ssn.getAttribute("nid").toString().split("_")[2]));
115 currentTreeNodeID = Integer.parseInt(ssn.getAttribute("nid").toString().split("_")[2]);
116 reviewLetterForm.setChecklistItemID(currentTreeNodeID);
117
118 itemList = EdoServiceLocator.getEdoItemService().getItemList(selectedCandidate.getCandidateDossierID().toString(), currentTreeNodeID+"");
119
120
121 if (CollectionUtils.isNotEmpty(itemList)) {
122 Collections.sort(itemList);
123
124 List<EdoItem> copy = new ArrayList<EdoItem>(itemList);
125 for (EdoItem item : copy) {
126
127
128
129 String reviewLevel = EdoServiceLocator.getEdoReviewLayerDefinitionService().getReviewLayerDefinitionById(item.getEdoReviewLayerDefId()).getReviewLevel();
130 if (new BigDecimal(reviewLevel).compareTo(highestAuthorizedViewReviewLevel) < 1 ) {
131 itemListJSON = itemListJSON.concat(EdoServiceLocator.getEdoItemService().getItemJSONString(item) + ",");
132 } else {
133 itemList.remove(item);
134 }
135 }
136 }
137 reviewLetterForm.setItemList(itemList);
138 request.setAttribute("itemlistJSON", itemListJSON);
139
140 request.setAttribute("hasSupplementalWaiting", false);
141 request.setAttribute("hasUploadReviewLetterSupplemental", false);
142
143
144 EdoDossierDocumentInfo documentHeader = EdoServiceLocator.getEdoDossierDocumentInfoService().getEdoDossierDocumentInfoByDossierId(selectedCandidate.getCandidateDossierID().toString());
145
146 if (documentHeader != null) {
147 List<EdoDossierDocumentInfo> suppDocHeaders = EdoServiceLocator.getEdoDossierDocumentInfoService().getPendingSupplementalDocuments(documentHeader.getEdoDossierId());
148 if (CollectionUtils.isNotEmpty(suppDocHeaders)) {
149 boolean isWaiting = false;
150 for (EdoDossierDocumentInfo docHeader : suppDocHeaders) {
151 isWaiting = isWaiting || EdoServiceLocator.getEdoSupplementalPendingStatusService().isWaiting(docHeader.getEdoDocumentId(),EdoContext.getPrincipalId());
152 }
153 if (isWaiting) {
154 request.setAttribute("hasSupplementalWaiting", true);
155 request.setAttribute("hasUploadReviewLetterSupplemental", EdoServiceLocator.getAuthorizationService().isAuthorizedToUploadReviewLetter_W(EdoContext.getPrincipalId()));
156 }
157 }
158 }
159
160 request.setAttribute("isRoutedAsReconsiderDocument", false);
161 if (EdoServiceLocator.getEdoDossierService().isRoutedAsReconsiderDocument(selectedCandidate.getCandidateDossierID().intValue())) {
162 request.setAttribute("isRoutedAsReconsiderDocument", true);
163 }
164
165
166 request.setAttribute("nodeID", currentTreeNodeID );
167 request.setAttribute("itemName", "Review Letters" );
168 request.setAttribute("itemDescription", "Review letters");
169 request.setAttribute("checklistItemID", currentTreeNodeID );
170 request.setAttribute("selectedCandidate", selectedCandidate);
171
172 String path = request.getRequestURL().toString().replace(request.getServletPath(), "").concat("/");
173 request.setAttribute("requestPath", path);
174
175 return super.execute(mapping, reviewLetterForm, request, response);
176 }
177
178 public ActionForward postFile(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
179
180 EdoSecondUnitForm edoReviewLetterForm = (EdoSecondUnitForm)form;
181 MessageMap msgmap = GlobalVariables.getMessageMap();
182 String itemListJSON = "";
183 boolean replaceFile = false;
184 boolean isNewFile = true;
185 BigDecimal itemID = BigDecimal.ZERO;
186 String itemReviewLayerID = null;
187 LocalDate currentDate = LocalDate.now();
188 String itemTypeID = EdoServiceLocator.getEdoItemTypeService().getItemTypeId(EdoConstants.EDO_ITEM_TYPE_NAME_REVIEW_LETTER, currentDate);
189
190 FormFile uploadFile = edoReviewLetterForm.getUploadFile();
191 int checklistItemID = edoReviewLetterForm.getChecklistItemID();
192 int selectedRvwLayer = edoReviewLetterForm.getSelectedRvwLayer();
193 String uploadUsername = EdoContext.getUser().getNetworkId();
194 config = ConfigContext.getCurrentContextConfig();
195 EdoSelectedCandidate selectedCandidate = (EdoSelectedCandidate) request.getSession().getAttribute("selectedCandidate");
196
197 HttpSession ssn = request.getSession();
198 String nidParam = ssn.getAttribute("nid").toString();
199 int currentTreeNodeID = Integer.parseInt(nidParam.split("_")[2]);
200
201
202 if (request.getParameterMap().containsKey("repl")) {
203 replaceFile = Boolean.parseBoolean(request.getParameter("repl"));
204 itemID = BigDecimal.valueOf(Integer.parseInt(request.getParameter("itemID")));
205 }
206
207 EdoSelectedCandidate candidate = (EdoSelectedCandidate)request.getSession().getAttribute("selectedCandidate");
208 String candidateUsername = candidate.getCandidateUsername();
209 BigDecimal dossierID = candidate.getCandidateDossierID();
210 String workflowId = EdoServiceLocator.getEdoDossierService().getEdoDossierById(dossierID.toString()).getWorkflowId();
211
212 EdoItem.Builder item = EdoItem.Builder.create();
213
214
215 String originalItemID = null;
216
217 if (ServletFileUpload.isMultipartContent(request)) {
218 DiskFileItemFactory factory = new DiskFileItemFactory();
219 factory.setSizeThreshold(EdoConstants.FILE_UPLOAD_PARAMETERS.THRESHHOLD_SIZE);
220 factory.setRepository(new File(System.getProperty("java.io.tmpdir")));
221
222 ServletFileUpload upload = new ServletFileUpload(factory);
223 upload.setFileSizeMax(EdoConstants.FILE_UPLOAD_PARAMETERS.MAX_FILE_SIZE);
224 upload.setSizeMax(EdoConstants.FILE_UPLOAD_PARAMETERS.REQUEST_SIZE);
225
226
227 if(!EdoRule.validateFileNameLength(uploadFile)) {
228 LOG.error("File name exceeds allowed length.");
229
230 ActionForward fwd = mapping.findForward("basic");
231 return fwd;
232 }
233
234 String storeFileName = candidateUsername + "_" + uploadFile.getFileName();
235 String fileName = uploadFile.getFileName();
236 String contentType = uploadFile.getContentType();
237 int uploadSize = uploadFile.getFileSize();
238
239
240 if (uploadSize < 1) {
241 LOG.error("File size is zero.");
242 msgmap.putError(EdoConstants.ErrorKeys.ERROR_KEYS, "error.fileUpload.empty");
243 ActionForward fwd = mapping.findForward("basic");
244 return fwd;
245 }
246
247 if (contentType.contains("Content-Dispostion") || "".equals(contentType)) {
248 contentType = EdoConstants.FILE_UPLOAD_PARAMETERS.DEFAULT_MIME_TYPE;
249 }
250 String uploadPath = EdoUtils.BuildUploadPath(candidateUsername, Integer.toString(checklistItemID));
251
252 if (uploadPath == null) {
253 LOG.error("Upload path does not exist: [" + uploadPath + "]");
254 msgmap.putError(EdoConstants.ErrorKeys.ERROR_KEYS,"error.fileUpload.path");
255 LOG.error("\n\n the upload path is null. It's either the candidateUserName is null or checklistItemID is null \n\n");
256 ActionForward fwd = mapping.findForward("basic");
257 return fwd;
258 }
259
260
261 request.setAttribute("message", "Upload has been completed successfully");
262 java.util.Date date = new java.util.Date();
263 long t = date.getTime();
264 java.sql.Timestamp sqlTimestamp = new java.sql.Timestamp(t);
265
266
267 if (isNewFile) {
268 item.setActionFullDateTime(new DateTime(sqlTimestamp));
269
270 item.setEdoItemTypeId(itemTypeID);
271 item.setRouted(true);
272 item.setUserPrincipalId(uploadUsername);
273 item.setEdoDossierId(dossierID.toString());
274 item.setEdoChecklistItemId(checklistItemID+"");
275 Integer nextRowIndexNum = EdoServiceLocator.getEdoItemService().getNextRowIndexNum(checklistItemID+"", uploadUsername);
276 item.setRowIndex(nextRowIndexNum);
277
278 if (selectedRvwLayer != 0) {
279
280 Map<String, EdoReviewLayerDefinition> lvlMap = EdoServiceLocator.getEdoReviewLayerDefinitionService().buildReviewLevelMap(EdoServiceLocator.getEdoReviewLayerDefinitionService().getReviewLayerDefinitions(workflowId));
281 itemReviewLayerID = lvlMap.get(BigDecimal.valueOf(selectedRvwLayer)).getEdoReviewLayerDefinitionId();
282 item.setEdoReviewLayerDefId(itemReviewLayerID.toString());
283 }
284 }
285
286 if (replaceFile) {
287 EdoItem edoItem = EdoServiceLocator.getEdoItemService().getEdoItem(itemID.toString());
288
289
290 originalItemID = edoItem.getEdoItemId();
291 if (!deleteFileFromFS(edoItem)) {
292
293 ActionForward fwd = mapping.findForward("basic");
294 return fwd;
295 }
296 }
297
298
299 item.setFileName(fileName);
300 item.setFileLocation(uploadPath + File.separator + storeFileName);
301 item.setContentType(contentType);
302 item.setUserPrincipalId(uploadUsername);
303 item.setActionFullDateTime(new DateTime(sqlTimestamp));
304
305 if (StringUtils.isNotBlank(storeFileName)) {
306 File newFile = new File(uploadPath, storeFileName);
307 isNewFile = !newFile.exists();
308 if ( isNewFile || replaceFile ) {
309 try {
310 FileOutputStream fos = new FileOutputStream(newFile);
311 fos.write(uploadFile.getFileData());
312 fos.flush();
313 fos.close();
314 LOG.info("File [" + item.getFileName() + "] written to the file system.");
315 } catch (Exception e) {
316 LOG.error("An exception occurred writing the file: [" + e.getMessage() + "]");
317 msgmap.putError(EdoConstants.ErrorKeys.ERROR_KEYS, "error.fileUpload.exception", e.getMessage() );
318 ActionForward fwd = mapping.findForward("basic");
319 return fwd;
320 }
321 } else {
322 LOG.error("The file [" + fileName + "] already exists in this checklist section");
323 msgmap.putError(EdoConstants.ErrorKeys.ERROR_KEYS,"error.fileUpload.exists", fileName);
324 ActionForward fwd = mapping.findForward("basic");
325 return fwd;
326 }
327 }
328
329
330
331 if (isNewFile || replaceFile) {
332 EdoServiceLocator.getEdoItemService().saveOrUpdate(item.build());
333 LOG.info("File entry [" + item.getEdoItemId() + "][" + item.getFileName() + "] updated/saved to the database.");
334 }
335 }
336
337
338 BigDecimal highestAuthorizedViewReviewLevel = BigDecimal.ZERO;
339 List<BigDecimal> authorizedViewReviewLetterLevels = EdoContext.getAuthorizedViewReviewLetterLevels();
340
341 if (CollectionUtils.isNotEmpty(authorizedViewReviewLetterLevels)) {
342 highestAuthorizedViewReviewLevel = Collections.max(authorizedViewReviewLetterLevels);
343 }
344
345 List<EdoItem> itemList = EdoServiceLocator.getEdoItemService().getItemList(selectedCandidate.getCandidateDossierID().toString(), currentTreeNodeID+"");
346
347
348
349
350
351 if (replaceFile) {
352 for (EdoItem oldItem : itemList) {
353 if (oldItem.getEdoItemId().equals(originalItemID)) {
354 EdoItem.Builder newItem = EdoItem.Builder.create(item);
355 itemList.remove(oldItem);
356 itemList.add(newItem.build());
357
358 break;
359 }
360 }
361 }
362
363 if (CollectionUtils.isNotEmpty(itemList)) {
364 Collections.sort(itemList);
365
366 List<EdoItem> copy = new ArrayList<EdoItem>(itemList);
367 for (EdoItem tmpItem : copy) {
368
369
370
371 String reviewLevel = EdoServiceLocator.getEdoReviewLayerDefinitionService().getReviewLayerDefinitionById(tmpItem.getEdoReviewLayerDefId()).getReviewLevel();
372 if (new BigDecimal(reviewLevel).compareTo(highestAuthorizedViewReviewLevel) < 1 ) {
373 itemListJSON = itemListJSON.concat(EdoServiceLocator.getEdoItemService().getItemJSONString(tmpItem) + ",");
374 } else {
375 itemList.remove(item);
376 }
377 }
378 }
379
380 edoReviewLetterForm.setItemList(itemList);
381
382 String path = request.getRequestURL().toString().replace(request.getServletPath(), "").concat("/");
383 request.setAttribute("requestPath", path);
384 request.setAttribute("itemlistJSON", itemListJSON);
385 request.setAttribute("nidFwd", nidParam);
386
387 ActionForward fwd = mapping.findForward("basic");
388
389 return fwd;
390 }
391
392 public ActionForward deleteConfirm(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
393
394 String itemListJSON = "";
395 String data = ((EdoSecondUnitForm)form).getFormData();
396 MessageMap msgmap = GlobalVariables.getMessageMap();
397 EdoSelectedCandidate selectedCandidate = (EdoSelectedCandidate) request.getSession().getAttribute("selectedCandidate");
398 EdoSecondUnitForm cliForm = (EdoSecondUnitForm) form;
399
400 HttpSession ssn = request.getSession();
401
402 String nidParam = ssn.getAttribute("nid").toString();
403
404 int currentTreeNodeID = Integer.parseInt(nidParam.split("_")[2]);
405
406 if (data == null) {
407 msgmap.putError(EdoConstants.ErrorKeys.ERROR_KEYS,"error.formData.null");
408 LOG.error("Form data missing");
409 return mapping.findForward("basic");
410 }
411
412 QueryParams itemData = new QueryParams(data);
413 List<String> params = itemData.getParameterValues("itemID");
414
415 for (String id : params) {
416 EdoItem item = EdoServiceLocator.getEdoItemService().getEdoItem(id);
417 if (deleteFileFromFS(item)) {
418
419 EdoServiceLocator.getEdoItemService().deleteItem(item);
420 LOG.info("File deleted [" + item.getFileName() + "]");
421 }
422 }
423
424 List<EdoItem> itemList = EdoServiceLocator.getEdoItemService().getItemList(selectedCandidate.getCandidateDossierID().toString(), currentTreeNodeID+"");
425 cliForm.setItemList(itemList);
426
427 if (itemList != null && itemList.size() > 0) {
428 Collections.sort(itemList);
429 for (EdoItem item : itemList) {
430 itemListJSON = itemListJSON.concat(EdoServiceLocator.getEdoItemService().getItemJSONString(item) + ",");
431 }
432 }
433
434 EdoItemTracker itemTracker = (EdoItemTracker) ssn.getAttribute("itemTracker");
435 itemTracker.clearItemsMarked();
436
437 String path = request.getRequestURL().toString().replace(request.getServletPath(), "").concat("/");
438 request.setAttribute("requestPath", path);
439 request.setAttribute("itemlistJSON", itemListJSON);
440 request.setAttribute("nidFwd", nidParam);
441
442 ActionForward fwd = mapping.findForward("basic");
443
444 return fwd;
445 }
446
447
448 private boolean deleteFileFromFS(EdoItem item) {
449
450 MessageMap msgmap = GlobalVariables.getMessageMap();
451 File fn = new File(item.getFileLocation());
452 Boolean fsOK = true;
453
454 if (fn.isFile() && fn.exists()) {
455 if (fn.canWrite()) {
456 try {
457 boolean deleteResult = fn.delete();
458 if (!deleteResult) {
459 fsOK = false;
460 msgmap.putError(EdoConstants.ErrorKeys.ERROR_KEYS, "error.fileDelete.null", fn.getName());
461 LOG.error("Error deleting file [" + item.getFileLocation() + "]");
462 }
463 } catch (Exception e) {
464 fsOK = false;
465 msgmap.putError(EdoConstants.ErrorKeys.ERROR_KEYS,"error.fileDelete.exception", e.getMessage() );
466 LOG.error("Error deleting file [" + item.getFileLocation() + "] " + e.getMessage() );
467 }
468 } else {
469 fsOK = false;
470 LOG.error("Can't delete file from [" + item.getFileLocation() + "]");
471 msgmap.putError(EdoConstants.ErrorKeys.ERROR_KEYS, "error.fileDelete.access", fn.getName());
472 }
473 } else {
474 fsOK = false;
475 msgmap.putError(EdoConstants.ErrorKeys.ERROR_KEYS, "error.fileDelete.invalid", fn.getName());
476 LOG.warn("Missing file from file system [" + item.getFileLocation() + "]");
477 }
478 return fsOK;
479 }
480
481 }