View Javadoc
1   /*
2    * Copyright 2007 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.coa.document;
17  
18  import java.security.GeneralSecurityException;
19  import java.sql.Date;
20  import java.util.List;
21  import java.util.Map;
22  
23  import org.apache.commons.lang.StringUtils;
24  import org.kuali.ole.coa.businessobject.AccountDelegate;
25  import org.kuali.ole.coa.businessobject.AccountDelegateGlobal;
26  import org.kuali.ole.coa.service.AccountDelegateService;
27  import org.kuali.ole.sys.OLEConstants;
28  import org.kuali.ole.sys.context.SpringContext;
29  import org.kuali.ole.sys.document.FinancialSystemMaintainable;
30  import org.kuali.rice.core.api.datetime.DateTimeService;
31  import org.kuali.rice.core.api.encryption.EncryptionService;
32  import org.kuali.rice.kns.document.MaintenanceDocument;
33  import org.kuali.rice.kns.service.BusinessObjectAuthorizationService;
34  import org.kuali.rice.kns.service.DataDictionaryService;
35  import org.kuali.rice.krad.maintenance.MaintenanceLock;
36  import org.kuali.rice.krad.util.ObjectUtils;
37  
38  /**
39   * This class is a special implementation of Maintainable specifically for Account Delegates. It was created to correctly update the
40   * default Start Date on edits and copies, ala JIRA #KULRNE-62.
41   */
42  public class AccountDelegateMaintainableImpl extends FinancialSystemMaintainable {
43      private static final org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(AccountDelegateMaintainableImpl.class);
44  
45      /**
46       * This method will reset AccountDelegate's Start Date to the current timestamp on edits and copies
47       * 
48       * @see org.kuali.rice.kns.maintenance.KualiMaintainableImpl#processAfterRetrieve()
49       */
50      @Override
51      public void processAfterCopy( MaintenanceDocument document, Map<String,String[]> parameters ) {
52          this.setStartDateDefault();
53          super.processAfterCopy( document, parameters );
54      }
55  
56      /**
57       * This method will reset AccountDelegate's Start Date to the current timestamp on edits and copies
58       * 
59       * @see org.kuali.rice.kns.maintenance.KualiMaintainableImpl#processAfterEdit()
60       */
61      @Override
62      public void processAfterEdit( MaintenanceDocument document, Map<String,String[]> parameters ) {
63          this.setStartDateDefault();
64          super.processAfterEdit( document, parameters );
65      }
66  
67      /**
68       * This method sets the start date on {@link Delegate} BO
69       */
70      protected void setStartDateDefault() {
71          if (this.businessObject != null && this.businessObject instanceof AccountDelegate) {
72              AccountDelegate delegate = (AccountDelegate) this.businessObject;
73              delegate.setAccountDelegateStartDate(new Date(SpringContext.getBean(DateTimeService.class).getCurrentDate().getTime()));
74          }
75      }
76  
77      /**
78       * Generates the appropriate maintenance locks for the {@link Delegate}
79       * 
80       * @see org.kuali.rice.kns.maintenance.KualiMaintainableImpl#generateMaintenanceLocks()
81       */
82      @Override
83      public List<MaintenanceLock> generateMaintenanceLocks() {
84          AccountDelegate delegate = (AccountDelegate) this.businessObject;
85          List<MaintenanceLock> locks = super.generateMaintenanceLocks();
86          if (delegate.isAccountsDelegatePrmrtIndicator()) {
87              locks.add(createMaintenanceLock(new String[] { "chartOfAccountsCode", "accountNumber", "financialDocumentTypeCode", "accountsDelegatePrmrtIndicator" }));
88          }
89          return locks;
90      }
91  
92      @Override
93      public String getLockingDocumentId() {
94         String lock = super.getLockingDocumentId();
95         if (StringUtils.isNotBlank(lock))
96             return lock;
97         else {
98             AccountDelegateService accountDelegateService = SpringContext.getBean(AccountDelegateService.class);
99             lock = accountDelegateService.getLockingDocumentId(this, getDocumentNumber());
100            return lock;
101        }
102     }
103     
104     /**
105      * This method creates a maintenance lock for the field names supplied
106      * 
107      * @param fieldNames
108      * @return the maintenance lock for supplied field names
109      */
110     protected MaintenanceLock createMaintenanceLock(String[] fieldNames) {
111         MaintenanceLock lock = new MaintenanceLock();
112         lock.setDocumentNumber(getDocumentNumber());
113         lock.setLockingRepresentation(createLockingRepresentation(fieldNames));
114         return lock;
115 
116     }
117 
118     /**
119      * This method create a locking representation for the field names supplied
120      * 
121      * @param fieldNames
122      * @return locking representation string
123      */
124     protected String createLockingRepresentation(String[] fieldNames) {
125         StringBuilder lockRepresentation = new StringBuilder();
126 
127         lockRepresentation.append(AccountDelegate.class.getName());
128         lockRepresentation.append(OLEConstants.Maintenance.AFTER_CLASS_DELIM);
129 
130         DataDictionaryService dataDictionaryService = SpringContext.getBean(DataDictionaryService.class); 
131         EncryptionService encryptionService = SpringContext.getBean(EncryptionService.class); 
132 
133         int count = 0;
134         for (String fieldName : fieldNames) {
135             lockRepresentation.append(fieldName);
136             lockRepresentation.append(OLEConstants.Maintenance.AFTER_FIELDNAME_DELIM);
137             lockRepresentation.append(retrieveFieldValueForLock(fieldName, dataDictionaryService, encryptionService));
138             if (count < (fieldNames.length - 1)) {
139                 lockRepresentation.append(OLEConstants.Maintenance.AFTER_VALUE_DELIM);
140             }
141             count += 1;
142         }
143 
144 
145         return lockRepresentation.toString();
146     }
147 
148     /**
149      * This method returns the field value of a given field, converting the value to a String and encrypting it if necessary
150      * 
151      * @param fieldName
152      * @param ddService
153      * @return string field value for a lock
154      */
155     protected String retrieveFieldValueForLock(String fieldName, DataDictionaryService ddService, EncryptionService encryptionService) {
156         Object fieldValue = ObjectUtils.getPropertyValue(this.businessObject, fieldName);
157         if (fieldValue == null) {
158             fieldValue = "";
159         }
160 
161         // check if field is a secure
162         if (SpringContext.getBean(BusinessObjectAuthorizationService.class).attributeValueNeedsToBeEncryptedOnFormsAndLinks(getBoClass(), fieldName)) {
163             try {
164                 fieldValue = encryptionService.encrypt(fieldValue);
165             }
166             catch (GeneralSecurityException e) {
167                 LOG.error("Unable to encrypt secure field for locking representation " + e.getMessage());
168                 throw new RuntimeException("Unable to encrypt secure field for locking representation " + e.getMessage());
169             }
170         }
171         return String.valueOf(fieldValue);
172     }
173     
174     /**
175      * This method created a MaintenanceLock for the chartOfAccountsCode and accountNumber for an AccountDelegateGlobal.
176      *
177      * @return the MainenanceLock
178      */
179     
180     public MaintenanceLock createGlobalAccountLock() {
181         
182         String[] fields = {"chartOfAccountsCode", "accountNumber"};
183         MaintenanceLock lock = new MaintenanceLock();
184         lock.setDocumentNumber(getDocumentNumber());
185         
186         StringBuilder lockRepresentation = new StringBuilder();
187 
188         lockRepresentation.append(AccountDelegateGlobal.class.getName());
189         lockRepresentation.append(OLEConstants.Maintenance.AFTER_CLASS_DELIM);
190 
191         DataDictionaryService dataDictionaryService = SpringContext.getBean(DataDictionaryService.class); 
192         EncryptionService encryptionService = SpringContext.getBean(EncryptionService.class); 
193         
194         int count = 0;
195         for (String fieldName : fields) {
196             lockRepresentation.append(fieldName);
197             lockRepresentation.append(OLEConstants.Maintenance.AFTER_FIELDNAME_DELIM);
198             lockRepresentation.append(retrieveFieldValueForLock(fieldName, dataDictionaryService, encryptionService));
199             if (count < (fields.length - 1)) {
200                 lockRepresentation.append(OLEConstants.Maintenance.AFTER_VALUE_DELIM);
201             }
202             count += 1;
203         }
204 
205         lock.setLockingRepresentation(lockRepresentation.toString());
206         
207         return lock;
208     }
209 
210     /**
211      * Overridden so that after account delegate is saved, it updates the proper account delegate role
212      * Defers saving to a service to guarantee that the delegate saves in a separate transaction
213      * @see org.kuali.rice.kns.maintenance.KualiMaintainableImpl#saveBusinessObject()
214      */
215     @Override
216     public void saveBusinessObject() {
217         final AccountDelegate accountDelegate = (AccountDelegate)getBusinessObject();
218         final AccountDelegateService accountDelegateService = SpringContext.getBean(AccountDelegateService.class);
219         
220         accountDelegateService.saveForMaintenanceDocument(accountDelegate);
221         
222         accountDelegateService.updateDelegationRole();
223     }
224 
225     
226 }