1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.kuali.rice.kns.web.struts.form;
17
18 import org.apache.commons.lang.StringUtils;
19 import org.apache.struts.upload.FormFile;
20 import org.kuali.rice.core.api.config.ConfigurationException;
21 import org.kuali.rice.core.api.util.RiceKeyConstants;
22 import org.kuali.rice.core.web.format.FormatException;
23 import org.kuali.rice.core.web.format.Formatter;
24 import org.kuali.rice.kew.api.WorkflowDocument;
25 import org.kuali.rice.kim.api.services.KimApiServiceLocator;
26 import org.kuali.rice.kns.document.MaintenanceDocument;
27 import org.kuali.rice.kns.document.MaintenanceDocumentBase;
28 import org.kuali.rice.kns.document.authorization.MaintenanceDocumentRestrictions;
29 import org.kuali.rice.kns.maintenance.Maintainable;
30 import org.kuali.rice.kns.service.KNSServiceLocator;
31 import org.kuali.rice.kns.service.MaintenanceDocumentDictionaryService;
32 import org.kuali.rice.kns.util.FieldUtils;
33 import org.kuali.rice.krad.bo.BusinessObject;
34 import org.kuali.rice.krad.bo.PersistableBusinessObject;
35 import org.kuali.rice.krad.datadictionary.exception.UnknownDocumentTypeException;
36 import org.kuali.rice.krad.document.Document;
37 import org.kuali.rice.krad.service.KRADServiceLocatorWeb;
38 import org.kuali.rice.krad.util.GlobalVariables;
39 import org.kuali.rice.krad.util.KRADConstants;
40 import org.kuali.rice.krad.util.ObjectUtils;
41
42 import javax.servlet.http.HttpServletRequest;
43 import java.lang.reflect.Constructor;
44 import java.lang.reflect.InvocationTargetException;
45 import java.util.Enumeration;
46 import java.util.HashMap;
47 import java.util.Iterator;
48 import java.util.List;
49 import java.util.Map;
50
51
52
53
54
55
56
57 public class KualiMaintenanceForm extends KualiDocumentFormBase {
58 protected static final org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(KualiMaintenanceForm.class);
59
60 protected static final long serialVersionUID = 1L;
61
62 protected String businessObjectClassName;
63 protected String description;
64 protected boolean readOnly;
65 protected Map<String, String> oldMaintainableValues;
66 protected Map<String, String> newMaintainableValues;
67 protected String maintenanceAction;
68
69
70
71
72 @Override
73 public void addRequiredNonEditableProperties(){
74 super.addRequiredNonEditableProperties();
75 registerRequiredNonEditableProperty(KRADConstants.BUSINESS_OBJECT_CLASS_ATTRIBUTE);
76 registerRequiredNonEditableProperty(KRADConstants.LOOKUP_RESULTS_BO_CLASS_NAME);
77 registerRequiredNonEditableProperty(KRADConstants.LOOKED_UP_COLLECTION_NAME);
78 registerRequiredNonEditableProperty(KRADConstants.LOOKUP_RESULTS_SEQUENCE_NUMBER);
79 registerRequiredNonEditableProperty(KRADConstants.FIELD_NAME_TO_FOCUS_ON_AFTER_SUBMIT);
80 }
81
82
83
84
85 protected String lookupResultsSequenceNumber;
86
87
88
89
90
91 protected String lookupResultsBOClassName;
92
93
94
95
96 protected String lookedUpCollectionName;
97
98 protected MaintenanceDocumentRestrictions authorizations;
99
100
101
102
103
104
105
106
107 @Override
108 public void postprocessRequestParameters(Map requestParameters) {
109 super.postprocessRequestParameters(requestParameters);
110
111 String docTypeName = null;
112 String[] docTypeNames = (String[]) requestParameters.get(KRADConstants.DOCUMENT_TYPE_NAME);
113 if ((docTypeNames != null) && (docTypeNames.length > 0)) {
114 docTypeName = docTypeNames[0];
115 }
116
117 if (StringUtils.isNotBlank(docTypeName)) {
118 if(this.getDocument() == null){
119 setDocTypeName(docTypeName);
120 Class documentClass = KRADServiceLocatorWeb.getDataDictionaryService().getDocumentClassByTypeName(docTypeName);
121 if (documentClass == null) {
122 throw new UnknownDocumentTypeException("unable to get class for unknown documentTypeName '" + docTypeName + "'");
123 }
124 if (!MaintenanceDocumentBase.class.isAssignableFrom(documentClass)) {
125 throw new ConfigurationException("Document class '" + documentClass + "' is not assignable to '" + MaintenanceDocumentBase.class + "'");
126 }
127 Document document = null;
128 try {
129 Class[] defaultConstructor = new Class[]{String.class};
130 Constructor cons = documentClass.getConstructor(defaultConstructor);
131 if (ObjectUtils.isNull(cons)) {
132 throw new ConfigurationException("Could not find constructor with document type name parameter needed for Maintenance Document Base class");
133 }
134 document = (Document) cons.newInstance(docTypeName);
135 } catch (SecurityException e) {
136 throw new RuntimeException("Error instantiating Maintenance Document", e);
137 } catch (NoSuchMethodException e) {
138 throw new RuntimeException("Error instantiating Maintenance Document: No constructor with String parameter found", e);
139 } catch (IllegalAccessException e) {
140 throw new RuntimeException("Error instantiating Maintenance Document", e);
141 } catch (InstantiationException e) {
142 throw new RuntimeException("Error instantiating Maintenance Document", e);
143 } catch (IllegalArgumentException e) {
144 throw new RuntimeException("Error instantiating Maintenance Document", e);
145 } catch (InvocationTargetException e) {
146 throw new RuntimeException("Error instantiating Maintenance Document", e);
147 }
148 if (document == null) {
149 throw new RuntimeException("Unable to instantiate document with type name '" + docTypeName + "' and document class '" + documentClass + "'");
150 }
151 setDocument(document);
152 }
153 }
154
155 MaintenanceDocumentBase maintenanceDocument = (MaintenanceDocumentBase) getDocument();
156
157
158 for ( Object obj : requestParameters.entrySet() ) {
159 String parameter = (String)((Map.Entry)obj).getKey();
160 if (parameter.toUpperCase().startsWith(KRADConstants.MAINTENANCE_NEW_MAINTAINABLE.toUpperCase())) {
161 String propertyName = parameter.substring(KRADConstants.MAINTENANCE_NEW_MAINTAINABLE.length());
162 Object propertyValue = requestParameters.get(parameter);
163
164 if(propertyValue != null && propertyValue instanceof FormFile) {
165 if(StringUtils.isNotEmpty(((FormFile)propertyValue).getFileName())) {
166 maintenanceDocument.setFileAttachment((FormFile) propertyValue);
167 }
168 maintenanceDocument.setAttachmentPropertyName(propertyName);
169 }
170 }
171 }
172 }
173
174
175
176
177 @Override
178 public void populate(HttpServletRequest request) {
179 super.populate(request);
180
181
182
183 if (StringUtils.isNotBlank(getDocTypeName())) {
184 Map<String, String> localOldMaintainableValues = new HashMap<String, String>();
185 Map<String, String> localNewMaintainableValues = new HashMap<String, String>();
186 Map<String,String> localNewCollectionValues = new HashMap<String,String>();
187 for (Enumeration i = request.getParameterNames(); i.hasMoreElements();) {
188 String parameter = (String) i.nextElement();
189 if (parameter.toUpperCase().startsWith(KRADConstants.MAINTENANCE_OLD_MAINTAINABLE.toUpperCase())) {
190 if (shouldPropertyBePopulatedInForm(parameter, request)) {
191 String propertyName = parameter.substring(KRADConstants.MAINTENANCE_OLD_MAINTAINABLE.length());
192 localOldMaintainableValues.put(propertyName, request.getParameter(parameter));
193 }
194 }
195 if (parameter.toUpperCase().startsWith(KRADConstants.MAINTENANCE_NEW_MAINTAINABLE.toUpperCase())) {
196 if (shouldPropertyBePopulatedInForm(parameter, request)) {
197 String propertyName = parameter.substring(KRADConstants.MAINTENANCE_NEW_MAINTAINABLE.length());
198 localNewMaintainableValues.put(propertyName, request.getParameter(parameter));
199 }
200 }
201 }
202
203
204
205 for ( Map.Entry<String, String> entry : localNewMaintainableValues.entrySet() ) {
206 String key = entry.getKey();
207 if ( key.startsWith( KRADConstants.MAINTENANCE_ADD_PREFIX ) ) {
208 localNewCollectionValues.put( key.substring( KRADConstants.MAINTENANCE_ADD_PREFIX.length() ),
209 entry.getValue() );
210 }
211 }
212 if ( LOG.isDebugEnabled() ) {
213 LOG.debug( "checked for add line parameters - got: " + localNewCollectionValues );
214 }
215
216 this.newMaintainableValues = localNewMaintainableValues;
217 this.oldMaintainableValues = localOldMaintainableValues;
218
219 MaintenanceDocumentBase maintenanceDocument = (MaintenanceDocumentBase) getDocument();
220
221 GlobalVariables.getMessageMap().addToErrorPath("document.oldMaintainableObject");
222 maintenanceDocument.getOldMaintainableObject().populateBusinessObject(localOldMaintainableValues, maintenanceDocument, getMethodToCall());
223 GlobalVariables.getMessageMap().removeFromErrorPath("document.oldMaintainableObject");
224
225 GlobalVariables.getMessageMap().addToErrorPath("document.newMaintainableObject");
226
227 Map cachedValues =
228 maintenanceDocument.getNewMaintainableObject().populateBusinessObject(localNewMaintainableValues, maintenanceDocument, getMethodToCall());
229
230 if(maintenanceDocument.getFileAttachment() != null) {
231 populateAttachmentPropertyForBO(maintenanceDocument);
232 }
233
234
235 localNewCollectionValues = KimApiServiceLocator.getPersonService().resolvePrincipalNamesToPrincipalIds((BusinessObject)maintenanceDocument.getNewMaintainableObject().getBusinessObject(), localNewCollectionValues);
236 cachedValues.putAll( maintenanceDocument.getNewMaintainableObject().populateNewCollectionLines( localNewCollectionValues, maintenanceDocument, getMethodToCall() ) );
237 GlobalVariables.getMessageMap().removeFromErrorPath("document.newMaintainableObject");
238
239 if (cachedValues.size() > 0) {
240 GlobalVariables.getMessageMap().putError(KRADConstants.DOCUMENT_ERRORS, RiceKeyConstants.ERROR_DOCUMENT_MAINTENANCE_FORMATTING_ERROR);
241 for (Iterator iter = cachedValues.keySet().iterator(); iter.hasNext();) {
242 String propertyName = (String) iter.next();
243 String value = (String) cachedValues.get(propertyName);
244 cacheUnconvertedValue(KRADConstants.MAINTENANCE_NEW_MAINTAINABLE + propertyName, value);
245 }
246 }
247 }
248 }
249
250 protected void populateAttachmentPropertyForBO(MaintenanceDocumentBase maintenanceDocument) {
251 try {
252 Class type = ObjectUtils.easyGetPropertyType(maintenanceDocument.getNewMaintainableObject().getBusinessObject(), maintenanceDocument.getAttachmentPropertyName());
253 ObjectUtils.setObjectProperty(maintenanceDocument.getNewMaintainableObject().getBusinessObject(), maintenanceDocument.getAttachmentPropertyName(), type, maintenanceDocument.getFileAttachment());
254 } catch (FormatException e) {
255 throw new RuntimeException("Exception occurred while setting attachment property on NewMaintainable bo", e);
256 } catch (IllegalAccessException e) {
257 throw new RuntimeException("Exception occurred while setting attachment property on NewMaintainable bo", e);
258 } catch (NoSuchMethodException e) {
259 throw new RuntimeException("Exception occurred while setting attachment property on NewMaintainable bo", e);
260 } catch (InvocationTargetException e) {
261 throw new RuntimeException("Exception occurred while setting attachment property on NewMaintainable bo", e);
262 }
263 }
264
265
266
267
268
269
270
271 public List getSections() {
272 if (getDocument() == null) {
273 throw new RuntimeException("Document not set in maintenance form.");
274 }
275 if (((MaintenanceDocumentBase) getDocument()).getNewMaintainableObject() == null) {
276 throw new RuntimeException("New maintainable not set in document.");
277 }
278 if ((KRADConstants.MAINTENANCE_EDIT_ACTION.equals(this.getMaintenanceAction())
279 || KRADConstants.MAINTENANCE_COPY_ACTION.equals(this.getMaintenanceAction())
280 || KRADConstants.MAINTENANCE_DELETE_ACTION.equals(this.getMaintenanceAction()))
281 && ((MaintenanceDocumentBase) getDocument()).getOldMaintainableObject() == null) {
282 throw new RuntimeException("Old maintainable not set in document.");
283 }
284
285
286
287
288
289
290
291
292 List keyFieldNames = KNSServiceLocator.getBusinessObjectMetaDataService().listPrimaryKeyFieldNames(((MaintenanceDocumentBase) getDocument()).getNewMaintainableObject().getBusinessObject().getClass());
293
294
295 Maintainable oldMaintainable = ((MaintenanceDocumentBase) getDocument()).getOldMaintainableObject();
296 oldMaintainable.setMaintenanceAction(getMaintenanceAction());
297 List oldMaintSections = oldMaintainable.getSections((MaintenanceDocument) getDocument(), null);
298
299 Maintainable newMaintainable = ((MaintenanceDocumentBase) getDocument()).getNewMaintainableObject();
300 newMaintainable.setMaintenanceAction(getMaintenanceAction());
301 List newMaintSections = newMaintainable.getSections((MaintenanceDocument) getDocument(), oldMaintainable);
302 WorkflowDocument workflowDocument = this.getDocument().getDocumentHeader().getWorkflowDocument();
303 String documentStatus = workflowDocument.getStatus().getCode();
304 String documentInitiatorPrincipalId = workflowDocument.getInitiatorPrincipalId();
305
306
307
308 List meshedSections = FieldUtils
309 .meshSections(oldMaintSections, newMaintSections, keyFieldNames, getMaintenanceAction(), isReadOnly(),
310 authorizations, documentStatus, documentInitiatorPrincipalId);
311
312 return meshedSections;
313 }
314
315
316
317
318 public String getMaintenanceAction() {
319 return maintenanceAction;
320 }
321
322
323
324
325 public String getBusinessObjectClassName() {
326 return businessObjectClassName;
327 }
328
329
330
331
332 public void setBusinessObjectClassName(String businessObjectClassName) {
333 this.businessObjectClassName = businessObjectClassName;
334 }
335
336
337
338
339 public String getDescription() {
340 return description;
341 }
342
343
344
345
346 public void setDescription(String description) {
347 this.description = description;
348 }
349
350
351
352
353 public boolean isReadOnly() {
354 return readOnly;
355 }
356
357
358
359
360 public void setReadOnly(boolean readOnly) {
361 this.readOnly = readOnly;
362 }
363
364
365
366
367 public Map getNewMaintainableValues() {
368 return newMaintainableValues;
369 }
370
371
372
373
374 public Map getOldMaintainableValues() {
375 return oldMaintainableValues;
376 }
377
378
379
380
381 public void setMaintenanceAction(String maintenanceAction) {
382 this.maintenanceAction = maintenanceAction;
383 }
384
385
386
387
388
389
390 public MaintenanceDocumentRestrictions getAuthorizations() {
391 return authorizations;
392 }
393
394
395
396
397
398
399 public void setAuthorizations(MaintenanceDocumentRestrictions authorizations) {
400 this.authorizations = authorizations;
401 }
402
403
404
405
406
407
408 public void setNewMaintainableValues(Map newMaintainableValues) {
409 this.newMaintainableValues = newMaintainableValues;
410 }
411
412
413
414
415
416
417
418 public void setOldMaintainableValues(Map oldMaintainableValues) {
419 this.oldMaintainableValues = oldMaintainableValues;
420 }
421
422
423 public String getLookupResultsSequenceNumber() {
424 return lookupResultsSequenceNumber;
425 }
426
427
428 public void setLookupResultsSequenceNumber(String lookupResultsSequenceNumber) {
429 this.lookupResultsSequenceNumber = lookupResultsSequenceNumber;
430 }
431
432
433 public String getLookupResultsBOClassName() {
434 return lookupResultsBOClassName;
435 }
436
437
438 public void setLookupResultsBOClassName(String lookupResultsBOClassName) {
439 this.lookupResultsBOClassName = lookupResultsBOClassName;
440 }
441
442
443 public String getLookedUpCollectionName() {
444 return lookedUpCollectionName;
445 }
446
447
448 public void setLookedUpCollectionName(String lookedUpCollectionName) {
449 this.lookedUpCollectionName = lookedUpCollectionName;
450 }
451
452 public String getAdditionalSectionsFile() {
453 if ( businessObjectClassName != null ) {
454 try {
455 MaintenanceDocumentDictionaryService maintenanceDocumentDictionaryService = KNSServiceLocator
456 .getMaintenanceDocumentDictionaryService();
457 String docTypeName = maintenanceDocumentDictionaryService.getDocumentTypeName(Class.forName(businessObjectClassName));
458 return maintenanceDocumentDictionaryService.getMaintenanceDocumentEntry(businessObjectClassName).getAdditionalSectionsFile();
459 } catch ( ClassNotFoundException ex ) {
460 LOG.error( "Unable to resolve business object class", ex);
461 }
462 }else{
463 MaintenanceDocumentDictionaryService maintenanceDocumentDictionaryService = KNSServiceLocator
464 .getMaintenanceDocumentDictionaryService();
465 return maintenanceDocumentDictionaryService.getMaintenanceDocumentEntry(this.getDocTypeName()).getAdditionalSectionsFile();
466 }
467 return null;
468 }
469
470
471
472
473
474
475 @Override
476 public String retrieveFormValueForLookupInquiryParameters(String parameterName, String parameterValueLocation) {
477 MaintenanceDocument maintDoc = (MaintenanceDocument) getDocument();
478 if (parameterValueLocation.toLowerCase().startsWith(KRADConstants.MAINTENANCE_OLD_MAINTAINABLE.toLowerCase())) {
479 String propertyName = parameterValueLocation.substring(KRADConstants.MAINTENANCE_OLD_MAINTAINABLE.length());
480 if (maintDoc.getOldMaintainableObject() != null && maintDoc.getOldMaintainableObject().getBusinessObject() != null) {
481 Object parameterValue = ObjectUtils.getPropertyValue(maintDoc.getOldMaintainableObject().getBusinessObject(), propertyName);
482 if (parameterValue == null) {
483 return null;
484 }
485 if (parameterValue instanceof String) {
486 return (String) parameterValue;
487 }
488 Formatter formatter = Formatter.getFormatter(parameterValue.getClass());
489 return (String) formatter.format(parameterValue);
490 }
491 }
492 if (parameterValueLocation.toLowerCase().startsWith(KRADConstants.MAINTENANCE_NEW_MAINTAINABLE.toLowerCase())) {
493
494 String propertyName = parameterValueLocation.substring(KRADConstants.MAINTENANCE_NEW_MAINTAINABLE.length());
495 String addPrefix = KRADConstants.ADD_PREFIX.toLowerCase() + ".";
496
497 if (propertyName.toLowerCase().startsWith(addPrefix)) {
498 propertyName = propertyName.substring(addPrefix.length());
499 String collectionName = parseAddCollectionName(propertyName);
500 propertyName = propertyName.substring(collectionName.length());
501 if (propertyName.startsWith(".")) { propertyName = propertyName.substring(1); }
502 PersistableBusinessObject newCollectionLine =
503 maintDoc.getNewMaintainableObject().getNewCollectionLine(collectionName);
504 Object parameterValue = ObjectUtils.getPropertyValue(newCollectionLine, propertyName);
505 if (parameterValue == null) {
506 return null;
507 }
508 if (parameterValue instanceof String) {
509 return (String) parameterValue;
510 }
511 Formatter formatter = Formatter.getFormatter(parameterValue.getClass());
512 return (String) formatter.format(parameterValue);
513 } else if (maintDoc.getNewMaintainableObject() != null && maintDoc.getNewMaintainableObject().getBusinessObject() != null) {
514 Object parameterValue = ObjectUtils.getPropertyValue(maintDoc.getNewMaintainableObject().getBusinessObject(), propertyName);
515 if (parameterValue == null) {
516 return null;
517 }
518 if (parameterValue instanceof String) {
519 return (String) parameterValue;
520 }
521 Formatter formatter = Formatter.getFormatter(parameterValue.getClass());
522 return (String) formatter.format(parameterValue);
523 }
524 }
525 return super.retrieveFormValueForLookupInquiryParameters(parameterName, parameterValueLocation);
526 }
527
528
529
530
531
532
533
534
535 protected String parseAddCollectionName(String propertyName) {
536 StringBuilder collectionNameBuilder = new StringBuilder();
537
538 boolean firstPathElement = true;
539 for (String pathElement : propertyName.split("\\.")) if (!StringUtils.isBlank(pathElement)) {
540 if (firstPathElement) {
541 firstPathElement = false;
542 } else {
543 collectionNameBuilder.append(".");
544 }
545 collectionNameBuilder.append(pathElement);
546 if (!(pathElement.endsWith("]") && pathElement.contains("["))) break;
547 }
548 String collectionName = collectionNameBuilder.toString();
549 return collectionName;
550 }
551
552
553
554
555
556
557
558 @Override
559 public boolean shouldPropertyBePopulatedInForm(
560 String requestParameterName, HttpServletRequest request) {
561
562
563 String methodToCallActionName = request.getParameter(KRADConstants.DISPATCH_REQUEST_PARAMETER);
564 if (StringUtils.equals(methodToCallActionName, KRADConstants.MAINTENANCE_COPY_METHOD_TO_CALL) ||
565 StringUtils.equals(methodToCallActionName, KRADConstants.MAINTENANCE_EDIT_METHOD_TO_CALL) ||
566 StringUtils.equals(methodToCallActionName, KRADConstants.MAINTENANCE_NEW_METHOD_TO_CALL) ||
567 StringUtils.equals(methodToCallActionName, KRADConstants.MAINTENANCE_NEWWITHEXISTING_ACTION) ||
568 StringUtils.equals(methodToCallActionName, KRADConstants.MAINTENANCE_DELETE_METHOD_TO_CALL)) {
569 return true;
570 }
571 if ( StringUtils.indexOf(methodToCallActionName, KRADConstants.TOGGLE_INACTIVE_METHOD ) == 0 ) {
572 return true;
573 }
574 return super.shouldPropertyBePopulatedInForm(requestParameterName, request);
575 }
576
577
578
579
580
581
582 @Override
583 public boolean shouldMethodToCallParameterBeUsed(
584 String methodToCallParameterName,
585 String methodToCallParameterValue, HttpServletRequest request) {
586
587 if (StringUtils.equals(methodToCallParameterValue, KRADConstants.MAINTENANCE_COPY_METHOD_TO_CALL) ||
588 StringUtils.equals(methodToCallParameterValue, KRADConstants.MAINTENANCE_EDIT_METHOD_TO_CALL) ||
589 StringUtils.equals(methodToCallParameterValue, KRADConstants.MAINTENANCE_NEW_METHOD_TO_CALL) ||
590 StringUtils.equals(methodToCallParameterValue, KRADConstants.MAINTENANCE_NEWWITHEXISTING_ACTION) ||
591 StringUtils.equals(methodToCallParameterValue, KRADConstants.MAINTENANCE_DELETE_METHOD_TO_CALL)) {
592 return true;
593 }
594 if ( StringUtils.indexOf(methodToCallParameterName, KRADConstants.DISPATCH_REQUEST_PARAMETER + "." + KRADConstants.TOGGLE_INACTIVE_METHOD ) == 0 ) {
595 return true;
596 }
597 return super.shouldMethodToCallParameterBeUsed(methodToCallParameterName,
598 methodToCallParameterValue, request);
599 }
600 }
601
602