View Javadoc
1   /**
2    * Copyright 2005-2015 The Kuali Foundation
3    *
4    * Licensed under the Educational Community License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    * http://www.opensource.org/licenses/ecl2.php
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  package org.kuali.rice.kns.web.struts.form;
17  
18  import java.lang.reflect.Constructor;
19  import java.lang.reflect.InvocationTargetException;
20  import java.util.Enumeration;
21  import java.util.HashMap;
22  import java.util.Iterator;
23  import java.util.List;
24  import java.util.Map;
25  import java.util.regex.Matcher;
26  import java.util.regex.Pattern;
27  
28  import javax.servlet.http.HttpServletRequest;
29  
30  import org.apache.commons.beanutils.PropertyUtils;
31  import org.apache.commons.lang.StringUtils;
32  import org.apache.struts.upload.FormFile;
33  import org.kuali.rice.core.api.config.ConfigurationException;
34  import org.kuali.rice.core.api.util.RiceKeyConstants;
35  import org.kuali.rice.core.web.format.FormatException;
36  import org.kuali.rice.core.web.format.Formatter;
37  import org.kuali.rice.kew.api.WorkflowDocument;
38  import org.kuali.rice.kim.api.services.KimApiServiceLocator;
39  import org.kuali.rice.kns.document.MaintenanceDocument;
40  import org.kuali.rice.kns.document.MaintenanceDocumentBase;
41  import org.kuali.rice.kns.document.authorization.MaintenanceDocumentRestrictions;
42  import org.kuali.rice.kns.maintenance.Maintainable;
43  import org.kuali.rice.kns.service.KNSServiceLocator;
44  import org.kuali.rice.kns.service.MaintenanceDocumentDictionaryService;
45  import org.kuali.rice.kns.util.FieldUtils;
46  import org.kuali.rice.krad.bo.BusinessObject;
47  import org.kuali.rice.krad.bo.PersistableAttachment;
48  import org.kuali.rice.krad.datadictionary.exception.UnknownDocumentTypeException;
49  import org.kuali.rice.krad.document.Document;
50  import org.kuali.rice.krad.service.KRADServiceLocatorWeb;
51  import org.kuali.rice.krad.util.GlobalVariables;
52  import org.kuali.rice.krad.util.KRADConstants;
53  import org.kuali.rice.krad.util.ObjectUtils;
54  
55  /**
56   * This class is the base action form for all maintenance documents.
57   * 
58   * @deprecated Use {@link org.kuali.rice.krad.web.form.MaintenanceDocumentForm}.
59   */
60  @Deprecated
61  public class KualiMaintenanceForm extends KualiDocumentFormBase {
62      protected static final org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(KualiMaintenanceForm.class);
63  
64      protected static final long serialVersionUID = 1L;
65  
66      protected String businessObjectClassName;
67      protected String description;
68      protected boolean readOnly;
69      protected Map<String, String> oldMaintainableValues;
70      protected Map<String, String> newMaintainableValues;
71      protected String maintenanceAction;
72      private static final Pattern ELEMENT_IN_COLLECTION = Pattern.compile("(.*)(\\[)([0-9]*)(\\])(.*)");
73  
74  
75  	/**
76       * @see KualiDocumentFormBase#addRequiredNonEditableProperties()
77       */
78      @Override
79      public void addRequiredNonEditableProperties(){
80      	super.addRequiredNonEditableProperties();
81      	registerRequiredNonEditableProperty(KRADConstants.BUSINESS_OBJECT_CLASS_ATTRIBUTE);
82      	registerRequiredNonEditableProperty(KRADConstants.LOOKUP_RESULTS_BO_CLASS_NAME);
83      	registerRequiredNonEditableProperty(KRADConstants.LOOKED_UP_COLLECTION_NAME);
84      	registerRequiredNonEditableProperty(KRADConstants.LOOKUP_RESULTS_SEQUENCE_NUMBER);
85      	registerRequiredNonEditableProperty(KRADConstants.FIELD_NAME_TO_FOCUS_ON_AFTER_SUBMIT);
86      }
87  
88      /**
89       * Used to indicate which result set we're using when refreshing/returning from a multi-value lookup
90       */
91      protected String lookupResultsSequenceNumber;
92      /**
93       * The type of result returned by the multi-value lookup
94       * 
95       * TODO: to be persisted in the lookup results service instead?
96       */
97      protected String lookupResultsBOClassName;
98      
99      /**
100      * The name of the collection looked up (by a multiple value lookup)
101      */
102     protected String lookedUpCollectionName;
103     
104     protected MaintenanceDocumentRestrictions authorizations;
105     
106     /**
107      * Override the default method to add the if statement which can't be called until after parameters from a multipart request
108      * have been made accessible, but which must be called before the parameter values are used to instantiate and populate business
109      * objects.
110      * 
111      * @param requestParameters
112      */
113     @Override
114     public void postprocessRequestParameters(Map requestParameters) {
115         super.postprocessRequestParameters(requestParameters);
116 
117         String docTypeName = null;
118         String[] docTypeNames = (String[]) requestParameters.get(KRADConstants.DOCUMENT_TYPE_NAME);
119         if ((docTypeNames != null) && (docTypeNames.length > 0)) {
120             docTypeName = docTypeNames[0];
121         }
122 
123         if (StringUtils.isNotBlank(docTypeName)) {          
124         	if(this.getDocument() == null){
125             setDocTypeName(docTypeName);
126             Class documentClass = KRADServiceLocatorWeb.getDataDictionaryService().getDocumentClassByTypeName(docTypeName);
127             if (documentClass == null) {
128                 throw new UnknownDocumentTypeException("unable to get class for unknown documentTypeName '" + docTypeName + "'");
129             }
130             if (!MaintenanceDocumentBase.class.isAssignableFrom(documentClass)) {
131                 throw new ConfigurationException("Document class '" + documentClass + "' is not assignable to '" + MaintenanceDocumentBase.class + "'");
132             }
133             Document document = null;
134             try {
135                 Class[] defaultConstructor = new Class[]{String.class};
136                 Constructor cons = documentClass.getConstructor(defaultConstructor);
137                 if (ObjectUtils.isNull(cons)) {
138                     throw new ConfigurationException("Could not find constructor with document type name parameter needed for Maintenance Document Base class");
139                 }
140                 document = (Document) cons.newInstance(docTypeName);
141             } catch (SecurityException e) {
142                 throw new RuntimeException("Error instantiating Maintenance Document", e);
143             } catch (NoSuchMethodException e) {
144                 throw new RuntimeException("Error instantiating Maintenance Document: No constructor with String parameter found", e);
145             } catch (IllegalAccessException e) {
146                 throw new RuntimeException("Error instantiating Maintenance Document", e);
147             } catch (InstantiationException e) {
148                 throw new RuntimeException("Error instantiating Maintenance Document", e);
149             } catch (IllegalArgumentException e) {
150                 throw new RuntimeException("Error instantiating Maintenance Document", e);
151             } catch (InvocationTargetException e) {
152                 throw new RuntimeException("Error instantiating Maintenance Document", e);
153             }
154             if (document == null) {
155                 throw new RuntimeException("Unable to instantiate document with type name '" + docTypeName + "' and document class '" + documentClass + "'");
156             }
157             setDocument(document);
158           } 
159        }
160         
161         MaintenanceDocumentBase maintenanceDocument = (MaintenanceDocumentBase) getDocument();
162 
163         //Handling the Multi-Part Attachment
164         for ( Object obj : requestParameters.entrySet() ) {
165             String parameter = (String)((Map.Entry)obj).getKey(); 
166             if (parameter.toUpperCase().startsWith(KRADConstants.MAINTENANCE_NEW_MAINTAINABLE.toUpperCase())) {
167                 String propertyName = parameter.substring(KRADConstants.MAINTENANCE_NEW_MAINTAINABLE.length());
168                 Object propertyValue = requestParameters.get(parameter);
169                 
170                 if(propertyValue != null && propertyValue instanceof FormFile) {
171                     populateAttachmentFile(maintenanceDocument, propertyName, (FormFile) propertyValue);
172                     if (propertyName.startsWith(KRADConstants.MAINTENANCE_ADD_PREFIX)) {
173                         String parsedPropertyName = propertyName.substring(
174                                 KRADConstants.MAINTENANCE_ADD_PREFIX.length());
175                         String collectionName = parseAddCollectionName(parseAddCollectionName(parsedPropertyName));
176                         maintenanceDocument.setAttachmentCollectionName(collectionName);
177                         maintenanceDocument.setAttachmentListPropertyName(propertyName.substring(KRADConstants.MAINTENANCE_ADD_PREFIX.length()).substring(collectionName.length() + 1));
178                     } else {
179                         //if property not part of collection
180                         Matcher matcher = ELEMENT_IN_COLLECTION.matcher(propertyName);
181                         if (!matcher.matches()) {
182                             maintenanceDocument.setAttachmentPropertyName(propertyName);
183                         }
184                     }
185                 }
186             }
187         }
188     }
189 
190     private void populateAttachmentFile(MaintenanceDocumentBase maintenanceDocument, String propertyName, FormFile propertyValue) {
191          if(StringUtils.isNotEmpty(((FormFile)propertyValue).getFileName())) {
192  	 	 	 Object boClass;
193              String boPropertyName;
194 
195              Matcher matcher = ELEMENT_IN_COLLECTION.matcher(propertyName);
196              if (propertyName.startsWith(KRADConstants.MAINTENANCE_ADD_PREFIX)) {
197                  String prefix = matcher.matches() ? "" : KRADConstants.MAINTENANCE_ADD_PREFIX;
198                  String collectionName = parseAddCollectionName(propertyName.substring(prefix.length()));
199                  boClass = maintenanceDocument.getNewMaintainableObject().getNewCollectionLine(collectionName);
200                  boPropertyName = propertyName.substring(prefix.length()).substring(collectionName.length() + 1);
201 
202                  setAttachmentProperty(boClass, boPropertyName, propertyValue);
203              } else {
204                  boClass = maintenanceDocument.getNewMaintainableObject().getBusinessObject();
205                  boPropertyName = propertyName;
206                  if(StringUtils.isNotEmpty(((FormFile)propertyValue).getFileName())
207                          && !matcher.matches()) {
208                      maintenanceDocument.setFileAttachment((FormFile) propertyValue);
209                  }
210                  setAttachmentProperty(boClass, boPropertyName, propertyValue);
211              }
212          }
213     }
214 
215     private void setAttachmentProperty(Object boClass, String propertyName, Object propertyValue) {
216         try {
217             PropertyUtils.setProperty(boClass, propertyName, propertyValue);
218         } catch (InvocationTargetException e) {
219             throw new RuntimeException("no setter for property '" + boClass.getClass().getName() + "." + propertyName + "'", e);
220         } catch (NoSuchMethodException e) {
221             throw new RuntimeException("no setter for property '" + boClass.getClass().getName() + "." + propertyName + "'", e);
222         } catch (IllegalAccessException e) {
223             throw new RuntimeException("problem accessing property '" + boClass.getClass().getName() + "." + propertyName + "'", e);
224         }
225     }
226 
227     /**
228      * Hook into populate so we can set the maintenance documents and feed the field values to its maintainables.
229      */
230     @Override
231     public void populate(HttpServletRequest request) {
232         super.populate(request);
233 
234 
235         // document type name is null on start, otherwise should be here
236         if (StringUtils.isNotBlank(getDocTypeName())) {
237             Map<String, String> localOldMaintainableValues = new HashMap<String, String>();
238             Map<String, String> localNewMaintainableValues = new HashMap<String, String>();
239             Map<String,String> localNewCollectionValues = new HashMap<String,String>();
240             for (Enumeration i = request.getParameterNames(); i.hasMoreElements();) {
241                 String parameter = (String) i.nextElement();
242                 if (parameter.toUpperCase().startsWith(KRADConstants.MAINTENANCE_OLD_MAINTAINABLE.toUpperCase())) {
243                 	if (shouldPropertyBePopulatedInForm(parameter, request)) {
244                         String propertyName = parameter.substring(KRADConstants.MAINTENANCE_OLD_MAINTAINABLE.length());
245                         localOldMaintainableValues.put(propertyName, request.getParameter(parameter));
246                     }
247                 }
248                 if (parameter.toUpperCase().startsWith(KRADConstants.MAINTENANCE_NEW_MAINTAINABLE.toUpperCase())) {
249                 	if (shouldPropertyBePopulatedInForm(parameter, request)) {
250                         String propertyName = parameter.substring(KRADConstants.MAINTENANCE_NEW_MAINTAINABLE.length());
251                         localNewMaintainableValues.put(propertyName, request.getParameter(parameter));
252                     }
253                 }
254             }
255             
256             // now, get all add lines and store them to a separate map
257             // for use in a separate call to the maintainable
258             for ( Map.Entry<String, String> entry : localNewMaintainableValues.entrySet() ) {
259                 String key = entry.getKey(); 
260                 if ( key.startsWith( KRADConstants.MAINTENANCE_ADD_PREFIX ) ) {
261                     localNewCollectionValues.put( key.substring( KRADConstants.MAINTENANCE_ADD_PREFIX.length() ),
262                             entry.getValue() );
263                 }
264             }
265             if ( LOG.isDebugEnabled() ) {
266                 LOG.debug( "checked for add line parameters - got: " + localNewCollectionValues );
267             }
268             
269             this.newMaintainableValues = localNewMaintainableValues;
270             this.oldMaintainableValues = localOldMaintainableValues;
271 
272             MaintenanceDocumentBase maintenanceDocument = (MaintenanceDocumentBase) getDocument();
273 
274             GlobalVariables.getMessageMap().addToErrorPath("document.oldMaintainableObject");
275             maintenanceDocument.getOldMaintainableObject().populateBusinessObject(localOldMaintainableValues, maintenanceDocument, getMethodToCall());
276             GlobalVariables.getMessageMap().removeFromErrorPath("document.oldMaintainableObject");
277 
278             GlobalVariables.getMessageMap().addToErrorPath("document.newMaintainableObject");
279             // update the main object
280             Map cachedValues = 
281             	maintenanceDocument.getNewMaintainableObject().populateBusinessObject(localNewMaintainableValues, maintenanceDocument, getMethodToCall());
282             
283             if(maintenanceDocument.getFileAttachment() != null) {
284                 populateAttachmentPropertyForBO(maintenanceDocument);
285             }
286             
287             // update add lines
288             localNewCollectionValues = KimApiServiceLocator.getPersonService().resolvePrincipalNamesToPrincipalIds((BusinessObject)maintenanceDocument.getNewMaintainableObject().getBusinessObject(), localNewCollectionValues);
289             cachedValues.putAll( maintenanceDocument.getNewMaintainableObject().populateNewCollectionLines( localNewCollectionValues, maintenanceDocument, getMethodToCall() ) );
290             GlobalVariables.getMessageMap().removeFromErrorPath("document.newMaintainableObject");
291 
292             if (cachedValues.size() > 0) {
293                 GlobalVariables.getMessageMap().putError(KRADConstants.DOCUMENT_ERRORS, RiceKeyConstants.ERROR_DOCUMENT_MAINTENANCE_FORMATTING_ERROR);
294                 for (Iterator iter = cachedValues.keySet().iterator(); iter.hasNext();) {
295                     String propertyName = (String) iter.next();
296                     String value = (String) cachedValues.get(propertyName);
297                     cacheUnconvertedValue(KRADConstants.MAINTENANCE_NEW_MAINTAINABLE + propertyName, value);
298                 }
299             }
300         }
301     }
302 
303     protected void populateAttachmentPropertyForBO(MaintenanceDocumentBase maintenanceDocument) {
304         try {
305             Object dataObject = maintenanceDocument.getNewMaintainableObject().getDataObject();
306             if (dataObject instanceof PersistableAttachment) {
307                 Class type = ObjectUtils.easyGetPropertyType(maintenanceDocument.getNewMaintainableObject().getDataObject(), maintenanceDocument.getAttachmentPropertyName());
308                 ObjectUtils.setObjectProperty(maintenanceDocument.getNewMaintainableObject().getBusinessObject(), maintenanceDocument.getAttachmentPropertyName(), type, maintenanceDocument.getFileAttachment());
309             }
310         } catch (FormatException e) {
311             throw new RuntimeException("Exception occurred while setting attachment property on NewMaintainable bo", e);
312         } catch (IllegalAccessException e) {
313             throw new RuntimeException("Exception occurred while setting attachment property on NewMaintainable bo", e);
314         } catch (NoSuchMethodException e) {
315             throw new RuntimeException("Exception occurred while setting attachment property on NewMaintainable bo", e);
316         } catch (InvocationTargetException e) {
317             throw new RuntimeException("Exception occurred while setting attachment property on NewMaintainable bo", e);
318         }
319     }
320     
321     /**
322      * Merges rows of old and new for each section (tab) of the ui. Also, renames fields to prevent naming conflicts and does
323      * setting of read only fields.
324      * 
325      * @return Returns the maintenanceSections.
326      */
327     public List getSections() {
328         if (getDocument() == null) {
329             throw new RuntimeException("Document not set in maintenance form.");
330         }
331         if (((MaintenanceDocumentBase) getDocument()).getNewMaintainableObject() == null) {
332             throw new RuntimeException("New maintainable not set in document.");
333         }
334         if ((KRADConstants.MAINTENANCE_EDIT_ACTION.equals(this.getMaintenanceAction())
335         		|| KRADConstants.MAINTENANCE_COPY_ACTION.equals(this.getMaintenanceAction())
336         		|| KRADConstants.MAINTENANCE_DELETE_ACTION.equals(this.getMaintenanceAction()))
337         		&& ((MaintenanceDocumentBase) getDocument()).getOldMaintainableObject() == null) {
338             throw new RuntimeException("Old maintainable not set in document.");
339         }
340 
341         // if the authorization stuff hasnt been applied yet, then apply it
342         //if (authorizations == null) {
343         //    applyAuthorizations();
344         //}
345 
346         
347         // get business object being maintained and its keys
348         List keyFieldNames = KRADServiceLocatorWeb.getLegacyDataAdapter().listPrimaryKeyFieldNames(((MaintenanceDocumentBase) getDocument()).getNewMaintainableObject().getBusinessObject().getClass());
349 
350         // sections for maintenance document
351         Maintainable oldMaintainable = ((MaintenanceDocumentBase) getDocument()).getOldMaintainableObject();
352         oldMaintainable.setMaintenanceAction(getMaintenanceAction());
353         List oldMaintSections = oldMaintainable.getSections((MaintenanceDocument) getDocument(), null);
354         
355         Maintainable newMaintainable = ((MaintenanceDocumentBase) getDocument()).getNewMaintainableObject();
356         newMaintainable.setMaintenanceAction(getMaintenanceAction());
357         List newMaintSections = newMaintainable.getSections((MaintenanceDocument) getDocument(), oldMaintainable);
358         WorkflowDocument workflowDocument = this.getDocument().getDocumentHeader().getWorkflowDocument();
359         String documentStatus =  workflowDocument.getStatus().getCode();
360         String documentInitiatorPrincipalId = workflowDocument.getInitiatorPrincipalId();
361         
362 
363         // mesh sections for proper jsp display
364         List meshedSections = FieldUtils
365                 .meshSections(oldMaintSections, newMaintSections, keyFieldNames, getMaintenanceAction(), isReadOnly(),
366                         authorizations, documentStatus, documentInitiatorPrincipalId);
367 
368         return meshedSections;
369     }    
370 
371     /**
372      * @return Returns the maintenanceAction.
373      */
374     public String getMaintenanceAction() {
375         return maintenanceAction;
376     }
377 
378     /**
379      * @return Returns the businessObjectClassName.
380      */
381     public String getBusinessObjectClassName() {
382         return businessObjectClassName;
383     }
384 
385     /**
386      * @param businessObjectClassName The businessObjectClassName to set.
387      */
388     public void setBusinessObjectClassName(String businessObjectClassName) {
389         this.businessObjectClassName = businessObjectClassName;
390     }
391 
392     /**
393      * @return Returns the description.
394      */
395     public String getDescription() {
396         return description;
397     }
398 
399     /**
400      * @param description The description to set.
401      */
402     public void setDescription(String description) {
403         this.description = description;
404     }
405 
406     /**
407      * @return Returns the isReadOnly.
408      */
409     public boolean isReadOnly() {
410         return readOnly;
411     }
412 
413     /**
414      * @param readOnly The isReadOnly to set.
415      */
416     public void setReadOnly(boolean readOnly) {
417         this.readOnly = readOnly;
418     }
419 
420     /**
421      * @return Returns the newMaintainableValues.
422      */
423     public Map getNewMaintainableValues() {
424         return newMaintainableValues;
425     }
426 
427     /**
428      * @return Returns the oldMaintainableValues.
429      */
430     public Map getOldMaintainableValues() {
431         return oldMaintainableValues;
432     }
433 
434     /**
435      * @param maintenanceAction The maintenanceAction to set.
436      */
437     public void setMaintenanceAction(String maintenanceAction) {
438         this.maintenanceAction = maintenanceAction;
439     }
440 
441     /**
442      * Gets the authorizations attribute.
443      * 
444      * @return Returns the authorizations.
445      */
446     public MaintenanceDocumentRestrictions getAuthorizations() {
447         return authorizations;
448     }
449 
450     /**
451      * Sets the authorizations attribute value.
452      * 
453      * @param authorizations The authorizations to set.
454      */
455     public void setAuthorizations(MaintenanceDocumentRestrictions authorizations) {
456         this.authorizations = authorizations;
457     }
458 
459     /**
460      * Sets the newMaintainableValues attribute value.
461      * 
462      * @param newMaintainableValues The newMaintainableValues to set.
463      */
464     public void setNewMaintainableValues(Map newMaintainableValues) {
465         this.newMaintainableValues = newMaintainableValues;
466     }
467 
468 
469     /**
470      * Sets the oldMaintainableValues attribute value.
471      * 
472      * @param oldMaintainableValues The oldMaintainableValues to set.
473      */
474     public void setOldMaintainableValues(Map oldMaintainableValues) {
475         this.oldMaintainableValues = oldMaintainableValues;
476     }
477 
478 
479     public String getLookupResultsSequenceNumber() {
480         return lookupResultsSequenceNumber;
481     }
482 
483 
484     public void setLookupResultsSequenceNumber(String lookupResultsSequenceNumber) {
485         this.lookupResultsSequenceNumber = lookupResultsSequenceNumber;
486     }
487 
488 
489     public String getLookupResultsBOClassName() {
490         return lookupResultsBOClassName;
491     }
492 
493 
494     public void setLookupResultsBOClassName(String lookupResultsBOClassName) {
495         this.lookupResultsBOClassName = lookupResultsBOClassName;
496     }
497 
498 
499     public String getLookedUpCollectionName() {
500         return lookedUpCollectionName;
501     }
502 
503 
504     public void setLookedUpCollectionName(String lookedUpCollectionName) {
505         this.lookedUpCollectionName = lookedUpCollectionName;
506     }
507 
508     public String getAdditionalSectionsFile() {
509         if ( businessObjectClassName != null ) {
510             try {
511                 MaintenanceDocumentDictionaryService maintenanceDocumentDictionaryService = KNSServiceLocator
512                         .getMaintenanceDocumentDictionaryService();
513                 String docTypeName = maintenanceDocumentDictionaryService.getDocumentTypeName(Class.forName(businessObjectClassName));
514                 return maintenanceDocumentDictionaryService.getMaintenanceDocumentEntry(businessObjectClassName).getAdditionalSectionsFile();
515             } catch ( ClassNotFoundException ex ) {
516                 LOG.error( "Unable to resolve business object class", ex);
517             }
518         }else{
519             MaintenanceDocumentDictionaryService maintenanceDocumentDictionaryService = KNSServiceLocator
520                     .getMaintenanceDocumentDictionaryService();
521             return maintenanceDocumentDictionaryService.getMaintenanceDocumentEntry(this.getDocTypeName()).getAdditionalSectionsFile();
522         }
523         return null;
524     }
525 
526 	/**
527 	 * This overridden method handles the case where maint doc properties do not reflect the true nature of the 
528 	 * 
529 	 * @see KualiForm#retrieveFormValueForLookupInquiryParameters(java.lang.String, java.lang.String)
530 	 */
531 	@Override
532 	public String retrieveFormValueForLookupInquiryParameters(String parameterName, String parameterValueLocation) {
533 		MaintenanceDocument maintDoc = (MaintenanceDocument) getDocument();
534 		if (parameterValueLocation.toLowerCase().startsWith(KRADConstants.MAINTENANCE_OLD_MAINTAINABLE.toLowerCase())) {
535 			String propertyName = parameterValueLocation.substring(KRADConstants.MAINTENANCE_OLD_MAINTAINABLE.length());
536 			if (maintDoc.getOldMaintainableObject() != null && maintDoc.getOldMaintainableObject().getBusinessObject() != null) {
537 				Object parameterValue = ObjectUtils.getPropertyValue(maintDoc.getOldMaintainableObject().getBusinessObject(), propertyName);
538 				if (parameterValue == null) {
539 					return null;
540 				}
541 				if (parameterValue instanceof String) {
542 					return (String) parameterValue;
543 				}
544 				Formatter formatter = Formatter.getFormatter(parameterValue.getClass());
545 				return (String) formatter.format(parameterValue); 
546 			}
547 		}
548 		if (parameterValueLocation.toLowerCase().startsWith(KRADConstants.MAINTENANCE_NEW_MAINTAINABLE.toLowerCase())) {
549 			// remove MAINT_NEW_MAINT from the pVL
550 			String propertyName = parameterValueLocation.substring(KRADConstants.MAINTENANCE_NEW_MAINTAINABLE.length());
551 			String addPrefix = KRADConstants.ADD_PREFIX.toLowerCase() + ".";
552 
553 			if (propertyName.toLowerCase().startsWith(addPrefix)) { // 
554 				propertyName = propertyName.substring(addPrefix.length()); // remove addPrefix from the propertyName
555 				String collectionName = parseAddCollectionName(propertyName);
556 				propertyName = propertyName.substring(collectionName.length()); // remove collectionName from pN
557 				if (propertyName.startsWith(".")) { propertyName = propertyName.substring(1); } // strip beginning "."
558 				Object newCollectionLine = 
559 					maintDoc.getNewMaintainableObject().getNewCollectionLine(collectionName);
560 				Object parameterValue = ObjectUtils.getPropertyValue(newCollectionLine, propertyName);
561 				if (parameterValue == null) {
562 					return null;
563 				}
564 				if (parameterValue instanceof String) {
565 					return (String) parameterValue;
566 				}
567 				Formatter formatter = Formatter.getFormatter(parameterValue.getClass());
568 				return (String) formatter.format(parameterValue);
569 			} else if (maintDoc.getNewMaintainableObject() != null && maintDoc.getNewMaintainableObject().getBusinessObject() != null) {
570 				Object parameterValue = ObjectUtils.getPropertyValue(maintDoc.getNewMaintainableObject().getBusinessObject(), propertyName);
571 				if (parameterValue == null) {
572 					return null;
573 				}
574 				if (parameterValue instanceof String) {
575 					return (String) parameterValue;
576 				}
577 				Formatter formatter = Formatter.getFormatter(parameterValue.getClass());
578 				return (String) formatter.format(parameterValue); 
579 			}
580 		}
581 		return super.retrieveFormValueForLookupInquiryParameters(parameterName, parameterValueLocation);
582 	}
583 
584 	/**
585 	 * This method returns the collection name (including nested collections) from a propertyName string
586 	 * 
587 	 * @param propertyName a parameterValueLocation w/ KRADConstants.MAINTENANCE_NEW_MAINTAINABLE +
588 	 * KRADConstants.ADD_PREFIX + "." stripped off the front
589 	 * @return the collectionName
590 	 */
591 	protected String parseAddCollectionName(String propertyName) {
592 		StringBuilder collectionNameBuilder = new StringBuilder();
593 
594 		boolean firstPathElement = true;
595         for (String pathElement : propertyName.split("\\.")) {
596             if (!StringUtils.isBlank(pathElement)) {
597                 if (firstPathElement) {
598                     firstPathElement = false;
599                 } else {
600                     collectionNameBuilder.append(".");
601                 }
602                 collectionNameBuilder.append(pathElement);
603                 if (!(pathElement.endsWith("]") && pathElement.contains("[")))
604                     break;
605             }
606         }
607 		String collectionName = collectionNameBuilder.toString();
608 		return collectionName;
609 	}
610 
611 
612 	/**
613 	 * This overridden method ...
614 	 * 
615 	 * @see KualiDocumentFormBase#shouldPropertyBePopulatedInForm(java.lang.String, javax.servlet.http.HttpServletRequest)
616 	 */
617 	@Override
618 	public boolean shouldPropertyBePopulatedInForm(
619 			String requestParameterName, HttpServletRequest request) {
620 		// the user clicked on a document initiation link
621 		//add delete check for 3070
622 		String methodToCallActionName = request.getParameter(KRADConstants.DISPATCH_REQUEST_PARAMETER);
623 		if (StringUtils.equals(methodToCallActionName, KRADConstants.MAINTENANCE_COPY_METHOD_TO_CALL) ||
624 				StringUtils.equals(methodToCallActionName, KRADConstants.MAINTENANCE_EDIT_METHOD_TO_CALL) ||
625 				StringUtils.equals(methodToCallActionName, KRADConstants.MAINTENANCE_NEW_METHOD_TO_CALL) ||
626 				StringUtils.equals(methodToCallActionName, KRADConstants.MAINTENANCE_NEWWITHEXISTING_ACTION) ||
627 				StringUtils.equals(methodToCallActionName, KRADConstants.MAINTENANCE_DELETE_METHOD_TO_CALL)) {
628 			return true;
629 		}
630 		if ( StringUtils.indexOf(methodToCallActionName, KRADConstants.TOGGLE_INACTIVE_METHOD ) == 0 ) {
631 			return true;
632 		}
633 		return super.shouldPropertyBePopulatedInForm(requestParameterName, request);
634 	}
635 
636 	/**
637 	 * This overridden method ...
638 	 * 
639 	 * @see KualiDocumentFormBase#shouldMethodToCallParameterBeUsed(java.lang.String, java.lang.String, javax.servlet.http.HttpServletRequest)
640 	 */
641 	@Override
642 	public boolean shouldMethodToCallParameterBeUsed(
643 			String methodToCallParameterName,
644 			String methodToCallParameterValue, HttpServletRequest request) {
645 		// the user clicked on a document initiation link
646 		if (StringUtils.equals(methodToCallParameterValue, KRADConstants.MAINTENANCE_COPY_METHOD_TO_CALL) ||
647 				StringUtils.equals(methodToCallParameterValue, KRADConstants.MAINTENANCE_EDIT_METHOD_TO_CALL) ||
648 				StringUtils.equals(methodToCallParameterValue, KRADConstants.MAINTENANCE_NEW_METHOD_TO_CALL) ||
649 				StringUtils.equals(methodToCallParameterValue, KRADConstants.MAINTENANCE_NEWWITHEXISTING_ACTION) ||
650 				StringUtils.equals(methodToCallParameterValue, KRADConstants.MAINTENANCE_DELETE_METHOD_TO_CALL)) {
651 			return true;
652 		}
653 		if ( StringUtils.indexOf(methodToCallParameterName, KRADConstants.DISPATCH_REQUEST_PARAMETER + "." + KRADConstants.TOGGLE_INACTIVE_METHOD ) == 0 ) {
654 			return true;
655 		}
656 		return super.shouldMethodToCallParameterBeUsed(methodToCallParameterName,
657 				methodToCallParameterValue, request);
658 	}
659 }
660 
661