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 }