Author: craigmcc
Date: Fri Apr 29 20:04:15 2005
New Revision: 165376

URL: http://svn.apache.org/viewcvs?rev=165376&view=rev
Log:
Correct property setting logic, per patch, and add unit test case.

PR: Bugzilla #34660
Submitted By:  Gary VanMatre <gvanmatre AT comcast.net>

Added:
    struts/shale/trunk/clay-plugin/src/test/org/apache/shale/clay/utils/
    
struts/shale/trunk/clay-plugin/src/test/org/apache/shale/clay/utils/PropUtilsTestCase.java
Modified:
    
struts/shale/trunk/clay-plugin/src/java/org/apache/shale/clay/component/chain/PropertyValueCommand.java
    
struts/shale/trunk/clay-plugin/src/java/org/apache/shale/clay/utils/PropUtils.java

Modified: 
struts/shale/trunk/clay-plugin/src/java/org/apache/shale/clay/component/chain/PropertyValueCommand.java
URL: 
http://svn.apache.org/viewcvs/struts/shale/trunk/clay-plugin/src/java/org/apache/shale/clay/component/chain/PropertyValueCommand.java?rev=165376&r1=165375&r2=165376&view=diff
==============================================================================
--- 
struts/shale/trunk/clay-plugin/src/java/org/apache/shale/clay/component/chain/PropertyValueCommand.java
 (original)
+++ 
struts/shale/trunk/clay-plugin/src/java/org/apache/shale/clay/component/chain/PropertyValueCommand.java
 Fri Apr 29 20:04:15 2005
@@ -23,6 +23,7 @@
 import javax.faces.el.ValueBinding;
 
 import org.apache.commons.beanutils.BeanUtils;
+import org.apache.commons.beanutils.PropertyUtils;
 import org.apache.commons.chain.Command;
 import org.apache.commons.chain.Context;
 import org.apache.commons.logging.Log;
@@ -99,13 +100,7 @@
                 
             }
         } else {
-            try {
-                BeanUtils.setProperty(child, attributeBean.getName(),
-                        attributeBean.getValue());
-            } catch (Exception e) {
-                PropUtils.setProperty(child, attributeBean.getName(),
-                        attributeBean.getValue(), null);
-            }
+            PropUtils.setProperty(child, attributeBean.getName(), 
attributeBean.getValue());
         }
         
         return isFinal;

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=165376&r1=165375&r2=165376&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 20:04:15 2005
@@ -27,13 +27,18 @@
 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;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.shale.clay.component.chain.PropertyValueCommand;
 
 public class PropUtils {
     
+    private static Log log;
+    static {
+        log = LogFactory.getLog(PropUtils.class);
+    }
+    
     /**
      * <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.
@@ -131,7 +136,7 @@
             try {
                 lfmtValue = lFormat.format(lArgs);
             } catch (Exception je) {
-                je.printStackTrace();
+                log.error(je);
             }
         } else {
             lfmtValue = source.toString();
@@ -184,7 +189,7 @@
                 source instanceof String) { // decoding the value of a string
             
             if (((String) source).length() == 0)
-                return null; // empty string reutrn null
+                return null; // empty string returns null
             
             if ((targetType == java.lang.Boolean.TYPE)
             || (targetType == java.lang.Boolean.class)) {
@@ -261,8 +266,8 @@
             for (int i = 0; i < numberPatterns.length; i++) {
                 try {
                     numericObj = (Number) lFormat.parseObject((String) source);
-                } catch (ParseException je) {
-                    //je.printStackTrace();
+                } catch (Exception je) {
+                    je.printStackTrace();
                 }
                 
                 if (numericObj != null)
@@ -344,102 +349,7 @@
         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
@@ -465,124 +375,92 @@
      * @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) {
-        
+    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()
+        String[] methodNames = new String[2];
+
+        //look for the getter to find the correct actual parameter type
+        if (propName.startsWith("is"))
+            methodNames[0] = propName;
+        else {
+            methodNames[0] = "get" + propName.substring(0, 1).toUpperCase()
+                    + propName.substring(1);
+            methodNames[1] = "is" + propName.substring(0, 1).toUpperCase()
                     + propName.substring(1);
-            //System.out.println(methodName);
+        }
+
+        //try to make a guess  
+        Method method = null;
+        next: for (int i = 0; i < methodNames.length; i++) {
+            if (methodNames[i] == null)
+                break;
+
             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;
+                method = bean.getClass().getMethod(methodNames[i], paramTypes);
+                break next;
+            } catch (SecurityException e) {
+                continue next;
+            } catch (NoSuchMethodException e) {
+                continue next;
+            }
+
+        }
+
+        paramTypes = new Class[1];
+        paramTypes[0] = (method == null) ? propValue.getClass() : method
+                .getReturnType();
+        
+        String setterMethodName = null;
+        if (propName.startsWith("is")) {
+            setterMethodName = "set" + propName.substring(2, 3).toUpperCase()
+                    + propName.substring(3);
+
+        } else {
+            setterMethodName = "set" + propName.substring(0, 1).toUpperCase()
+                    + propName.substring(1);
+        }  
+        method = null;
+        try {
+            method = bean.getClass().getMethod(setterMethodName, 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(setterMethodName,
+                            paramTypes);
+                } catch (Exception je) {
+                    continue next;
                 }
+                break;
             }
+        }
+        
+        if (method != null) {
+            // convert the source data type to the target type
+            Object[] paramValues = { decodeSimpleProperty(propValue, 
paramTypes[0],
+                    pattern) };
+            method.setAccessible(true);
             
-            Object[] paramValues =
-            { decodeSimpleProperty(propValue, paramTypes[0], pattern)};
-            
-            if (method != null) {
-                method.setAccessible(true);
+            try {
                 method.invoke(bean, paramValues);
+            } catch (IllegalArgumentException e) {
+                throw new RuntimeException(e);
+            } catch (IllegalAccessException e) {
+                throw new RuntimeException(e);
+            } catch (InvocationTargetException e) {
+                throw new RuntimeException(e);
             }
-            
-            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;
-    }
-    
 }

Added: 
struts/shale/trunk/clay-plugin/src/test/org/apache/shale/clay/utils/PropUtilsTestCase.java
URL: 
http://svn.apache.org/viewcvs/struts/shale/trunk/clay-plugin/src/test/org/apache/shale/clay/utils/PropUtilsTestCase.java?rev=165376&view=auto
==============================================================================
--- 
struts/shale/trunk/clay-plugin/src/test/org/apache/shale/clay/utils/PropUtilsTestCase.java
 (added)
+++ 
struts/shale/trunk/clay-plugin/src/test/org/apache/shale/clay/utils/PropUtilsTestCase.java
 Fri Apr 29 20:04:15 2005
@@ -0,0 +1,161 @@
+/*
+ * Copyright 2004-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.
+ */
+
+package org.apache.shale.clay.utils;
+
+import junit.framework.TestCase;
+
+/**
+ * <p>
+ * Tests the capabilities of the [EMAIL PROTECTED] 
org.apache.shale.clay.utils.PropUtils}
+ * </>
+ */
+public class PropUtilsTestCase extends TestCase {
+
+    private class MockBean {
+        public boolean isEscape() {
+            return isEscape;
+        }
+
+        public void setEscape(boolean isEscape) {
+            this.isEscape = isEscape;
+        }
+
+        public boolean isGlobal() {
+            return isGlobal;
+        }
+
+        public void setGlobal(boolean isGlobal) {
+            this.isGlobal = isGlobal;
+        }
+
+        public double getMaximumDouble() {
+            return maximumDouble;
+        }
+
+        public void setMaximumDouble(double maximumDouble) {
+            this.maximumDouble = maximumDouble;
+        }
+
+        public int getMaximumInt() {
+            return maximumInt;
+        }
+
+        public void setMaximumInt(int maximumInt) {
+            this.maximumInt = maximumInt;
+        }
+
+        public String getValue() {
+            return value;
+        }
+
+        public void setValue(String value) {
+            this.value = value;
+        }
+
+        private boolean isGlobal = false;
+
+        private boolean isEscape = false;
+
+        private String value = null;
+
+        private int maximumInt = 0;
+
+        private double maximumDouble = 0;
+
+    }
+
+    /**
+     * <p>Tests setting boolean properties from a String
+     * with and without a "is" prefix</p>
+     */
+    public void testBoolean() {
+        MockBean bean = new MockBean();
+
+        PropUtils.setProperty(bean, "isGlobal", "true");
+        assertTrue("isGlobal equals true", bean.isGlobal() == true);
+
+        PropUtils.setProperty(bean, "global", "false");
+        assertTrue("isGlobal equals false", bean.isGlobal() == false);
+
+        PropUtils.setProperty(bean, "isEscape", "true");
+        assertTrue("isEscape equals true", bean.isEscape() == true);
+
+        PropUtils.setProperty(bean, "escape", "false");
+        assertTrue("isEscape equals false", bean.isEscape() == false);
+
+    }
+
+    /**
+     * <p>Tests setting a int property from a String</p>
+     */
+    public void testInteger() {
+        MockBean bean = new MockBean();
+
+        PropUtils.setProperty(bean, "maximumInt", "10");
+        assertTrue("maximumInt equals 10", bean.getMaximumInt() == 10);
+
+        PropUtils.setProperty(bean, "maximumInt", "0");
+        assertTrue("maximumInt equals 0", bean.getMaximumInt() == 0);
+
+        PropUtils.setProperty(bean, "maximumInt", "$999.10");
+        assertTrue("maximumInt equals 999", bean.getMaximumInt() == 999);
+
+        PropUtils.setProperty(bean, "maximumInt",
+                
"9999999999999999999999999999999999999999999999999.9999999999");
+        assertTrue("maximumInt equals Integer.MAX_VALUE",
+                bean.getMaximumInt() == Integer.MAX_VALUE);
+
+    }
+
+    /**
+     * <p>Tests setting a int property from a String</p>
+     */
+    public void testDouble() {
+        MockBean bean = new MockBean();
+
+        PropUtils.setProperty(bean, "maximumDouble", "10");
+        assertTrue("maximumDouble equals 10", bean.getMaximumDouble() == 10);
+
+        PropUtils.setProperty(bean, "maximumDouble", "$999.10", "$###.00");
+        assertTrue("maximumDouble equals $999.10",
+                bean.getMaximumDouble() == 999.10);
+
+        
+        PropUtils.setProperty(bean, "maximumDouble", ".00001", ".#####");
+        assertTrue("maximumDouble equals .00001",
+                bean.getMaximumDouble() == .00001);
+       
+        PropUtils
+                .setProperty(bean, "maximumDouble", "999,999.99", 
"###,###.##");
+        assertTrue("maximumDouble equals 999,999.99,",
+                bean.getMaximumDouble() == 999999.99);
+
+    }
+    
+    /**
+     * <p>Tests setting a String property from a String</p>
+     */
+    public void testString() {
+        MockBean bean = new MockBean();
+
+        PropUtils.setProperty(bean, "value", "#{managed-bean-name.value}");
+        assertTrue("value equals \"#{managed-bean-name.value}\"", 
bean.getValue().equals("#{managed-bean-name.value}"));
+
+        
+    }
+
+}
\ No newline at end of file



---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to