View Javadoc
1   /*
2    * Copyright 2008 The Kuali Foundation
3    * 
4    * Licensed under the Educational Community License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    * 
8    * http://www.opensource.org/licenses/ecl2.php
9    * 
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  package org.kuali.ole.module.purap.document;
17  
18  import org.kuali.ole.module.purap.businessobject.ReceivingAddress;
19  import org.kuali.ole.module.purap.document.service.ReceivingAddressService;
20  import org.kuali.ole.sys.OLEConstants;
21  import org.kuali.ole.sys.context.SpringContext;
22  import org.kuali.ole.sys.document.FinancialSystemMaintainable;
23  import org.kuali.rice.core.api.encryption.EncryptionService;
24  import org.kuali.rice.kew.api.WorkflowDocument;
25  import org.kuali.rice.kns.service.BusinessObjectAuthorizationService;
26  import org.kuali.rice.kns.service.DataDictionaryService;
27  import org.kuali.rice.krad.bo.DocumentHeader;
28  import org.kuali.rice.krad.maintenance.MaintenanceLock;
29  import org.kuali.rice.krad.service.BusinessObjectService;
30  import org.kuali.rice.krad.util.ObjectUtils;
31  
32  import java.security.GeneralSecurityException;
33  import java.util.Collection;
34  import java.util.List;
35  
36  /**
37   * ReceivingAddressMaintainableImpl is a special implementation of FinancialSystemMaintainable for ReceivingAddresss.
38   * It generates extra locks for other receiving addresses related to the one being updated in the maintenance document,
39   * and updates the ones affected during post-processing to enforce certain contraints among these objects.
40   */
41  public class ReceivingAddressMaintainableImpl extends FinancialSystemMaintainable {
42      private static final org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(ReceivingAddressMaintainableImpl.class);
43  
44      /**
45       * Generates the appropriate maintenance locks for {@link ReceivingAddress}
46       *
47       * @see org.kuali.rice.kns.maintenance.KualiMaintainableImpl#generateMaintenanceLocks()
48       */
49      @Override
50      public List<MaintenanceLock> generateMaintenanceLocks() {
51          ReceivingAddress receivingAddress = (ReceivingAddress) this.businessObject;
52          List<MaintenanceLock> locks = super.generateMaintenanceLocks();
53          if (receivingAddress.isDefaultIndicator() && receivingAddress.isActive()) {
54              locks.add(createMaintenanceLock(new String[]{"chartOfAccountsCode", "organizationCode", "defaultIndicator", "active"}));
55          }
56          return locks;
57      }
58  
59      /**
60       * Creates a maintenance lock for the field names supplied.
61       *
62       * @param fieldNames
63       * @return the maintenance lock for supplied field names
64       */
65      private MaintenanceLock createMaintenanceLock(String[] fieldNames) {
66          MaintenanceLock lock = new MaintenanceLock();
67          lock.setDocumentNumber(getDocumentNumber());
68          lock.setLockingRepresentation(createLockingRepresentation(fieldNames));
69          return lock;
70      }
71  
72      /**
73       * Creates a locking representation for the field names supplied.
74       *
75       * @param fieldNames
76       * @return locking representation string
77       */
78      private String createLockingRepresentation(String[] fieldNames) {
79          StringBuilder lockRepresentation = new StringBuilder();
80  
81          lockRepresentation.append(ReceivingAddress.class.getName());
82          lockRepresentation.append(OLEConstants.Maintenance.AFTER_CLASS_DELIM);
83  
84          DataDictionaryService dataDictionaryService = SpringContext.getBean(DataDictionaryService.class);
85          EncryptionService encryptionService = SpringContext.getBean(EncryptionService.class);
86  
87          int count = 0;
88          for (String fieldName : fieldNames) {
89              lockRepresentation.append(fieldName);
90              lockRepresentation.append(OLEConstants.Maintenance.AFTER_FIELDNAME_DELIM);
91              lockRepresentation.append(retrieveFieldValueForLock(fieldName, dataDictionaryService, encryptionService));
92              if (count < (fieldNames.length - 1)) {
93                  lockRepresentation.append(OLEConstants.Maintenance.AFTER_VALUE_DELIM);
94              }
95              count += 1;
96          }
97  
98          return lockRepresentation.toString();
99      }
100 
101     /**
102      * Returns the field value of a given field, converting the value to a String and encrypting it if necessary.
103      *
104      * @param fieldName
105      * @param ddService
106      * @return string field value for a lock
107      */
108     private String retrieveFieldValueForLock(String fieldName, DataDictionaryService ddService, EncryptionService encryptionService) {
109         Object fieldValue = ObjectUtils.getPropertyValue(this.businessObject, fieldName);
110         if (fieldValue == null) {
111             fieldValue = "";
112         }
113 
114         // check if field is a secure
115         if (SpringContext.getBean(BusinessObjectAuthorizationService.class).attributeValueNeedsToBeEncryptedOnFormsAndLinks(getBoClass(), fieldName)) {
116             try {
117                 fieldValue = encryptionService.encrypt(fieldValue);
118             } catch (GeneralSecurityException e) {
119                 LOG.error("Unable to encrypt secure field for locking representation " + e.getMessage());
120                 throw new RuntimeException("Unable to encrypt secure field for locking representation " + e.getMessage());
121             }
122         }
123         return String.valueOf(fieldValue);
124     }
125 
126     /**
127      * Checks if there's any active receiving address set to default other than this one;
128      * if so, set them to non-default.
129      *
130      * @see org.kuali.rice.kns.maintenance.KualiMaintainableImpl#doRouteStatusChange(org.kuali.rice.krad.bo.DocumentHeader)
131      */
132     @Override
133     public void doRouteStatusChange(DocumentHeader header) {
134         super.doRouteStatusChange(header);
135 
136         ReceivingAddress ra = (ReceivingAddress) getBusinessObject();
137         // proceed only if this bo is active and default.
138         if (!ra.isActive() || !ra.isDefaultIndicator())
139             return;
140 
141         WorkflowDocument workflowDoc = header.getWorkflowDocument();
142         // this code is only executed when the final approval occurs
143         if (workflowDoc.isProcessed()) {
144             /*
145             Map criteria = new HashMap();
146             criteria.put(OLEPropertyConstants.CHART_OF_ACCOUNTS_CODE, ra.getChartOfAccountsCode());
147             criteria.put(OLEPropertyConstants.ORGANIZATION_CODE, ra.getOrganizationCode());
148             criteria.put(PurapPropertyConstants.RCVNG_ADDR_DFLT_IND, true);        
149             criteria.put(PurapPropertyConstants.RCVNG_ADDR_ACTIVE, true);        
150             List<ReceivingAddress> addresses = (List)SpringContext.getBean(BusinessObjectService.class).findMatching(ReceivingAddress.class, criteria);
151             */
152             Collection<ReceivingAddress> addresses = SpringContext.getBean(ReceivingAddressService.class).findDefaultByChartOrg(ra.getChartOfAccountsCode(), ra.getOrganizationCode());
153             for (ReceivingAddress rai : addresses) {
154                 if (!rai.getReceivingAddressIdentifier().equals(ra.getReceivingAddressIdentifier())) {
155                     rai.setDefaultIndicator(false);
156                     SpringContext.getBean(BusinessObjectService.class).save(rai);
157                 }
158             }
159         }
160     }
161 
162 }