View Javadoc
1   /*
2    * Copyright 2009 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.sys.batch.service;
17  
18  import java.util.HashMap;
19  import java.util.LinkedHashMap;
20  import java.util.Map;
21  
22  import org.kuali.ole.gl.businessobject.AccountBalance;
23  import org.kuali.rice.krad.bo.BusinessObject;
24  import org.kuali.rice.krad.bo.PersistableBusinessObjectBase;
25  import org.springframework.transaction.annotation.Transactional;
26  
27  /**
28   * This class CANNOT be used by 2 processes simultaneously. It is for very specific batch processes that should not run at the same
29   * time, and initialize and destroy must be called and the beginning and end of each process that uses it.
30   */
31  @Transactional
32  public abstract class AbstractBatchTransactionalCachingService implements WrappingBatchService {
33      protected Map<String,BusinessObject> referenceValueCache;
34      protected Map<Class,PreviousValueReference> previousValueCache;
35  
36      public void initialize() {
37          referenceValueCache = new HashMap<String,BusinessObject>();
38          previousValueCache = new HashMap<Class,PreviousValueReference>();
39      }
40  
41      public void destroy() {
42          referenceValueCache = null;
43          previousValueCache = null;
44      }
45  
46      static final class NonExistentReferenceBusinessObject extends PersistableBusinessObjectBase {        
47          
48          protected LinkedHashMap toStringMapper_RICE20_REFACTORME() {
49              throw new UnsupportedOperationException();
50          }
51      }
52      protected static final BusinessObject NON_EXISTENT_REFERENCE_CACHE_VALUE = new NonExistentReferenceBusinessObject();
53      protected String getCacheKey(Class clazz, Object...objects) {
54          StringBuffer cacheKey = new StringBuffer(clazz.getName());
55          for (int i = 0; i < objects.length; i++) {
56              cacheKey.append("-").append(objects[i]);
57          }
58          return cacheKey.toString();
59      }
60      protected abstract class ReferenceValueRetriever<T extends BusinessObject> {
61          public T get(Class<T> type, Object...keys) {
62              String cacheKey = getCacheKey(type, keys);
63              BusinessObject businessObject = referenceValueCache.get(cacheKey);
64              if (businessObject == null) {
65                  try {
66                      businessObject = useDao();
67                  }
68                  catch (Exception e) {
69                      throw new RuntimeException("Unable to getBusinessObject in AccountingCycleCachingServiceImpl: " + cacheKey, e);
70                  }
71                  if (businessObject == null) {
72                      referenceValueCache.put(cacheKey, NON_EXISTENT_REFERENCE_CACHE_VALUE);
73                  }
74                  else {
75                      referenceValueCache.put(cacheKey, businessObject);
76                      retrieveReferences((T)businessObject);
77                  }
78              }
79              else if (businessObject instanceof NonExistentReferenceBusinessObject) {
80                  businessObject = null;
81              }
82              return (T)businessObject;        
83          }
84          protected abstract T useDao();
85          protected abstract void retrieveReferences(T object);
86      }
87      public class PreviousValueReference<T extends BusinessObject> {
88          protected String key = "";
89          protected T value;
90          public T getValue() {
91              return value;
92          }
93          public void update(T value, String key) {
94              this.key = key;
95              this.value = value;            
96          }
97          public void update(T value, Object...keys) {
98              update (value, getCacheKey(value.getClass(), keys));
99          }
100     }
101     protected abstract class PreviousValueRetriever<T extends BusinessObject> {
102         public T get(Class<T> type, Object...keys) {
103             String cacheKey = getCacheKey(type, keys);
104             if (!cacheKey.equals(previousValueCache.get(AccountBalance.class).key.equals(cacheKey))) {
105                 previousValueCache.get(type).update(useDao(), cacheKey);
106             }
107             return (T)previousValueCache.get(type).getValue();
108         }
109         protected abstract T useDao();
110     }
111 }