View Javadoc

1   /*
2    * Copyright 2005-2007 The Kuali Foundation
3    *
4    *
5    * Licensed under the Educational Community License, Version 2.0 (the "License");
6    * you may not use this file except in compliance with the License.
7    * You may obtain a copy of the License at
8    *
9    * http://www.opensource.org/licenses/ecl2.php
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  package org.kuali.rice.kew.util;
18  
19  import java.io.PrintWriter;
20  import java.io.StringWriter;
21  import java.net.InetAddress;
22  import java.net.UnknownHostException;
23  import java.sql.Timestamp;
24  import java.util.ArrayList;
25  import java.util.Calendar;
26  import java.util.Collection;
27  import java.util.Collections;
28  import java.util.Comparator;
29  import java.util.Date;
30  import java.util.HashMap;
31  import java.util.HashSet;
32  import java.util.List;
33  import java.util.Map;
34  import java.util.Set;
35  
36  import org.apache.commons.collections.KeyValue;
37  import org.apache.commons.lang.StringUtils;
38  import org.apache.commons.lang.text.StrSubstitutor;
39  import org.kuali.rice.core.util.RiceConstants;
40  import org.kuali.rice.kew.actionrequest.ActionRequestValue;
41  import org.kuali.rice.kew.exception.WorkflowRuntimeException;
42  import org.kuali.rice.kim.util.KimConstants;
43  import org.kuali.rice.kns.bo.Parameter;
44  import org.kuali.rice.kns.service.KNSServiceLocator;
45  
46  
47  /**
48   * Various static utility methods.
49   *
50   * @author Kuali Rice Team (rice.collab@kuali.org)
51   */
52  public class Utilities {
53      /**
54       * Commons-Lang StrSubstitor which substitutes variables specified like ${name} in strings,
55       * using a lookup implementation that pulls variables from the core config
56       */
57      private static StrSubstitutor substitutor = new StrSubstitutor(new ConfigStringLookup());
58  
59      /**
60       * Performs variable substitution on the specified string, replacing variables specified like ${name}
61       * with the value of the corresponding config parameter obtained from the current context Config object.
62       * This version of the method also takes a namespace to qualify the parameter.
63       * @param namespace the namespace to use for qualifying the parameter
64       * @param string the string on which to perform variable substitution
65       * @return a string with any variables substituted with configuration parameter values
66       */
67      public static String substituteConfigParameters(String namespace, String string) {
68      	StrSubstitutor sub = new StrSubstitutor(new ConfigStringLookup(namespace));
69          return sub.replace(string);
70      }
71          
72      /**
73       * Performs variable substitution on the specified string, replacing variables specified like ${name}
74       * with the value of the corresponding config parameter obtained from the current context Config object
75       * @param string the string on which to perform variable substitution
76       * @return a string with any variables substituted with configuration parameter values
77       */
78      public static String substituteConfigParameters(String string) {
79          return substitutor.replace(string);
80      }
81      
82      public static String getKNSParameterValue(String nameSpace, String detailType, String name) {
83          Parameter parameter = KNSServiceLocator.getParameterService().retrieveParameter(nameSpace, detailType, name);
84          if (parameter == null) {
85              return null;
86          }
87          return parameter.getParameterValue();
88      }
89  
90      public static boolean getKNSParameterBooleanValue(String nameSpace, String detailType, String name) {
91      	return getKNSParameterBooleanValue(nameSpace, detailType, name, false);
92      }
93      
94      public static boolean getKNSParameterBooleanValue(String nameSpace, String detailType, String name, boolean defaultValue) {
95          Parameter parameter = KNSServiceLocator.getParameterService().retrieveParameter(nameSpace, detailType, name);
96          if (parameter == null || StringUtils.isBlank(parameter.getParameterValue())) {
97              return defaultValue;
98          }
99          if (parameter.getParameterValue().trim().equals("Y")) {
100             return true;
101         } else {
102             return false;
103         }
104     }
105 
106     public static String parseGroupNamespaceCode(String namespaceAndNameCombo) {
107         if (namespaceAndNameCombo == null) {
108             return null;
109         }
110         String[] groupData = namespaceAndNameCombo.split(KEWConstants.KIM_GROUP_NAMESPACE_NAME_DELIMITER_CHARACTER);
111         if (groupData.length == 1) {
112             return KimConstants.KIM_GROUP_WORKFLOW_NAMESPACE_CODE;
113         } else if (groupData.length == 2) {
114             return groupData[0].trim();
115         } else {
116             return null;
117         }
118     }
119 
120     public static String parseGroupName(String namespaceAndNameCombo) {
121         if (namespaceAndNameCombo == null) {
122             return null;
123         }
124         String[] groupData = namespaceAndNameCombo.split(KEWConstants.KIM_GROUP_NAMESPACE_NAME_DELIMITER_CHARACTER);
125         if (groupData.length == 1) {
126             return groupData[0].trim();
127         } else if (groupData.length == 2) {
128             return groupData[1].trim();
129         } else {
130             return null;
131         }
132     }
133 
134     public static boolean isEmpty(String value) {
135         return value == null || value.trim().equals("");
136     }
137 
138     public static boolean isEmpty(Collection collection) {
139         return collection == null || collection.isEmpty();
140     }
141 
142     public static boolean isEmpty(Object[] array) {
143         return array == null || array.length == 0;
144     }
145 
146     public static boolean equals (Object a, Object b) {
147         return ((a == null && b == null) || (a != null && a.equals(b)));
148     }
149 
150     public static String collectStackTrace(Throwable t) {
151         StringWriter sw = new StringWriter();
152         PrintWriter pw = new PrintWriter(sw);
153         t.printStackTrace(pw);
154         pw.close();
155         return sw.toString();
156     }
157 
158     public static Calendar convertTimestamp(Timestamp timestamp) {
159         if (timestamp == null) {
160             return null;
161         }
162         Calendar calendar = Calendar.getInstance();
163         calendar.setTime(timestamp);
164         return calendar;
165     }
166 
167     public static Timestamp convertCalendar(Calendar calendar) {
168         if (calendar == null) {
169             return null;
170         }
171         return new Timestamp(calendar.getTime().getTime());
172     }
173 
174     public static Set asSet(Object[] objects) {
175         Set set = new HashSet();
176         if (objects != null) {
177             for (int index = 0; index < objects.length; index++) {
178                 Object object = objects[index];
179                 set.add(object);
180             }
181         }
182         return set;
183     }
184 
185     public static Set asSet(Object object) {
186         Set set = new HashSet();
187         if (object != null) {
188             set.add(object);
189         }
190         return set;
191     }
192 
193     public static List asList(Object object) {
194         List<Object> list = new ArrayList<Object>(1);
195         if (object != null) {
196             list.add(object);
197         }
198         return list;
199     }
200 
201     /**
202      *
203      *	Consider moving out of this class if this bugs
204      */
205     public static class PrioritySorter implements Comparator<ActionRequestValue> {
206         public int compare(ActionRequestValue ar1, ActionRequestValue ar2) {
207             int value = ar1.getPriority().compareTo(ar2.getPriority());
208             if (value == 0) {
209                 value = ActionRequestValue.compareActionCode(ar1.getActionRequested(), ar2.getActionRequested(), true);
210                 if (value == 0) {
211                     if ( (ar1.getActionRequestId() != null) && (ar2.getActionRequestId() != null) ) {
212                         value = ar1.getActionRequestId().compareTo(ar2.getActionRequestId());
213                     } else {
214                         // if even one action request id is null at this point return that the two are equal
215                         value = 0;
216                     }
217                 }
218             }
219             return value;
220         }
221     }
222 
223     /**
224      *
225      *	Consider moving out of this class if this bugs
226      */
227     public static class RouteLogActionRequestSorter extends PrioritySorter implements Comparator<ActionRequestValue> {
228         public int compare(ActionRequestValue ar1, ActionRequestValue ar2) {
229             if (! ar1.getChildrenRequests().isEmpty()) {
230                 Collections.sort(ar1.getChildrenRequests(), this);
231             }
232             if (! ar2.getChildrenRequests().isEmpty()) {
233                 Collections.sort(ar2.getChildrenRequests(), this);
234             }
235 
236             int routeLevelCompareVal = ar1.getRouteLevel().compareTo(ar2.getRouteLevel());
237             if (routeLevelCompareVal != 0) {
238                 return routeLevelCompareVal;
239             }
240 
241             if (ar1.isActive() && ar2.isPending()) {
242                 return -1;
243             } else if (ar2.isActive() && ar1.isPending()) {
244                 return 1;
245             }
246 
247             return super.compare(ar1, ar2);
248         }
249     }
250 
251     public static boolean validateDate(String date, boolean dateOptional) {
252         if ((date == null) || date.trim().equals("")) {
253             if (dateOptional) {
254                 return true;
255             } else {
256                 return false;
257             }
258         }
259 
260         try {
261             Date parsedDate = RiceConstants.getDefaultDateFormat().parse(date.trim());
262             if (! RiceConstants.getDefaultDateFormat().format(parsedDate).equals(date)) return false;
263             Calendar calendar = Calendar.getInstance();
264             calendar.setTime(parsedDate);
265             int yearInt = calendar.get(Calendar.YEAR);
266             if (yearInt <= 0 || yearInt > 2999) {
267               return false;
268             }
269             return true;
270         } catch (Exception ex) {
271             return false;
272         }
273     }
274 
275     public static boolean checkDateRanges(String fromDate, String toDate) {
276         try {
277             Date parsedDate = KNSServiceLocator.getDateTimeService().convertToDate(fromDate.trim());
278             Calendar fromCalendar = Calendar.getInstance();
279             fromCalendar.setLenient(false);
280             fromCalendar.setTime(parsedDate);
281             fromCalendar.set(Calendar.HOUR_OF_DAY, 0);
282             fromCalendar.set(Calendar.MINUTE, 0);
283             fromCalendar.set(Calendar.SECOND, 0);
284             fromCalendar.set(Calendar.MILLISECOND, 0);
285             parsedDate = KNSServiceLocator.getDateTimeService().convertToDate(toDate.trim());
286             Calendar toCalendar = Calendar.getInstance();
287             toCalendar.setLenient(false);
288             toCalendar.setTime(parsedDate);
289             toCalendar.set(Calendar.HOUR_OF_DAY, 0);
290             toCalendar.set(Calendar.MINUTE, 0);
291             toCalendar.set(Calendar.SECOND, 0);
292             toCalendar.set(Calendar.MILLISECOND, 0);
293             if (fromCalendar.after(toCalendar)) {
294                 return false;
295             }
296             return true;
297         } catch (Exception ex) {
298             return false;
299         }
300     }
301 
302     /**
303      * Performs a "brute force" comparison of collections by testing whether the collections contain each other.
304      * This circuments any particular uniqueness or ordering constraints on the collections
305      * (for instance, lists that are unordered but contain the same elements, where a hashset would not suffice
306      * for comparison purposes because it enforces element uniqueness)
307      */
308     public static boolean collectionsEquivalent(Collection a, Collection b) {
309         if (a == null && b == null) return true;
310         if (a == null ^ b == null) return false;
311         return a.containsAll(b) && b.containsAll(a);
312     }
313 
314     public static String getIpNumber() {
315         try {
316             return InetAddress.getLocalHost().getHostAddress();
317         } catch (UnknownHostException e) {
318             throw new WorkflowRuntimeException("Error retrieving ip number.", e);
319         }
320     }
321 
322     public static String getHostName() {
323         try {
324             return InetAddress.getLocalHost().getHostName();
325         } catch (UnknownHostException e) {
326             throw new WorkflowRuntimeException("Error retrieving host name.", e);
327         }
328     }
329 
330     /**
331      * Helper method that takes a List of {@link KeyValue} and presents it as a Map
332      * @param <T> the key type
333      * @param <Z> the value type
334      * @param collection collection of {@link KeyValue}
335      * @return a Map<T,Z> representing the keys and values in the KeyValue collection
336      */
337     public static <T,Z> Map<T, Z> getKeyValueCollectionAsMap(List<? extends KeyValue> collection) {
338         Map<T, Z> map = new HashMap<T, Z>(collection.size());
339         for (KeyValue kv: collection) {
340             map.put((T) kv.getKey(), (Z) kv.getValue());
341         }
342         return map;
343     }
344 
345     /**
346      * Helper method that takes a List of {@link KeyValue} and presents it as a Map containing
347      * KeyValue values
348      * @param <T> the key type
349      * @param <Z> the collection/map value type, which must be a KeyValue
350      * @param collection collection of {@link KeyValue}
351      * @return a Map<T,Z> where keys of the KeyValues in the collection are mapped to their respective KeyValue object
352      */
353     public static <T,Z  extends KeyValue> Map<T, Z> getKeyValueCollectionAsLookupTable(List<Z> collection) {
354         Map<T, Z> map = new HashMap<T, Z>(collection.size());
355         for (Z kv: collection) {
356             map.put((T) kv.getKey(), kv);
357         }
358         return map;
359     }
360 }