001 /** 002 * Copyright 2005-2011 The Kuali Foundation 003 * 004 * Licensed under the Educational Community License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.opensource.org/licenses/ecl2.php 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016 package org.kuali.rice.kns.web.struts.action; 017 018 import org.apache.commons.beanutils.PropertyUtils; 019 import org.apache.commons.lang.StringUtils; 020 import org.apache.ojb.broker.metadata.ClassNotPersistenceCapableException; 021 import org.apache.struts.action.ActionForm; 022 import org.apache.struts.action.ActionForward; 023 import org.apache.struts.action.ActionMapping; 024 import org.kuali.rice.core.api.CoreApiServiceLocator; 025 import org.kuali.rice.core.api.encryption.EncryptionService; 026 import org.kuali.rice.core.api.util.ClassLoaderUtils; 027 import org.kuali.rice.core.api.util.RiceConstants; 028 import org.kuali.rice.core.api.util.RiceKeyConstants; 029 import org.kuali.rice.core.framework.persistence.jpa.OrmUtils; 030 import org.kuali.rice.core.framework.persistence.jpa.criteria.Criteria; 031 import org.kuali.rice.core.framework.persistence.jpa.criteria.QueryByCriteria; 032 import org.kuali.rice.core.framework.persistence.jpa.metadata.EntityDescriptor; 033 import org.kuali.rice.core.framework.persistence.jpa.metadata.FieldDescriptor; 034 import org.kuali.rice.core.framework.persistence.jpa.metadata.MetadataManager; 035 import org.kuali.rice.core.web.format.Formatter; 036 import org.kuali.rice.kew.api.KewApiConstants; 037 import org.kuali.rice.kim.api.identity.Person; 038 import org.kuali.rice.kns.datadictionary.MaintainableCollectionDefinition; 039 import org.kuali.rice.kns.datadictionary.MaintenanceDocumentEntry; 040 import org.kuali.rice.kns.document.MaintenanceDocument; 041 import org.kuali.rice.kns.document.MaintenanceDocumentBase; 042 import org.kuali.rice.kns.document.authorization.MaintenanceDocumentRestrictions; 043 import org.kuali.rice.kns.lookup.LookupResultsService; 044 import org.kuali.rice.kns.maintenance.Maintainable; 045 import org.kuali.rice.kns.rule.event.KualiAddLineEvent; 046 import org.kuali.rice.kns.service.KNSServiceLocator; 047 import org.kuali.rice.kns.service.MaintenanceDocumentDictionaryService; 048 import org.kuali.rice.kns.util.KNSGlobalVariables; 049 import org.kuali.rice.kns.util.MaintenanceUtils; 050 import org.kuali.rice.kns.util.WebUtils; 051 import org.kuali.rice.kns.web.struts.form.KualiDocumentFormBase; 052 import org.kuali.rice.kns.web.struts.form.KualiForm; 053 import org.kuali.rice.kns.web.struts.form.KualiMaintenanceForm; 054 import org.kuali.rice.krad.bo.DocumentAttachment; 055 import org.kuali.rice.krad.bo.PersistableAttachment; 056 import org.kuali.rice.krad.bo.PersistableBusinessObject; 057 import org.kuali.rice.krad.bo.PersistableBusinessObjectExtension; 058 import org.kuali.rice.krad.document.authorization.MaintenanceDocumentAuthorizer; 059 import org.kuali.rice.krad.exception.DocumentTypeAuthorizationException; 060 import org.kuali.rice.krad.service.KRADServiceLocatorWeb; 061 import org.kuali.rice.krad.service.LookupService; 062 import org.kuali.rice.krad.util.GlobalVariables; 063 import org.kuali.rice.krad.util.KRADConstants; 064 import org.kuali.rice.krad.util.KRADPropertyConstants; 065 import org.kuali.rice.krad.util.ObjectUtils; 066 067 import javax.persistence.PersistenceException; 068 import javax.servlet.http.HttpServletRequest; 069 import javax.servlet.http.HttpServletResponse; 070 import java.lang.reflect.Field; 071 import java.lang.reflect.InvocationTargetException; 072 import java.security.GeneralSecurityException; 073 import java.util.ArrayList; 074 import java.util.Collection; 075 import java.util.Enumeration; 076 import java.util.HashMap; 077 import java.util.Iterator; 078 import java.util.List; 079 import java.util.Map; 080 081 /** 082 * This class handles actions for maintenance documents. These include creating new edit, and copying of maintenance records. 083 */ 084 public class KualiMaintenanceDocumentAction extends KualiDocumentActionBase { 085 protected static final org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(KualiMaintenanceDocumentAction.class); 086 087 protected MaintenanceDocumentDictionaryService maintenanceDocumentDictionaryService = null; 088 protected EncryptionService encryptionService; 089 protected LookupService lookupService; 090 protected LookupResultsService lookupResultsService; 091 092 public KualiMaintenanceDocumentAction() { 093 super(); 094 maintenanceDocumentDictionaryService = KNSServiceLocator.getMaintenanceDocumentDictionaryService(); 095 encryptionService = CoreApiServiceLocator.getEncryptionService(); 096 } 097 098 @Override 099 public ActionForward execute(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception { 100 request.setAttribute(KRADConstants.PARAM_MAINTENANCE_VIEW_MODE, KRADConstants.PARAM_MAINTENANCE_VIEW_MODE_MAINTENANCE); 101 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 request.setAttribute(KRADConstants.MAINTENANCE_ACTN, KRADConstants.MAINTENANCE_NEW_ACTION); 109 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 if (request.getParameter("document." + KRADPropertyConstants.DOCUMENT_NUMBER) == null) { // object copy 118 return setupMaintenance(mapping, form, request, response, KRADConstants.MAINTENANCE_COPY_ACTION); 119 } 120 else { // document copy 121 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 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 if (isFormRepresentingLockObject((KualiDocumentFormBase)form)) { 138 return super.delete(mapping, form, request, response); 139 } 140 KNSGlobalVariables.getMessageList().add(RiceKeyConstants.MESSAGE_DELETE); 141 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 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 KualiMaintenanceForm maintenanceForm = (KualiMaintenanceForm) form; 159 MaintenanceDocument document = null; 160 161 // create a new document object, if required (on NEW object, or other reasons) 162 if (maintenanceForm.getDocument() == null) { 163 if (StringUtils.isEmpty(maintenanceForm.getBusinessObjectClassName()) && StringUtils.isEmpty(maintenanceForm.getDocTypeName())) { 164 throw new IllegalArgumentException("Document type name or bo class not given!"); 165 } 166 167 String documentTypeName = maintenanceForm.getDocTypeName(); 168 // get document type if not passed 169 if (StringUtils.isEmpty(documentTypeName)) { 170 documentTypeName = maintenanceDocumentDictionaryService.getDocumentTypeName(Class.forName(maintenanceForm.getBusinessObjectClassName())); 171 maintenanceForm.setDocTypeName(documentTypeName); 172 } 173 174 if (StringUtils.isEmpty(documentTypeName)) { 175 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 if (KRADConstants.MAINTENANCE_NEW_ACTION.equals(maintenanceAction) || KRADConstants.MAINTENANCE_COPY_ACTION.equals(maintenanceAction)) { 180 Class boClass = maintenanceDocumentDictionaryService.getDataObjectClass(documentTypeName); 181 boolean allowsNewOrCopy = getBusinessObjectAuthorizationService().canCreate(boClass, GlobalVariables.getUserSession().getPerson(), documentTypeName); 182 if (!allowsNewOrCopy) { 183 LOG.error("Document type " + documentTypeName + " does not allow new or copy actions."); 184 throw new DocumentTypeAuthorizationException(GlobalVariables.getUserSession().getPerson().getPrincipalId(), "newOrCopy", documentTypeName); 185 } 186 } 187 188 // get new document from service 189 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 maintenanceForm.setDocument(document); 200 } 201 else { 202 document = (MaintenanceDocument) maintenanceForm.getDocument(); 203 } 204 205 // retrieve business object from request parameters 206 if (!(KRADConstants.MAINTENANCE_NEW_ACTION.equals(maintenanceAction)) && !(KRADConstants.MAINTENANCE_NEWWITHEXISTING_ACTION.equals(maintenanceAction))) { 207 Map requestParameters = buildKeyMapFromRequest(document.getNewMaintainableObject(), request); 208 PersistableBusinessObject oldBusinessObject = null; 209 try { 210 oldBusinessObject = (PersistableBusinessObject) getLookupService().findObjectBySearch(Class.forName(maintenanceForm.getBusinessObjectClassName()), requestParameters); 211 } catch ( ClassNotPersistenceCapableException ex ) { 212 if ( !document.getOldMaintainableObject().isExternalBusinessObject() ) { 213 throw new RuntimeException( "BO Class: " + maintenanceForm.getBusinessObjectClassName() + " is not persistable and is not externalizable - configuration error" ); 214 } 215 // otherwise, let fall through 216 } 217 if (oldBusinessObject == null && !document.getOldMaintainableObject().isExternalBusinessObject()) { 218 throw new RuntimeException("Cannot retrieve old record for maintenance document, incorrect parameters passed on maint url: " + requestParameters ); 219 } 220 221 if(document.getOldMaintainableObject().isExternalBusinessObject()){ 222 if ( oldBusinessObject == null ) { 223 try { 224 oldBusinessObject = (PersistableBusinessObject)document.getOldMaintainableObject().getBoClass().newInstance(); 225 } catch ( Exception ex ) { 226 throw new RuntimeException( "External BO maintainable was null and unable to instantiate for old maintainable object.", ex ); 227 } 228 } 229 populateBOWithCopyKeyValues(request, oldBusinessObject, document.getOldMaintainableObject()); 230 document.getOldMaintainableObject().prepareBusinessObject(oldBusinessObject); 231 oldBusinessObject = document.getOldMaintainableObject().getBusinessObject(); 232 } 233 234 // Temp solution for loading extension objects - need to find a better way 235 final String TMP_NM = oldBusinessObject.getClass().getName(); 236 final int START_INDEX = TMP_NM.indexOf('.', TMP_NM.indexOf('.') + 1) + 1; 237 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 if (oldBusinessObject.getExtension() != null) { 240 PersistableBusinessObjectExtension boe = oldBusinessObject.getExtension(); 241 EntityDescriptor entity = MetadataManager.getEntityDescriptor(oldBusinessObject.getExtension().getClass()); 242 Criteria extensionCriteria = new Criteria(boe.getClass().getName()); 243 for (FieldDescriptor fieldDescriptor : entity.getPrimaryKeys()) { 244 try { 245 Field field = oldBusinessObject.getClass().getDeclaredField(fieldDescriptor.getName()); 246 field.setAccessible(true); 247 extensionCriteria.eq(fieldDescriptor.getName(), field.get(oldBusinessObject)); 248 } catch (Exception e) { 249 LOG.error(e.getMessage(),e); 250 } 251 } 252 try { 253 boe = (PersistableBusinessObjectExtension) new QueryByCriteria(getEntityManagerFactory().createEntityManager(), extensionCriteria).toQuery().getSingleResult(); 254 } catch (PersistenceException e) {} 255 oldBusinessObject.setExtension(boe); 256 } 257 } 258 259 PersistableBusinessObject newBusinessObject = (PersistableBusinessObject) ObjectUtils.deepCopy(oldBusinessObject); 260 261 // set business object instance for editing 262 Class<? extends PersistableBusinessObject> businessObjectClass = ClassLoaderUtils.getClass(maintenanceForm.getBusinessObjectClassName(), PersistableBusinessObject.class); 263 document.getOldMaintainableObject().setBusinessObject(oldBusinessObject); 264 document.getOldMaintainableObject().setBoClass(businessObjectClass); 265 document.getNewMaintainableObject().setBusinessObject(newBusinessObject); 266 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 if (KRADConstants.MAINTENANCE_COPY_ACTION.equals(maintenanceAction)) { 271 if (!document.isFieldsClearedOnCopy()) { 272 //for issue KULRice 3072 273 Class boClass = maintenanceDocumentDictionaryService.getDataObjectClass( 274 maintenanceForm.getDocTypeName()); 275 if(!maintenanceDocumentDictionaryService.getPreserveLockingKeysOnCopy(boClass)) 276 clearPrimaryKeyFields(document); 277 278 clearUnauthorizedNewFields(document); 279 280 Maintainable maintainable = document.getNewMaintainableObject(); 281 282 maintainable.processAfterCopy( document, request.getParameterMap() ); 283 284 // mark so that this clearing doesnt happen again 285 document.setFieldsClearedOnCopy(true); 286 287 // mark so that blank required fields will be populated with default values 288 maintainable.setGenerateBlankRequiredValues(maintenanceForm.getDocTypeName()); 289 } 290 } 291 else if (KRADConstants.MAINTENANCE_EDIT_ACTION.equals(maintenanceAction)) { 292 boolean allowsEdit = getBusinessObjectAuthorizationService().canMaintain(oldBusinessObject, GlobalVariables.getUserSession().getPerson(), document.getDocumentHeader().getWorkflowDocument().getDocumentTypeName()); 293 if (!allowsEdit) { 294 LOG.error("Document type " + document.getDocumentHeader().getWorkflowDocument().getDocumentTypeName() + " does not allow edit actions."); 295 throw new DocumentTypeAuthorizationException(GlobalVariables.getUserSession().getPerson().getPrincipalId(), "edit", document.getDocumentHeader().getWorkflowDocument().getDocumentTypeName()); 296 } 297 document.getNewMaintainableObject().processAfterEdit( document, request.getParameterMap() ); 298 } 299 //3070 300 else if (KRADConstants.MAINTENANCE_DELETE_ACTION.equals(maintenanceAction)) { 301 boolean allowsDelete = getBusinessObjectAuthorizationService().canMaintain(oldBusinessObject, GlobalVariables.getUserSession().getPerson(), document.getDocumentHeader().getWorkflowDocument().getDocumentTypeName()); 302 if (!allowsDelete) { 303 LOG.error("Document type " + document.getDocumentHeader().getWorkflowDocument().getDocumentTypeName() + " does not allow delete actions."); 304 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 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 PersistableBusinessObject newBO = document.getNewMaintainableObject().getBusinessObject(); 322 Map<String, String> parameters = buildKeyMapFromRequest(document.getNewMaintainableObject(), request); 323 copyParametersToBO(parameters, newBO); 324 newBO.refresh(); 325 document.getNewMaintainableObject().setupNewFromExisting( document, request.getParameterMap() ); 326 } 327 328 // for new maintainble need to pick up default values 329 if (KRADConstants.MAINTENANCE_NEW_ACTION.equals(maintenanceAction)) { 330 document.getNewMaintainableObject().setGenerateDefaultValues(maintenanceForm.getDocTypeName()); 331 document.getNewMaintainableObject().processAfterNew( document, request.getParameterMap() ); 332 333 // If a maintenance lock exists, warn the user. 334 MaintenanceUtils.checkForLockingDocument(document.getNewMaintainableObject(), false); 335 } 336 337 // set maintenance action state 338 document.getNewMaintainableObject().setMaintenanceAction(maintenanceAction); 339 maintenanceForm.setMaintenanceAction(maintenanceAction); 340 341 // attach any extra JS from the data dictionary 342 MaintenanceDocumentEntry entry = maintenanceDocumentDictionaryService.getMaintenanceDocumentEntry(document.getDocumentHeader().getWorkflowDocument().getDocumentTypeName()); 343 if (LOG.isDebugEnabled()) { 344 LOG.debug("maintenanceForm.getAdditionalScriptFiles(): " + maintenanceForm.getAdditionalScriptFiles()); 345 } 346 if (maintenanceForm.getAdditionalScriptFiles().isEmpty()) { 347 maintenanceForm.getAdditionalScriptFiles().addAll(entry.getWebScriptFiles()); 348 } 349 350 // Retrieve notes topic display flag from data dictionary and add to document 351 document.setDisplayTopicFieldInNotes(entry.getDisplayTopicFieldInNotes()); 352 353 return mapping.findForward(RiceConstants.MAPPING_BASIC); 354 } 355 356 protected void populateBOWithCopyKeyValues(HttpServletRequest request, PersistableBusinessObject oldBusinessObject, Maintainable oldMaintainableObject) throws Exception{ 357 List keyFieldNamesToCopy = new ArrayList(); 358 Map<String, String> parametersToCopy; 359 if (!StringUtils.isBlank(request.getParameter(KRADConstants.COPY_KEYS))) { 360 String[] copyKeys = request.getParameter(KRADConstants.COPY_KEYS).split(KRADConstants.FIELD_CONVERSIONS_SEPARATOR); 361 for (String copyKey: copyKeys) { 362 keyFieldNamesToCopy.add(copyKey); 363 } 364 } 365 parametersToCopy = getRequestParameters(keyFieldNamesToCopy, oldMaintainableObject, request); 366 if(parametersToCopy!=null && parametersToCopy.size()>0){ 367 copyParametersToBO(parametersToCopy, oldBusinessObject); 368 } 369 } 370 371 protected void copyParametersToBO(Map<String, String> parameters, PersistableBusinessObject newBO) throws Exception{ 372 for (String parmName : parameters.keySet()) { 373 String propertyValue = parameters.get(parmName); 374 375 if (StringUtils.isNotBlank(propertyValue)) { 376 String propertyName = parmName; 377 // set value of property in bo 378 if (PropertyUtils.isWriteable(newBO, propertyName)) { 379 Class type = ObjectUtils.easyGetPropertyType(newBO, propertyName); 380 if (type != null && Formatter.getFormatter(type) != null) { 381 Formatter formatter = Formatter.getFormatter(type); 382 Object obj = formatter.convertFromPresentationFormat(propertyValue); 383 ObjectUtils.setObjectProperty(newBO, propertyName, obj.getClass(), obj); 384 } 385 else { 386 ObjectUtils.setObjectProperty(newBO, propertyName, String.class, propertyValue); 387 } 388 } 389 } 390 } 391 } 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 KualiDocumentFormBase documentForm = (KualiDocumentFormBase) form; 405 MaintenanceDocumentBase document = (MaintenanceDocumentBase) documentForm.getDocument(); 406 document.refreshReferenceObject("attachment"); 407 DocumentAttachment attachment = document.getAttachment(); 408 if(attachment != null) { 409 streamToResponse(attachment.getAttachmentContent(), attachment.getFileName(), attachment.getContentType(), response); 410 } 411 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 KualiDocumentFormBase documentForm = (KualiDocumentFormBase) form; 428 MaintenanceDocumentBase document = (MaintenanceDocumentBase) documentForm.getDocument(); 429 document.refreshReferenceObject("attachment"); 430 getBusinessObjectService().delete(document.getAttachment()); 431 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 KualiDocumentFormBase documentForm = (KualiDocumentFormBase) form; 447 MaintenanceDocumentBase document = (MaintenanceDocumentBase) documentForm.getDocument(); 448 449 ActionForward forward = super.route(mapping, form, request, response); 450 if(document.getNewMaintainableObject().getBusinessObject() instanceof PersistableAttachment) { 451 PersistableAttachment bo = (PersistableAttachment) getBusinessObjectService().retrieve(document.getNewMaintainableObject().getBusinessObject()); 452 request.setAttribute("fileName", bo.getFileName()); 453 } 454 455 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 super.docHandler(mapping, form, request, response); 464 KualiMaintenanceForm kualiMaintenanceForm = (KualiMaintenanceForm) form; 465 466 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 if (kualiMaintenanceForm.getDocument() instanceof MaintenanceDocument) { 468 kualiMaintenanceForm.setReadOnly(true); 469 kualiMaintenanceForm.setMaintenanceAction(((MaintenanceDocument) kualiMaintenanceForm.getDocument()).getNewMaintainableObject().getMaintenanceAction()); 470 471 //Retrieving the FileName from BO table 472 Maintainable tmpMaintainable = ((MaintenanceDocument) kualiMaintenanceForm.getDocument()).getNewMaintainableObject(); 473 if(tmpMaintainable.getBusinessObject() instanceof PersistableAttachment) { 474 PersistableAttachment bo = (PersistableAttachment) getBusinessObjectService().retrieve(tmpMaintainable.getBusinessObject()); 475 if(bo != null) 476 request.setAttribute("fileName", bo.getFileName()); 477 } 478 } 479 else { 480 LOG.error("Illegal State: document is not a maintenance document"); 481 throw new IllegalStateException("Document is not a maintenance document"); 482 } 483 } 484 else if (KewApiConstants.INITIATE_COMMAND.equals(kualiMaintenanceForm.getCommand())) { 485 kualiMaintenanceForm.setReadOnly(false); 486 return setupMaintenance(mapping, form, request, response, KRADConstants.MAINTENANCE_NEW_ACTION); 487 } 488 else { 489 LOG.error("We should never have gotten to here"); 490 throw new IllegalStateException("docHandler called with invalid parameters"); 491 } 492 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 KualiMaintenanceForm maintenanceForm = (KualiMaintenanceForm) form; 501 502 WebUtils.reuseErrorMapFromPreviousRequest(maintenanceForm); 503 maintenanceForm.setDerivedValuesOnForm(request); 504 505 refreshAdHocRoutingWorkgroupLookups(request, maintenanceForm); 506 MaintenanceDocument document = (MaintenanceDocument) maintenanceForm.getDocument(); 507 508 // call refresh on new maintainable 509 Map<String, String> requestParams = new HashMap<String, String>(); 510 for (Enumeration i = request.getParameterNames(); i.hasMoreElements();) { 511 String requestKey = (String) i.nextElement(); 512 String requestValue = request.getParameter(requestKey); 513 requestParams.put(requestKey, requestValue); 514 } 515 516 // Add multiple values from Lookup 517 Collection<PersistableBusinessObject> rawValues = null; 518 if (StringUtils.equals(KRADConstants.MULTIPLE_VALUE, maintenanceForm.getRefreshCaller())) { 519 String lookupResultsSequenceNumber = maintenanceForm.getLookupResultsSequenceNumber(); 520 if (StringUtils.isNotBlank(lookupResultsSequenceNumber)) { 521 // actually returning from a multiple value lookup 522 String lookupResultsBOClassName = maintenanceForm.getLookupResultsBOClassName(); 523 Class lookupResultsBOClass = Class.forName(lookupResultsBOClassName); 524 525 rawValues = getLookupResultsService().retrieveSelectedResultBOs(lookupResultsSequenceNumber, lookupResultsBOClass, GlobalVariables.getUserSession().getPerson().getPrincipalId()); 526 } 527 } 528 529 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 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 document.getNewMaintainableObject().addMultipleValueLookupResults(document, collectionName, rawValues, false, document.getNewMaintainableObject().getBusinessObject()); 549 if (LOG.isInfoEnabled()) { 550 LOG.info("********************doing editing 3 in refersh()***********************."); 551 } 552 boolean isEdit = KRADConstants.MAINTENANCE_EDIT_ACTION.equals(maintenanceForm.getMaintenanceAction()); 553 boolean isCopy = KRADConstants.MAINTENANCE_COPY_ACTION.equals(maintenanceForm.getMaintenanceAction()); 554 555 if (isEdit || isCopy) { 556 document.getOldMaintainableObject().addMultipleValueLookupResults(document, collectionName, rawValues, true, document.getOldMaintainableObject().getBusinessObject()); 557 document.getOldMaintainableObject().refresh(maintenanceForm.getRefreshCaller(), requestParams, document); 558 } 559 } 560 561 document.getNewMaintainableObject().refresh(maintenanceForm.getRefreshCaller(), requestParams, document); 562 563 //pass out customAction from methodToCall parameter. Call processAfterPost 564 String fullParameter = (String) request.getAttribute(KRADConstants.METHOD_TO_CALL_ATTRIBUTE); 565 if(StringUtils.contains(fullParameter, KRADConstants.CUSTOM_ACTION)){ 566 String customAction = StringUtils.substringBetween(fullParameter, KRADConstants.METHOD_TO_CALL_PARM1_LEFT_DEL, KRADConstants.METHOD_TO_CALL_PARM1_RIGHT_DEL); 567 String[] actionValue = new String[1]; 568 actionValue[0]= StringUtils.substringAfter(customAction, "."); 569 Map<String,String[]> paramMap = request.getParameterMap(); 570 paramMap.put(KRADConstants.CUSTOM_ACTION, actionValue); 571 doProcessingAfterPost( (KualiMaintenanceForm) form, paramMap ); 572 } 573 574 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 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 if (!StringUtils.isBlank(request.getParameter(KRADConstants.OVERRIDE_KEYS))) { 586 String[] overrideKeys = request.getParameter(KRADConstants.OVERRIDE_KEYS).split(KRADConstants.FIELD_CONVERSIONS_SEPARATOR); 587 keyFieldNames = new ArrayList(); 588 for (String overrideKey : overrideKeys) { 589 keyFieldNames.add(overrideKey); 590 } 591 } 592 else { 593 keyFieldNames = getBusinessObjectMetaDataService().listPrimaryKeyFieldNames(maintainable.getBusinessObject().getClass()); 594 } 595 return getRequestParameters(keyFieldNames, maintainable, request); 596 } 597 598 protected Map<String, String> getRequestParameters(List keyFieldNames, Maintainable maintainable, HttpServletRequest request){ 599 600 Map<String, String> requestParameters = new HashMap<String, String>(); 601 602 603 for (Iterator iter = keyFieldNames.iterator(); iter.hasNext();) { 604 String keyPropertyName = (String) iter.next(); 605 606 if (request.getParameter(keyPropertyName) != null) { 607 String keyValue = request.getParameter(keyPropertyName); 608 609 // Check if this element was encrypted, if it was decrypt it 610 if (getBusinessObjectAuthorizationService().attributeValueNeedsToBeEncryptedOnFormsAndLinks(maintainable.getBoClass(), keyPropertyName)) { 611 try { 612 keyValue = StringUtils.removeEnd(keyValue, EncryptionService.ENCRYPTION_POST_PREFIX); 613 keyValue = encryptionService.decrypt(keyValue); 614 } 615 catch (GeneralSecurityException e) { 616 throw new RuntimeException(e); 617 } 618 } 619 620 621 requestParameters.put(keyPropertyName, keyValue); 622 } 623 } 624 625 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 String parameterName = (String) request.getAttribute(KRADConstants.METHOD_TO_CALL_ATTRIBUTE); 637 String collectionName = null; 638 if (StringUtils.isNotBlank(parameterName)) { 639 collectionName = StringUtils.substringBetween(parameterName, methodToCall + ".", ".("); 640 } 641 return collectionName; 642 } 643 644 Collection extractCollection(PersistableBusinessObject bo, String collectionName) { 645 // retrieve the collection from the business object 646 Collection maintCollection = (Collection) ObjectUtils.getPropertyValue(bo, collectionName); 647 return maintCollection; 648 } 649 650 Class extractCollectionClass(String docTypeName, String collectionName) { 651 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 KualiMaintenanceForm maintenanceForm = (KualiMaintenanceForm) form; 659 MaintenanceDocument document = (MaintenanceDocument) maintenanceForm.getDocument(); 660 Maintainable oldMaintainable = document.getOldMaintainableObject(); 661 Maintainable newMaintainable = document.getNewMaintainableObject(); 662 663 String collectionName = extractCollectionName(request, KRADConstants.ADD_LINE_METHOD); 664 if (collectionName == null) { 665 LOG.error("Unable to get find collection name and class in request."); 666 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 if ((StringUtils.lastIndexOf(collectionName, "]") + 1) == collectionName.length()) { 671 collectionName = StringUtils.substringBeforeLast(collectionName, "["); 672 } 673 674 PersistableBusinessObject bo = newMaintainable.getBusinessObject(); 675 Collection maintCollection = extractCollection(bo, collectionName); 676 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 PersistableBusinessObject addBO = newMaintainable.getNewCollectionLine(collectionName); 682 if (LOG.isDebugEnabled()) { 683 LOG.debug("obtained addBO from newCollectionLine: " + addBO); 684 } 685 686 // link up the user fields, if any 687 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 newMaintainable.processBeforeAddLine(collectionName, collectionClass, addBO); 691 692 // apply rules to the addBO 693 boolean rulePassed = false; 694 if (LOG.isDebugEnabled()) { 695 LOG.debug("about to call AddLineEvent applyRules: document=" + document + "\ncollectionName=" + collectionName + "\nBO=" + addBO); 696 } 697 rulePassed = getKualiRuleService().applyRules(new KualiAddLineEvent(document, collectionName, addBO)); 698 699 // if the rule evaluation passed, let's add it 700 if (rulePassed) { 701 if (LOG.isInfoEnabled()) { 702 LOG.info("********************doing editing 4 in addline()***********************."); 703 } 704 // if edit or copy action, just add empty instance to old maintainable 705 boolean isEdit = KRADConstants.MAINTENANCE_EDIT_ACTION.equals(maintenanceForm.getMaintenanceAction()); 706 boolean isCopy = KRADConstants.MAINTENANCE_COPY_ACTION.equals(maintenanceForm.getMaintenanceAction()); 707 708 709 if (isEdit || isCopy) { 710 PersistableBusinessObject oldBo = oldMaintainable.getBusinessObject(); 711 Collection oldMaintCollection = (Collection) ObjectUtils.getPropertyValue(oldBo, collectionName); 712 713 if (oldMaintCollection == null) { 714 oldMaintCollection = new ArrayList(); 715 } 716 if (PersistableBusinessObject.class.isAssignableFrom(collectionClass)) { 717 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 placeholder.setNewCollectionRecord(true); 724 ((List) oldMaintCollection).add(placeholder); 725 } 726 else { 727 LOG.warn("Should be a instance of PersistableBusinessObject"); 728 ((List) oldMaintCollection).add(collectionClass.newInstance()); 729 } 730 // update collection in maintenance business object 731 ObjectUtils.setObjectProperty(oldBo, collectionName, List.class, oldMaintCollection); 732 } 733 734 newMaintainable.addNewLineToCollection(collectionName); 735 int subCollectionIndex = 0; 736 for (Object aSubCollection : maintCollection) { 737 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 doProcessingAfterPost( (KualiMaintenanceForm) form, request ); 772 773 return mapping.findForward(RiceConstants.MAPPING_BASIC); 774 } 775 776 protected int getSubCollectionIndex(Object object, String documentTypeName) { 777 int index = 1; 778 MaintainableCollectionDefinition theCollectionDefinition = null; 779 for (MaintainableCollectionDefinition maintainableCollectionDefinition : maintenanceDocumentDictionaryService.getMaintainableCollections(documentTypeName)) { 780 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 theCollectionDefinition = maintainableCollectionDefinition; 783 break; 784 } 785 } 786 if (theCollectionDefinition != null) { 787 for (MaintainableCollectionDefinition subCollDef : theCollectionDefinition.getMaintainableCollections()) { 788 String name = subCollDef.getName(); 789 String capitalFirst = name.substring(0, 1).toUpperCase(); 790 String methodName = "get" + capitalFirst + name.substring(1); 791 List subCollectionList = new ArrayList(); 792 try { 793 subCollectionList = (List) object.getClass().getMethod(methodName).invoke(object); 794 } 795 catch (InvocationTargetException ite) { 796 // this shouldn't happen 797 } 798 catch (IllegalAccessException iae) { 799 // this shouldn't happen 800 } 801 catch (NoSuchMethodException nme) { 802 // this shouldn't happen 803 } 804 index += subCollectionList.size(); 805 } 806 } 807 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 KualiMaintenanceForm maintenanceForm = (KualiMaintenanceForm) form; 817 MaintenanceDocument document = (MaintenanceDocument) maintenanceForm.getDocument(); 818 Maintainable oldMaintainable = document.getOldMaintainableObject(); 819 Maintainable newMaintainable = document.getNewMaintainableObject(); 820 821 String collectionName = extractCollectionName(request, KRADConstants.DELETE_LINE_METHOD); 822 if (collectionName == null) { 823 LOG.error("Unable to get find collection name in request."); 824 throw new RuntimeException("Unable to get find collection class in request."); 825 } 826 827 PersistableBusinessObject bo = newMaintainable.getBusinessObject(); 828 Collection maintCollection = extractCollection(bo, collectionName); 829 if (collectionName == null) { 830 LOG.error("Collection is null in parent business object."); 831 throw new RuntimeException("Collection is null in parent business object."); 832 } 833 834 int deleteRecordIndex = getLineToDelete(request); 835 if (deleteRecordIndex < 0 || deleteRecordIndex > maintCollection.size() - 1) { 836 if (collectionName == null) { 837 LOG.error("Invalid index for deletion of collection record: " + deleteRecordIndex); 838 throw new RuntimeException("Invalid index for deletion of collection record: " + deleteRecordIndex); 839 } 840 } 841 842 ((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 if (KRADConstants.MAINTENANCE_EDIT_ACTION.equals(maintenanceForm.getMaintenanceAction()) || 846 KRADConstants.MAINTENANCE_COPY_ACTION.equals(maintenanceForm.getMaintenanceAction())) { 847 bo = oldMaintainable.getBusinessObject(); 848 maintCollection = extractCollection(bo, collectionName); 849 850 if (collectionName == null) { 851 LOG.error("Collection is null in parent business object."); 852 throw new RuntimeException("Collection is null in parent business object."); 853 } 854 855 ((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 doProcessingAfterPost( (KualiMaintenanceForm) form, request ); 897 898 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 KualiMaintenanceForm maintenanceForm = (KualiMaintenanceForm) form; 906 MaintenanceDocument document = (MaintenanceDocument) maintenanceForm.getDocument(); 907 Maintainable oldMaintainable = document.getOldMaintainableObject(); 908 Maintainable newMaintainable = document.getNewMaintainableObject(); 909 910 String collectionName = extractCollectionName(request, KRADConstants.TOGGLE_INACTIVE_METHOD); 911 if (collectionName == null) { 912 LOG.error("Unable to get find collection name in request."); 913 throw new RuntimeException("Unable to get find collection class in request."); 914 } 915 916 String parameterName = (String) request.getAttribute(KRADConstants.METHOD_TO_CALL_ATTRIBUTE); 917 boolean showInactive = Boolean.parseBoolean(StringUtils.substringBetween(parameterName, KRADConstants.METHOD_TO_CALL_BOPARM_LEFT_DEL, ".")); 918 919 oldMaintainable.setShowInactiveRecords(collectionName, showInactive); 920 newMaintainable.setShowInactiveRecords(collectionName, showInactive); 921 922 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 PersistableBusinessObject bo = document.getNewMaintainableObject().getBusinessObject(); 935 List<String> keyFieldNames = getBusinessObjectMetaDataService().listPrimaryKeyFieldNames(bo.getClass()); 936 937 for (String keyFieldName : keyFieldNames) { 938 try { 939 ObjectUtils.setObjectProperty(bo, keyFieldName, null); 940 } 941 catch (Exception e) { 942 LOG.error("Unable to clear primary key field: " + e.getMessage()); 943 throw new RuntimeException("Unable to clear primary key field: " + e.getMessage()); 944 } 945 } 946 } 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 Person user = GlobalVariables.getUserSession().getPerson(); 957 958 // get the correct documentAuthorizer for this document 959 MaintenanceDocumentAuthorizer documentAuthorizer = (MaintenanceDocumentAuthorizer) getDocumentHelperService().getDocumentAuthorizer(document); 960 961 // get a new instance of MaintenanceDocumentAuthorizations for this context 962 MaintenanceDocumentRestrictions maintenanceDocumentRestrictions = getBusinessObjectAuthorizationService().getMaintenanceDocumentRestrictions(document, user); 963 964 // get a reference to the newBo 965 PersistableBusinessObject newBo = document.getNewMaintainableObject().getBusinessObject(); 966 967 document.getNewMaintainableObject().clearBusinessObjectOfRestrictedValues(maintenanceDocumentRestrictions); 968 } 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 MaintenanceDocument document = (MaintenanceDocument) ((KualiMaintenanceForm)form).getDocument(); 978 Maintainable maintainable = document.getNewMaintainableObject(); 979 PersistableBusinessObject bo = maintainable.getBusinessObject(); 980 981 getBusinessObjectService().linkUserFields(bo); 982 983 maintainable.processAfterPost(document, request.getParameterMap() ); 984 } 985 986 protected void doProcessingAfterPost( KualiForm form, Map<String,String[]> parameters ) { 987 MaintenanceDocument document = (MaintenanceDocument) ((KualiMaintenanceForm)form).getDocument(); 988 Maintainable maintainable = document.getNewMaintainableObject(); 989 PersistableBusinessObject bo = maintainable.getBusinessObject(); 990 991 getBusinessObjectService().linkUserFields(bo); 992 993 maintainable.processAfterPost(document, parameters ); 994 } 995 996 protected void populateAuthorizationFields(KualiDocumentFormBase formBase){ 997 super.populateAuthorizationFields(formBase); 998 999 KualiMaintenanceForm maintenanceForm = (KualiMaintenanceForm) formBase; 1000 MaintenanceDocument maintenanceDocument = (MaintenanceDocument) maintenanceForm.getDocument(); 1001 MaintenanceDocumentAuthorizer maintenanceDocumentAuthorizer = (MaintenanceDocumentAuthorizer) getDocumentHelperService().getDocumentAuthorizer(maintenanceDocument); 1002 Person user = GlobalVariables.getUserSession().getPerson(); 1003 maintenanceForm.setReadOnly(!formBase.getDocumentActions().containsKey(KRADConstants.KUALI_ACTION_CAN_EDIT)); 1004 MaintenanceDocumentRestrictions maintenanceDocumentAuthorizations = getBusinessObjectAuthorizationService().getMaintenanceDocumentRestrictions(maintenanceDocument, user); 1005 maintenanceForm.setAuthorizations(maintenanceDocumentAuthorizations); 1006 } 1007 1008 public LookupService getLookupService() { 1009 if ( lookupService == null ) { 1010 lookupService = KRADServiceLocatorWeb.getLookupService(); 1011 } 1012 return this.lookupService; 1013 } 1014 1015 public LookupResultsService getLookupResultsService() { 1016 if ( lookupResultsService == null ) { 1017 lookupResultsService = KNSServiceLocator.getLookupResultsService(); 1018 } 1019 return this.lookupResultsService; 1020 } 1021 1022 }