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