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