001/** 002 * Copyright 2005-2016 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 */ 016package org.kuali.rice.kns.web.struts.action; 017 018import org.apache.commons.beanutils.PropertyUtils; 019import org.apache.commons.collections.CollectionUtils; 020import org.apache.commons.lang.StringUtils; 021import org.apache.ojb.broker.metadata.ClassNotPersistenceCapableException; 022import org.apache.struts.action.ActionForm; 023import org.apache.struts.action.ActionForward; 024import org.apache.struts.action.ActionMapping; 025import org.apache.struts.upload.FormFile; 026import org.kuali.rice.core.api.CoreApiServiceLocator; 027import org.kuali.rice.core.api.encryption.EncryptionService; 028import org.kuali.rice.core.api.util.ClassLoaderUtils; 029import org.kuali.rice.core.api.util.RiceConstants; 030import org.kuali.rice.core.api.util.RiceKeyConstants; 031import org.kuali.rice.core.api.util.io.SerializationUtils; 032import org.kuali.rice.core.web.format.Formatter; 033import org.kuali.rice.kew.api.KewApiConstants; 034import org.kuali.rice.kim.api.identity.Person; 035import org.kuali.rice.kns.datadictionary.MaintainableCollectionDefinition; 036import org.kuali.rice.kns.datadictionary.MaintenanceDocumentEntry; 037import org.kuali.rice.kns.document.MaintenanceDocument; 038import org.kuali.rice.kns.document.MaintenanceDocumentBase; 039import org.kuali.rice.kns.document.authorization.MaintenanceDocumentAuthorizer; 040import org.kuali.rice.kns.document.authorization.MaintenanceDocumentRestrictions; 041import org.kuali.rice.kns.lookup.LookupResultsService; 042import org.kuali.rice.kns.maintenance.Maintainable; 043import org.kuali.rice.kns.rule.event.KualiAddLineEvent; 044import org.kuali.rice.kns.service.KNSServiceLocator; 045import org.kuali.rice.kns.service.MaintenanceDocumentDictionaryService; 046import org.kuali.rice.kns.util.KNSGlobalVariables; 047import org.kuali.rice.kns.util.MaintenanceUtils; 048import org.kuali.rice.kns.util.WebUtils; 049import org.kuali.rice.kns.web.struts.form.KualiDocumentFormBase; 050import org.kuali.rice.kns.web.struts.form.KualiForm; 051import org.kuali.rice.kns.web.struts.form.KualiMaintenanceForm; 052import org.kuali.rice.krad.bo.DocumentAttachment; 053import org.kuali.rice.krad.bo.MultiDocumentAttachment; 054import org.kuali.rice.krad.bo.PersistableAttachment; 055import org.kuali.rice.krad.bo.PersistableAttachmentList; 056import org.kuali.rice.krad.bo.PersistableBusinessObject; 057import org.kuali.rice.krad.exception.DocumentTypeAuthorizationException; 058import org.kuali.rice.krad.service.KRADServiceLocatorWeb; 059import org.kuali.rice.krad.service.LookupService; 060import org.kuali.rice.krad.util.GlobalVariables; 061import org.kuali.rice.krad.util.KRADConstants; 062import org.kuali.rice.krad.util.KRADPropertyConstants; 063import org.kuali.rice.krad.util.ObjectUtils; 064 065import javax.servlet.http.HttpServletRequest; 066import javax.servlet.http.HttpServletResponse; 067import java.lang.reflect.InvocationTargetException; 068import java.lang.reflect.Method; 069import java.security.GeneralSecurityException; 070import java.util.ArrayList; 071import java.util.Collection; 072import java.util.Enumeration; 073import java.util.HashMap; 074import java.util.Iterator; 075import java.util.List; 076import java.util.Map; 077 078/** 079 * This class handles actions for maintenance documents. These include creating new edit, and copying of maintenance records. 080 * 081 * @deprecated Use {@link org.kuali.rice.krad.maintenance.MaintenanceDocumentController}. 082 */ 083@Deprecated 084public 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 maintenanceForm.setDocument(document); 191 } 192 else { 193 document = (MaintenanceDocument) maintenanceForm.getDocument(); 194 } 195 196 // retrieve business object from request parameters 197 if (!(KRADConstants.MAINTENANCE_NEW_ACTION.equals(maintenanceAction)) 198 && !(KRADConstants.MAINTENANCE_NEWWITHEXISTING_ACTION.equals(maintenanceAction))) { 199 Map requestParameters = buildKeyMapFromRequest(document.getNewMaintainableObject(), request); 200 PersistableBusinessObject oldBusinessObject = null; 201 try { 202 oldBusinessObject = (PersistableBusinessObject) getLookupService().findObjectBySearch(Class.forName(maintenanceForm.getBusinessObjectClassName()), requestParameters); 203 } catch ( ClassNotPersistenceCapableException ex ) { 204 if ( !document.getOldMaintainableObject().isExternalBusinessObject() ) { 205 throw new RuntimeException( "BO Class: " + maintenanceForm.getBusinessObjectClassName() + " is not persistable and is not externalizable - configuration error" ); 206 } 207 // otherwise, let fall through 208 } 209 if (oldBusinessObject == null && !document.getOldMaintainableObject().isExternalBusinessObject()) { 210 throw new RuntimeException("Cannot retrieve old record for maintenance document, incorrect parameters passed on maint url: " + requestParameters ); 211 } 212 213 if(document.getOldMaintainableObject().isExternalBusinessObject()){ 214 if ( oldBusinessObject == null ) { 215 try { 216 oldBusinessObject = (PersistableBusinessObject)document.getOldMaintainableObject().getBoClass().newInstance(); 217 } catch ( Exception ex ) { 218 throw new RuntimeException( "External BO maintainable was null and unable to instantiate for old maintainable object.", ex ); 219 } 220 } 221 populateBOWithCopyKeyValues(request, oldBusinessObject, document.getOldMaintainableObject()); 222 document.getOldMaintainableObject().prepareBusinessObject(oldBusinessObject); 223 oldBusinessObject = document.getOldMaintainableObject().getBusinessObject(); 224 } 225 226 PersistableBusinessObject newBusinessObject = (PersistableBusinessObject) SerializationUtils.deepCopy( 227 oldBusinessObject); 228 229 // set business object instance for editing 230 Class<? extends PersistableBusinessObject> businessObjectClass = ClassLoaderUtils.getClass(maintenanceForm.getBusinessObjectClassName(), PersistableBusinessObject.class); 231 document.getOldMaintainableObject().setBusinessObject(oldBusinessObject); 232 document.getOldMaintainableObject().setBoClass(businessObjectClass); 233 document.getNewMaintainableObject().setBusinessObject(newBusinessObject); 234 document.getNewMaintainableObject().setBoClass(businessObjectClass); 235 236 237 // on a COPY, clear any fields that this user isnt authorized for, and also 238 // clear the primary key fields and the version number and objectId 239 if (KRADConstants.MAINTENANCE_COPY_ACTION.equals(maintenanceAction)) { 240 if (!document.isFieldsClearedOnCopy()) { 241 //for issue KULRice 3072 242 Class boClass = maintenanceDocumentDictionaryService.getDataObjectClass( 243 maintenanceForm.getDocTypeName()); 244 if (!maintenanceDocumentDictionaryService.getPreserveLockingKeysOnCopy(boClass)) { 245 clearPrimaryKeyFields(document); 246 } 247 248 clearUnauthorizedNewFields(document); 249 250 Maintainable maintainable = document.getNewMaintainableObject(); 251 252 maintainable.processAfterCopy( document, request.getParameterMap() ); 253 254 // mark so that this clearing doesnt happen again 255 document.setFieldsClearedOnCopy(true); 256 257 // mark so that blank required fields will be populated with default values 258 maintainable.setGenerateBlankRequiredValues(maintenanceForm.getDocTypeName()); 259 } 260 } 261 else if (KRADConstants.MAINTENANCE_EDIT_ACTION.equals(maintenanceAction)) { 262 boolean allowsEdit = getBusinessObjectAuthorizationService().canMaintain(oldBusinessObject, GlobalVariables.getUserSession().getPerson(), document.getDocumentHeader().getWorkflowDocument().getDocumentTypeName()); 263 if (!allowsEdit) { 264 LOG.error("Document type " + document.getDocumentHeader().getWorkflowDocument().getDocumentTypeName() + " does not allow edit actions."); 265 throw new DocumentTypeAuthorizationException(GlobalVariables.getUserSession().getPerson().getPrincipalId(), "edit", document.getDocumentHeader().getWorkflowDocument().getDocumentTypeName()); 266 } 267 document.getNewMaintainableObject().processAfterEdit( document, request.getParameterMap() ); 268 } 269 //3070 270 else if (KRADConstants.MAINTENANCE_DELETE_ACTION.equals(maintenanceAction)) { 271 boolean allowsDelete = getBusinessObjectAuthorizationService().canMaintain(oldBusinessObject, GlobalVariables.getUserSession().getPerson(), document.getDocumentHeader().getWorkflowDocument().getDocumentTypeName()); 272 if (!allowsDelete) { 273 LOG.error("Document type " + document.getDocumentHeader().getWorkflowDocument().getDocumentTypeName() + " does not allow delete actions."); 274 throw new DocumentTypeAuthorizationException(GlobalVariables.getUserSession().getPerson().getPrincipalId(), "delete", document.getDocumentHeader().getWorkflowDocument().getDocumentTypeName()); 275 } 276 //document.getNewMaintainableObject().processAfterEdit( document, request.getParameterMap() ); 277 } 278 } 279 // if new with existing we need to populate we need to populate with passed in parameters 280 if (KRADConstants.MAINTENANCE_NEWWITHEXISTING_ACTION.equals(maintenanceAction)) { 281 // TODO: this code should be abstracted out into a helper 282 // also is it a problem that we're not calling setGenerateDefaultValues? it blanked out the below values when I did 283 // maybe we need a new generateDefaultValues that doesn't overwrite? 284 PersistableBusinessObject newBO = document.getNewMaintainableObject().getBusinessObject(); 285 Map<String, String> parameters = buildKeyMapFromRequest(document.getNewMaintainableObject(), request); 286 copyParametersToBO(parameters, newBO); 287 newBO.refresh(); 288 document.getNewMaintainableObject().setupNewFromExisting( document, request.getParameterMap() ); 289 } 290 291 // for new maintainble need to pick up default values 292 if (KRADConstants.MAINTENANCE_NEW_ACTION.equals(maintenanceAction)) { 293 document.getNewMaintainableObject().setGenerateDefaultValues(maintenanceForm.getDocTypeName()); 294 document.getNewMaintainableObject().processAfterNew( document, request.getParameterMap() ); 295 296 // If a maintenance lock exists, warn the user. 297 MaintenanceUtils.checkForLockingDocument(document.getNewMaintainableObject(), false); 298 } 299 300 // set maintenance action state 301 document.getNewMaintainableObject().setMaintenanceAction(maintenanceAction); 302 maintenanceForm.setMaintenanceAction(maintenanceAction); 303 304 // attach any extra JS from the data dictionary 305 MaintenanceDocumentEntry entry = maintenanceDocumentDictionaryService.getMaintenanceDocumentEntry(document.getDocumentHeader().getWorkflowDocument().getDocumentTypeName()); 306 if (LOG.isDebugEnabled()) { 307 LOG.debug("maintenanceForm.getAdditionalScriptFiles(): " + maintenanceForm.getAdditionalScriptFiles()); 308 } 309 if (maintenanceForm.getAdditionalScriptFiles().isEmpty()) { 310 maintenanceForm.getAdditionalScriptFiles().addAll(entry.getWebScriptFiles()); 311 } 312 313 // Retrieve notes topic display flag from data dictionary and add to document 314 document.setDisplayTopicFieldInNotes(entry.getDisplayTopicFieldInNotes()); 315 316 return mapping.findForward(RiceConstants.MAPPING_BASIC); 317 } 318 319 protected void populateBOWithCopyKeyValues(HttpServletRequest request, PersistableBusinessObject oldBusinessObject, Maintainable oldMaintainableObject) throws Exception{ 320 List keyFieldNamesToCopy = new ArrayList(); 321 Map<String, String> parametersToCopy; 322 if (!StringUtils.isBlank(request.getParameter(KRADConstants.COPY_KEYS))) { 323 String[] copyKeys = request.getParameter(KRADConstants.COPY_KEYS).split(KRADConstants.FIELD_CONVERSIONS_SEPARATOR); 324 for (String copyKey: copyKeys) { 325 keyFieldNamesToCopy.add(copyKey); 326 } 327 } 328 parametersToCopy = getRequestParameters(keyFieldNamesToCopy, oldMaintainableObject, request); 329 if(parametersToCopy!=null && parametersToCopy.size()>0){ 330 copyParametersToBO(parametersToCopy, oldBusinessObject); 331 } 332 } 333 334 protected void copyParametersToBO(Map<String, String> parameters, PersistableBusinessObject newBO) throws Exception{ 335 for (String parmName : parameters.keySet()) { 336 String propertyValue = parameters.get(parmName); 337 338 if (StringUtils.isNotBlank(propertyValue)) { 339 String propertyName = parmName; 340 // set value of property in bo 341 if (PropertyUtils.isWriteable(newBO, propertyName)) { 342 Class type = ObjectUtils.easyGetPropertyType(newBO, propertyName); 343 if (type != null && Formatter.getFormatter(type) != null) { 344 Formatter formatter = Formatter.getFormatter(type); 345 Object obj = formatter.convertFromPresentationFormat(propertyValue); 346 ObjectUtils.setObjectProperty(newBO, propertyName, obj.getClass(), obj); 347 } 348 else { 349 ObjectUtils.setObjectProperty(newBO, propertyName, String.class, propertyValue); 350 } 351 } 352 } 353 } 354 } 355 356 /** 357 * Downloads the attachment to the user's browser 358 * 359 * @param mapping 360 * @param form 361 * @param request 362 * @param response 363 * @return ActionForward 364 * @throws Exception 365 */ 366 public ActionForward downloadAttachment(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception { 367 KualiDocumentFormBase documentForm = (KualiDocumentFormBase) form; 368 MaintenanceDocumentBase document = (MaintenanceDocumentBase) documentForm.getDocument(); 369 370 int line = getSelectedLine(request); 371 if (line < 0) { 372 DocumentAttachment documentAttachment = document.getAttachment(); 373 if (documentAttachment != null 374 && documentAttachment.getAttachmentContent() != null) { 375 376 streamToResponse(documentAttachment.getAttachmentContent(), documentAttachment.getFileName(), documentAttachment.getContentType(), response); 377 return null; 378 } 379 PersistableAttachment attachment = (PersistableAttachment) document.getNewMaintainableObject().getBusinessObject(); 380 String attachmentPropNm = document.getAttachmentPropertyName(); 381 FormFile attachmentFromBusinessObject = null; 382 byte[] attachmentContent; 383 String fileName = attachment.getFileName(); 384 String contentType = attachment.getContentType(); 385 if (StringUtils.isNotBlank(attachmentPropNm)) { 386 String attachmentPropNmSetter = "get" + attachmentPropNm.substring(0, 1).toUpperCase() + attachmentPropNm.substring(1, attachmentPropNm.length()); 387 attachmentFromBusinessObject = (FormFile)(attachment.getClass().getDeclaredMethod(attachmentPropNmSetter).invoke(attachment)); 388 } 389 if (attachmentFromBusinessObject != null 390 && attachmentFromBusinessObject.getInputStream() != null) { 391 attachmentContent = attachmentFromBusinessObject.getFileData(); 392 fileName = attachmentFromBusinessObject.getFileName(); 393 contentType = attachmentFromBusinessObject.getContentType(); 394 } else { 395 attachmentContent = attachment.getAttachmentContent(); 396 } 397 if (StringUtils.isNotBlank(fileName) 398 && contentType != null 399 && attachmentContent != null) { 400 streamToResponse(attachmentContent, fileName, contentType, response); 401 } 402 } else { 403 404 // attachment is part of a collection 405 PersistableAttachmentList<PersistableAttachment> attachmentsBo = (PersistableAttachmentList<PersistableAttachment>) document.getNewMaintainableObject().getBusinessObject(); 406 if (CollectionUtils.isEmpty(attachmentsBo.getAttachments())) { 407 document.populateAttachmentListForBO(); 408 } 409 410 List<? extends PersistableAttachment> attachments = attachmentsBo.getAttachments(); 411 if (CollectionUtils.isNotEmpty(attachments) 412 && attachments.size() > line) { 413 PersistableAttachment attachment = attachmentsBo.getAttachments().get(line); 414 415 //it is possible that document hasn't been saved (attachment just added) and the attachment content is still in the FormFile 416 //need to grab it if that is the case. 417 byte[] attachmentContent; // = attachment.getAttachmentContent(); 418 String fileName = attachment.getFileName(); 419 String contentType = attachment.getContentType(); 420 String attachmentPropNm = document.getAttachmentListPropertyName(); 421 FormFile attachmentFromBusinessObject = null; 422 if (StringUtils.isNotBlank(attachmentPropNm)) { 423 String attachmentPropNmSetter = "get" + attachmentPropNm.substring(0, 1).toUpperCase() + attachmentPropNm.substring(1, attachmentPropNm.length()); 424 attachmentFromBusinessObject = (FormFile)(attachment.getClass().getDeclaredMethod(attachmentPropNmSetter).invoke(attachment)); 425 } 426 //Use form file data if it exists 427 //if (attachmentContent == null) { 428 429 if (attachmentFromBusinessObject != null 430 && attachmentFromBusinessObject.getInputStream() != null) { 431 attachmentContent = attachmentFromBusinessObject.getFileData(); 432 fileName = attachmentFromBusinessObject.getFileName(); 433 contentType = attachmentFromBusinessObject.getContentType(); 434 } else { 435 attachmentContent = attachment.getAttachmentContent(); 436 } 437 438 if (attachmentContent != null) { 439 streamToResponse(attachmentContent, fileName, contentType, response); 440 } else { 441 // last ditch effort to find the correct attachment 442 //check to see if attachment is populated on document first, so no copying done unless necessary 443 List<MultiDocumentAttachment> multiDocumentAttachs = document.getAttachments(); 444 if (CollectionUtils.isNotEmpty(multiDocumentAttachs)) { 445 for (MultiDocumentAttachment multiAttach : multiDocumentAttachs) { 446 if (multiAttach.getFileName().equals(fileName) 447 && multiAttach.getContentType().equals(contentType)) { 448 streamToResponse(multiAttach.getAttachmentContent(), multiAttach.getFileName(), multiAttach.getContentType(), response); 449 break; 450 } 451 } 452 } 453 } 454 } 455 } 456 return null; 457 } 458 459 460 /** 461 * 462 * This method used to replace the attachment 463 * @param mapping 464 * @param form 465 * @param request 466 * @param response 467 * @return 468 * @throws Exception 469 */ 470 public ActionForward replaceAttachment(ActionMapping mapping, ActionForm form, HttpServletRequest request, 471 HttpServletResponse response) throws Exception { 472 KualiDocumentFormBase documentForm = (KualiDocumentFormBase) form; 473 MaintenanceDocumentBase document = (MaintenanceDocumentBase) documentForm.getDocument(); 474 475 int lineNum = getSelectedLine(request); 476 477 if (lineNum < 0) { 478 479 document.refreshReferenceObject("attachment"); 480 documentForm.setAttachmentFile(null); 481 document.setFileAttachment(null); 482 getBusinessObjectService().delete(document.getAttachment()); 483 document.setAttachment(null); 484 485 PersistableAttachment attachment = (PersistableAttachment) document.getNewMaintainableObject().getBusinessObject(); 486 487 attachment.setAttachmentContent(null); 488 attachment.setContentType(null); 489 attachment.setFileName(null); 490 //pBo.setAttachmentFile(null); 491 492 String attachmentPropNm = document.getAttachmentPropertyName(); 493 String attachmentPropNmSetter = "set" + attachmentPropNm.substring(0, 1).toUpperCase() + attachmentPropNm.substring(1, attachmentPropNm.length()); 494 Class propNameSetterSig = null; 495 496 try { 497 Method[] methods = attachment.getClass().getMethods(); 498 for (Method method : methods) { 499 if (method.getName().equals(attachmentPropNmSetter)) { 500 propNameSetterSig = method.getParameterTypes()[0]; 501 attachment.getClass().getDeclaredMethod(attachmentPropNmSetter, propNameSetterSig).invoke(attachment, (Object) null); 502 break; 503 } 504 } 505 } catch (Exception e) { 506 LOG.error("Not able to get the attachment " + e.getMessage()); 507 throw new RuntimeException( 508 "Not able to get the attachment " + e.getMessage()); 509 } 510 } else { 511 document.refreshReferenceObject("attachments"); 512 getBusinessObjectService().delete(document.getAttachment()); 513 514 PersistableAttachmentList<PersistableAttachment> attachmentListBo = (PersistableAttachmentList<PersistableAttachment>) document.getNewMaintainableObject().getBusinessObject(); 515 516 PersistableAttachment attachment = (PersistableAttachment)attachmentListBo.getAttachments().get(lineNum); 517 attachment.setAttachmentContent(null); 518 attachment.setContentType(null); 519 attachment.setFileName(null); 520 521 String attachmentPropNm = document.getAttachmentListPropertyName(); 522 String attachmentPropNmSetter = "set" + attachmentPropNm.substring(0, 1).toUpperCase() + attachmentPropNm.substring(1, attachmentPropNm.length()); 523 Class propNameSetterSig = null; 524 525 try { 526 Method[] methods = attachment.getClass().getMethods(); 527 for (Method method : methods) { 528 if (method.getName().equals(attachmentPropNmSetter)) { 529 propNameSetterSig = method.getParameterTypes()[0]; 530 attachment.getClass().getDeclaredMethod(attachmentPropNmSetter, propNameSetterSig).invoke(attachment, (Object) null); 531 break; 532 } 533 } 534 } catch (Exception e) { 535 LOG.error("Not able to get the attachment " + e.getMessage()); 536 throw new RuntimeException( 537 "Not able to get the attachment " + e.getMessage()); 538 } 539 } 540 541 return mapping.findForward(RiceConstants.MAPPING_BASIC); 542 } 543 544 /** 545 * route the document using the document service 546 * 547 * @param mapping 548 * @param form 549 * @param request 550 * @param response 551 * @return ActionForward 552 * @throws Exception 553 */ 554 @Override 555 public ActionForward route(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception { 556 KualiDocumentFormBase documentForm = (KualiDocumentFormBase) form; 557 MaintenanceDocumentBase document = (MaintenanceDocumentBase) documentForm.getDocument(); 558 559 ActionForward forward = super.route(mapping, form, request, response); 560 PersistableBusinessObject businessObject = document.getNewMaintainableObject().getBusinessObject(); 561 if(businessObject instanceof PersistableAttachment) { 562 document.populateAttachmentForBO(); 563 String fileName = ((PersistableAttachment) businessObject).getFileName(); 564 if(StringUtils.isEmpty(fileName)) { 565 PersistableAttachment existingBO = (PersistableAttachment) getBusinessObjectService().retrieve(document.getNewMaintainableObject().getBusinessObject()); 566 if (existingBO == null) { 567 if (document.getAttachment() != null) { 568 fileName = document.getAttachment().getFileName(); 569 } else { 570 fileName = ""; 571 } 572 } else { 573 fileName = (existingBO != null ? existingBO.getFileName() : ""); 574 } 575 request.setAttribute("fileName", fileName); 576 } 577 } 578 return forward; 579 } 580 581 /** 582 * Handles creating and loading of documents. 583 */ 584 @Override 585 public ActionForward docHandler(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception { 586 ActionForward af = super.docHandler(mapping, form, request, response); 587 if (af.getName().equals(KRADConstants.KRAD_INITIATED_DOCUMENT_VIEW_NAME)) 588 { 589 return af; 590 } 591 KualiMaintenanceForm kualiMaintenanceForm = (KualiMaintenanceForm) form; 592 593 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) { 594 if (kualiMaintenanceForm.getDocument() instanceof MaintenanceDocument) { 595 kualiMaintenanceForm.setReadOnly(true); 596 kualiMaintenanceForm.setMaintenanceAction(((MaintenanceDocument) kualiMaintenanceForm.getDocument()).getNewMaintainableObject().getMaintenanceAction()); 597 598 //Retrieving the FileName from BO table 599 Maintainable tmpMaintainable = ((MaintenanceDocument) kualiMaintenanceForm.getDocument()).getNewMaintainableObject(); 600 if(tmpMaintainable.getBusinessObject() instanceof PersistableAttachment) { 601 PersistableAttachment bo = (PersistableAttachment) getBusinessObjectService().retrieve(tmpMaintainable.getBusinessObject()); 602 if (bo != null) { 603 request.setAttribute("fileName", bo.getFileName()); 604 } 605 } 606 } 607 else { 608 LOG.error("Illegal State: document is not a maintenance document"); 609 throw new IllegalArgumentException("Document is not a maintenance document"); 610 } 611 } 612 else if (KewApiConstants.INITIATE_COMMAND.equals(kualiMaintenanceForm.getCommand())) { 613 kualiMaintenanceForm.setReadOnly(false); 614 return setupMaintenance(mapping, form, request, response, KRADConstants.MAINTENANCE_NEW_ACTION); 615 } 616 else { 617 LOG.error("We should never have gotten to here"); 618 throw new IllegalArgumentException("docHandler called with invalid parameters"); 619 } 620 return mapping.findForward(RiceConstants.MAPPING_BASIC); 621 } 622 623 /** 624 * Called on return from a lookup. 625 */ 626 @Override 627 public ActionForward refresh(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception { 628 KualiMaintenanceForm maintenanceForm = (KualiMaintenanceForm) form; 629 630 WebUtils.reuseErrorMapFromPreviousRequest(maintenanceForm); 631 maintenanceForm.setDerivedValuesOnForm(request); 632 633 refreshAdHocRoutingWorkgroupLookups(request, maintenanceForm); 634 MaintenanceDocument document = (MaintenanceDocument) maintenanceForm.getDocument(); 635 636 // call refresh on new maintainable 637 Map<String, String> requestParams = new HashMap<String, String>(); 638 for (Enumeration i = request.getParameterNames(); i.hasMoreElements();) { 639 String requestKey = (String) i.nextElement(); 640 String requestValue = request.getParameter(requestKey); 641 requestParams.put(requestKey, requestValue); 642 } 643 644 // Add multiple values from Lookup 645 Collection<PersistableBusinessObject> rawValues = null; 646 if (StringUtils.equals(KRADConstants.MULTIPLE_VALUE, maintenanceForm.getRefreshCaller())) { 647 String lookupResultsSequenceNumber = maintenanceForm.getLookupResultsSequenceNumber(); 648 if (StringUtils.isNotBlank(lookupResultsSequenceNumber)) { 649 // actually returning from a multiple value lookup 650 String lookupResultsBOClassName = maintenanceForm.getLookupResultsBOClassName(); 651 Class lookupResultsBOClass = Class.forName(lookupResultsBOClassName); 652 653 rawValues = getLookupResultsService().retrieveSelectedResultBOs(lookupResultsSequenceNumber, lookupResultsBOClass, GlobalVariables.getUserSession().getPerson().getPrincipalId()); 654 } 655 } 656 657 if (rawValues != null) { // KULCOA-1073 - caused by this block running unnecessarily? 658 // we need to run the business rules on all the newly added items to the collection 659 // KULCOA-1000, KULCOA-1004 removed business rule validation on multiple value return 660 // (this was running before the objects were added anyway) 661 // getKualiRuleService().applyRules(new SaveDocumentEvent(document)); 662 String collectionName = maintenanceForm.getLookedUpCollectionName(); 663 //TODO: Cathy remember to delete this block of comments after I've tested. 664 // PersistableBusinessObject bo = document.getNewMaintainableObject().getBusinessObject(); 665 // Collection maintCollection = this.extractCollection(bo, collectionName); 666 // String docTypeName = ((MaintenanceDocument) maintenanceForm.getDocument()).getDocumentHeader().getWorkflowDocument().getDocumentType(); 667 // Class collectionClass = extractCollectionClass(docTypeName, collectionName); 668 // 669 // List<MaintainableSectionDefinition> sections = maintenanceDocumentDictionaryService.getMaintainableSections(docTypeName); 670 // Map<String, String> template = MaintenanceUtils.generateMultipleValueLookupBOTemplate(sections, collectionName); 671 // for (PersistableBusinessObject nextBo : rawValues) { 672 // PersistableBusinessObject templatedBo = (PersistableBusinessObject) ObjectUtils.createHybridBusinessObject(collectionClass, nextBo, template); 673 // templatedBo.setNewCollectionRecord(true); 674 // maintCollection.add(templatedBo); 675 // } 676 document.getNewMaintainableObject().addMultipleValueLookupResults(document, collectionName, rawValues, false, document.getNewMaintainableObject().getBusinessObject()); 677 if (LOG.isInfoEnabled()) { 678 LOG.info("********************doing editing 3 in refersh()***********************."); 679 } 680 boolean isEdit = KRADConstants.MAINTENANCE_EDIT_ACTION.equals(maintenanceForm.getMaintenanceAction()); 681 boolean isCopy = KRADConstants.MAINTENANCE_COPY_ACTION.equals(maintenanceForm.getMaintenanceAction()); 682 683 if (isEdit || isCopy) { 684 document.getOldMaintainableObject().addMultipleValueLookupResults(document, collectionName, rawValues, true, document.getOldMaintainableObject().getBusinessObject()); 685 document.getOldMaintainableObject().refresh(maintenanceForm.getRefreshCaller(), requestParams, document); 686 } 687 } 688 689 document.getNewMaintainableObject().refresh(maintenanceForm.getRefreshCaller(), requestParams, document); 690 691 //pass out customAction from methodToCall parameter. Call processAfterPost 692 String fullParameter = (String) request.getAttribute(KRADConstants.METHOD_TO_CALL_ATTRIBUTE); 693 if(StringUtils.contains(fullParameter, KRADConstants.CUSTOM_ACTION)){ 694 String customAction = StringUtils.substringBetween(fullParameter, KRADConstants.METHOD_TO_CALL_PARM1_LEFT_DEL, KRADConstants.METHOD_TO_CALL_PARM1_RIGHT_DEL); 695 String[] actionValue = new String[1]; 696 actionValue[0]= StringUtils.substringAfter(customAction, "."); 697 Map<String,String[]> paramMap = new HashMap<String,String[]>(request.getParameterMap()); 698 paramMap.put(KRADConstants.CUSTOM_ACTION, actionValue); 699 doProcessingAfterPost( (KualiMaintenanceForm) form, paramMap ); 700 } 701 702 return mapping.findForward(RiceConstants.MAPPING_BASIC); 703 } 704 705 /** 706 * Gets keys for the maintainable business object from the persistence metadata explorer. Checks for existence of key property 707 * names as request parameters, if found adds them to the returned hash map. 708 */ 709 protected Map buildKeyMapFromRequest(Maintainable maintainable, HttpServletRequest request) { 710 List keyFieldNames = null; 711 // are override keys listed in the request? If so, then those need to be our keys, 712 // not the primary keye fields for the BO 713 if (!StringUtils.isBlank(request.getParameter(KRADConstants.OVERRIDE_KEYS))) { 714 String[] overrideKeys = request.getParameter(KRADConstants.OVERRIDE_KEYS).split(KRADConstants.FIELD_CONVERSIONS_SEPARATOR); 715 keyFieldNames = new ArrayList(); 716 for (String overrideKey : overrideKeys) { 717 keyFieldNames.add(overrideKey); 718 } 719 } 720 else { 721 keyFieldNames = KRADServiceLocatorWeb.getLegacyDataAdapter().listPrimaryKeyFieldNames(maintainable.getBusinessObject().getClass()); 722 } 723 return getRequestParameters(keyFieldNames, maintainable, request); 724 } 725 726 protected Map<String, String> getRequestParameters(List keyFieldNames, Maintainable maintainable, HttpServletRequest request){ 727 728 Map<String, String> requestParameters = new HashMap<String, String>(); 729 730 731 for (Iterator iter = keyFieldNames.iterator(); iter.hasNext();) { 732 String keyPropertyName = (String) iter.next(); 733 734 if (request.getParameter(keyPropertyName) != null) { 735 String keyValue = request.getParameter(keyPropertyName); 736 737 // Check if this element was encrypted, if it was decrypt it 738 if (getBusinessObjectAuthorizationService().attributeValueNeedsToBeEncryptedOnFormsAndLinks(maintainable.getBoClass(), keyPropertyName)) { 739 try { 740 keyValue = StringUtils.removeEnd(keyValue, EncryptionService.ENCRYPTION_POST_PREFIX); 741 if(CoreApiServiceLocator.getEncryptionService().isEnabled()) { 742 keyValue = encryptionService.decrypt(keyValue); 743 } 744 } 745 catch (GeneralSecurityException e) { 746 throw new RuntimeException(e); 747 } 748 } 749 750 751 requestParameters.put(keyPropertyName, keyValue); 752 } 753 } 754 755 return requestParameters; 756 757 } 758 759 /** 760 * Convert a Request into a Map<String,String>. Technically, Request parameters do not neatly translate into a Map of Strings, 761 * because a given parameter may legally appear more than once (so a Map of String[] would be more accurate.) This method should 762 * be safe for business objects, but may not be reliable for more general uses. 763 */ 764 String extractCollectionName(HttpServletRequest request, String methodToCall) { 765 // collection name and underlying object type from request parameter 766 String parameterName = (String) request.getAttribute(KRADConstants.METHOD_TO_CALL_ATTRIBUTE); 767 String collectionName = null; 768 if (StringUtils.isNotBlank(parameterName)) { 769 collectionName = StringUtils.substringBetween(parameterName, methodToCall + ".", ".("); 770 } 771 return collectionName; 772 } 773 774 Collection extractCollection(Object bo, String collectionName) { 775 // retrieve the collection from the business object 776 Collection maintCollection = (Collection) ObjectUtils.getPropertyValue(bo, collectionName); 777 return maintCollection; 778 } 779 780 Class extractCollectionClass(String docTypeName, String collectionName) { 781 return maintenanceDocumentDictionaryService.getCollectionBusinessObjectClass(docTypeName, collectionName); 782 } 783 784 /** 785 * Adds a line to a collection being maintained in a many section. 786 */ 787 public ActionForward addLine(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception { 788 KualiMaintenanceForm maintenanceForm = (KualiMaintenanceForm) form; 789 MaintenanceDocument document = (MaintenanceDocument) maintenanceForm.getDocument(); 790 Maintainable oldMaintainable = document.getOldMaintainableObject(); 791 Maintainable newMaintainable = document.getNewMaintainableObject(); 792 793 String collectionName = extractCollectionName(request, KRADConstants.ADD_LINE_METHOD); 794 if (collectionName == null) { 795 LOG.error("Unable to get find collection name and class in request."); 796 throw new RuntimeException("Unable to get find collection name and class in request."); 797 } 798 799 // if dealing with sub collection it will have a "[" 800 if ((StringUtils.lastIndexOf(collectionName, "]") + 1) == collectionName.length()) { 801 collectionName = StringUtils.substringBeforeLast(collectionName, "["); 802 } 803 804 Object bo = newMaintainable.getBusinessObject(); 805 Collection maintCollection = extractCollection(bo, collectionName); 806 Class collectionClass = extractCollectionClass(((MaintenanceDocument) maintenanceForm.getDocument()).getDocumentHeader().getWorkflowDocument().getDocumentTypeName(), collectionName); 807 808 // TODO: sort of collection, new instance should be first 809 810 // get the BO from the new collection line holder 811 PersistableBusinessObject addBO = newMaintainable.getNewCollectionLine(collectionName); 812 if (LOG.isDebugEnabled()) { 813 LOG.debug("obtained addBO from newCollectionLine: " + addBO); 814 } 815 816 // link up the user fields, if any 817 getBusinessObjectService().linkUserFields(addBO); 818 819 //KULRICE-4264 - a hook to change the state of the business object, which is the "new line" of a collection, before it is validated 820 newMaintainable.processBeforeAddLine(collectionName, collectionClass, addBO); 821 822 // apply rules to the addBO 823 boolean rulePassed = false; 824 if (LOG.isDebugEnabled()) { 825 LOG.debug("about to call AddLineEvent applyRules: document=" + document + "\ncollectionName=" + collectionName + "\nBO=" + addBO); 826 } 827 rulePassed = getKualiRuleService().applyRules(new KualiAddLineEvent(document, collectionName, addBO)); 828 829 // if the rule evaluation passed, let's add it 830 if (rulePassed) { 831 if (LOG.isInfoEnabled()) { 832 LOG.info("********************doing editing 4 in addline()***********************."); 833 } 834 // if edit or copy action, just add empty instance to old maintainable 835 boolean isEdit = KRADConstants.MAINTENANCE_EDIT_ACTION.equals(maintenanceForm.getMaintenanceAction()); 836 boolean isCopy = KRADConstants.MAINTENANCE_COPY_ACTION.equals(maintenanceForm.getMaintenanceAction()); 837 838 839 if (isEdit || isCopy) { 840 Object oldBo = oldMaintainable.getBusinessObject(); 841 Collection oldMaintCollection = (Collection) ObjectUtils.getPropertyValue(oldBo, collectionName); 842 843 if (oldMaintCollection == null) { 844 oldMaintCollection = new ArrayList(); 845 } 846 if (PersistableBusinessObject.class.isAssignableFrom(collectionClass)) { 847 PersistableBusinessObject placeholder = (PersistableBusinessObject) collectionClass.newInstance(); 848 // KULRNE-4538: must set it as a new collection record, because the maintainable will set the BO that gets added 849 // to the new maintainable as a new collection record 850 851 // if not set, then the subcollections of the newly added object will appear as read only 852 // see FieldUtils.getContainerRows on how the delete button is rendered 853 placeholder.setNewCollectionRecord(true); 854 ((List) oldMaintCollection).add(placeholder); 855 } 856 else { 857 LOG.warn("Should be a instance of PersistableBusinessObject"); 858 ((List) oldMaintCollection).add(collectionClass.newInstance()); 859 } 860 // update collection in maintenance business object 861 ObjectUtils.setObjectProperty(oldBo, collectionName, List.class, oldMaintCollection); 862 } 863 864 newMaintainable.addNewLineToCollection(collectionName); 865 int subCollectionIndex = 0; 866 for (Object aSubCollection : maintCollection) { 867 subCollectionIndex += getSubCollectionIndex(aSubCollection, maintenanceForm.getDocTypeName()); 868 } 869 //TODO: Should we keep this logic and continue using currentTabIndex as the key in the tabStates HashMap ? 870 // 871 // String parameter = (String) request.getAttribute(Constants.METHOD_TO_CALL_ATTRIBUTE); 872 // String indexStr = StringUtils.substringBetween(parameter, Constants.METHOD_TO_CALL_PARM13_LEFT_DEL, Constants.METHOD_TO_CALL_PARM13_RIGHT_DEL); 873 // // + 1 is for the fact that the first element of a collection is on the next tab 874 // int index = Integer.parseInt(indexStr) + subCollectionIndex + 1; 875 // Map<String, String> tabStates = maintenanceForm.getTabStates(); 876 // Map<String, String> copyOfTabStates = new HashMap<String, String>(); 877 // 878 // int incrementor = 0; 879 // for (String tabState : tabStates.keySet()) { 880 // String originalValue = maintenanceForm.getTabState(Integer.toString(incrementor)); 881 // copyOfTabStates.put(Integer.toString(incrementor), originalValue); 882 // incrementor++; 883 // } 884 // 885 // int i = index; 886 // if (tabStates.containsKey(Integer.toString(i-1))) { 887 // tabStates.remove(Integer.toString(i-1)); 888 // } 889 // while (i < copyOfTabStates.size() + 1) { 890 // String originalValue = copyOfTabStates.get(Integer.toString(i-1)); 891 // if (tabStates.containsKey(Integer.toString(i))) { 892 // tabStates.remove(Integer.toString(i)); 893 // } 894 // tabStates.put(Integer.toString(i), originalValue); 895 // i++; 896 // } 897 898 899 // End of whether we should continue to keep this logic and use currentTabIndex as the key 900 } 901 doProcessingAfterPost( (KualiMaintenanceForm) form, request ); 902 903 return mapping.findForward(RiceConstants.MAPPING_BASIC); 904 } 905 906 protected int getSubCollectionIndex(Object object, String documentTypeName) { 907 int index = 1; 908 MaintainableCollectionDefinition theCollectionDefinition = null; 909 for (MaintainableCollectionDefinition maintainableCollectionDefinition : maintenanceDocumentDictionaryService.getMaintainableCollections(documentTypeName)) { 910 if (maintainableCollectionDefinition.getBusinessObjectClass().equals(object.getClass())) { 911 // we've found the collection we were looking for, so let's find all of its subcollections 912 theCollectionDefinition = maintainableCollectionDefinition; 913 break; 914 } 915 } 916 if (theCollectionDefinition != null) { 917 for (MaintainableCollectionDefinition subCollDef : theCollectionDefinition.getMaintainableCollections()) { 918 String name = subCollDef.getName(); 919 String capitalFirst = name.substring(0, 1).toUpperCase(); 920 String methodName = "get" + capitalFirst + name.substring(1); 921 List subCollectionList = new ArrayList(); 922 try { 923 subCollectionList = (List) object.getClass().getMethod(methodName).invoke(object); 924 } 925 catch (InvocationTargetException ite) { 926 // this shouldn't happen 927 } 928 catch (IllegalAccessException iae) { 929 // this shouldn't happen 930 } 931 catch (NoSuchMethodException nme) { 932 // this shouldn't happen 933 } 934 index += subCollectionList.size(); 935 } 936 } 937 return index; 938 } 939 940 /** 941 * Deletes a collection line that is pending by this document. The collection name and the index to delete is embedded into the 942 * delete button name. These parameters are extracted, the collection pulled out of the parent business object, and finally the 943 * collection record at the specified index is removed for the new maintainable, and the old if we are dealing with an edit. 944 */ 945 public ActionForward deleteLine(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception { 946 KualiMaintenanceForm maintenanceForm = (KualiMaintenanceForm) form; 947 MaintenanceDocument document = (MaintenanceDocument) maintenanceForm.getDocument(); 948 Maintainable oldMaintainable = document.getOldMaintainableObject(); 949 Maintainable newMaintainable = document.getNewMaintainableObject(); 950 951 String collectionName = extractCollectionName(request, KRADConstants.DELETE_LINE_METHOD); 952 if (collectionName == null) { 953 LOG.error("Unable to get find collection name in request."); 954 throw new RuntimeException("Unable to get find collection class in request."); 955 } 956 957 PersistableBusinessObject bo = newMaintainable.getBusinessObject(); 958 Collection maintCollection = extractCollection(bo, collectionName); 959 if (collectionName == null) { 960 LOG.error("Collection is null in parent business object."); 961 throw new RuntimeException("Collection is null in parent business object."); 962 } 963 964 int deleteRecordIndex = getLineToDelete(request); 965 if (deleteRecordIndex < 0 || deleteRecordIndex > maintCollection.size() - 1) { 966 if (collectionName == null) { 967 LOG.error("Invalid index for deletion of collection record: " + deleteRecordIndex); 968 throw new RuntimeException("Invalid index for deletion of collection record: " + deleteRecordIndex); 969 } 970 } 971 972 ((List) maintCollection).remove(deleteRecordIndex); 973 974 // if it's either an edit or a copy, need to remove the collection from the old maintainable as well 975 if (KRADConstants.MAINTENANCE_EDIT_ACTION.equals(maintenanceForm.getMaintenanceAction()) || 976 KRADConstants.MAINTENANCE_COPY_ACTION.equals(maintenanceForm.getMaintenanceAction())) { 977 bo = oldMaintainable.getBusinessObject(); 978 maintCollection = extractCollection(bo, collectionName); 979 980 if (collectionName == null) { 981 LOG.error("Collection is null in parent business object."); 982 throw new RuntimeException("Collection is null in parent business object."); 983 } 984 985 ((List) maintCollection).remove(deleteRecordIndex); 986 } 987 988 // remove the tab state information of the tab that the deleted element originally occupied, so that it will keep tab states 989 // consistent 990 // String parameter = (String) request.getAttribute(Constants.METHOD_TO_CALL_ATTRIBUTE); 991 // String indexStr = StringUtils.substringBetween(parameter, Constants.METHOD_TO_CALL_PARM13_LEFT_DEL, Constants.METHOD_TO_CALL_PARM13_RIGHT_DEL); 992 // int index = Integer.parseInt(indexStr); 993 // maintenanceForm.removeTabState(index); 994 995 996 // TODO: Should we keep this logic and continue using currentTabIndex as the key in the tabStates HashMap ? 997 // 998 // String parameter = (String) request.getAttribute(Constants.METHOD_TO_CALL_ATTRIBUTE); 999 // String indexStr = StringUtils.substringBetween(parameter, Constants.METHOD_TO_CALL_PARM13_LEFT_DEL, Constants.METHOD_TO_CALL_PARM13_RIGHT_DEL); 1000 // // + 1 is for the fact that the first element of a collection is on the next tab 1001 // int index = Integer.parseInt(indexStr) + 1; 1002 // Map<String, String> tabStates = maintenanceForm.getTabStates(); 1003 // Map<String, String> copyOfTabStates = new HashMap<String, String>(); 1004 // 1005 // int incrementor = 0; 1006 // for (String tabState : tabStates.keySet()) { 1007 // String originalValue = maintenanceForm.getTabState(Integer.toString(incrementor)); 1008 // copyOfTabStates.put(Integer.toString(incrementor), originalValue); 1009 // incrementor++; 1010 // } 1011 // 1012 // int i = index; 1013 // 1014 // while (i < copyOfTabStates.size() ) { 1015 // String originalValue = copyOfTabStates.get(Integer.toString(i)); 1016 // if (tabStates.containsKey(Integer.toString(i-1))) { 1017 // tabStates.remove(Integer.toString(i-1)); 1018 // } 1019 // tabStates.put(Integer.toString(i-1), originalValue); 1020 // i++; 1021 // } 1022 // 1023 // 1024 //End of whether we should continue to keep this logic and use currentTabIndex as the key 1025 1026 doProcessingAfterPost( (KualiMaintenanceForm) form, request ); 1027 1028 return mapping.findForward(RiceConstants.MAPPING_BASIC); 1029 } 1030 1031 /** 1032 * Turns on (or off) the inactive record display for a maintenance collection. 1033 */ 1034 public ActionForward toggleInactiveRecordDisplay(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception { 1035 KualiMaintenanceForm maintenanceForm = (KualiMaintenanceForm) form; 1036 MaintenanceDocument document = (MaintenanceDocument) maintenanceForm.getDocument(); 1037 Maintainable oldMaintainable = document.getOldMaintainableObject(); 1038 Maintainable newMaintainable = document.getNewMaintainableObject(); 1039 1040 String collectionName = extractCollectionName(request, KRADConstants.TOGGLE_INACTIVE_METHOD); 1041 if (collectionName == null) { 1042 LOG.error("Unable to get find collection name in request."); 1043 throw new RuntimeException("Unable to get find collection class in request."); 1044 } 1045 1046 String parameterName = (String) request.getAttribute(KRADConstants.METHOD_TO_CALL_ATTRIBUTE); 1047 boolean showInactive = Boolean.parseBoolean(StringUtils.substringBetween(parameterName, KRADConstants.METHOD_TO_CALL_BOPARM_LEFT_DEL, ".")); 1048 1049 oldMaintainable.setShowInactiveRecords(collectionName, showInactive); 1050 newMaintainable.setShowInactiveRecords(collectionName, showInactive); 1051 1052 return mapping.findForward(RiceConstants.MAPPING_BASIC); 1053 } 1054 1055 /** 1056 * This method clears the value of the primary key fields on a Business Object. 1057 * 1058 * @param document - document to clear the pk fields on 1059 */ 1060 protected void clearPrimaryKeyFields(MaintenanceDocument document) { 1061 // get business object being maintained and its keys 1062 PersistableBusinessObject bo = document.getNewMaintainableObject().getBusinessObject(); 1063 List<String> keyFieldNames = KRADServiceLocatorWeb.getLegacyDataAdapter().listPrimaryKeyFieldNames(bo.getClass()); 1064 1065 for (String keyFieldName : keyFieldNames) { 1066 try { 1067 ObjectUtils.setObjectProperty(bo, keyFieldName, null); 1068 } 1069 catch (Exception e) { 1070 LOG.error("Unable to clear primary key field: " + e.getMessage()); 1071 throw new RuntimeException("Unable to clear primary key field: " + e.getMessage()); 1072 } 1073 } 1074 bo.setObjectId(null); 1075 bo.setVersionNumber(new Long(1)); 1076 } 1077 1078 /** 1079 * This method is used as part of the Copy functionality, to clear any field values that the user making the copy does not have 1080 * permissions to modify. This will prevent authorization errors on a copy. 1081 * 1082 * @param document - document to be adjusted 1083 */ 1084 protected void clearUnauthorizedNewFields(MaintenanceDocument document) { 1085 // get a reference to the current user 1086 Person user = GlobalVariables.getUserSession().getPerson(); 1087 1088 // get a new instance of MaintenanceDocumentAuthorizations for this context 1089 MaintenanceDocumentRestrictions maintenanceDocumentRestrictions = getBusinessObjectAuthorizationService().getMaintenanceDocumentRestrictions(document, user); 1090 1091 document.getNewMaintainableObject().clearBusinessObjectOfRestrictedValues(maintenanceDocumentRestrictions); 1092 } 1093 1094 /** 1095 * This method does all special processing on a document that should happen on each HTTP post (ie, save, route, approve, etc). 1096 * 1097 * @param form 1098 */ 1099 @SuppressWarnings("unchecked") 1100 protected void doProcessingAfterPost( KualiForm form, HttpServletRequest request ) { 1101 MaintenanceDocument document = (MaintenanceDocument) ((KualiMaintenanceForm)form).getDocument(); 1102 Maintainable maintainable = document.getNewMaintainableObject(); 1103 Object bo = maintainable.getBusinessObject(); 1104 1105 getBusinessObjectService().linkUserFields(bo); 1106 1107 maintainable.processAfterPost(document, request.getParameterMap() ); 1108 } 1109 1110 protected void doProcessingAfterPost( KualiForm form, Map<String,String[]> parameters ) { 1111 MaintenanceDocument document = (MaintenanceDocument) ((KualiMaintenanceForm)form).getDocument(); 1112 Maintainable maintainable = document.getNewMaintainableObject(); 1113 Object bo = maintainable.getBusinessObject(); 1114 1115 getBusinessObjectService().linkUserFields(bo); 1116 1117 maintainable.processAfterPost(document, parameters ); 1118 } 1119 1120 protected void populateAuthorizationFields(KualiDocumentFormBase formBase){ 1121 super.populateAuthorizationFields(formBase); 1122 1123 KualiMaintenanceForm maintenanceForm = (KualiMaintenanceForm) formBase; 1124 MaintenanceDocument maintenanceDocument = (MaintenanceDocument) maintenanceForm.getDocument(); 1125 MaintenanceDocumentAuthorizer maintenanceDocumentAuthorizer = (MaintenanceDocumentAuthorizer) getDocumentHelperService().getDocumentAuthorizer(maintenanceDocument); 1126 Person user = GlobalVariables.getUserSession().getPerson(); 1127 maintenanceForm.setReadOnly(!formBase.getDocumentActions().containsKey(KRADConstants.KUALI_ACTION_CAN_EDIT)); 1128 MaintenanceDocumentRestrictions maintenanceDocumentAuthorizations = getBusinessObjectAuthorizationService().getMaintenanceDocumentRestrictions(maintenanceDocument, user); 1129 maintenanceForm.setAuthorizations(maintenanceDocumentAuthorizations); 1130 } 1131 1132 public LookupService getLookupService() { 1133 if ( lookupService == null ) { 1134 lookupService = KRADServiceLocatorWeb.getLookupService(); 1135 } 1136 return this.lookupService; 1137 } 1138 1139 public LookupResultsService getLookupResultsService() { 1140 if ( lookupResultsService == null ) { 1141 lookupResultsService = KNSServiceLocator.getLookupResultsService(); 1142 } 1143 return this.lookupResultsService; 1144 } 1145 1146}