View Javadoc
1   package org.kuali.ole.describe.keyvalue;
2   
3   import com.google.common.base.Predicates;
4   import com.google.common.collect.Collections2;
5   import com.google.common.collect.Lists;
6   import org.apache.log4j.Logger;
7   import org.kuali.ole.OLEConstants;
8   import org.kuali.ole.deliver.bo.OleTemporaryCirculationHistory;
9   import org.kuali.ole.deliver.processor.LoanProcessor;
10  import org.kuali.ole.deliver.bo.OleLoanDocument;
11  import org.kuali.ole.deliver.bo.OleDeliverRequestBo;
12  import org.kuali.ole.deliver.service.CircDeskLocationResolver;
13  import org.kuali.ole.docstore.common.document.content.instance.Item;
14  import org.kuali.ole.docstore.common.document.content.instance.Location;
15  import org.kuali.ole.docstore.common.document.content.instance.LocationLevel;
16  import org.kuali.ole.docstore.common.document.content.instance.OleHoldings;
17  import org.kuali.ole.describe.bo.OleLocation;
18  import org.kuali.ole.describe.bo.OleLocationLevel;
19  import org.kuali.ole.sys.context.SpringContext;
20  import org.kuali.ole.util.DocstoreUtil;
21  import org.kuali.rice.core.api.config.property.ConfigContext;
22  import org.kuali.rice.core.api.util.ConcreteKeyValue;
23  import org.kuali.rice.core.api.util.KeyValue;
24  import org.kuali.rice.krad.keyvalues.KeyValuesBase;
25  import org.kuali.rice.krad.service.BusinessObjectService;
26  import org.kuali.rice.krad.service.KRADServiceLocator;
27  
28  import java.util.*;
29  import java.util.regex.Matcher;
30  import java.util.regex.Pattern;
31  
32  /**
33   * LocationValuesBuilder used to render the values for LocationValuesBuilder dropdown control.
34   */
35  public class LocationValuesBuilder extends KeyValuesBase {
36  
37      private static final Logger LOG = Logger.getLogger(LocationValuesBuilder.class);
38  
39      public static List<KeyValue> locationKeyValues = null;
40  
41      public static long timeLastRefreshed;
42  
43  
44      public static int refreshInterval = 300;     // in seconds
45      private CircDeskLocationResolver circDeskLocationResolver;
46  
47      private CircDeskLocationResolver getCircDeskLocationResolver() {
48          if (circDeskLocationResolver == null) {
49              circDeskLocationResolver = new CircDeskLocationResolver();
50          }
51          return circDeskLocationResolver;
52      }
53  
54      public void setCircDeskLocationResolver(CircDeskLocationResolver circDeskLocationResolver) {
55          this.circDeskLocationResolver = circDeskLocationResolver;
56      }
57      /**
58       * This method returns the List of ConcreteKeyValue,
59       * ConcreteKeyValue has two arguments LevelCode and
60       * LocationName.
61       *
62       * @return List<KeyValue>
63       */
64  
65      private DocstoreUtil docstoreUtil;
66      public DocstoreUtil getDocstoreUtil() {
67  
68          if (docstoreUtil == null) {
69              docstoreUtil = SpringContext.getBean(DocstoreUtil.class);
70  
71          }
72          return docstoreUtil;
73      }
74      @Override
75      public List<KeyValue> getKeyValues() {
76  
77          List<KeyValue> options = initLocationDetails();
78  
79          List<KeyValue> locationList = new ArrayList<KeyValue>();
80          Map<String, String> map = new HashMap<String, String>();
81          for (KeyValue option : options) {
82              map.put(option.getKey(), option.getValue());
83  
84          }
85          Map<String, Object> locationMap = sortByLocation(map);
86          for (Map.Entry<String, Object> entry : locationMap.entrySet()) {
87              locationList.add(new ConcreteKeyValue(entry.getKey(), (String) entry.getValue()));
88          }
89          return locationList;
90      }
91  
92      public static List<KeyValue> initLocationDetails() {
93  
94          List<KeyValue> options = new ArrayList<KeyValue>();
95          BusinessObjectService businessObjectService = KRADServiceLocator.getBusinessObjectService();
96  
97          Map parentCriteria1 = new HashMap();
98          parentCriteria1.put("levelCode", "SHELVING");
99          List<OleLocationLevel> oleLocationLevel = (List<OleLocationLevel>) businessObjectService.findMatching(OleLocationLevel.class, parentCriteria1);
100         String shelvingId = oleLocationLevel.get(0).getLevelId();
101         options.add(new ConcreteKeyValue("", ""));
102         Map parentCriteria = new HashMap();
103         parentCriteria.put("levelId", shelvingId);
104         Collection<OleLocation> oleLocationCollection = businessObjectService.findMatching(OleLocation.class, parentCriteria);
105         for (OleLocation oleLocation : oleLocationCollection) {
106             String locationName = oleLocation.getLocationName();
107             String levelId = oleLocation.getLevelId();
108             String levelCode = oleLocation.getLocationCode();
109             boolean parentId = oleLocation.getParentLocationId() != null ? true : false;
110             while (parentId) {
111                 Map criteriaMap = new HashMap();
112                 criteriaMap.put("locationId", oleLocation.getParentLocationId());
113                 OleLocation location = businessObjectService.findByPrimaryKey(OleLocation.class,
114                         criteriaMap);
115                 if (locationName != null) {
116                     locationName = location.getLocationName() + "/" + locationName;
117                 }
118                 if (levelCode != null) {
119                     levelCode = location.getLocationCode() + "/" + levelCode;
120                 }
121                 parentId = location.getParentLocationId() != null ? true : false;
122                 oleLocation = location;
123             }
124             //String key = levelCode + "|" + locationName;
125             options.add(new ConcreteKeyValue(levelCode, levelCode));
126         }
127         return options;
128     }
129 
130 
131     public static List<String> retrieveLocationDetailsForSuggest(String locationVal) {
132         List<KeyValue> locationKeyValues = retrieveLocationDetails();
133         List<String> locationValues = new ArrayList<String>();
134         for (KeyValue keyValue : locationKeyValues) {
135             locationValues.add(keyValue.getKey());
136         }
137 
138         Pattern pattern = Pattern.compile("[?$(){}\\[\\]\\^\\\\]");
139         Matcher matcher = pattern.matcher(locationVal);
140         if (matcher.matches()) {
141             return new ArrayList<String>();
142         }
143 
144         if (!locationVal.equalsIgnoreCase("*")) {
145             locationValues = Lists.newArrayList(Collections2.filter(locationValues, Predicates.contains(Pattern.compile(locationVal, Pattern.CASE_INSENSITIVE))));
146         }
147         Collections.sort(locationValues);
148         return locationValues;
149     }
150 
151     private static List<KeyValue> retrieveLocationDetails() {
152         long currentTime = System.currentTimeMillis() / 1000;
153         if (locationKeyValues == null) {
154             locationKeyValues = initLocationDetails();
155             timeLastRefreshed = currentTime;
156         } else {
157             if (currentTime - timeLastRefreshed > refreshInterval) {
158                 locationKeyValues = initLocationDetails();
159                 timeLastRefreshed = currentTime;
160             }
161         }
162         return locationKeyValues;
163     }
164 
165     private Map<String, Object> sortByLocation(Map<String, String> parentCriteria) {
166         Map<String, Object> map = new LinkedHashMap<String, Object>();
167 
168         List<String> keyList = new ArrayList<String>(parentCriteria.keySet());
169         List<String> valueList = new ArrayList<String>(parentCriteria.values());
170         Set<String> sortedSet = new TreeSet<String>(valueList);
171         Object[] sortedArray = sortedSet.toArray();
172         int size = sortedArray.length;
173         for (int i = 0; i < size; i++) {
174             map.put(keyList.get(valueList.indexOf(sortedArray[i])), sortedArray[i]);
175         }
176         return map;
177     }
178 
179 
180     public String getLocation(LocationLevel oleLocationLevel) {
181         String location = null;
182         if (OLEConstants.LOCATION_LEVEL_SHELVING.equalsIgnoreCase(oleLocationLevel.getLevel()))
183             location = oleLocationLevel.getName();
184         else
185             location = getLocation(oleLocationLevel.getLocationLevel());
186         if ("".equals(location) || location == null)
187             return null;
188         return location;
189     }
190 
191 
192     public String getShelvingLocation(Location oleLocation) throws Exception {
193         if (oleLocation == null) {
194             return "";
195         }
196         LocationLevel locationLevel = oleLocation.getLocationLevel();
197         if (locationLevel != null) {
198             while (locationLevel != null && locationLevel.getLocationLevel() != null && !locationLevel.getLevel().equalsIgnoreCase(OLEConstants.OleDeliverRequest.SHELVING)) {
199                 locationLevel = locationLevel.getLocationLevel();
200             }
201             return locationLevel.getName();
202         }
203         return null;
204     }
205 
206 
207     /**
208      * This method returns location details.
209      *
210      * @param oleItem
211      * @param object
212      * @throws Exception
213      */
214     public void getLocation(Item oleItem, Object object, String instanceUUID) throws Exception {
215         LOG.debug("Inside the getLocation method");
216         try {
217             Location physicalLocation = oleItem.getLocation();
218             LocationLevel locationLevel = null;
219             locationLevel = physicalLocation.getLocationLevel();
220             getOleLocationLevel(object, locationLevel);
221         } catch (Exception itemException) {
222             LOG.error("--------------Invalid Item location data.---------------" + itemException);
223             try {
224 
225                 OleHoldings oleHoldings =getDocstoreUtil().getOleHoldings(instanceUUID);
226                 if (oleHoldings != null) {
227                     Location physicalLocation = oleHoldings.getLocation();
228                     LocationLevel locationLevel = null;
229                     locationLevel = physicalLocation.getLocationLevel();
230                     getOleLocationLevel(object, locationLevel);
231                 }
232             } catch (Exception holdingException) {
233                 LOG.error("--------------Invalid Holding location data.---------------" + itemException);
234                 throw new Exception(ConfigContext.getCurrentContextConfig().getProperty(OLEConstants.INVAL_LOC));
235             }
236         }
237     }
238 
239 
240     /**
241      * Populate location levels.
242      *
243      * @param object
244      * @param locationLevel
245      * @throws Exception
246      */
247     public void getOleLocationLevel(Object object, LocationLevel locationLevel) throws Exception {
248         LOG.debug("Inside the getOleLocationLevel method");
249         StringBuffer location = new StringBuffer();
250         while (locationLevel.getLocationLevel() != null) {
251             OleLocationLevel oleLocationLevel = getCircDeskLocationResolver().getLocationLevelByName(locationLevel.getLevel());
252             OleLocation oleLocation = new OleLocation();
253             if (!"".equals(locationLevel.getName())) {
254                 oleLocation = getLocationByLocationCode(locationLevel.getName());
255             }
256             setLocation(location, oleLocationLevel.getLevelName(), oleLocation.getLocationCode(), oleLocation.getLocationName(), object);
257             locationLevel = locationLevel.getLocationLevel();
258         }
259         if (object instanceof OleDeliverRequestBo) {
260             OleDeliverRequestBo oleDeliverRequestBo = (OleDeliverRequestBo) object;
261             oleDeliverRequestBo.setShelvingLocation(locationLevel.getName());
262         }
263         if(object instanceof OleTemporaryCirculationHistory){
264               OleTemporaryCirculationHistory oleTemporaryCirculationHistory=(OleTemporaryCirculationHistory)object;
265             oleTemporaryCirculationHistory.setShelvingLocation(locationLevel.getName());
266 
267         }
268     }
269 
270     /**
271      * This method returns location using location code.
272      *
273      * @param locationCode
274      * @return
275      * @throws Exception
276      */
277     private OleLocation getLocationByLocationCode(String locationCode) throws Exception {
278         LOG.debug("Inside the getLocationByLocationCode method");
279         Map barMap = new HashMap();
280         barMap.put(OLEConstants.LOC_CD, locationCode);
281         List<OleLocation> matchingLocation = (List<OleLocation>) KRADServiceLocator.getBusinessObjectService().findMatching(OleLocation.class, barMap);
282         return matchingLocation.get(0);
283     }
284 
285     /**
286      * sets the value for location levels in Loan Document.
287      *
288      * @param locationLevelName
289      * @param locationCode
290      * @param object
291      * @return OleLoanDocument
292      * @throws Exception
293      */
294     private void setLocation(StringBuffer location, String locationLevelName, String locationCode, String locationName, Object object) throws Exception {
295         LOG.debug("Inside the setLocation method");
296         OleLoanDocument oleLoanDocument = null;
297         OleDeliverRequestBo oleDeliverRequestBo = null;
298         if (object instanceof OleLoanDocument) {
299             oleLoanDocument = (OleLoanDocument) object;
300         } else if (object instanceof OleDeliverRequestBo) {
301             oleDeliverRequestBo = (OleDeliverRequestBo) object;
302         }
303         if (locationCode != null) {
304             if (oleLoanDocument != null) {
305                 if (locationLevelName.equalsIgnoreCase(OLEConstants.LOCATION_LEVEL_SHELVING)) {
306                     location.append(locationName);
307                     oleLoanDocument.setItemLocation(locationCode);
308                 } else if (locationLevelName.equalsIgnoreCase(OLEConstants.LOCATION_LEVEL_COLLECTION)) {
309                     location.append(locationName + "-");
310                     oleLoanDocument.setItemCollection(locationCode);
311                 } else if (locationLevelName.equalsIgnoreCase(OLEConstants.LOCATION_LEVEL_LIBRARY)) {
312                     location.append(locationName + "-");
313                     oleLoanDocument.setItemLibrary(locationCode);
314                 } else if (locationLevelName.equalsIgnoreCase(OLEConstants.LOCATION_LEVEL_INSTITUTION)) {
315                     location.append(locationName + "-");
316                     oleLoanDocument.setItemInstitution(locationCode);
317                 } else if (locationLevelName.equalsIgnoreCase(OLEConstants.LOCATION_LEVEL_CAMPUS)) {
318                     location.append(locationName + "-");
319                     oleLoanDocument.setItemCampus(locationCode);
320                 }
321             } else if (oleDeliverRequestBo != null) {
322                 if (locationLevelName.equalsIgnoreCase(OLEConstants.LOCATION_LEVEL_SHELVING)) {
323                     oleDeliverRequestBo.setShelvingLocation(locationCode);
324                 } else if (locationLevelName.equalsIgnoreCase(OLEConstants.LOCATION_LEVEL_COLLECTION)) {
325                     oleDeliverRequestBo.setItemCollection(locationCode);
326                 } else if (locationLevelName.equalsIgnoreCase(OLEConstants.LOCATION_LEVEL_LIBRARY)) {
327                     oleDeliverRequestBo.setItemLibrary(locationCode);
328                 } else if (locationLevelName.equalsIgnoreCase(OLEConstants.LOCATION_LEVEL_INSTITUTION)) {
329                     oleDeliverRequestBo.setItemInstitution(locationCode);
330                 } else if (locationLevelName.equalsIgnoreCase(OLEConstants.LOCATION_LEVEL_CAMPUS)) {
331                     oleDeliverRequestBo.setItemCampus(locationCode);
332                 }
333             }
334 
335         }
336     }
337 
338 }