Coverage Report - org.kuali.rice.kns.web.struts.action.KualiMaintenanceDocumentAction
 
Classes in this File Line Coverage Branch Coverage Complexity
KualiMaintenanceDocumentAction
0%
0/405
0%
0/194
5.097
 
 1  
 
 2  
 /*
 3  
  * Copyright 2005-2007 The Kuali Foundation
 4  
  * 
 5  
  * Licensed under the Educational Community License, Version 2.0 (the "License");
 6  
  * you may not use this file except in compliance with the License.
 7  
  * You may obtain a copy of the License at
 8  
  * 
 9  
  * http://www.opensource.org/licenses/ecl2.php
 10  
  * 
 11  
  * Unless required by applicable law or agreed to in writing, software
 12  
  * distributed under the License is distributed on an "AS IS" BASIS,
 13  
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 14  
  * See the License for the specific language governing permissions and
 15  
  * limitations under the License.
 16  
  */
 17  
 package org.kuali.rice.kns.web.struts.action;
 18  
 
 19  
 import java.lang.reflect.Field;
 20  
 import java.lang.reflect.InvocationTargetException;
 21  
 import java.security.GeneralSecurityException;
 22  
 import java.util.ArrayList;
 23  
 import java.util.Collection;
 24  
 import java.util.Enumeration;
 25  
 import java.util.HashMap;
 26  
 import java.util.Iterator;
 27  
 import java.util.List;
 28  
 import java.util.Map;
 29  
 
 30  
 import javax.persistence.PersistenceException;
 31  
 import javax.servlet.http.HttpServletRequest;
 32  
 import javax.servlet.http.HttpServletResponse;
 33  
 
 34  
 import org.apache.commons.beanutils.PropertyUtils;
 35  
 import org.apache.commons.lang.StringUtils;
 36  
 import org.apache.ojb.broker.metadata.ClassNotPersistenceCapableException;
 37  
 import org.apache.struts.action.ActionForm;
 38  
 import org.apache.struts.action.ActionForward;
 39  
 import org.apache.struts.action.ActionMapping;
 40  
 import org.kuali.rice.core.api.encryption.EncryptionService;
 41  
 import org.kuali.rice.core.api.services.CoreApiServiceLocator;
 42  
 import org.kuali.rice.core.framework.persistence.jpa.OrmUtils;
 43  
 import org.kuali.rice.core.framework.persistence.jpa.criteria.Criteria;
 44  
 import org.kuali.rice.core.framework.persistence.jpa.criteria.QueryByCriteria;
 45  
 import org.kuali.rice.core.framework.persistence.jpa.metadata.EntityDescriptor;
 46  
 import org.kuali.rice.core.framework.persistence.jpa.metadata.FieldDescriptor;
 47  
 import org.kuali.rice.core.framework.persistence.jpa.metadata.MetadataManager;
 48  
 import org.kuali.rice.core.util.ClassLoaderUtils;
 49  
 import org.kuali.rice.core.util.RiceConstants;
 50  
 import org.kuali.rice.core.util.RiceKeyConstants;
 51  
 import org.kuali.rice.core.web.format.Formatter;
 52  
 import org.kuali.rice.kew.util.KEWConstants;
 53  
 import org.kuali.rice.kim.bo.Person;
 54  
 import org.kuali.rice.kns.bo.DocumentAttachment;
 55  
 import org.kuali.rice.kns.bo.PersistableAttachment;
 56  
 import org.kuali.rice.kns.bo.PersistableBusinessObject;
 57  
 import org.kuali.rice.kns.bo.PersistableBusinessObjectExtension;
 58  
 import org.kuali.rice.kns.datadictionary.DocumentEntry;
 59  
 import org.kuali.rice.kns.datadictionary.MaintainableCollectionDefinition;
 60  
 import org.kuali.rice.kns.document.MaintenanceDocument;
 61  
 import org.kuali.rice.kns.document.MaintenanceDocumentBase;
 62  
 import org.kuali.rice.kns.document.authorization.MaintenanceDocumentAuthorizer;
 63  
 import org.kuali.rice.kns.document.authorization.MaintenanceDocumentRestrictions;
 64  
 import org.kuali.rice.kns.exception.DocumentTypeAuthorizationException;
 65  
 import org.kuali.rice.kns.lookup.LookupResultsService;
 66  
 import org.kuali.rice.kns.maintenance.Maintainable;
 67  
 import org.kuali.rice.kns.rule.event.KualiAddLineEvent;
 68  
 import org.kuali.rice.kns.service.*;
 69  
 import org.kuali.rice.kns.util.GlobalVariables;
 70  
 import org.kuali.rice.kns.util.KNSConstants;
 71  
 import org.kuali.rice.kns.util.KNSPropertyConstants;
 72  
 import org.kuali.rice.kns.util.MaintenanceUtils;
 73  
 import org.kuali.rice.kns.util.ObjectUtils;
 74  
 import org.kuali.rice.kns.util.WebUtils;
 75  
 import org.kuali.rice.kns.web.struts.form.KualiDocumentFormBase;
 76  
 import org.kuali.rice.kns.web.struts.form.KualiForm;
 77  
 import org.kuali.rice.kns.web.struts.form.KualiMaintenanceForm;
 78  
 
 79  
 /**
 80  
  * This class handles actions for maintenance documents. These include creating new edit, and copying of maintenance records.
 81  
  */
 82  
 public class KualiMaintenanceDocumentAction extends KualiDocumentActionBase {
 83  0
     protected static final org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(KualiMaintenanceDocumentAction.class);
 84  
 
 85  0
     protected MaintenanceDocumentDictionaryService maintenanceDocumentDictionaryService = null;
 86  
     protected EncryptionService encryptionService;
 87  
     protected LookupService lookupService;
 88  
     protected LookupResultsService lookupResultsService;
 89  
 
 90  
         public KualiMaintenanceDocumentAction() {
 91  0
                 super();
 92  0
                 maintenanceDocumentDictionaryService = KNSServiceLocatorWeb.getMaintenanceDocumentDictionaryService();
 93  0
                 encryptionService = CoreApiServiceLocator.getEncryptionService();
 94  0
         }
 95  
 
 96  
         @Override
 97  
         public ActionForward execute(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {        
 98  0
                 request.setAttribute(KNSConstants.PARAM_MAINTENANCE_VIEW_MODE, KNSConstants.PARAM_MAINTENANCE_VIEW_MODE_MAINTENANCE);
 99  0
                 return super.execute(mapping, form, request, response);
 100  
         }
 101  
 
 102  
         /**
 103  
          * Calls setup Maintenance for new action.
 104  
          */
 105  
         public ActionForward start(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
 106  0
                 request.setAttribute(KNSConstants.MAINTENANCE_ACTN, KNSConstants.MAINTENANCE_NEW_ACTION);
 107  0
                 return setupMaintenance(mapping, form, request, response, KNSConstants.MAINTENANCE_NEW_ACTION);
 108  
         }
 109  
 
 110  
         /**
 111  
          * Calls setupMaintenance for copy action.
 112  
          */
 113  
         public ActionForward copy(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
 114  
                 // check for copy document number
 115  0
                 if (request.getParameter("document." + KNSPropertyConstants.DOCUMENT_NUMBER) == null) { // object copy
 116  0
                         return setupMaintenance(mapping, form, request, response, KNSConstants.MAINTENANCE_COPY_ACTION);
 117  
                 }
 118  
                 else { // document copy
 119  0
                         throw new UnsupportedOperationException("System does not support copying of maintenance documents.");
 120  
                 }
 121  
         }
 122  
 
 123  
         /**
 124  
          * Calls setupMaintenance for edit action.
 125  
          */
 126  
         public ActionForward edit(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
 127  
         
 128  0
                 return setupMaintenance(mapping, form, request, response, KNSConstants.MAINTENANCE_EDIT_ACTION);
 129  
         }
 130  
 
 131  
         /**
 132  
          * KUALRice 3070 Calls setupMaintenance for delete action.
 133  
          */
 134  
         public ActionForward delete(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
 135  0
                 if (isFormRepresentingLockObject((KualiDocumentFormBase)form)) {
 136  0
                          return super.delete(mapping, form, request, response);
 137  
                 }
 138  0
                 GlobalVariables.getMessageList().add(RiceKeyConstants.MESSAGE_DELETE);
 139  0
                 return setupMaintenance(mapping, form, request, response, KNSConstants.MAINTENANCE_DELETE_ACTION);
 140  
         }
 141  
         
 142  
         /**
 143  
          * Calls setupMaintenance for new object that have existing objects attributes.
 144  
          */
 145  
         public ActionForward newWithExisting(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
 146  0
                 return setupMaintenance(mapping, form, request, response, KNSConstants.MAINTENANCE_NEWWITHEXISTING_ACTION);
 147  
         }
 148  
 
 149  
         /**
 150  
          * Gets a new document for a maintenance record. The maintainable is specified with the documentTypeName or business object
 151  
          * class request parameter and request parameters are parsed for key values for retrieving the business object. Forward to the
 152  
          * maintenance jsp which renders the page based on the maintainable's field specifications. Retrieves an existing business
 153  
          * object for edit and copy. Checks locking on edit.
 154  
          */
 155  
     protected ActionForward setupMaintenance(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response, String maintenanceAction) throws Exception {
 156  0
                 KualiMaintenanceForm maintenanceForm = (KualiMaintenanceForm) form;
 157  0
                 MaintenanceDocument document = null;
 158  
 
 159  
                 // create a new document object, if required (on NEW object, or other reasons)
 160  0
                 if (maintenanceForm.getDocument() == null) {
 161  0
                         if (StringUtils.isEmpty(maintenanceForm.getBusinessObjectClassName()) && StringUtils.isEmpty(maintenanceForm.getDocTypeName())) {
 162  0
                                 throw new IllegalArgumentException("Document type name or bo class not given!");
 163  
                         }
 164  
 
 165  0
                         String documentTypeName = maintenanceForm.getDocTypeName();
 166  
                         // get document type if not passed
 167  0
                         if (StringUtils.isEmpty(documentTypeName)) {
 168  0
                                 documentTypeName = maintenanceDocumentDictionaryService.getDocumentTypeName(Class.forName(maintenanceForm.getBusinessObjectClassName()));
 169  0
                                 maintenanceForm.setDocTypeName(documentTypeName);
 170  
                         }
 171  
 
 172  0
                         if (StringUtils.isEmpty(documentTypeName)) {
 173  0
                                 throw new RuntimeException("documentTypeName is empty; does this Business Object have a maintenance document definition? " + maintenanceForm.getBusinessObjectClassName());
 174  
                         }
 175  
 
 176  
                         // check doc type allows new or copy if that action was requested
 177  0
                         if (KNSConstants.MAINTENANCE_NEW_ACTION.equals(maintenanceAction) || KNSConstants.MAINTENANCE_COPY_ACTION.equals(maintenanceAction)) {
 178  0
                                 Class boClass = maintenanceDocumentDictionaryService.getBusinessObjectClass(documentTypeName);
 179  0
                                 boolean allowsNewOrCopy = getBusinessObjectAuthorizationService().canCreate(boClass, GlobalVariables.getUserSession().getPerson(), documentTypeName);
 180  0
                                 if (!allowsNewOrCopy) {
 181  0
                                         LOG.error("Document type " + documentTypeName + " does not allow new or copy actions.");
 182  0
                                         throw new DocumentTypeAuthorizationException(GlobalVariables.getUserSession().getPerson().getPrincipalId(), "newOrCopy", documentTypeName);
 183  
                                 }
 184  
                         }
 185  
 
 186  
                         // get new document from service
 187  0
                         document = (MaintenanceDocument) getDocumentService().getNewDocument(maintenanceForm.getDocTypeName());
 188  
                         // Check for an auto-incrementing PK and set it if needed
 189  
                         //            if (document.getNewMaintainableObject().getBoClass().isAnnotationPresent(Sequence.class)) {
 190  
                         //                            Sequence sequence = (Sequence) document.getNewMaintainableObject().getBoClass().getAnnotation(Sequence.class);
 191  
                         //                            Long pk = OrmUtils.getNextAutoIncValue(sequence);
 192  
                         //                            OrmUtils.populateAutoIncValue(document.getOldMaintainableObject().getBusinessObject(), pk);
 193  
                         //                            OrmUtils.populateAutoIncValue(document.getNewMaintainableObject().getBusinessObject(), pk);
 194  
                         //                            document.getOldMaintainableObject().getBusinessObject().setAutoIncrementSet(true);
 195  
                         //                            document.getNewMaintainableObject().getBusinessObject().setAutoIncrementSet(true);
 196  
                         //            }
 197  0
                         maintenanceForm.setDocument(document);
 198  0
                 }
 199  
                 else {
 200  0
                         document = (MaintenanceDocument) maintenanceForm.getDocument();
 201  
                 }
 202  
 
 203  
                 // retrieve business object from request parameters
 204  0
                 if (!(KNSConstants.MAINTENANCE_NEW_ACTION.equals(maintenanceAction)) && !(KNSConstants.MAINTENANCE_NEWWITHEXISTING_ACTION.equals(maintenanceAction))) {
 205  0
                         Map requestParameters = buildKeyMapFromRequest(document.getNewMaintainableObject(), request);
 206  0
             PersistableBusinessObject oldBusinessObject = null;
 207  
             try {
 208  0
                     oldBusinessObject = (PersistableBusinessObject) getLookupService().findObjectBySearch(Class.forName(maintenanceForm.getBusinessObjectClassName()), requestParameters);
 209  0
             } catch ( ClassNotPersistenceCapableException ex ) {
 210  0
                     if ( !document.getOldMaintainableObject().isExternalBusinessObject() ) {
 211  0
                             throw new RuntimeException( "BO Class: " + maintenanceForm.getBusinessObjectClassName() + " is not persistable and is not externalizable - configuration error" );
 212  
                     }
 213  
                     // otherwise, let fall through
 214  0
             }
 215  0
                         if (oldBusinessObject == null && !document.getOldMaintainableObject().isExternalBusinessObject()) {
 216  0
                 throw new RuntimeException("Cannot retrieve old record for maintenance document, incorrect parameters passed on maint url: " + requestParameters );
 217  
                         } 
 218  
 
 219  0
                         if(document.getOldMaintainableObject().isExternalBusinessObject()){
 220  0
                     if ( oldBusinessObject == null ) {
 221  
                             try {
 222  0
                                     oldBusinessObject = (PersistableBusinessObject)document.getOldMaintainableObject().getBoClass().newInstance();
 223  0
                             } catch ( Exception ex ) {
 224  0
                                     throw new RuntimeException( "External BO maintainable was null and unable to instantiate for old maintainable object.", ex );
 225  0
                             }
 226  
                     }
 227  0
                                 populateBOWithCopyKeyValues(request, oldBusinessObject, document.getOldMaintainableObject());
 228  0
                                 document.getOldMaintainableObject().prepareBusinessObject(oldBusinessObject);
 229  0
                     oldBusinessObject = document.getOldMaintainableObject().getBusinessObject();
 230  
                         }
 231  
 
 232  
                         // Temp solution for loading extension objects - need to find a better way
 233  0
                         final String TMP_NM = oldBusinessObject.getClass().getName();
 234  0
                         final int START_INDEX = TMP_NM.indexOf('.', TMP_NM.indexOf('.') + 1) + 1;
 235  0
                         if ( ( OrmUtils.isJpaEnabled() || OrmUtils.isJpaEnabled(TMP_NM.substring(START_INDEX, TMP_NM.indexOf('.', TMP_NM.indexOf('.', START_INDEX) + 1))) ) &&
 236  
                                         OrmUtils.isJpaAnnotated(oldBusinessObject.getClass()) && oldBusinessObject.getExtension() != null && OrmUtils.isJpaAnnotated(oldBusinessObject.getExtension().getClass())) {
 237  0
                                 if (oldBusinessObject.getExtension() != null) {
 238  0
                                         PersistableBusinessObjectExtension boe = oldBusinessObject.getExtension();
 239  0
                                         EntityDescriptor entity = MetadataManager.getEntityDescriptor(oldBusinessObject.getExtension().getClass());
 240  0
                                         Criteria extensionCriteria = new Criteria(boe.getClass().getName());
 241  0
                                         for (FieldDescriptor fieldDescriptor : entity.getPrimaryKeys()) {
 242  
                                                 try {
 243  0
                                                         Field field = oldBusinessObject.getClass().getDeclaredField(fieldDescriptor.getName());
 244  0
                                                         field.setAccessible(true);
 245  0
                                                         extensionCriteria.eq(fieldDescriptor.getName(), field.get(oldBusinessObject));
 246  0
                                                 } catch (Exception e) {
 247  0
                                                         LOG.error(e.getMessage(),e);
 248  0
                                                 }
 249  
                                         }                                
 250  
                                         try {
 251  0
                                                 boe = (PersistableBusinessObjectExtension) new QueryByCriteria(getEntityManagerFactory().createEntityManager(), extensionCriteria).toQuery().getSingleResult();
 252  0
                                         } catch (PersistenceException e) {}
 253  0
                                         oldBusinessObject.setExtension(boe);
 254  
                                 }
 255  
                         }
 256  
 
 257  0
                         PersistableBusinessObject newBusinessObject = (PersistableBusinessObject) ObjectUtils.deepCopy(oldBusinessObject);
 258  
 
 259  
                         // set business object instance for editing
 260  0
                         Class<? extends PersistableBusinessObject> businessObjectClass = ClassLoaderUtils.getClass(maintenanceForm.getBusinessObjectClassName(), PersistableBusinessObject.class); 
 261  0
                         document.getOldMaintainableObject().setBusinessObject(oldBusinessObject);
 262  0
                         document.getOldMaintainableObject().setBoClass(businessObjectClass);
 263  0
                         document.getNewMaintainableObject().setBusinessObject(newBusinessObject);
 264  0
                         document.getNewMaintainableObject().setBoClass(businessObjectClass);
 265  
 
 266  
                         // on a COPY, clear any fields that this user isnt authorized for, and also
 267  
                         // clear the primary key fields
 268  0
                         if (KNSConstants.MAINTENANCE_COPY_ACTION.equals(maintenanceAction)) {
 269  0
                                 if (!document.isFieldsClearedOnCopy()) {
 270  
                                         //for issue KULRice 3072
 271  0
                                         Class boClass = maintenanceDocumentDictionaryService.getBusinessObjectClass(maintenanceForm.getDocTypeName());
 272  0
                                         if(!maintenanceDocumentDictionaryService.getPreserveLockingKeysOnCopy(boClass))
 273  0
                                                 clearPrimaryKeyFields(document);
 274  
 
 275  0
                                         clearUnauthorizedNewFields(document);
 276  
 
 277  0
                                         Maintainable maintainable = document.getNewMaintainableObject();
 278  
 
 279  0
                                         maintainable.processAfterCopy( document, request.getParameterMap() );
 280  
 
 281  
                                         // mark so that this clearing doesnt happen again
 282  0
                                         document.setFieldsClearedOnCopy(true);
 283  
 
 284  
                                         // mark so that blank required fields will be populated with default values
 285  0
                                         maintainable.setGenerateBlankRequiredValues(maintenanceForm.getDocTypeName());
 286  0
                                 }
 287  
                         }
 288  0
                         else if (KNSConstants.MAINTENANCE_EDIT_ACTION.equals(maintenanceAction)) {                                                
 289  0
                                 boolean allowsEdit = getBusinessObjectAuthorizationService().canMaintain(oldBusinessObject, GlobalVariables.getUserSession().getPerson(), document.getDocumentHeader().getWorkflowDocument().getDocumentType());  
 290  0
                                 if (!allowsEdit) {
 291  0
                                         LOG.error("Document type " + document.getDocumentHeader().getWorkflowDocument().getDocumentType() + " does not allow edit actions.");
 292  0
                                         throw  new DocumentTypeAuthorizationException(GlobalVariables.getUserSession().getPerson().getPrincipalId(), "edit", document.getDocumentHeader().getWorkflowDocument().getDocumentType());
 293  
                                 }
 294  0
                                 document.getNewMaintainableObject().processAfterEdit( document, request.getParameterMap() );
 295  0
                         }
 296  
                         //3070
 297  0
                         else if (KNSConstants.MAINTENANCE_DELETE_ACTION.equals(maintenanceAction)) {                        
 298  0
                                 boolean allowsDelete = getBusinessObjectAuthorizationService().canMaintain(oldBusinessObject, GlobalVariables.getUserSession().getPerson(), document.getDocumentHeader().getWorkflowDocument().getDocumentType());  
 299  0
                                 if (!allowsDelete) {
 300  0
                                         LOG.error("Document type " + document.getDocumentHeader().getWorkflowDocument().getDocumentType() + " does not allow delete actions.");
 301  0
                                         throw  new DocumentTypeAuthorizationException(GlobalVariables.getUserSession().getPerson().getPrincipalId(), "delete", document.getDocumentHeader().getWorkflowDocument().getDocumentType());
 302  
                                 }        
 303  
                                 //document.getNewMaintainableObject().processAfterEdit( document, request.getParameterMap() );
 304  
                         }
 305  
                         // Check for an auto-incrementing PK and set it if needed
 306  
                         //            if (document.getNewMaintainableObject().getBoClass().isAnnotationPresent(Sequence.class)) {
 307  
                         //                            Sequence sequence = (Sequence) document.getNewMaintainableObject().getBoClass().getAnnotation(Sequence.class);
 308  
                         //                            Long pk = OrmUtils.getNextAutoIncValue(sequence);
 309  
                         //                            OrmUtils.populateAutoIncValue(document.getNewMaintainableObject().getBusinessObject(), pk);
 310  
                         //                            document.getNewMaintainableObject().getBusinessObject().setAutoIncrementSet(true);
 311  
                         //            }
 312  
                 }
 313  
                 // if new with existing we need to populate we need to populate with passed in parameters
 314  0
                 if (KNSConstants.MAINTENANCE_NEWWITHEXISTING_ACTION.equals(maintenanceAction)) {
 315  
                         // TODO: this code should be abstracted out into a helper
 316  
                         // also is it a problem that we're not calling setGenerateDefaultValues? it blanked out the below values when I did
 317  
                         // maybe we need a new generateDefaultValues that doesn't overwrite?
 318  0
                         PersistableBusinessObject newBO = document.getNewMaintainableObject().getBusinessObject();
 319  0
                         Map<String, String> parameters = buildKeyMapFromRequest(document.getNewMaintainableObject(), request);
 320  0
                         copyParametersToBO(parameters, newBO);
 321  0
                         newBO.refresh();
 322  0
                         document.getNewMaintainableObject().setupNewFromExisting( document, request.getParameterMap() );
 323  
                 }
 324  
 
 325  
                 // for new maintainble need to pick up default values
 326  0
                 if (KNSConstants.MAINTENANCE_NEW_ACTION.equals(maintenanceAction)) {
 327  0
                         document.getNewMaintainableObject().setGenerateDefaultValues(maintenanceForm.getDocTypeName());
 328  0
                         document.getNewMaintainableObject().processAfterNew( document, request.getParameterMap() );
 329  
 
 330  
                         // If a maintenance lock exists, warn the user.
 331  0
                         MaintenanceUtils.checkForLockingDocument(document.getNewMaintainableObject(), false);
 332  
                 }
 333  
 
 334  
                 // set maintenance action state
 335  0
                 document.getNewMaintainableObject().setMaintenanceAction(maintenanceAction);
 336  0
                 maintenanceForm.setMaintenanceAction(maintenanceAction);
 337  
 
 338  
                 // attach any extra JS from the data dictionary
 339  0
                 if (LOG.isDebugEnabled()) {
 340  0
                         LOG.debug("maintenanceForm.getAdditionalScriptFiles(): " + maintenanceForm.getAdditionalScriptFiles());
 341  
                 }
 342  0
                 if (maintenanceForm.getAdditionalScriptFiles().isEmpty()) {
 343  0
                         DocumentEntry docEntry = getDataDictionaryService().getDataDictionary().getDocumentEntry(document.getDocumentHeader().getWorkflowDocument().getDocumentType());
 344  0
                         maintenanceForm.getAdditionalScriptFiles().addAll(docEntry.getWebScriptFiles());
 345  
                 }
 346  
 
 347  
                 // Retrieve notes topic display flag from data dictionary and add to document
 348  
                 //      
 349  0
                 DocumentEntry entry = maintenanceDocumentDictionaryService.getMaintenanceDocumentEntry(document.getDocumentHeader().getWorkflowDocument().getDocumentType());
 350  0
                 document.setDisplayTopicFieldInNotes(entry.getDisplayTopicFieldInNotes());
 351  
 
 352  0
                 return mapping.findForward(RiceConstants.MAPPING_BASIC);
 353  
         }
 354  
 
 355  
     protected void populateBOWithCopyKeyValues(HttpServletRequest request, PersistableBusinessObject oldBusinessObject, Maintainable oldMaintainableObject) throws Exception{
 356  0
                 List keyFieldNamesToCopy = new ArrayList();
 357  
                 Map<String, String> parametersToCopy;
 358  0
                 if (!StringUtils.isBlank(request.getParameter(KNSConstants.COPY_KEYS))) {
 359  0
                         String[] copyKeys = request.getParameter(KNSConstants.COPY_KEYS).split(KNSConstants.FIELD_CONVERSIONS_SEPARATOR);
 360  0
                         for (String copyKey: copyKeys) {
 361  0
                                 keyFieldNamesToCopy.add(copyKey);
 362  
                         }
 363  
                 }
 364  0
                 parametersToCopy = getRequestParameters(keyFieldNamesToCopy, oldMaintainableObject, request);
 365  0
                 if(parametersToCopy!=null && parametersToCopy.size()>0){
 366  0
                         copyParametersToBO(parametersToCopy, oldBusinessObject);
 367  
                 }
 368  0
         }
 369  
 
 370  
     protected void copyParametersToBO(Map<String, String> parameters, PersistableBusinessObject newBO) throws Exception{
 371  0
                 for (String parmName : parameters.keySet()) {
 372  0
                         String propertyValue = parameters.get(parmName);
 373  
 
 374  0
                         if (StringUtils.isNotBlank(propertyValue)) {
 375  0
                                 String propertyName = parmName;
 376  
                                 // set value of property in bo
 377  0
                                 if (PropertyUtils.isWriteable(newBO, propertyName)) {
 378  0
                                         Class type = ObjectUtils.easyGetPropertyType(newBO, propertyName);
 379  0
                                         if (type != null && Formatter.getFormatter(type) != null) {
 380  0
                                                 Formatter formatter = Formatter.getFormatter(type);
 381  0
                                                 Object obj = formatter.convertFromPresentationFormat(propertyValue);
 382  0
                                                 ObjectUtils.setObjectProperty(newBO, propertyName, obj.getClass(), obj);
 383  0
                                         }
 384  
                                         else {
 385  0
                                                 ObjectUtils.setObjectProperty(newBO, propertyName, String.class, propertyValue);
 386  
                                         }
 387  
                                 }
 388  
                         }
 389  0
                 }
 390  0
         }
 391  
 
 392  
         /**
 393  
          * Downloads the attachment to the user's browser
 394  
          *
 395  
          * @param mapping
 396  
          * @param form
 397  
          * @param request
 398  
          * @param response
 399  
          * @return ActionForward
 400  
          * @throws Exception
 401  
          */
 402  
         public ActionForward downloadAttachment(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
 403  0
                 KualiDocumentFormBase documentForm = (KualiDocumentFormBase) form;
 404  0
                 MaintenanceDocumentBase document = (MaintenanceDocumentBase) documentForm.getDocument();
 405  0
                 document.refreshReferenceObject("attachment");
 406  0
                 DocumentAttachment attachment = document.getAttachment();
 407  0
                 if(attachment != null) {
 408  0
                         streamToResponse(attachment.getAttachmentContent(), attachment.getFileName(), attachment.getContentType(), response); 
 409  
                 }
 410  0
                 return null;
 411  
         }
 412  
 
 413  
 
 414  
         /**
 415  
          * 
 416  
          * This method used to replace the attachment
 417  
          * @param mapping
 418  
          * @param form
 419  
          * @param request
 420  
          * @param response
 421  
          * @return
 422  
          * @throws Exception
 423  
          */
 424  
         public ActionForward replaceAttachment(ActionMapping mapping, ActionForm form, HttpServletRequest request,
 425  
                         HttpServletResponse response) throws Exception {
 426  0
                 KualiDocumentFormBase documentForm = (KualiDocumentFormBase) form;
 427  0
                 MaintenanceDocumentBase document = (MaintenanceDocumentBase) documentForm.getDocument();
 428  0
                 document.refreshReferenceObject("attachment");
 429  0
                 getBusinessObjectService().delete(document.getAttachment());
 430  0
                 return mapping.findForward(RiceConstants.MAPPING_BASIC);
 431  
         }
 432  
 
 433  
         /**
 434  
          * route the document using the document service
 435  
          * 
 436  
          * @param mapping
 437  
          * @param form
 438  
          * @param request
 439  
          * @param response
 440  
          * @return ActionForward
 441  
          * @throws Exception
 442  
          */
 443  
         @Override
 444  
         public ActionForward route(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
 445  0
                 KualiDocumentFormBase documentForm = (KualiDocumentFormBase) form;
 446  0
                 MaintenanceDocumentBase document = (MaintenanceDocumentBase) documentForm.getDocument();
 447  
 
 448  0
                 ActionForward forward = super.route(mapping, form, request, response);
 449  0
                 if(document.getNewMaintainableObject().getBusinessObject() instanceof PersistableAttachment) {
 450  0
                         PersistableAttachment bo = (PersistableAttachment) getBusinessObjectService().retrieve(document.getNewMaintainableObject().getBusinessObject());
 451  0
                         request.setAttribute("fileName", bo.getFileName());
 452  
                 }
 453  
 
 454  0
                 return forward;
 455  
         }
 456  
 
 457  
         /**
 458  
          * Handles creating and loading of documents.
 459  
          */
 460  
         @Override
 461  
         public ActionForward docHandler(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
 462  0
                 super.docHandler(mapping, form, request, response);
 463  0
                 KualiMaintenanceForm kualiMaintenanceForm = (KualiMaintenanceForm) form;
 464  
 
 465  0
                 if (KEWConstants.ACTIONLIST_COMMAND.equals(kualiMaintenanceForm.getCommand()) || KEWConstants.DOCSEARCH_COMMAND.equals(kualiMaintenanceForm.getCommand()) || KEWConstants.SUPERUSER_COMMAND.equals(kualiMaintenanceForm.getCommand()) || KEWConstants.HELPDESK_ACTIONLIST_COMMAND.equals(kualiMaintenanceForm.getCommand()) && kualiMaintenanceForm.getDocId() != null) {
 466  0
                         if (kualiMaintenanceForm.getDocument() instanceof MaintenanceDocument) {
 467  0
                                 kualiMaintenanceForm.setReadOnly(true);
 468  0
                                 kualiMaintenanceForm.setMaintenanceAction(((MaintenanceDocument) kualiMaintenanceForm.getDocument()).getNewMaintainableObject().getMaintenanceAction());
 469  
 
 470  
                                 //Retrieving the FileName from BO table
 471  0
                                 Maintainable tmpMaintainable = ((MaintenanceDocument) kualiMaintenanceForm.getDocument()).getNewMaintainableObject();
 472  0
                                 if(tmpMaintainable.getBusinessObject() instanceof PersistableAttachment) {
 473  0
                                         PersistableAttachment bo = (PersistableAttachment) getBusinessObjectService().retrieve(tmpMaintainable.getBusinessObject());
 474  0
                                         if(bo != null)
 475  0
                                                 request.setAttribute("fileName", bo.getFileName());
 476  
                                 }
 477  0
                         }
 478  
                         else {
 479  0
                                 LOG.error("Illegal State: document is not a maintenance document");
 480  0
                                 throw new IllegalStateException("Document is not a maintenance document");
 481  
                         }
 482  
                 }
 483  0
                 else if (KEWConstants.INITIATE_COMMAND.equals(kualiMaintenanceForm.getCommand())) {
 484  0
                         kualiMaintenanceForm.setReadOnly(false);
 485  0
                         return setupMaintenance(mapping, form, request, response, KNSConstants.MAINTENANCE_NEW_ACTION);
 486  
                 }
 487  
                 else {
 488  0
                         LOG.error("We should never have gotten to here");
 489  0
                         throw new IllegalStateException("docHandler called with invalid parameters");
 490  
                 }
 491  0
                 return mapping.findForward(RiceConstants.MAPPING_BASIC);
 492  
         }
 493  
 
 494  
         /**
 495  
          * Called on return from a lookup.
 496  
          */
 497  
         @Override
 498  
         public ActionForward refresh(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
 499  0
                 KualiMaintenanceForm maintenanceForm = (KualiMaintenanceForm) form;
 500  
 
 501  0
                 WebUtils.reuseErrorMapFromPreviousRequest(maintenanceForm);
 502  0
                 maintenanceForm.setDerivedValuesOnForm(request);
 503  
 
 504  0
                 refreshAdHocRoutingWorkgroupLookups(request, maintenanceForm);
 505  0
                 MaintenanceDocument document = (MaintenanceDocument) maintenanceForm.getDocument();
 506  
 
 507  
                 // call refresh on new maintainable
 508  0
                 Map<String, String> requestParams = new HashMap<String, String>();
 509  0
                 for (Enumeration i = request.getParameterNames(); i.hasMoreElements();) {
 510  0
                         String requestKey = (String) i.nextElement();
 511  0
                         String requestValue = request.getParameter(requestKey);
 512  0
                         requestParams.put(requestKey, requestValue);
 513  0
                 }
 514  
 
 515  
                 // Add multiple values from Lookup
 516  0
                 Collection<PersistableBusinessObject> rawValues = null;
 517  0
                 if (StringUtils.equals(KNSConstants.MULTIPLE_VALUE, maintenanceForm.getRefreshCaller())) {
 518  0
                         String lookupResultsSequenceNumber = maintenanceForm.getLookupResultsSequenceNumber();
 519  0
                         if (StringUtils.isNotBlank(lookupResultsSequenceNumber)) {
 520  
                                 // actually returning from a multiple value lookup
 521  0
                                 String lookupResultsBOClassName = maintenanceForm.getLookupResultsBOClassName();
 522  0
                                 Class lookupResultsBOClass = Class.forName(lookupResultsBOClassName);
 523  
 
 524  0
                                 rawValues = getLookupResultsService().retrieveSelectedResultBOs(lookupResultsSequenceNumber, lookupResultsBOClass, GlobalVariables.getUserSession().getPerson().getPrincipalId());
 525  
                         }
 526  
                 }
 527  
 
 528  0
                 if (rawValues != null) { // KULCOA-1073 - caused by this block running unnecessarily?
 529  
                         // we need to run the business rules on all the newly added items to the collection
 530  
                         // KULCOA-1000, KULCOA-1004 removed business rule validation on multiple value return
 531  
                         // (this was running before the objects were added anyway)
 532  
                         // getKualiRuleService().applyRules(new SaveDocumentEvent(document));
 533  0
                         String collectionName = maintenanceForm.getLookedUpCollectionName();
 534  
                         //TODO: Cathy remember to delete this block of comments after I've tested.            
 535  
                         //            PersistableBusinessObject bo = document.getNewMaintainableObject().getBusinessObject();
 536  
                         //            Collection maintCollection = this.extractCollection(bo, collectionName);
 537  
                         //            String docTypeName = ((MaintenanceDocument) maintenanceForm.getDocument()).getDocumentHeader().getWorkflowDocument().getDocumentType();
 538  
                         //            Class collectionClass = extractCollectionClass(docTypeName, collectionName);
 539  
                         //
 540  
                         //            List<MaintainableSectionDefinition> sections = maintenanceDocumentDictionaryService.getMaintainableSections(docTypeName);
 541  
                         //            Map<String, String> template = MaintenanceUtils.generateMultipleValueLookupBOTemplate(sections, collectionName);
 542  
                         //            for (PersistableBusinessObject nextBo : rawValues) {
 543  
                         //                PersistableBusinessObject templatedBo = (PersistableBusinessObject) ObjectUtils.createHybridBusinessObject(collectionClass, nextBo, template);
 544  
                         //                templatedBo.setNewCollectionRecord(true);
 545  
                         //                maintCollection.add(templatedBo);
 546  
                         //            }
 547  0
                         document.getNewMaintainableObject().addMultipleValueLookupResults(document, collectionName, rawValues, false, document.getNewMaintainableObject().getBusinessObject());
 548  0
                         if (LOG.isInfoEnabled()) {
 549  0
                                 LOG.info("********************doing editing 3 in refersh()***********************.");
 550  
                         }
 551  0
                         boolean isEdit = KNSConstants.MAINTENANCE_EDIT_ACTION.equals(maintenanceForm.getMaintenanceAction());
 552  0
                         boolean isCopy = KNSConstants.MAINTENANCE_COPY_ACTION.equals(maintenanceForm.getMaintenanceAction());
 553  
 
 554  0
                         if (isEdit || isCopy) {
 555  0
                                 document.getOldMaintainableObject().addMultipleValueLookupResults(document, collectionName, rawValues, true, document.getOldMaintainableObject().getBusinessObject());
 556  0
                                 document.getOldMaintainableObject().refresh(maintenanceForm.getRefreshCaller(), requestParams, document);
 557  
                         }
 558  
                 }
 559  
 
 560  0
                 document.getNewMaintainableObject().refresh(maintenanceForm.getRefreshCaller(), requestParams, document);
 561  
 
 562  
                 //pass out customAction from methodToCall parameter. Call processAfterPost
 563  0
                 String fullParameter = (String) request.getAttribute(KNSConstants.METHOD_TO_CALL_ATTRIBUTE);
 564  0
                 if(StringUtils.contains(fullParameter, KNSConstants.CUSTOM_ACTION)){
 565  0
                         String customAction = StringUtils.substringBetween(fullParameter, KNSConstants.METHOD_TO_CALL_PARM1_LEFT_DEL, KNSConstants.METHOD_TO_CALL_PARM1_RIGHT_DEL);
 566  0
                         String[] actionValue = new String[1];
 567  0
                         actionValue[0]= StringUtils.substringAfter(customAction, ".");
 568  0
                         Map<String,String[]> paramMap = request.getParameterMap();
 569  0
                         paramMap.put(KNSConstants.CUSTOM_ACTION, actionValue);
 570  0
                         doProcessingAfterPost( (KualiMaintenanceForm) form, paramMap );
 571  
                 }
 572  
 
 573  0
                 return mapping.findForward(RiceConstants.MAPPING_BASIC);
 574  
         }
 575  
 
 576  
         /**
 577  
          * Gets keys for the maintainable business object from the persistence metadata explorer. Checks for existence of key property
 578  
          * names as request parameters, if found adds them to the returned hash map.
 579  
          */
 580  
     protected Map buildKeyMapFromRequest(Maintainable maintainable, HttpServletRequest request) {
 581  0
                 List keyFieldNames = null;
 582  
                 // are override keys listed in the request? If so, then those need to be our keys,
 583  
                 // not the primary keye fields for the BO
 584  0
                 if (!StringUtils.isBlank(request.getParameter(KNSConstants.OVERRIDE_KEYS))) {
 585  0
                         String[] overrideKeys = request.getParameter(KNSConstants.OVERRIDE_KEYS).split(KNSConstants.FIELD_CONVERSIONS_SEPARATOR);
 586  0
                         keyFieldNames = new ArrayList();
 587  0
                         for (String overrideKey : overrideKeys) {
 588  0
                                 keyFieldNames.add(overrideKey);
 589  
                         }
 590  0
                 }
 591  
                 else {
 592  0
                         keyFieldNames = getBusinessObjectMetaDataService().listPrimaryKeyFieldNames(maintainable.getBusinessObject().getClass());
 593  
                 }
 594  0
                 return getRequestParameters(keyFieldNames, maintainable, request);
 595  
         }
 596  
 
 597  
     protected Map<String, String> getRequestParameters(List keyFieldNames, Maintainable maintainable, HttpServletRequest request){
 598  
 
 599  0
                 Map<String, String> requestParameters = new HashMap<String, String>();
 600  
 
 601  
 
 602  0
                 for (Iterator iter = keyFieldNames.iterator(); iter.hasNext();) {
 603  0
                         String keyPropertyName = (String) iter.next();
 604  
 
 605  0
                         if (request.getParameter(keyPropertyName) != null) {
 606  0
                                 String keyValue = request.getParameter(keyPropertyName);
 607  
 
 608  
                                 // Check if this element was encrypted, if it was decrypt it
 609  0
                 if (getBusinessObjectAuthorizationService().attributeValueNeedsToBeEncryptedOnFormsAndLinks(maintainable.getBoClass(), keyPropertyName)) {
 610  
                                         try {
 611  0
                             keyValue = StringUtils.removeEnd(keyValue, EncryptionService.ENCRYPTION_POST_PREFIX);
 612  0
                                                 keyValue = encryptionService.decrypt(keyValue);
 613  
                                         }
 614  0
                                         catch (GeneralSecurityException e) {
 615  0
                                                 throw new RuntimeException(e);
 616  0
                                         }
 617  
                                 }
 618  
 
 619  
 
 620  0
                                 requestParameters.put(keyPropertyName, keyValue);
 621  
                         }
 622  0
                 }
 623  
 
 624  0
                 return requestParameters;
 625  
 
 626  
         }
 627  
 
 628  
         /**
 629  
          * Convert a Request into a Map<String,String>. Technically, Request parameters do not neatly translate into a Map of Strings,
 630  
          * because a given parameter may legally appear more than once (so a Map of String[] would be more accurate.) This method should
 631  
          * be safe for business objects, but may not be reliable for more general uses.
 632  
          */
 633  
         String extractCollectionName(HttpServletRequest request, String methodToCall) {
 634  
                 // collection name and underlying object type from request parameter
 635  0
                 String parameterName = (String) request.getAttribute(KNSConstants.METHOD_TO_CALL_ATTRIBUTE);
 636  0
                 String collectionName = null;
 637  0
                 if (StringUtils.isNotBlank(parameterName)) {
 638  0
                         collectionName = StringUtils.substringBetween(parameterName, methodToCall + ".", ".(");
 639  
                 }
 640  0
                 return collectionName;
 641  
         }
 642  
 
 643  
         Collection extractCollection(PersistableBusinessObject bo, String collectionName) {
 644  
                 // retrieve the collection from the business object
 645  0
                 Collection maintCollection = (Collection) ObjectUtils.getPropertyValue(bo, collectionName);
 646  0
                 return maintCollection;
 647  
         }
 648  
 
 649  
         Class extractCollectionClass(String docTypeName, String collectionName) {
 650  0
                 return maintenanceDocumentDictionaryService.getCollectionBusinessObjectClass(docTypeName, collectionName);
 651  
         }
 652  
 
 653  
         /**
 654  
          * Adds a line to a collection being maintained in a many section.
 655  
          */
 656  
         public ActionForward addLine(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
 657  0
                 KualiMaintenanceForm maintenanceForm = (KualiMaintenanceForm) form;
 658  0
                 MaintenanceDocument document = (MaintenanceDocument) maintenanceForm.getDocument();
 659  0
                 Maintainable oldMaintainable = document.getOldMaintainableObject();
 660  0
                 Maintainable newMaintainable = document.getNewMaintainableObject();
 661  
 
 662  0
                 String collectionName = extractCollectionName(request, KNSConstants.ADD_LINE_METHOD);
 663  0
                 if (collectionName == null) {
 664  0
                         LOG.error("Unable to get find collection name and class in request.");
 665  0
                         throw new RuntimeException("Unable to get find collection name and class in request.");
 666  
                 }
 667  
 
 668  
                 // if dealing with sub collection it will have a "["
 669  0
                 if ((StringUtils.lastIndexOf(collectionName, "]") + 1) == collectionName.length()) {
 670  0
                         collectionName = StringUtils.substringBeforeLast(collectionName, "[");
 671  
                 }
 672  
 
 673  0
                 PersistableBusinessObject bo = newMaintainable.getBusinessObject();
 674  0
                 Collection maintCollection = extractCollection(bo, collectionName);
 675  0
                 Class collectionClass = extractCollectionClass(((MaintenanceDocument) maintenanceForm.getDocument()).getDocumentHeader().getWorkflowDocument().getDocumentType(), collectionName);
 676  
 
 677  
                 // TODO: sort of collection, new instance should be first
 678  
 
 679  
                 // get the BO from the new collection line holder
 680  0
                 PersistableBusinessObject addBO = newMaintainable.getNewCollectionLine(collectionName);
 681  0
                 if (LOG.isDebugEnabled()) {
 682  0
                         LOG.debug("obtained addBO from newCollectionLine: " + addBO);
 683  
                 }
 684  
 
 685  
                 // link up the user fields, if any
 686  0
                 getBusinessObjectService().linkUserFields(addBO);
 687  
 
 688  
                 //KULRICE-4264 - a hook to change the state of the business object, which is the "new line" of a collection, before it is validated
 689  0
                 newMaintainable.processBeforeAddLine(collectionName, collectionClass, addBO);
 690  
                 
 691  
                 // apply rules to the addBO
 692  0
                 boolean rulePassed = false;
 693  0
                 if (LOG.isDebugEnabled()) {
 694  0
                         LOG.debug("about to call AddLineEvent applyRules: document=" + document + "\ncollectionName=" + collectionName + "\nBO=" + addBO);
 695  
                 }
 696  0
                 rulePassed = getKualiRuleService().applyRules(new KualiAddLineEvent(document, collectionName, addBO));
 697  
 
 698  
                 // if the rule evaluation passed, let's add it
 699  0
                 if (rulePassed) {
 700  0
                         if (LOG.isInfoEnabled()) {
 701  0
                                 LOG.info("********************doing editing 4 in addline()***********************.");
 702  
                         }
 703  
                         // if edit or copy action, just add empty instance to old maintainable
 704  0
                         boolean isEdit = KNSConstants.MAINTENANCE_EDIT_ACTION.equals(maintenanceForm.getMaintenanceAction());
 705  0
                         boolean isCopy = KNSConstants.MAINTENANCE_COPY_ACTION.equals(maintenanceForm.getMaintenanceAction());
 706  
 
 707  
 
 708  0
                         if (isEdit || isCopy) {
 709  0
                                 PersistableBusinessObject oldBo = oldMaintainable.getBusinessObject();
 710  0
                                 Collection oldMaintCollection = (Collection) ObjectUtils.getPropertyValue(oldBo, collectionName);
 711  
 
 712  0
                                 if (oldMaintCollection == null) {
 713  0
                                         oldMaintCollection = new ArrayList();
 714  
                                 }
 715  0
                                 if (PersistableBusinessObject.class.isAssignableFrom(collectionClass)) {
 716  0
                                         PersistableBusinessObject placeholder = (PersistableBusinessObject) collectionClass.newInstance();
 717  
                                         // KULRNE-4538: must set it as a new collection record, because the maintainable will set the BO that gets added
 718  
                                         // to the new maintainable as a new collection record
 719  
 
 720  
                                         // if not set, then the subcollections of the newly added object will appear as read only
 721  
                                         // see FieldUtils.getContainerRows on how the delete button is rendered
 722  0
                                         placeholder.setNewCollectionRecord(true);
 723  0
                                         ((List) oldMaintCollection).add(placeholder);
 724  0
                                 }
 725  
                                 else {
 726  0
                                         LOG.warn("Should be a instance of PersistableBusinessObject");
 727  0
                                         ((List) oldMaintCollection).add(collectionClass.newInstance());
 728  
                                 }
 729  
                                 // update collection in maintenance business object
 730  0
                                 ObjectUtils.setObjectProperty(oldBo, collectionName, List.class, oldMaintCollection);
 731  
                         }
 732  
 
 733  0
                         newMaintainable.addNewLineToCollection(collectionName);
 734  0
                         int subCollectionIndex = 0;
 735  0
                         for (Object aSubCollection : maintCollection) {
 736  0
                                 subCollectionIndex += getSubCollectionIndex(aSubCollection, maintenanceForm.getDocTypeName());
 737  
                         }
 738  
                         //TODO: Should we keep this logic and continue using currentTabIndex as the key in the tabStates HashMap ?
 739  
                         //            
 740  
                         //            String parameter = (String) request.getAttribute(Constants.METHOD_TO_CALL_ATTRIBUTE);
 741  
                         //            String indexStr = StringUtils.substringBetween(parameter, Constants.METHOD_TO_CALL_PARM13_LEFT_DEL, Constants.METHOD_TO_CALL_PARM13_RIGHT_DEL);
 742  
                         //            // + 1 is for the fact that the first element of a collection is on the next tab
 743  
                         //            int index = Integer.parseInt(indexStr) + subCollectionIndex + 1;
 744  
                         //            Map<String, String> tabStates = maintenanceForm.getTabStates();
 745  
                         //            Map<String, String> copyOfTabStates = new HashMap<String, String>();
 746  
                         //
 747  
                         //            int incrementor = 0;
 748  
                         //            for (String tabState : tabStates.keySet()) {
 749  
                         //                    String originalValue = maintenanceForm.getTabState(Integer.toString(incrementor));
 750  
                         //                copyOfTabStates.put(Integer.toString(incrementor), originalValue);
 751  
                         //                incrementor++;
 752  
                         //            }
 753  
                         //
 754  
                         //            int i = index;
 755  
                         //                if (tabStates.containsKey(Integer.toString(i-1))) {
 756  
                         //                        tabStates.remove(Integer.toString(i-1));
 757  
                         //                }
 758  
                         //            while (i < copyOfTabStates.size() + 1) {
 759  
                         //                String originalValue = copyOfTabStates.get(Integer.toString(i-1));
 760  
                         //                if (tabStates.containsKey(Integer.toString(i))) {
 761  
                         //                    tabStates.remove(Integer.toString(i));
 762  
                         //                }
 763  
                         //                tabStates.put(Integer.toString(i), originalValue);
 764  
                         //                i++;
 765  
                         //            }
 766  
 
 767  
 
 768  
                         // End of whether we should continue to keep this logic and use currentTabIndex as the key            
 769  
                 }
 770  0
                 doProcessingAfterPost( (KualiMaintenanceForm) form, request );
 771  
 
 772  0
                 return mapping.findForward(RiceConstants.MAPPING_BASIC);
 773  
         }
 774  
 
 775  
     protected int getSubCollectionIndex(Object object, String documentTypeName) {
 776  0
                 int index = 1;
 777  0
                 MaintainableCollectionDefinition theCollectionDefinition = null;
 778  0
                 for (MaintainableCollectionDefinition maintainableCollectionDefinition : maintenanceDocumentDictionaryService.getMaintainableCollections(documentTypeName)) {
 779  0
                         if (maintainableCollectionDefinition.getBusinessObjectClass().equals(object.getClass())) {
 780  
                                 // we've found the collection we were looking for, so let's find all of its subcollections
 781  0
                                 theCollectionDefinition = maintainableCollectionDefinition;
 782  0
                                 break;
 783  
                         }
 784  
                 }
 785  0
                 if (theCollectionDefinition != null) {
 786  0
                         for (MaintainableCollectionDefinition subCollDef : theCollectionDefinition.getMaintainableCollections()) {
 787  0
                                 String name = subCollDef.getName();
 788  0
                                 String capitalFirst = name.substring(0, 1).toUpperCase();
 789  0
                                 String methodName = "get" + capitalFirst + name.substring(1);
 790  0
                                 List subCollectionList = new ArrayList();
 791  
                                 try {
 792  0
                                         subCollectionList = (List) object.getClass().getMethod(methodName).invoke(object);
 793  
                                 }
 794  0
                                 catch (InvocationTargetException ite) {
 795  
                                         // this shouldn't happen
 796  
                                 }
 797  0
                                 catch (IllegalAccessException iae) {
 798  
                                         // this shouldn't happen
 799  
                                 }
 800  0
                                 catch (NoSuchMethodException nme) {
 801  
                                         // this shouldn't happen
 802  0
                                 }
 803  0
                                 index += subCollectionList.size();
 804  0
                         }
 805  
                 }
 806  0
                 return index;
 807  
         }
 808  
 
 809  
         /**
 810  
          * Deletes a collection line that is pending by this document. The collection name and the index to delete is embedded into the
 811  
          * delete button name. These parameters are extracted, the collection pulled out of the parent business object, and finally the
 812  
          * collection record at the specified index is removed for the new maintainable, and the old if we are dealing with an edit.
 813  
          */
 814  
         public ActionForward deleteLine(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
 815  0
                 KualiMaintenanceForm maintenanceForm = (KualiMaintenanceForm) form;
 816  0
                 MaintenanceDocument document = (MaintenanceDocument) maintenanceForm.getDocument();
 817  0
                 Maintainable oldMaintainable = document.getOldMaintainableObject();
 818  0
                 Maintainable newMaintainable = document.getNewMaintainableObject();
 819  
 
 820  0
                 String collectionName = extractCollectionName(request, KNSConstants.DELETE_LINE_METHOD);
 821  0
                 if (collectionName == null) {
 822  0
                         LOG.error("Unable to get find collection name in request.");
 823  0
                         throw new RuntimeException("Unable to get find collection class in request.");
 824  
                 }
 825  
 
 826  0
                 PersistableBusinessObject bo = newMaintainable.getBusinessObject();
 827  0
                 Collection maintCollection = extractCollection(bo, collectionName);
 828  0
                 if (collectionName == null) {
 829  0
                         LOG.error("Collection is null in parent business object.");
 830  0
                         throw new RuntimeException("Collection is null in parent business object.");
 831  
                 }
 832  
 
 833  0
                 int deleteRecordIndex = getLineToDelete(request);
 834  0
                 if (deleteRecordIndex < 0 || deleteRecordIndex > maintCollection.size() - 1) {
 835  0
                         if (collectionName == null) {
 836  0
                                 LOG.error("Invalid index for deletion of collection record: " + deleteRecordIndex);
 837  0
                                 throw new RuntimeException("Invalid index for deletion of collection record: " + deleteRecordIndex);
 838  
                         }
 839  
                 }
 840  
 
 841  0
                 ((List) maintCollection).remove(deleteRecordIndex);
 842  
 
 843  
                 // if it's either an edit or a copy, need to remove the collection from the old maintainable as well
 844  0
                 if (KNSConstants.MAINTENANCE_EDIT_ACTION.equals(maintenanceForm.getMaintenanceAction()) ||
 845  
                                 KNSConstants.MAINTENANCE_COPY_ACTION.equals(maintenanceForm.getMaintenanceAction())) {
 846  0
                         bo = oldMaintainable.getBusinessObject();
 847  0
                         maintCollection = extractCollection(bo, collectionName);
 848  
 
 849  0
                         if (collectionName == null) {
 850  0
                                 LOG.error("Collection is null in parent business object.");
 851  0
                                 throw new RuntimeException("Collection is null in parent business object.");
 852  
                         }
 853  
 
 854  0
                         ((List) maintCollection).remove(deleteRecordIndex);
 855  
                 }
 856  
 
 857  
                 // remove the tab state information of the tab that the deleted element originally occupied, so that it will keep tab states
 858  
                 // consistent
 859  
                 //        String parameter = (String) request.getAttribute(Constants.METHOD_TO_CALL_ATTRIBUTE);
 860  
                 //        String indexStr = StringUtils.substringBetween(parameter, Constants.METHOD_TO_CALL_PARM13_LEFT_DEL, Constants.METHOD_TO_CALL_PARM13_RIGHT_DEL);
 861  
                 //        int index = Integer.parseInt(indexStr);
 862  
                 //        maintenanceForm.removeTabState(index);
 863  
 
 864  
 
 865  
                 //      TODO: Should we keep this logic and continue using currentTabIndex as the key in the tabStates HashMap ?        
 866  
                 //        
 867  
                 //        String parameter = (String) request.getAttribute(Constants.METHOD_TO_CALL_ATTRIBUTE);
 868  
                 //        String indexStr = StringUtils.substringBetween(parameter, Constants.METHOD_TO_CALL_PARM13_LEFT_DEL, Constants.METHOD_TO_CALL_PARM13_RIGHT_DEL);
 869  
                 //        // + 1 is for the fact that the first element of a collection is on the next tab
 870  
                 //        int index = Integer.parseInt(indexStr) +  1;
 871  
                 //        Map<String, String> tabStates = maintenanceForm.getTabStates();
 872  
                 //        Map<String, String> copyOfTabStates = new HashMap<String, String>();
 873  
                 //
 874  
                 //        int incrementor = 0;
 875  
                 //        for (String tabState : tabStates.keySet()) {
 876  
                 //                String originalValue = maintenanceForm.getTabState(Integer.toString(incrementor));
 877  
                 //            copyOfTabStates.put(Integer.toString(incrementor), originalValue);
 878  
                 //            incrementor++;
 879  
                 //        }
 880  
                 //
 881  
                 //        int i = index;
 882  
                 //
 883  
                 //        while (i < copyOfTabStates.size() ) {
 884  
                 //            String originalValue = copyOfTabStates.get(Integer.toString(i));
 885  
                 //            if (tabStates.containsKey(Integer.toString(i-1))) {
 886  
                 //                tabStates.remove(Integer.toString(i-1));
 887  
                 //            }
 888  
                 //            tabStates.put(Integer.toString(i-1), originalValue);
 889  
                 //            i++;
 890  
                 //        }
 891  
                 //
 892  
                 //        
 893  
                 //End of whether we should continue to keep this logic and use currentTabIndex as the key            
 894  
 
 895  0
                 doProcessingAfterPost( (KualiMaintenanceForm) form, request );
 896  
 
 897  0
                 return mapping.findForward(RiceConstants.MAPPING_BASIC);
 898  
         }
 899  
 
 900  
         /**
 901  
          * Turns on (or off) the inactive record display for a maintenance collection.
 902  
          */
 903  
         public ActionForward toggleInactiveRecordDisplay(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
 904  0
                 KualiMaintenanceForm maintenanceForm = (KualiMaintenanceForm) form;
 905  0
                 MaintenanceDocument document = (MaintenanceDocument) maintenanceForm.getDocument();
 906  0
                 Maintainable oldMaintainable = document.getOldMaintainableObject();
 907  0
                 Maintainable newMaintainable = document.getNewMaintainableObject();
 908  
 
 909  0
                 String collectionName = extractCollectionName(request, KNSConstants.TOGGLE_INACTIVE_METHOD);
 910  0
                 if (collectionName == null) {
 911  0
                         LOG.error("Unable to get find collection name in request.");
 912  0
                         throw new RuntimeException("Unable to get find collection class in request.");
 913  
                 }  
 914  
 
 915  0
                 String parameterName = (String) request.getAttribute(KNSConstants.METHOD_TO_CALL_ATTRIBUTE);
 916  0
                 boolean showInactive = Boolean.parseBoolean(StringUtils.substringBetween(parameterName, KNSConstants.METHOD_TO_CALL_BOPARM_LEFT_DEL, "."));
 917  
 
 918  0
                 oldMaintainable.setShowInactiveRecords(collectionName, showInactive);
 919  0
                 newMaintainable.setShowInactiveRecords(collectionName, showInactive);
 920  
 
 921  0
                 return mapping.findForward(RiceConstants.MAPPING_BASIC);
 922  
         }
 923  
 
 924  
 
 925  
 
 926  
         /**
 927  
          * This method clears the value of the primary key fields on a Business Object.
 928  
          * 
 929  
          * @param document - document to clear the pk fields on
 930  
          */
 931  
     protected void clearPrimaryKeyFields(MaintenanceDocument document) {
 932  
                 // get business object being maintained and its keys
 933  0
                 PersistableBusinessObject bo = document.getNewMaintainableObject().getBusinessObject();
 934  0
                 List<String> keyFieldNames = getBusinessObjectMetaDataService().listPrimaryKeyFieldNames(bo.getClass());
 935  
 
 936  0
                 for (String keyFieldName : keyFieldNames) {
 937  
                         try {
 938  0
                                 ObjectUtils.setObjectProperty(bo, keyFieldName, null);
 939  
                         }
 940  0
                         catch (Exception e) {
 941  0
                                 LOG.error("Unable to clear primary key field: " + e.getMessage());
 942  0
                                 throw new RuntimeException("Unable to clear primary key field: " + e.getMessage());
 943  0
                         }
 944  
                 }
 945  0
         }
 946  
 
 947  
         /**
 948  
          * This method is used as part of the Copy functionality, to clear any field values that the user making the copy does not have
 949  
          * permissions to modify. This will prevent authorization errors on a copy.
 950  
          * 
 951  
          * @param document - document to be adjusted
 952  
          */
 953  
     protected void clearUnauthorizedNewFields(MaintenanceDocument document) {
 954  
                 // get a reference to the current user
 955  0
                 Person user = GlobalVariables.getUserSession().getPerson();
 956  
 
 957  
                 // get the correct documentAuthorizer for this document
 958  0
                 MaintenanceDocumentAuthorizer documentAuthorizer = (MaintenanceDocumentAuthorizer) getDocumentHelperService().getDocumentAuthorizer(document);
 959  
 
 960  
                 // get a new instance of MaintenanceDocumentAuthorizations for this context
 961  0
                 MaintenanceDocumentRestrictions maintenanceDocumentRestrictions = getBusinessObjectAuthorizationService().getMaintenanceDocumentRestrictions(document, user);
 962  
 
 963  
                 // get a reference to the newBo
 964  0
                 PersistableBusinessObject newBo = document.getNewMaintainableObject().getBusinessObject();
 965  
 
 966  0
                 document.getNewMaintainableObject().clearBusinessObjectOfRestrictedValues(maintenanceDocumentRestrictions);
 967  0
         }
 968  
 
 969  
         /**
 970  
          * This method does all special processing on a document that should happen on each HTTP post (ie, save, route, approve, etc).
 971  
          * 
 972  
          * @param form
 973  
          */
 974  
         @SuppressWarnings("unchecked")
 975  
         protected void doProcessingAfterPost( KualiForm form, HttpServletRequest request ) {
 976  0
                 MaintenanceDocument document = (MaintenanceDocument) ((KualiMaintenanceForm)form).getDocument();
 977  0
                 Maintainable maintainable = document.getNewMaintainableObject();
 978  0
                 PersistableBusinessObject bo = maintainable.getBusinessObject();
 979  
 
 980  0
                 getBusinessObjectService().linkUserFields(bo);
 981  
 
 982  0
                 maintainable.processAfterPost(document, request.getParameterMap() );
 983  0
         }
 984  
 
 985  
         protected void doProcessingAfterPost( KualiForm form, Map<String,String[]> parameters ) {
 986  0
                 MaintenanceDocument document = (MaintenanceDocument) ((KualiMaintenanceForm)form).getDocument();
 987  0
                 Maintainable maintainable = document.getNewMaintainableObject();
 988  0
                 PersistableBusinessObject bo = maintainable.getBusinessObject();
 989  
 
 990  0
                 getBusinessObjectService().linkUserFields(bo);
 991  
 
 992  0
                 maintainable.processAfterPost(document, parameters );
 993  0
         }
 994  
 
 995  
         protected void populateAuthorizationFields(KualiDocumentFormBase formBase){
 996  0
                 super.populateAuthorizationFields(formBase);
 997  
 
 998  0
                 KualiMaintenanceForm maintenanceForm = (KualiMaintenanceForm) formBase;
 999  0
                 MaintenanceDocument maintenanceDocument = (MaintenanceDocument) maintenanceForm.getDocument();
 1000  0
                 MaintenanceDocumentAuthorizer maintenanceDocumentAuthorizer = (MaintenanceDocumentAuthorizer) getDocumentHelperService().getDocumentAuthorizer(maintenanceDocument);
 1001  0
                 Person user = GlobalVariables.getUserSession().getPerson();
 1002  0
                 maintenanceForm.setReadOnly(!formBase.getDocumentActions().containsKey(KNSConstants.KUALI_ACTION_CAN_EDIT));
 1003  0
                 MaintenanceDocumentRestrictions maintenanceDocumentAuthorizations = getBusinessObjectAuthorizationService().getMaintenanceDocumentRestrictions(maintenanceDocument, user);
 1004  0
                 maintenanceForm.setAuthorizations(maintenanceDocumentAuthorizations);
 1005  0
         }
 1006  
 
 1007  
         public LookupService getLookupService() {
 1008  0
                 if ( lookupService == null ) {
 1009  0
                         lookupService = KNSServiceLocatorWeb.getLookupService();
 1010  
                 }
 1011  0
                 return this.lookupService;
 1012  
         }
 1013  
 
 1014  
         public LookupResultsService getLookupResultsService() {
 1015  0
                 if ( lookupResultsService == null ) {
 1016  0
                         lookupResultsService = KNSServiceLocatorWeb.getLookupResultsService();
 1017  
                 }
 1018  0
                 return this.lookupResultsService;
 1019  
         }
 1020  
 
 1021  
 }