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