Modified: struts/shale/trunk/clay-plugin/src/java/org/apache/shale/clay/utils/PropUtils.java URL: http://svn.apache.org/viewcvs/struts/shale/trunk/clay-plugin/src/java/org/apache/shale/clay/utils/PropUtils.java?rev=165369&r1=165368&r2=165369&view=diff ============================================================================== --- struts/shale/trunk/clay-plugin/src/java/org/apache/shale/clay/utils/PropUtils.java (original) +++ struts/shale/trunk/clay-plugin/src/java/org/apache/shale/clay/utils/PropUtils.java Fri Apr 29 18:39:50 2005 @@ -1,546 +1,588 @@ -/* - * Copyright 2005 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * $Id$ - */ - -package org.apache.shale.clay.utils; - -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; -import java.math.BigDecimal; -import java.math.BigInteger; -import java.text.DecimalFormat; -import java.text.Format; -import java.text.MessageFormat; -import java.text.ParseException; -import java.text.SimpleDateFormat; -import java.util.HashMap; -import java.util.Map; -import java.util.StringTokenizer; -import java.util.TreeSet; - -public class PropUtils { - - - public static String formatSimpleProperty(Object source, String pattern) { - - boolean lhasFormat = false; - boolean lisMsgFormat = false; - - Object lArgs = null; - String lPattern = null; - String lfmtValue = null; - Format lFormat = null; - - if (source == null) - return ""; - - lPattern = pattern; - - if ((lPattern != null) && (pattern.length() > 0)) { - lhasFormat = true; - if (pattern.indexOf('{') > -1) - lisMsgFormat = true; - } - - if (source instanceof Boolean) { - lArgs = new Object[1]; - ((Object[]) lArgs)[0] = - ((((Boolean) source).booleanValue()) ? "Yes" : "No"); - lPattern = "{0}"; - lisMsgFormat = lhasFormat = true; - - } else if (lisMsgFormat) { - //message format requires the value be passed in an array - lArgs = new Object[1]; - ((Object[]) lArgs)[0] = source; - } else { - lArgs = source; - } - - if (lisMsgFormat) { - - if (lhasFormat) { - lFormat = new MessageFormat(lPattern); - } - - } else if (source instanceof Number) { - - if ((source instanceof Byte) - || (source instanceof Short) - || (source instanceof Integer) - || (source instanceof Long) - || (source instanceof BigInteger)) { - - if (!lhasFormat) { - lFormat = new DecimalFormat("#0"); - } else - lFormat = new DecimalFormat(lPattern); - - } else if ( - (source instanceof Float) - || (source instanceof Double) - || (source instanceof BigDecimal)) { - - if (!lhasFormat) { - lFormat = new DecimalFormat("#0.00"); - } else - lFormat = new DecimalFormat(lPattern); - } - - } else if (source instanceof java.util.Date) { - - if (!lhasFormat) { - lFormat = new SimpleDateFormat("MM/dd/yyyy"); - } else - lFormat = new SimpleDateFormat(lPattern); - } else if (source.getClass().isArray()) { - - lArgs = source; - StringBuffer listPattern = new StringBuffer(); - int n = ((Object[]) lArgs).length; - for (int i = 0; i < n; i++) - listPattern.append((i > 0) ? "," : "").append("{").append( - i).append( - "}"); - lFormat = new MessageFormat(listPattern.toString()); - listPattern = null; - } - - if (lFormat != null) { - try { - lfmtValue = lFormat.format(lArgs); - } catch (Exception je) { - je.printStackTrace(); - } - } else { - lfmtValue = source.toString(); - } - - lFormat = null; - lArgs = null; - lPattern = null; - - return lfmtValue; - } - - private final static String[] numberPatterns = - { "#0", "#.##", "$#.##", "###,###.00", "$###,###.00", "$ ###,###.00" }; - private final static String[] datePatterns = - { "MM/dd/yy", "MM/dd/yyyy", "yyyy/MM/dd", "MM-dd-yyyy", "yyyy-MM-dd" }; - - /** - * @param source object - * @param targetType object class type - * @param targetPattern that should be used to convert the source to the target - * @return an instance of the target object holding the value of the source instance - */ - public static Object decodeSimpleProperty( - Object source, - Class targetType, - String targetPattern) { - - // if the target type is the same as the source type, return the source - if ((source == null) || (source.getClass() == targetType) || (targetType == Object.class)) - return source; - - Object targetObj = null; - Format lFormat = null; - - if (targetType == String.class) { // converting to a string - - return formatSimpleProperty(source, targetPattern); - - } else if ( - source instanceof String) { // decoding the value of a string - - if (((String) source).length() == 0) - return null; // empty string reutrn null - - if ((targetType == java.lang.Boolean.TYPE) - || (targetType == java.lang.Boolean.class)) { - if ((((String) source).charAt(0) == 'T') - || (((String) source).charAt(0) == 'Y') - || (((String) source).charAt(0) == 't') - || (((String) source).charAt(0) == 'y')) - targetObj = new java.lang.Boolean(true); - else - targetObj = new java.lang.Boolean(false); - - return targetObj; - - } else if ( - (targetType == java.util.Date.class) - || (targetType == java.sql.Date.class)) { - - if ((targetPattern != null) && (targetPattern.length() > 0)) - lFormat = new SimpleDateFormat(targetPattern); - else - lFormat = new SimpleDateFormat(datePatterns[0]); - - for (int i = 0; i < datePatterns.length; ++i) { - - try { - targetObj = lFormat.parseObject((String) source); - } catch (ParseException je) { - //je.printStackTrace(); - } - - if (targetObj != null) - break; - - ((SimpleDateFormat) lFormat).applyPattern(datePatterns[i]); - - } - - if ((targetObj != null) && (targetType == java.sql.Date.class)) - return new java.sql.Date( - ((java.util.Date) targetObj).getTime()); - - return targetObj; - - } else if ( - (targetType == java.lang.Byte.TYPE) - || (targetType == java.lang.Byte.class) - || (targetType == java.lang.Short.TYPE) - || (targetType == java.lang.Short.class) - || (targetType == java.lang.Integer.TYPE) - || (targetType == java.lang.Integer.class) - || (targetType == java.lang.Long.TYPE) - || (targetType == java.lang.Long.class) - || (targetType == java.math.BigInteger.class)) { - - if ((targetPattern != null) && (targetPattern.length() > 0)) - lFormat = new DecimalFormat(targetPattern); - else - lFormat = new DecimalFormat(numberPatterns[0]); - - } else if ( - (targetType == java.lang.Double.TYPE) - || (targetType == java.lang.Double.class) - || (targetType == java.lang.Float.TYPE) - || (targetType == java.lang.Float.class) - || (targetType == java.math.BigDecimal.class)) { - - if ((targetPattern != null) && (targetPattern.length() > 0)) - lFormat = new DecimalFormat(targetPattern); - else - lFormat = new DecimalFormat(numberPatterns[2]); - } - - Number numericObj = null; - for (int i = 0; i < numberPatterns.length; i++) { - try { - numericObj = (Number) lFormat.parseObject((String) source); - } catch (ParseException je) { - //je.printStackTrace(); - } - - if (numericObj != null) - break; - - ((DecimalFormat) lFormat).applyPattern(numberPatterns[i]); - } - - if (numericObj == null) - return null; - - if ((targetType == java.lang.Byte.TYPE) - || (targetType == java.lang.Byte.class)) - targetObj = new java.lang.Byte((byte) numericObj.byteValue()); - else if ( - (targetType == java.lang.Short.TYPE) - || (targetType == java.lang.Short.class)) - targetObj = - new java.lang.Short((short) numericObj.shortValue()); - else if ( - (targetType == java.lang.Integer.TYPE) - || (targetType == java.lang.Integer.class)) - targetObj = new java.lang.Integer((int) numericObj.intValue()); - else if ( - (targetType == java.lang.Long.TYPE) - || (targetType == java.lang.Long.class)) - targetObj = new java.lang.Long((long) numericObj.longValue()); - else if ( - (targetType == java.lang.Double.TYPE) - || (targetType == java.lang.Double.class)) - targetObj = new java.lang.Double(numericObj.doubleValue()); - else if ( - (targetType == java.lang.Float.TYPE) - || (targetType == java.lang.Float.class)) - targetObj = new java.lang.Float(numericObj.floatValue()); - else if (targetType == java.math.BigDecimal.class) - targetObj = new java.math.BigDecimal(numericObj.doubleValue()); - - return targetObj; - - } else if (source instanceof Number) { - - Number numericObj = (Number) source; - - if ((targetType == java.lang.Byte.TYPE) - || (targetType == java.lang.Byte.class)) - targetObj = new java.lang.Byte((byte) numericObj.byteValue()); - else if ( - (targetType == java.lang.Short.TYPE) - || (targetType == java.lang.Short.class)) - targetObj = - new java.lang.Short((short) numericObj.shortValue()); - else if ( - (targetType == java.lang.Integer.TYPE) - || (targetType == java.lang.Integer.class)) - targetObj = new java.lang.Integer((int) numericObj.intValue()); - else if ( - (targetType == java.lang.Long.TYPE) - || (targetType == java.lang.Long.class)) - targetObj = new java.lang.Long((long) numericObj.longValue()); - else if ( - (targetType == java.lang.Double.TYPE) - || (targetType == java.lang.Double.class)) - targetObj = new java.lang.Double(numericObj.doubleValue()); - else if ( - (targetType == java.lang.Float.TYPE) - || (targetType == java.lang.Float.class)) - targetObj = new java.lang.Float(numericObj.floatValue()); - else if (targetType == java.math.BigDecimal.class) - targetObj = new java.math.BigDecimal(numericObj.doubleValue()); - - return targetObj; - - } else - targetObj = source; // complext type, no conversion - - lFormat = null; - - return targetObj; - } - - /** - * <p/>Returns an array of string of all the bean properties. Only looks a - * the getter methods so the setters can be overloaded. True beans do not - * allow the setters to be overloaded. - *</p> - */ - public static String[] getPropertyNames(Object bean) { - - if (bean == null) - return new String[0]; - - Method[] methods = bean.getClass().getMethods(); - TreeSet ts = new TreeSet(); - - for (int i = 0; i < methods.length; ++i) { - Method method = methods[i]; - String methodName = method.getName(); - if ((methodName.startsWith("get")) - && (method.getParameterTypes().length == 0) - && (method.getModifiers() == 1) - && (!methodName.endsWith("IsNull"))) { - - String attrName = - methodName.substring(3, 4).toLowerCase() - + methodName.substring(4); - ts.add(attrName); - } - methodName = null; - method = null; - } - - String[] names = new String[ts.size()]; - ts.toArray(names); - methods = null; - ts = null; - - return names; - - }; - - public static Object getProperty(Object bean, String propName) { - - if (bean == null) - return null; - - Object prop = null; - Class[] paramTypes = new Class[0]; - Method isNullMethod = null; - boolean isNullValue = false; - String methodName = - "get" - + propName.substring(0, 1).toUpperCase() - + propName.substring(1); - - String isNullMethodName = methodName + "IsNull"; - Object[] paramValues = new Object[0]; - - try { - isNullMethod = - bean.getClass().getMethod(isNullMethodName, paramTypes); - Boolean isNull = (Boolean) isNullMethod.invoke(bean, paramValues); - if (isNull.booleanValue()) - return null; - } catch (IllegalAccessException e) { - } catch (InvocationTargetException e) { - } catch (NoSuchMethodException e) { - } - - try { - Method method = bean.getClass().getMethod(methodName, paramTypes); - - method.setAccessible(true); - prop = method.invoke(bean, paramValues); - - paramValues = null; - method = null; - - } catch (NoSuchMethodException je) { - je.printStackTrace(); - } catch (IllegalAccessException je) { - je.printStackTrace(); - } catch (InvocationTargetException je) { - je.printStackTrace(); - } - - paramTypes = null; - methodName = null; - - return prop; - } - - public static void setProperty( - Object bean, - String propName, - Object propValue) { - - setProperty(bean, propName, propValue, null); - - } - - public static void setProperty( - Object bean, - String propName, - Object propValue, - String pattern) { - - if (bean == null) - return; - - Class[] paramTypes = new Class[0]; - String methodName = null; - - try { - - Method method = null; - int tries = 0; //retry counter - - next : do { - tries++; //increment retry counter - methodName = - "get" - + propName.substring(0, 1).toUpperCase() - + propName.substring(1); - try { - method = bean.getClass().getMethod(methodName, paramTypes); - } catch (Exception e) { - } - - if ((propValue == null) && (method == null)) - return; // must have a getter - else if ((propValue == null) && (method != null)) { - if (method.getReturnType().isPrimitive()) { - // null value for a primitive type is not possible - propName = propName + "IsNull"; - // check for a rustts invented null state - propValue = new Boolean(true); - continue next; //try again - } else // null assignment for object type is valid - break next; //exit for loop - } - - } while (tries < 2); //iterations - - paramTypes = new Class[1]; - - // We now should succeed in every case except when setting - // an object data type to null where there is no getter available - - paramTypes[0] = - (method == null) - ? propValue.getClass() - : method.getReturnType(); - - methodName = - "set" - + propName.substring(0, 1).toUpperCase() - + propName.substring(1); - //System.out.println(methodName); - try { - method = bean.getClass().getMethod(methodName, paramTypes); - } catch (Exception e) { - //no getter found, no setter with the same type as the incoming property value - //look for a setter with a signature matching an implemented interface of the property value - Class[] interfaces = propValue.getClass().getInterfaces(); - next : for (int i = 0; i < interfaces.length; ++i) { - try { - paramTypes[0] = interfaces[i]; - method = - bean.getClass().getMethod(methodName, paramTypes); - } catch (Exception je) { - continue next; - } - break; - } - } - - Object[] paramValues = - { decodeSimpleProperty(propValue, paramTypes[0], pattern)}; - - if (method != null) { - method.setAccessible(true); - method.invoke(bean, paramValues); - } - - paramValues = null; - - method = null; - - } catch (Exception je) { - je.printStackTrace(); - } - - paramTypes = null; - methodName = null; - - } - - public static Map describe(Object bean) { - - Map attrs = new HashMap(); - String[] propertyNames = getPropertyNames(bean); - - if (propertyNames != null) { - for (int i = 0; i < propertyNames.length; ++i) { - attrs.put( - propertyNames[i], - getProperty(bean, propertyNames[i])); - } - } - - propertyNames = null; - - return attrs; - } - -} +/* + * Copyright 2005 The Apache Software Foundation. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * $Id$ + */ + +package org.apache.shale.clay.utils; + +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.math.BigDecimal; +import java.math.BigInteger; +import java.text.DecimalFormat; +import java.text.Format; +import java.text.MessageFormat; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.HashMap; +import java.util.Map; +import java.util.StringTokenizer; +import java.util.TreeSet; + +public class PropUtils { + + /** + * <p>A utility method that will format the source object using the pattern. + * The data type of the source object will determine the formatting strategy. + * <p> + * @param source object to format + * @param pattern to use or <code>null</code> value will assume a default pattern + * @return formated source as a String + */ + public static String formatSimpleProperty(Object source, String pattern) { + + boolean lhasFormat = false; + boolean lisMsgFormat = false; + + Object lArgs = null; + String lPattern = null; + String lfmtValue = null; + Format lFormat = null; + + if (source == null) + return ""; + + lPattern = pattern; + + if ((lPattern != null) && (pattern.length() > 0)) { + lhasFormat = true; + if (pattern.indexOf('{') > -1) + lisMsgFormat = true; + } + + if (source instanceof Boolean) { + lArgs = new Object[1]; + ((Object[]) lArgs)[0] = + ((((Boolean) source).booleanValue()) ? "Yes" : "No"); + lPattern = "{0}"; + lisMsgFormat = lhasFormat = true; + + } else if (lisMsgFormat) { + //message format requires the value be passed in an array + lArgs = new Object[1]; + ((Object[]) lArgs)[0] = source; + } else { + lArgs = source; + } + + if (lisMsgFormat) { + + if (lhasFormat) { + lFormat = new MessageFormat(lPattern); + } + + } else if (source instanceof Number) { + + if ((source instanceof Byte) + || (source instanceof Short) + || (source instanceof Integer) + || (source instanceof Long) + || (source instanceof BigInteger)) { + + if (!lhasFormat) { + lFormat = new DecimalFormat("#0"); + } else + lFormat = new DecimalFormat(lPattern); + + } else if ( + (source instanceof Float) + || (source instanceof Double) + || (source instanceof BigDecimal)) { + + if (!lhasFormat) { + lFormat = new DecimalFormat("#0.00"); + } else + lFormat = new DecimalFormat(lPattern); + } + + } else if (source instanceof java.util.Date) { + + if (!lhasFormat) { + lFormat = new SimpleDateFormat("MM/dd/yyyy"); + } else + lFormat = new SimpleDateFormat(lPattern); + } else if (source.getClass().isArray()) { + + lArgs = source; + StringBuffer listPattern = new StringBuffer(); + int n = ((Object[]) lArgs).length; + for (int i = 0; i < n; i++) + listPattern.append((i > 0) ? "," : "").append("{").append( + i).append( + "}"); + lFormat = new MessageFormat(listPattern.toString()); + listPattern = null; + } + + if (lFormat != null) { + try { + lfmtValue = lFormat.format(lArgs); + } catch (Exception je) { + je.printStackTrace(); + } + } else { + lfmtValue = source.toString(); + } + + lFormat = null; + lArgs = null; + lPattern = null; + + return lfmtValue; + } + + /** + * <p>A list of numeric patterns that will be applied in sequence when attempting + * to decode a number from a string</p> + */ + private final static String[] numberPatterns = + { "#0", "#.##", "$#.##", "###,###.00", "$###,###.00", "$ ###,###.00" }; + /** + * <p>A list of date patterns that are used in sequence when attempting to + * decode a date from a string</p> + */ + private final static String[] datePatterns = + { "MM/dd/yy", "MM/dd/yyyy", "yyyy/MM/dd", "MM-dd-yyyy", "yyyy-MM-dd" }; + + /** + * <p>A simple function that tries to convert one type into another<p> + * @param source object to convert from + * @param targetType object class type to convert the source to + * @param targetPattern that should be used to convert the source to the target + * @return an instance of the target object holding the value of the source instance + */ + public static Object decodeSimpleProperty( + Object source, + Class targetType, + String targetPattern) { + + // if the target type is the same as the source type, return the source + if ((source == null) || (source.getClass() == targetType) || (targetType == Object.class)) + return source; + + Object targetObj = null; + Format lFormat = null; + + if (targetType == String.class) { // converting to a string + + return formatSimpleProperty(source, targetPattern); + + } else if ( + source instanceof String) { // decoding the value of a string + + if (((String) source).length() == 0) + return null; // empty string reutrn null + + if ((targetType == java.lang.Boolean.TYPE) + || (targetType == java.lang.Boolean.class)) { + if ((((String) source).charAt(0) == 'T') + || (((String) source).charAt(0) == 'Y') + || (((String) source).charAt(0) == 't') + || (((String) source).charAt(0) == 'y')) + targetObj = new java.lang.Boolean(true); + else + targetObj = new java.lang.Boolean(false); + + return targetObj; + + } else if ( + (targetType == java.util.Date.class) + || (targetType == java.sql.Date.class)) { + + if ((targetPattern != null) && (targetPattern.length() > 0)) + lFormat = new SimpleDateFormat(targetPattern); + else + lFormat = new SimpleDateFormat(datePatterns[0]); + + for (int i = 0; i < datePatterns.length; ++i) { + + try { + targetObj = lFormat.parseObject((String) source); + } catch (ParseException je) { + //je.printStackTrace(); + } + + if (targetObj != null) + break; + + ((SimpleDateFormat) lFormat).applyPattern(datePatterns[i]); + + } + + if ((targetObj != null) && (targetType == java.sql.Date.class)) + return new java.sql.Date( + ((java.util.Date) targetObj).getTime()); + + return targetObj; + + } else if ( + (targetType == java.lang.Byte.TYPE) + || (targetType == java.lang.Byte.class) + || (targetType == java.lang.Short.TYPE) + || (targetType == java.lang.Short.class) + || (targetType == java.lang.Integer.TYPE) + || (targetType == java.lang.Integer.class) + || (targetType == java.lang.Long.TYPE) + || (targetType == java.lang.Long.class) + || (targetType == java.math.BigInteger.class)) { + + if ((targetPattern != null) && (targetPattern.length() > 0)) + lFormat = new DecimalFormat(targetPattern); + else + lFormat = new DecimalFormat(numberPatterns[0]); + + } else if ( + (targetType == java.lang.Double.TYPE) + || (targetType == java.lang.Double.class) + || (targetType == java.lang.Float.TYPE) + || (targetType == java.lang.Float.class) + || (targetType == java.math.BigDecimal.class)) { + + if ((targetPattern != null) && (targetPattern.length() > 0)) + lFormat = new DecimalFormat(targetPattern); + else + lFormat = new DecimalFormat(numberPatterns[2]); + } + + Number numericObj = null; + for (int i = 0; i < numberPatterns.length; i++) { + try { + numericObj = (Number) lFormat.parseObject((String) source); + } catch (ParseException je) { + //je.printStackTrace(); + } + + if (numericObj != null) + break; + + ((DecimalFormat) lFormat).applyPattern(numberPatterns[i]); + } + + if (numericObj == null) + return null; + + if ((targetType == java.lang.Byte.TYPE) + || (targetType == java.lang.Byte.class)) + targetObj = new java.lang.Byte((byte) numericObj.byteValue()); + else if ( + (targetType == java.lang.Short.TYPE) + || (targetType == java.lang.Short.class)) + targetObj = + new java.lang.Short((short) numericObj.shortValue()); + else if ( + (targetType == java.lang.Integer.TYPE) + || (targetType == java.lang.Integer.class)) + targetObj = new java.lang.Integer((int) numericObj.intValue()); + else if ( + (targetType == java.lang.Long.TYPE) + || (targetType == java.lang.Long.class)) + targetObj = new java.lang.Long((long) numericObj.longValue()); + else if ( + (targetType == java.lang.Double.TYPE) + || (targetType == java.lang.Double.class)) + targetObj = new java.lang.Double(numericObj.doubleValue()); + else if ( + (targetType == java.lang.Float.TYPE) + || (targetType == java.lang.Float.class)) + targetObj = new java.lang.Float(numericObj.floatValue()); + else if (targetType == java.math.BigDecimal.class) + targetObj = new java.math.BigDecimal(numericObj.doubleValue()); + + return targetObj; + + } else if (source instanceof Number) { + + Number numericObj = (Number) source; + + if ((targetType == java.lang.Byte.TYPE) + || (targetType == java.lang.Byte.class)) + targetObj = new java.lang.Byte((byte) numericObj.byteValue()); + else if ( + (targetType == java.lang.Short.TYPE) + || (targetType == java.lang.Short.class)) + targetObj = + new java.lang.Short((short) numericObj.shortValue()); + else if ( + (targetType == java.lang.Integer.TYPE) + || (targetType == java.lang.Integer.class)) + targetObj = new java.lang.Integer((int) numericObj.intValue()); + else if ( + (targetType == java.lang.Long.TYPE) + || (targetType == java.lang.Long.class)) + targetObj = new java.lang.Long((long) numericObj.longValue()); + else if ( + (targetType == java.lang.Double.TYPE) + || (targetType == java.lang.Double.class)) + targetObj = new java.lang.Double(numericObj.doubleValue()); + else if ( + (targetType == java.lang.Float.TYPE) + || (targetType == java.lang.Float.class)) + targetObj = new java.lang.Float(numericObj.floatValue()); + else if (targetType == java.math.BigDecimal.class) + targetObj = new java.math.BigDecimal(numericObj.doubleValue()); + + return targetObj; + + } else + targetObj = source; // complext type, no conversion + + lFormat = null; + + return targetObj; + } + + /** + * <p/>Returns an array of string of all the bean properties. Only looks at + * the getter methods so the setters can be overloaded. "True" beans do not + * allow the setters to be overloaded. + *</p> + */ + public static String[] getPropertyNames(Object bean) { + + if (bean == null) + return new String[0]; + + Method[] methods = bean.getClass().getMethods(); + TreeSet ts = new TreeSet(); + + for (int i = 0; i < methods.length; ++i) { + Method method = methods[i]; + String methodName = method.getName(); + if ((methodName.startsWith("get")) + && (method.getParameterTypes().length == 0) + && (method.getModifiers() == 1) + && (!methodName.endsWith("IsNull"))) { + + String attrName = + methodName.substring(3, 4).toLowerCase() + + methodName.substring(4); + ts.add(attrName); + } + methodName = null; + method = null; + } + + String[] names = new String[ts.size()]; + ts.toArray(names); + methods = null; + ts = null; + + return names; + + }; + + /** + * <p>Uses a little reflection action to return an object property from a bean</p> + * @param bean source bean holding the property + * @param propName name of the target property + * @return the target property or a null value + */ + public static Object getProperty(Object bean, String propName) { + + if (bean == null) + return null; + + Object prop = null; + Class[] paramTypes = new Class[0]; + Method isNullMethod = null; + boolean isNullValue = false; + String methodName = + "get" + + propName.substring(0, 1).toUpperCase() + + propName.substring(1); + + String isNullMethodName = methodName + "IsNull"; + Object[] paramValues = new Object[0]; + + try { + isNullMethod = + bean.getClass().getMethod(isNullMethodName, paramTypes); + Boolean isNull = (Boolean) isNullMethod.invoke(bean, paramValues); + if (isNull.booleanValue()) + return null; + } catch (IllegalAccessException e) { + } catch (InvocationTargetException e) { + } catch (NoSuchMethodException e) { + } + + try { + Method method = bean.getClass().getMethod(methodName, paramTypes); + + method.setAccessible(true); + prop = method.invoke(bean, paramValues); + + paramValues = null; + method = null; + + } catch (NoSuchMethodException je) { + je.printStackTrace(); + } catch (IllegalAccessException je) { + je.printStackTrace(); + } catch (InvocationTargetException je) { + je.printStackTrace(); + } + + paramTypes = null; + methodName = null; + + return prop; + } + + /** + * <p>Sets a simple property on a bean using the reflection API. This will attempt to normalize + * the data types if the propValue is not the same type as in the bean</p> + * @param bean target bean + * @param propName property name on the target bean + * @param propValue source property value + */ + public static void setProperty( + Object bean, + String propName, + Object propValue) { + + setProperty(bean, propName, propValue, null); + + } + + /** + * <p>Sets a property on a bean. The data type of the propValue will be normalize to + * the target bean and the pattern is used in that decoding</p> + * @param bean the target bean + * @param propName name of the target property + * @param propValue source value of the property + * @param pattern used to convert data types between the propValue and the bean properties actual type. + */ + public static void setProperty( + Object bean, + String propName, + Object propValue, + String pattern) { + + if (bean == null) + return; + + Class[] paramTypes = new Class[0]; + String methodName = null; + + try { + + Method method = null; + int tries = 0; //retry counter + + next : do { + tries++; //increment retry counter + methodName = + "get" + + propName.substring(0, 1).toUpperCase() + + propName.substring(1); + try { + method = bean.getClass().getMethod(methodName, paramTypes); + } catch (Exception e) { + } + + if ((propValue == null) && (method == null)) + return; // must have a getter + else if ((propValue == null) && (method != null)) { + if (method.getReturnType().isPrimitive()) { + // null value for a primitive type is not possible + propName = propName + "IsNull"; + // check for a rustts invented null state + propValue = new Boolean(true); + continue next; //try again + } else // null assignment for object type is valid + break next; //exit for loop + } + + } while (tries < 2); //iterations + + paramTypes = new Class[1]; + + // We now should succeed in every case except when setting + // an object data type to null where there is no getter available + + paramTypes[0] = + (method == null) + ? propValue.getClass() + : method.getReturnType(); + + methodName = + "set" + + propName.substring(0, 1).toUpperCase() + + propName.substring(1); + //System.out.println(methodName); + try { + method = bean.getClass().getMethod(methodName, paramTypes); + } catch (Exception e) { + //no getter found, no setter with the same type as the incoming property value + //look for a setter with a signature matching an implemented interface of the property value + Class[] interfaces = propValue.getClass().getInterfaces(); + next : for (int i = 0; i < interfaces.length; ++i) { + try { + paramTypes[0] = interfaces[i]; + method = + bean.getClass().getMethod(methodName, paramTypes); + } catch (Exception je) { + continue next; + } + break; + } + } + + Object[] paramValues = + { decodeSimpleProperty(propValue, paramTypes[0], pattern)}; + + if (method != null) { + method.setAccessible(true); + method.invoke(bean, paramValues); + } + + paramValues = null; + + method = null; + + } catch (Exception je) { + je.printStackTrace(); + } + + paramTypes = null; + methodName = null; + + } + + /** + * <p>Copies the state of the source bean's properties into a Map collection</p> + * @param bean source bean + * @return target Map of bean properties + */ + public static Map describe(Object bean) { + + Map attrs = new HashMap(); + String[] propertyNames = getPropertyNames(bean); + + if (propertyNames != null) { + for (int i = 0; i < propertyNames.length; ++i) { + attrs.put( + propertyNames[i], + getProperty(bean, propertyNames[i])); + } + } + + propertyNames = null; + + return attrs; + } + +}
--------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]