001/** 002 * Copyright 2005-2018 The Kuali Foundation 003 * 004 * Licensed under the Educational Community License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.opensource.org/licenses/ecl2.php 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016package org.kuali.rice.krad.util; 017 018import org.apache.commons.beanutils.PropertyUtils; 019 020import java.beans.PropertyDescriptor; 021 022/** 023 * A utility class for determining the data type of classes and their attributes. 024 * 025 * @author Kuali Rice Team (rice.collab@kuali.org) 026 */ 027public class DataTypeUtil { 028 029 private DataTypeUtil() {} 030 031 public static String determineFieldDataType(Class<?> type, String attributeName) { 032 final Class<?> attributeType = thieveAttributeType(type, attributeName); 033 return determineDataType(attributeType); 034 } 035 /** 036 * Determines the datatype of the given class. 037 * 038 * @param attributeType the class whose datatype is to be determined. 039 * @return String representation of the datatype. Defaults to string. 040 */ 041 public static String determineDataType(Class<?> attributeType) { 042 if (isStringy(attributeType)) { 043 return KRADConstants.DATA_TYPE_STRING; // our most common case should go first 044 } 045 if (isDecimaltastic(attributeType)) { 046 return KRADConstants.DATA_TYPE_FLOAT; 047 } 048 if (isDateLike(attributeType)) { 049 return KRADConstants.DATA_TYPE_DATE; 050 } 051 if (isIntsy(attributeType)) { 052 return KRADConstants.DATA_TYPE_LONG; 053 } 054 if (isBooleanable(attributeType)) { 055 return KRADConstants.DATA_TYPE_BOOLEAN; 056 } 057 return KRADConstants.DATA_TYPE_STRING; // default to String 058 } 059 060 /** 061 * Determines if the given Class is a String 062 * @param type the class to check for Stringiness 063 * @return true if the Class is a String, false otherwise 064 */ 065 public static boolean isStringy(Class<?> type) { 066 return java.lang.String.class.isAssignableFrom(type); 067 } 068 069 /** 070 * Determines if the given class is enough like a date to store values of it as a SearchableAttributeDateTimeValue 071 * @param type the class to determine the type of 072 * @return true if it is like a date, false otherwise 073 */ 074 public static boolean isDateLike(Class<?> type) { 075 return java.util.Date.class.isAssignableFrom(type); 076 } 077 078 /** 079 * Determines if the given class is enough like a Float to store values of it as a SearchableAttributeFloatValue 080 * @param type the class to determine of the type of 081 * @return true if it is like a "float", false otherwise 082 */ 083 public static boolean isDecimaltastic(Class<?> type) { 084 return java.lang.Double.class.isAssignableFrom(type) || java.lang.Float.class.isAssignableFrom(type) || type.equals(Double.TYPE) || type.equals(Float.TYPE) || java.math.BigDecimal.class.isAssignableFrom(type) || org.kuali.rice.core.api.util.type.KualiDecimal.class.isAssignableFrom(type); 085 } 086 087 /** 088 * Determines if the given class is enough like a "long" to store values of it as a SearchableAttributeLongValue 089 * @param type the class to determine the type of 090 * @return true if it is like a "long", false otherwise 091 */ 092 public static boolean isIntsy(Class<?> type) { 093 return java.lang.Integer.class.isAssignableFrom(type) || java.lang.Long.class.isAssignableFrom(type) || java.lang.Short.class.isAssignableFrom(type) || java.lang.Byte.class.isAssignableFrom(type) || java.math.BigInteger.class.isAssignableFrom(type) || type.equals(Integer.TYPE) || type.equals(Long.TYPE) || type.equals(Short.TYPE) || type.equals(Byte.TYPE); 094 } 095 096 /** 097 * Determines if the given class is enough like a boolean, to index it as a String "Y" or "N" 098 * @param type the class to determine the type of 099 * @return true if it is like a boolean, false otherwise 100 */ 101 public static boolean isBooleanable(Class<?> type) { 102 return java.lang.Boolean.class.isAssignableFrom(type) || type.equals(Boolean.TYPE); 103 } 104 105 /** 106 * Given a BusinessObject class and an attribute name, determines the class of that attribute on the BusinessObject class 107 * @param boClass a class extending BusinessObject 108 * @param attributeKey the name of a field on that class 109 * @return the Class of the given attribute 110 */ 111 private static Class<?> thieveAttributeType(Class<?> boClass, String attributeKey) { 112 for (PropertyDescriptor prop : PropertyUtils.getPropertyDescriptors(boClass)) { 113 if (prop.getName().equals(attributeKey)) { 114 return prop.getPropertyType(); 115 } 116 } 117 return null; 118 } 119 120}