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