1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.kuali.rice.kns.web.struts.action;
17
18 import org.apache.commons.collections.CollectionUtils;
19 import org.apache.commons.lang.StringUtils;
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.action.RedirectingActionForward;
24 import org.kuali.rice.core.api.util.RiceConstants;
25 import org.kuali.rice.core.api.util.RiceKeyConstants;
26 import org.kuali.rice.kim.api.KimConstants;
27 import org.kuali.rice.kim.api.services.KimApiServiceLocator;
28 import org.kuali.rice.kns.inquiry.Inquirable;
29 import org.kuali.rice.kns.util.WebUtils;
30 import org.kuali.rice.kns.web.struts.form.InquiryForm;
31 import org.kuali.rice.kns.web.ui.Field;
32 import org.kuali.rice.kns.web.ui.Row;
33 import org.kuali.rice.kns.web.ui.Section;
34 import org.kuali.rice.krad.bo.Attachment;
35 import org.kuali.rice.krad.bo.BusinessObject;
36 import org.kuali.rice.krad.bo.Exporter;
37 import org.kuali.rice.krad.bo.Note;
38 import org.kuali.rice.krad.bo.PersistableAttachment;
39 import org.kuali.rice.krad.bo.PersistableAttachmentList;
40 import org.kuali.rice.krad.datadictionary.BusinessObjectEntry;
41 import org.kuali.rice.krad.exception.AuthorizationException;
42 import org.kuali.rice.krad.service.KRADServiceLocator;
43 import org.kuali.rice.krad.service.KRADServiceLocatorWeb;
44 import org.kuali.rice.krad.service.ModuleService;
45 import org.kuali.rice.krad.service.NoteService;
46 import org.kuali.rice.krad.util.GlobalVariables;
47 import org.kuali.rice.krad.util.KRADConstants;
48 import org.kuali.rice.krad.util.KRADUtils;
49
50 import javax.servlet.http.HttpServletRequest;
51 import javax.servlet.http.HttpServletResponse;
52 import java.io.ByteArrayOutputStream;
53 import java.io.IOException;
54 import java.lang.reflect.Method;
55 import java.util.Collections;
56 import java.util.List;
57 import java.util.Map;
58
59
60
61
62 public class KualiInquiryAction extends KualiAction {
63 private static final org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(KualiInquiryAction.class);
64 private NoteService noteService;
65
66 @Override
67 protected void checkAuthorization(ActionForm form, String methodToCall) throws AuthorizationException {
68 if (!(form instanceof InquiryForm)) {
69 super.checkAuthorization(form, methodToCall);
70 } else {
71 try {
72 if(!KRADConstants.DOWNLOAD_BO_ATTACHMENT_METHOD.equals(methodToCall)){
73 Class businessObjectClass = Class.forName(((InquiryForm) form).getBusinessObjectClassName());
74 if (!KimApiServiceLocator.getPermissionService().isAuthorizedByTemplate(
75 GlobalVariables.getUserSession().getPrincipalId(), KRADConstants.KNS_NAMESPACE,
76 KimConstants.PermissionTemplateNames.INQUIRE_INTO_RECORDS,
77 KRADUtils.getNamespaceAndComponentSimpleName(businessObjectClass),
78 Collections.<String, String>emptyMap())) {
79
80 throw new AuthorizationException(GlobalVariables.getUserSession().getPerson().getPrincipalName(),
81 "inquire",
82 businessObjectClass.getSimpleName());
83 }
84 }
85 }
86 catch (ClassNotFoundException e) {
87 LOG.warn("Unable to load BusinessObject class: " + ((InquiryForm) form).getBusinessObjectClassName(), e);
88 super.checkAuthorization(form, methodToCall);
89 }
90 }
91 }
92
93 @Override
94 protected Map<String, String> getRoleQualification(ActionForm form,
95 String methodToCall) {
96 Map<String, String> roleQualification = super.getRoleQualification(
97 form, methodToCall);
98 if (form instanceof InquiryForm) {
99 Map<String, String> primaryKeys = ((InquiryForm) form)
100 .getInquiryPrimaryKeys();
101 if (primaryKeys != null) {
102 for (String keyName : primaryKeys.keySet()) {
103 roleQualification.put(keyName, primaryKeys.get(keyName));
104 }
105 }
106 }
107 return roleQualification;
108 }
109
110 @Override
111 public ActionForward execute(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
112 request.setAttribute(KRADConstants.PARAM_MAINTENANCE_VIEW_MODE, KRADConstants.PARAM_MAINTENANCE_VIEW_MODE_INQUIRY);
113 return super.execute(mapping, form, request, response);
114 }
115
116
117
118
119
120 public ActionForward start(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
121 InquiryForm inquiryForm = (InquiryForm) form;
122 if (inquiryForm.getBusinessObjectClassName() == null) {
123 LOG.error("Business object name not given.");
124 throw new RuntimeException("Business object name not given.");
125 }
126
127 Class boClass = Class.forName(inquiryForm.getBusinessObjectClassName());
128 ModuleService responsibleModuleService = KRADServiceLocatorWeb.getKualiModuleService().getResponsibleModuleService(boClass);
129 if(responsibleModuleService!=null && responsibleModuleService.isExternalizable(boClass)){
130 String redirectUrl = responsibleModuleService.getExternalizableBusinessObjectInquiryUrl(boClass, (Map<String, String[]>) request.getParameterMap());
131 ActionForward redirectingActionForward = new RedirectingActionForward(redirectUrl);
132 redirectingActionForward.setModule("/");
133 return redirectingActionForward;
134 }
135
136 return continueWithInquiry(mapping, form, request, response);
137 }
138
139
140
141
142
143
144
145
146
147
148
149
150 public ActionForward downloadAttachment(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
151 InquiryForm inquiryForm = (InquiryForm) form;
152 int line = getSelectedLine(request);
153
154 BusinessObject bo = retrieveBOFromInquirable(inquiryForm);
155 if (line < 0) {
156 if (bo instanceof PersistableAttachment) {
157 PersistableAttachment attachment = (PersistableAttachment)bo;
158 if (StringUtils.isNotBlank(attachment.getFileName())
159 && attachment.getAttachmentContent() != null) {
160 streamToResponse(attachment.getAttachmentContent(), attachment.getFileName(), attachment.getContentType(), response);
161 }
162 }
163 } else {
164 if (bo instanceof PersistableAttachmentList) {
165 PersistableAttachmentList<PersistableAttachment> attachmentsBo = (PersistableAttachmentList<PersistableAttachment>)bo;
166 if (CollectionUtils.isEmpty(attachmentsBo.getAttachments())) {
167 return null;
168 }
169
170 List<? extends PersistableAttachment> attachments = attachmentsBo.getAttachments();
171 if (CollectionUtils.isNotEmpty(attachments)
172 && attachments.size() > line) {
173 PersistableAttachment attachment = (PersistableAttachment)attachmentsBo.getAttachments().get(line);
174 streamToResponse(attachment.getAttachmentContent(), attachment.getFileName(), attachment.getContentType(), response);
175 }
176 }
177 }
178 return null;
179 }
180
181 public ActionForward downloadCustomBOAttachment(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
182 String fileName = request.getParameter(KRADConstants.BO_ATTACHMENT_FILE_NAME);
183 String contentType = request.getParameter(KRADConstants.BO_ATTACHMENT_FILE_CONTENT_TYPE);
184 String fileContentBoField = request.getParameter(KRADConstants.BO_ATTACHMENT_FILE_CONTENT_FIELD);
185
186 if (fileName != null
187 && contentType != null
188 && fileContentBoField != null) {
189
190 checkAuthorization(form, findMethodToCall(form, request));
191
192 fileName = StringUtils.replace(fileName, " ", "_");
193
194 InquiryForm inquiryForm = (InquiryForm) form;
195 BusinessObject bo = retrieveBOFromInquirable(inquiryForm);
196 checkBO(bo);
197
198 Class clazz = (bo.getClass());
199 Method method = clazz.getMethod("get"+StringUtils.capitalize(fileContentBoField));
200 byte[] fileContents = (byte[]) method.invoke(bo);
201 streamToResponse(fileContents, fileName, contentType,response);
202 } else {
203 if (fileName == null) {
204 LOG.error("Request Parameter \""+ KRADConstants.BO_ATTACHMENT_FILE_NAME + "\" not provided.");
205 }
206 if (contentType == null) {
207 LOG.error("Request Parameter \""+ KRADConstants.BO_ATTACHMENT_FILE_CONTENT_TYPE + "\" not provided.");
208 }
209 if (fileContentBoField == null) {
210 LOG.error("Request Parameter \""+ KRADConstants.BO_ATTACHMENT_FILE_CONTENT_FIELD + "\" not provided.");
211 }
212 }
213 return null;
214 }
215
216
217
218
219
220
221
222
223
224
225
226
227 public ActionForward downloadBOAttachment(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
228 Long noteIdentifier = Long.valueOf(request.getParameter(KRADConstants.NOTE_IDENTIFIER));
229
230 Note note = this.getNoteService().getNoteByNoteId(noteIdentifier);
231 if(note != null){
232 Attachment attachment = note.getAttachment();
233 if(attachment != null){
234
235 attachment.setNote(note);
236 WebUtils.saveMimeInputStreamAsFile(response, attachment.getAttachmentMimeTypeCode(), attachment.getAttachmentContents(), attachment.getAttachmentFileName(), attachment.getAttachmentFileSize().intValue());
237 }
238 return null;
239 }
240
241 return mapping.findForward(RiceConstants.MAPPING_BASIC);
242 }
243
244 public ActionForward continueWithInquiry(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
245 InquiryForm inquiryForm = (InquiryForm) form;
246
247 if (inquiryForm.getBusinessObjectClassName() == null) {
248 LOG.error("Business object name not given.");
249 throw new RuntimeException("Business object name not given.");
250 }
251
252 BusinessObject bo = retrieveBOFromInquirable(inquiryForm);
253 checkBO(bo);
254
255 populateSections(mapping, request, inquiryForm, bo);
256
257 return mapping.findForward(RiceConstants.MAPPING_BASIC);
258 }
259
260
261
262
263 public ActionForward toggleInactiveRecordDisplay(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
264 InquiryForm inquiryForm = (InquiryForm) form;
265 if (inquiryForm.getBusinessObjectClassName() == null) {
266 LOG.error("Business object name not given.");
267 throw new RuntimeException("Business object name not given.");
268 }
269
270 BusinessObject bo = retrieveBOFromInquirable(inquiryForm);
271 checkBO(bo);
272
273 Inquirable kualiInquirable = inquiryForm.getInquirable();
274
275 String collectionName = extractCollectionName(request, KRADConstants.TOGGLE_INACTIVE_METHOD);
276 if (collectionName == null) {
277 LOG.error("Unable to get find collection name in request.");
278 throw new RuntimeException("Unable to get find collection class in request.");
279 }
280 String parameterName = (String) request.getAttribute(KRADConstants.METHOD_TO_CALL_ATTRIBUTE);
281 boolean showInactive = Boolean.parseBoolean(StringUtils.substringBetween(parameterName, KRADConstants.METHOD_TO_CALL_BOPARM_LEFT_DEL, "."));
282 kualiInquirable.setShowInactiveRecords(collectionName, showInactive);
283
284
285 populateSections(mapping, request, inquiryForm, bo);
286
287 if (showInactive) {
288 reopenInactiveRecords(inquiryForm, collectionName);
289 }
290
291 return mapping.findForward(RiceConstants.MAPPING_BASIC);
292 }
293
294
295
296
297
298
299
300 protected void reopenInactiveRecords(InquiryForm inquiryForm, String collectionName) {
301 for (Object sectionAsObject : inquiryForm.getSections()) {
302 final Section section = (Section)sectionAsObject;
303 for (Row row: section.getRows()) {
304 for (Field field : row.getFields()) {
305 if (field.getFieldType().equals(Field.CONTAINER) && field.getContainerName().startsWith(collectionName)) {
306 final String tabKey = WebUtils.generateTabKey(generateCollectionSubTabName(field));
307 inquiryForm.getTabStates().put(tabKey, "OPEN");
308 }
309 }
310 }
311 }
312 }
313
314
315
316
317
318
319
320 protected String generateCollectionSubTabName(Field field) {
321 final String containerName = field.getContainerElementName();
322 final String cleanedContainerName =
323 (containerName == null) ?
324 "" :
325 containerName.replaceAll("\\d+", "");
326 StringBuilder subTabName = new StringBuilder(cleanedContainerName);
327 for (Field containerField : field.getContainerDisplayFields()) {
328 subTabName.append(containerField.getPropertyValue());
329 }
330 return subTabName.toString();
331 }
332
333 @Override
334 public ActionForward toggleTab(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
335 InquiryForm inquiryForm = (InquiryForm) form;
336 if (inquiryForm.getBusinessObjectClassName() == null) {
337 LOG.error("Business object name not given.");
338 throw new RuntimeException("Business object name not given.");
339 }
340
341 BusinessObject bo = retrieveBOFromInquirable(inquiryForm);
342 checkBO(bo);
343
344 populateSections(mapping, request, inquiryForm, bo);
345
346 Inquirable kualiInquirable = inquiryForm.getInquirable();
347
348 return super.toggleTab(mapping, form, request, response);
349 }
350
351
352
353
354
355
356 @Override
357 public ActionForward hideAllTabs(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
358
359 InquiryForm inquiryForm = (InquiryForm) form;
360 if (inquiryForm.getBusinessObjectClassName() == null) {
361 LOG.error("Business object name not given.");
362 throw new RuntimeException("Business object name not given.");
363 }
364
365 BusinessObject bo = retrieveBOFromInquirable(inquiryForm);
366 checkBO(bo);
367
368 populateSections(mapping, request, inquiryForm, bo);
369
370 return super.hideAllTabs(mapping, form, request, response);
371 }
372
373
374
375
376 @Override
377 public ActionForward showAllTabs(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
378
379 InquiryForm inquiryForm = (InquiryForm) form;
380 if (inquiryForm.getBusinessObjectClassName() == null) {
381 LOG.error("Business object name not given.");
382 throw new RuntimeException("Business object name not given.");
383 }
384
385 BusinessObject bo = retrieveBOFromInquirable(inquiryForm);
386 checkBO(bo);
387
388 populateSections(mapping, request, inquiryForm, bo);
389
390 return super.showAllTabs(mapping, form, request, response);
391 }
392
393
394
395
396 public ActionForward export(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
397 InquiryForm inquiryForm = (InquiryForm) form;
398 if (inquiryForm.isCanExport()) {
399 BusinessObject bo = retrieveBOFromInquirable(inquiryForm);
400 checkBO(bo);
401 if (bo != null) {
402 BusinessObjectEntry businessObjectEntry = KRADServiceLocatorWeb.getDataDictionaryService().getDataDictionary().getBusinessObjectEntry(inquiryForm.getBusinessObjectClassName());
403 Class<? extends Exporter> exporterClass = businessObjectEntry.getExporterClass();
404 if (exporterClass != null) {
405 Exporter exporter = exporterClass.newInstance();
406 response.setContentType(KRADConstants.XML_MIME_TYPE);
407 response.setHeader("Content-disposition", "attachment; filename=export.xml");
408 exporter.export(businessObjectEntry.getBusinessObjectClass(), Collections.singletonList(bo), KRADConstants.XML_FORMAT, response.getOutputStream());
409 }
410 } else {
411
412 populateSections(mapping, request, inquiryForm, bo);
413 return mapping.findForward(RiceConstants.MAPPING_BASIC);
414 }
415 }
416
417 return null;
418 }
419
420
421
422
423
424
425 protected String extractCollectionName(HttpServletRequest request, String methodToCall) {
426
427 String parameterName = (String) request.getAttribute(KRADConstants.METHOD_TO_CALL_ATTRIBUTE);
428 String collectionName = null;
429 if (StringUtils.isNotBlank(parameterName)) {
430 collectionName = StringUtils.substringBetween(parameterName, methodToCall + ".", ".(");
431 }
432 return collectionName;
433 }
434
435 protected BusinessObject retrieveBOFromInquirable(InquiryForm inquiryForm) {
436 Inquirable kualiInquirable = inquiryForm.getInquirable();
437
438 BusinessObject bo = kualiInquirable.getBusinessObject(inquiryForm.retrieveInquiryDecryptedPrimaryKeys());
439 if (bo == null) {
440 LOG.error("No records found in inquiry action.");
441 GlobalVariables.getMessageMap().putError(KRADConstants.GLOBAL_ERRORS, RiceKeyConstants.ERROR_INQUIRY);
442 }
443 return bo;
444 }
445
446 protected void populateSections(ActionMapping mapping, HttpServletRequest request, InquiryForm inquiryForm, BusinessObject bo) {
447 Inquirable kualiInquirable = inquiryForm.getInquirable();
448
449 if (bo != null) {
450
451 List<Section> sections = kualiInquirable.getSections(bo);
452 inquiryForm.setSections(sections);
453 kualiInquirable.addAdditionalSections(sections, bo);
454 } else {
455 inquiryForm.setSections(getEmptySections(kualiInquirable.getTitle()));
456 }
457
458 request.setAttribute(KRADConstants.INQUIRABLE_ATTRIBUTE_NAME, kualiInquirable);
459 }
460
461
462
463
464
465
466
467
468 protected void streamToResponse(byte[] fileContents, String fileName, String fileContentType,HttpServletResponse response) throws Exception{
469 ByteArrayOutputStream baos = null;
470 try{
471 baos = new ByteArrayOutputStream(fileContents.length);
472 baos.write(fileContents);
473 WebUtils.saveMimeOutputStreamAsFile(response, fileContentType, baos, fileName);
474 }finally{
475 try{
476 if(baos!=null){
477 baos.close();
478 baos = null;
479 }
480 }catch(IOException ioEx){
481 LOG.error("Error while downloading attachment");
482 throw new RuntimeException("IOException occurred while downloading attachment", ioEx);
483 }
484 }
485 }
486
487
488
489
490
491 private List<Section> getEmptySections(String title) {
492 final Row row = new Row(Collections.<Field>emptyList());
493
494 final Section section = new Section(Collections.singletonList(row));
495 section.setErrorKey("*");
496 section.setSectionTitle(title != null ? title : "");
497 section.setNumberOfColumns(0);
498
499 return Collections.singletonList(section);
500 }
501
502
503
504
505
506
507 private void checkBO(BusinessObject bo) {
508 if (bo == null && GlobalVariables.getMessageMap().hasNoMessages()) {
509 throw new UnsupportedOperationException("The record you have inquired on does not exist.");
510 }
511 }
512
513 protected NoteService getNoteService() {
514 if ( noteService == null ) {
515 noteService = KRADServiceLocator.getNoteService();
516 }
517 return this.noteService;
518 }
519 }