View Javadoc

1   /**
2    * Copyright 2010 The Kuali Foundation Licensed under the
3    * Educational Community License, Version 2.0 (the "License"); you may
4    * not use this file except in compliance with the License. You may
5    * obtain a copy of the License at
6    *
7    * http://www.osedu.org/licenses/ECL-2.0
8    *
9    * Unless required by applicable law or agreed to in writing,
10   * software distributed under the License is distributed on an "AS IS"
11   * BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
12   * or implied. See the License for the specific language governing
13   * permissions and limitations under the License.
14   */
15  
16  package org.kuali.rice.kns.datadictionary.validation;
17  
18  import java.math.BigDecimal;
19  import java.text.ParseException;
20  import java.util.Collection;
21  import java.util.Date;
22  
23  import org.apache.commons.lang.StringUtils;
24  import org.kuali.rice.core.api.datetime.DateTimeService;
25  import org.kuali.rice.kns.datadictionary.exception.AttributeValidationException;
26  import org.kuali.rice.kns.util.ObjectUtils;
27  
28  /**
29   * Inherited from Kuali Student and adapted extensively, this class provides static utility methods for validation processing. 
30   * 
31   * @author Kuali Rice Team (rice.collab@kuali.org)
32   */
33  public class ValidationUtils {
34  
35  	public static String buildPath(String attributePath, String attributeName) {
36  		if (StringUtils.isNotBlank(attributeName)) {
37  			if (StringUtils.isNotBlank(attributePath)) 
38  				return new StringBuilder(attributePath).append(".").append(attributeName).toString();
39  		
40  			return attributeName;
41  		}
42  		return attributePath;
43  	}
44  	
45  	public static boolean compareValues(Object value1, Object value2,
46  			DataType dataType, String operator, boolean isCaseSensitive, DateTimeService dateTimeService) {
47  
48  		boolean result = false;
49  		Integer compareResult = null;
50  
51  		if("has_value".equalsIgnoreCase(operator)){
52  			if(value1==null){
53  				return "false".equals(value2.toString().toLowerCase());
54  			}
55  			if(value1 instanceof Collection && ((Collection<?>) value1).isEmpty()){
56  				return "false".equals(value2.toString().toLowerCase());
57  			}
58  			return "true".equals(value2.toString().toLowerCase());
59  		}		
60  		// Convert objects into appropriate data types
61  		if (null != dataType) {
62  			if (DataType.STRING.equals(dataType)) {
63  			    String v1 = getString(value1);
64  				String v2 = getString(value2);
65  
66  				if(!isCaseSensitive) {
67  				    v1 = v1.toUpperCase();
68  				    v2 = v2.toUpperCase();
69  				}
70  				
71  				compareResult = v1.compareTo(v2);
72  			} else if (DataType.INTEGER.equals(dataType)) {
73  				Integer v1 = getInteger(value1);
74  				Integer v2 = getInteger(value2);
75  				compareResult = v1.compareTo(v2);
76  			} else if (DataType.LONG.equals(dataType)) {
77  				Long v1 = getLong(value1);
78  				Long v2 = getLong(value2);
79  				compareResult = v1.compareTo(v2);
80  			} else if (DataType.DOUBLE.equals(dataType)) {
81  				Double v1 = getDouble(value1);
82  				Double v2 = getDouble(value2);
83  				compareResult = v1.compareTo(v2);
84  			} else if (DataType.FLOAT.equals(dataType)) {
85  				Float v1 = getFloat(value1);
86  				Float v2 = getFloat(value2);
87  				compareResult = v1.compareTo(v2);
88  			} else if (DataType.BOOLEAN.equals(dataType)) {
89  				Boolean v1 = getBoolean(value1);
90  				Boolean v2 = getBoolean(value2);
91  				compareResult = v1.compareTo(v2);
92  			} else if (DataType.DATE.equals(dataType)) {
93  				Date v1 = getDate(value1, dateTimeService);
94  				Date v2 = getDate(value2, dateTimeService);
95  				compareResult = v1.compareTo(v2);
96  			}
97  		}
98  
99  		if (null != compareResult) {
100 			if (("equals".equalsIgnoreCase(operator)
101 					|| "greater_than_equal".equalsIgnoreCase(operator) || "less_than_equal"
102 					.equalsIgnoreCase(operator))
103 					&& 0 == compareResult) {
104 				result = true;
105 			}
106 
107 			if (("not_equal".equalsIgnoreCase (operator)
108      || "greater_than".equalsIgnoreCase(operator)) && compareResult >= 1) {
109 				result = true;
110 			}
111 
112 			if (("not_equal".equalsIgnoreCase (operator)
113      || "less_than".equalsIgnoreCase(operator)) && compareResult <= -1) {
114 				result = true;
115 			}
116 		}
117 
118 		return result;
119 	}
120 
121 	public static Integer getInteger(Object o) {
122 		Integer result = null;
123 		if (o instanceof Integer)
124 			return (Integer) o;
125 		if (o == null)
126 			return null;
127 		if (o instanceof Number)
128 			return ((Number) o).intValue();
129 		String s = o.toString();
130 		if (s != null && s.trim().length() > 0) {
131 			result = Integer.valueOf(s.trim());
132 		}
133 		return result;
134 	}
135 
136 	public static Long getLong(Object o) {
137 		Long result = null;
138 		if (o instanceof Long)
139 			return (Long) o;
140 		if (o == null)
141 			return null;
142 		if (o instanceof Number)
143 			return ((Number) o).longValue();
144 		String s = o.toString();
145 		if (s != null && s.trim().length() > 0) {
146 			result = Long.valueOf(s.trim());
147 		}
148 		return result;
149 	}
150 
151 	public static Float getFloat(Object o) {
152 		Float result = null;
153 		if (o instanceof Float)
154 			return (Float) o;
155 		if (o == null)
156 			return null;
157 		if (o instanceof Number)
158 			return ((Number) o).floatValue();
159 		String s = o.toString();
160 		if (s != null && s.trim().length() > 0) {
161 			result = Float.valueOf(s.trim());
162 		}
163 		return result;
164 	}
165 
166 	public static Double getDouble(Object o) {
167 		Double result = null;
168 		if (o instanceof BigDecimal)
169 			return ((BigDecimal) o).doubleValue();
170 		if (o instanceof Double)
171 			return (Double) o;
172 		if (o == null)
173 			return null;
174 		if (o instanceof Number)
175 			return ((Number) o).doubleValue();
176 		String s = o.toString();
177 		if (s != null && s.trim().length() > 0) {
178 			result = Double.valueOf(s.trim());
179 		}
180 		return result;
181 	}
182 
183 	public static Date getDate(Object o, DateTimeService dateTimeService) throws IllegalArgumentException {
184 		Date result = null;
185 		if (o instanceof Date)
186 			return (Date) o;
187 		if (o == null)
188 			return null;
189 		String s = o.toString();
190 		if (s != null && s.trim().length() > 0) {
191 			try {
192 				result = dateTimeService.convertToDate(s.trim());
193 			} catch (ParseException e) {
194 				throw new IllegalArgumentException(e);
195 			} 
196 		}
197 		return result;
198 	}
199 
200 	public static String getString(Object o) {
201 		if (o instanceof String)
202 			return (String) o;
203 		if (o == null)
204 			return null;
205 		return o.toString();
206 	}
207 
208 	public static Boolean getBoolean(Object o) {
209 		Boolean result = null;
210 		if (o instanceof Boolean)
211 			return (Boolean) o;
212 		if (o == null)
213 			return null;
214 		String s = o.toString();
215 		if (s != null && s.trim().length() > 0) {
216 			result = Boolean.parseBoolean(s.trim());
217 		}
218 		return result;
219 	}	
220 	
221 
222     public static boolean hasText(String string) {
223 
224         if (string == null || string.length() < 1) {
225             return false;
226         }
227         int stringLength = string.length();
228 
229         for (int i = 0; i < stringLength; i++) {
230             char currentChar = string.charAt(i);
231             if (' ' != currentChar || '\t' != currentChar || '\n' != currentChar) {
232                 return true;
233             }
234         }
235 
236         return false;
237     }
238     
239     public static boolean isNullOrEmpty(Object value) {
240     	return ObjectUtils.isNull(value) || (value instanceof String && StringUtils.isBlank(((String) value).trim()));
241     }
242     
243 	
244 	public static enum Result { VALID, INVALID, UNDEFINED };
245 	
246 	public static Object convertToDataType(Object value, DataType dataType, DateTimeService dateTimeService) throws AttributeValidationException {
247 		Object returnValue = value;
248 		
249 		if (null == value)
250 			return null;
251 		
252 		switch (dataType) {
253 		case BOOLEAN:
254 			if (! (value instanceof Boolean)) {
255 				returnValue = Boolean.valueOf(value.toString());
256 				
257 				// Since the Boolean.valueOf is exceptionally loose - it basically takes any string and makes it false
258 				if (!value.toString().equalsIgnoreCase("TRUE") && !value.toString().equalsIgnoreCase("FALSE"))
259 					throw new AttributeValidationException("Value " + value.toString() + " is not a boolean!");
260 			}
261 			break;
262 		case INTEGER:
263 			if (! (value instanceof Number)) {
264 				returnValue = Integer.valueOf(value.toString());
265 			}
266 			break;
267 		case LONG:
268 			if (! (value instanceof Number)) {
269 				returnValue = Long.valueOf(value.toString());
270 			}
271 			break;
272 		case DOUBLE:
273 			if (! (value instanceof Number)) {
274 				returnValue = Double.valueOf(value.toString());
275 			}
276 			if (((Double)returnValue).isNaN())
277 				throw new AttributeValidationException("Infinite Double values are not valid!");		
278 			if (((Double)returnValue).isInfinite())
279 				throw new AttributeValidationException("Infinite Double values are not valid!");
280 			break;
281 		case FLOAT:
282 			if (! (value instanceof Number)) {
283 				returnValue = Float.valueOf(value.toString());
284 			}
285 			if (((Float)returnValue).isNaN())
286 				throw new AttributeValidationException("NaN Float values are not valid!");
287 			if (((Float)returnValue).isInfinite())
288 				throw new AttributeValidationException("Infinite Float values are not valid!");
289 			break;
290 		case TRUNCATED_DATE:
291 		case DATE:
292 			if (! (value instanceof Date)) {
293 				try {
294 					returnValue = dateTimeService.convertToDate(value.toString());
295 				} catch (ParseException pe) {
296 					throw new AttributeValidationException("Value " + value.toString() + " is not a date!");
297 				}
298 			}
299 			break;
300 		case STRING:
301 		case COMPLEX:
302 			break;
303 		}
304 		
305 		return returnValue;
306 	}
307 	
308 	public static <T> Result isGreaterThan(T value, Comparable<T> limit) {
309 		return limit == null ? Result.UNDEFINED : ( limit.compareTo(value) < 0 ? Result.VALID : Result.INVALID );
310 	}
311 	
312 	public static <T> Result isGreaterThanOrEqual(T value, Comparable<T> limit) {
313 		return limit == null ? Result.UNDEFINED : ( limit.compareTo(value) <= 0 ? Result.VALID : Result.INVALID );
314 	}
315 	
316 	public static <T> Result isLessThan(T value, Comparable<T> limit) {
317 		return limit == null ? Result.UNDEFINED : ( limit.compareTo(value) > 0 ? Result.VALID : Result.INVALID );
318 	}
319 	
320 	public static <T> Result isLessThanOrEqual(T value, Comparable<T> limit) {
321 		return limit == null ? Result.UNDEFINED : ( limit.compareTo(value) >= 0 ? Result.VALID : Result.INVALID );
322 	}
323 	
324 	
325     public static String[] getPathTokens(String fieldPath) {
326         return (fieldPath != null && fieldPath.contains(".") ? fieldPath.split("\\.") : new String[]{fieldPath});
327     }
328 
329 }
330