Anonymous avatar Anonymous committed 79acd6e

Changing type conversion errors to be set into a Map in the ActionContext and adding a ConversionErrorInterceptor to set the conversion errors into the field errors.

git-svn-id: http://svn.opensymphony.com/svn/xwork/trunk@136 e221344d-f017-0410-9bd5-d282ab1896d7

Comments (0)

Files changed (7)

src/java/com/opensymphony/xwork/ActionContext.java

 
 import com.opensymphony.xwork.util.OgnlValueStack;
 
+import java.util.HashMap;
 import java.util.Locale;
 import java.util.Map;
 
     public static final String LOCALE = "com.opensymphony.xwork.ActionContext.locale";
     public static final String TYPE_CONVERTER = "com.opensymphony.xwork.ActionContext.typeConverter";
     public static final String ACTION_INVOCATION = "com.opensymphony.xwork.ActionContext.actionInvocation";
+    public static final String CONVERSION_ERRORS = "com.opensymphony.xwork.ActionContext.conversionErrors";
 
     //~ Instance fields ////////////////////////////////////////////////////////
 
         return context;
     }
 
+    public void setConversionErrors(Map conversionErrors) {
+        put(CONVERSION_ERRORS, conversionErrors);
+    }
+
+    public Map getConversionErrors() {
+        Map errors = (Map) get(CONVERSION_ERRORS);
+
+        if (errors == null) {
+            errors = new HashMap();
+            setConversionErrors(errors);
+        }
+
+        return errors;
+    }
+
     /**
      * Sets the Locale for the current request
      * @param locale

src/java/com/opensymphony/xwork/interceptor/ChainingInterceptor.java

  */
 package com.opensymphony.xwork.interceptor;
 
-import com.opensymphony.xwork.ActionContext;
 import com.opensymphony.xwork.ActionInvocation;
 import com.opensymphony.xwork.util.CompoundRoot;
 import com.opensymphony.xwork.util.OgnlUtil;
 import com.opensymphony.xwork.util.OgnlValueStack;
 
+import java.util.ArrayList;
+import java.util.Collections;
 import java.util.Iterator;
 import java.util.List;
-import java.util.Collections;
-import java.util.ArrayList;
 
 
 /**
     protected void before(ActionInvocation invocation) throws Exception {
         OgnlValueStack stack = invocation.getStack();
         CompoundRoot root = stack.getRoot();
+
         if (root.size() > 1) {
             List list = new ArrayList(root);
             list.remove(0);
             Collections.reverse(list);
+
             Iterator iterator = list.iterator();
 
             while (iterator.hasNext()) {

src/java/com/opensymphony/xwork/interceptor/ConversionErrorInterceptor.java

+/*
+ * Copyright (c) 2002-2003 by OpenSymphony
+ * All rights reserved.
+ */
+package com.opensymphony.xwork.interceptor;
+
+import com.opensymphony.xwork.ActionContext;
+import com.opensymphony.xwork.ActionInvocation;
+import com.opensymphony.xwork.util.OgnlValueStack;
+import com.opensymphony.xwork.util.XWorkConverter;
+
+import java.util.Iterator;
+import java.util.Map;
+
+
+/**
+ * ConversionErrorInterceptor adds conversion errors from the ActionContext to the Action's field errors
+ * @author Jason Carreira
+ * Date: Nov 27, 2003 3:57:06 PM
+ */
+public class ConversionErrorInterceptor extends AroundInterceptor {
+    //~ Methods ////////////////////////////////////////////////////////////////
+
+    protected void after(ActionInvocation dispatcher, String result) throws Exception {
+    }
+
+    protected void before(ActionInvocation invocation) throws Exception {
+        ActionContext invocationContext = invocation.getInvocationContext();
+        Map conversionErrors = invocationContext.getConversionErrors();
+        OgnlValueStack stack = invocationContext.getValueStack();
+
+        for (Iterator iterator = conversionErrors.entrySet().iterator();
+                iterator.hasNext();) {
+            Map.Entry entry = (Map.Entry) iterator.next();
+            String propertyName = (String) entry.getKey();
+            Object value = entry.getValue();
+
+            if (shouldAddError(propertyName, value)) {
+                String message = XWorkConverter.getConversionErrorMessage(propertyName, stack);
+                String addFieldErrorExpression = "addFieldError('" + propertyName + "','" + message + "')";
+                stack.findValue(addFieldErrorExpression);
+            }
+        }
+    }
+
+    protected boolean shouldAddError(String propertyName, Object value) {
+        return true;
+    }
+}

src/java/com/opensymphony/xwork/util/XWorkConverter.java

 package com.opensymphony.xwork.util;
 
 import com.opensymphony.util.FileManager;
+
 import com.opensymphony.xwork.ActionContext;
 
 import ognl.*;
 
     private static XWorkConverter instance;
     private static final Log LOG = LogFactory.getLog(XWorkConverter.class);
-
     public static final String REPORT_CONVERSION_ERRORS = "report.conversion.errors";
     public static final String CONVERSION_PROPERTY_FULLNAME = "conversion.property.fullName";
 
 
     //~ Methods ////////////////////////////////////////////////////////////////
 
+    public static String getConversionErrorMessage(String propertyName, OgnlValueStack stack) {
+        String defaultMessage = "Invalid field value for field \"" + propertyName + "\".";
+        String getTextExpression = "getText('invalid.fieldvalue." + propertyName + "','" + defaultMessage + "')";
+        String message = (String) stack.findValue(getTextExpression);
+
+        if (message == null) {
+            message = defaultMessage;
+        }
+
+        return message;
+    }
+
     public static XWorkConverter getInstance() {
         if (instance == null) {
             instance = new XWorkConverter();
             if ((target instanceof CompoundRoot) && (context != null)) {
                 OgnlContext ognlContext = (OgnlContext) context;
                 Evaluation eval = ognlContext.getCurrentEvaluation();
+
                 if (eval == null) {
                     eval = ognlContext.getLastEvaluation();
                 }
 
-                if (eval != null && eval.getLastChild() != null) {
+                if ((eval != null) && (eval.getLastChild() != null)) {
                     // since we changed what the source was (tricked Ognl essentially)
-                    if (eval.getLastChild().getLastChild() != null
-                            && eval.getLastChild().getLastChild().getSource() != null
-                            && eval.getLastChild().getLastChild().getSource().getClass() != CompoundRoot.class) {
+                    if ((eval.getLastChild().getLastChild() != null) && (eval.getLastChild().getLastChild().getSource() != null) && (eval.getLastChild().getLastChild().getSource().getClass() != CompoundRoot.class)) {
                         clazz = eval.getLastChild().getLastChild().getSource().getClass();
                     } else {
                         clazz = eval.getLastChild().getSource().getClass();
 
                     if (mapping == null) {
                         mapping = buildConverterMapping(clazz);
-
                     } else {
                         mapping = conditionalReload(clazz, mapping);
                     }
         }
 
         if (tc == null) {
-            if (toClass.equals(String.class) && value != null && !(value.getClass().equals(String.class) || value.getClass().equals(String[].class))) {
+            if (toClass.equals(String.class) && (value != null) && !(value.getClass().equals(String.class) || value.getClass().equals(String[].class))) {
                 // when converting to a string, use the source target's class's converter
                 tc = lookup(value.getClass());
             } else {
         }
     }
 
+    public TypeConverter lookup(String className) {
+        TypeConverter result = (TypeConverter) defaultMappings.get(className);
+
+        //Looks for super classes
+        if (result == null) {
+            Class clazz = null;
+
+            try {
+                clazz = Thread.currentThread().getContextClassLoader().loadClass(className);
+            } catch (ClassNotFoundException cnfe) {
+            }
+
+            result = lookupSuper(clazz);
+
+            if (result != null) {
+                //Register now, the next lookup will be faster
+                registerConverter(className, result);
+            }
+        }
+
+        return result;
+    }
+
+    public TypeConverter lookup(Class clazz) {
+        return lookup(clazz.getName());
+    }
+
+    public void registerConverter(String className, TypeConverter converter) {
+        defaultMappings.put(className, converter);
+    }
+
+    protected void handleConversionException(Map context, String property, Object value, Object object) {
+        if ((context.get(REPORT_CONVERSION_ERRORS) == Boolean.TRUE)) {
+            String realProperty = property;
+            String fullName = (String) context.get(CONVERSION_PROPERTY_FULLNAME);
+
+            if (fullName != null) {
+                realProperty = fullName;
+            }
+
+            Map conversionErrors = (Map) context.get(ActionContext.CONVERSION_ERRORS);
+
+            if (conversionErrors == null) {
+                conversionErrors = new HashMap();
+                context.put(ActionContext.CONVERSION_ERRORS, conversionErrors);
+            }
+
+            conversionErrors.put(realProperty, value);
+        }
+    }
+
     private Object acceptableErrorValue(Class toClass) {
         if (!toClass.isPrimitive()) {
             return null;
         return null;
     }
 
+    private String buildConverterFilename(Class clazz) {
+        String className = clazz.getName();
+        String resource = className.replace('.', '/') + "-conversion.properties";
+
+        return resource;
+    }
+
     private Map buildConverterMapping(Class clazz) throws Exception {
         Map mapping = new HashMap();
 
         String resource = buildConverterFilename(clazz);
-        InputStream is = FileManager.loadFile(resource,clazz);
+        InputStream is = FileManager.loadFile(resource, clazz);
 
         if (is != null) {
             Properties props = new Properties();
             mapping.putAll(props);
 
             for (Iterator iterator = mapping.entrySet().iterator();
-                 iterator.hasNext();) {
+                    iterator.hasNext();) {
                 Map.Entry entry = (Map.Entry) iterator.next();
                 entry.setValue(createTypeConverter((String) entry.getValue()));
             }
+
             mappings.put(clazz, mapping);
         } else {
             noMapping.add(clazz);
         }
-        return mapping;
-    }
 
-    private String buildConverterFilename(Class clazz) {
-        String className = clazz.getName();
-        String resource = className.replace('.', '/') + "-conversion.properties";
-        return resource;
+        return mapping;
     }
 
     private Map conditionalReload(Class clazz, Map oldValues) throws Exception {
         Map mapping = oldValues;
+
         if (FileManager.isReloadingConfigs()) {
             if (FileManager.fileNeedsReloading(buildConverterFilename(clazz))) {
                 mapping = buildConverterMapping(clazz);
             }
         }
+
         return mapping;
     }
 
-    public TypeConverter lookup(String className) {
-        TypeConverter result = (TypeConverter) defaultMappings.get(className);
+    private TypeConverter createTypeConverter(String className) throws Exception, InstantiationException {
+        Class conversionClass = Thread.currentThread().getContextClassLoader().loadClass(className);
 
-        //Looks for super classes
-        if (result == null) {
-            Class clazz = null;
-            try {
-                clazz = Thread.currentThread().getContextClassLoader().loadClass(className);
-            } catch (ClassNotFoundException cnfe) {
-            }
+        return (TypeConverter) conversionClass.newInstance();
+    }
 
-            result = lookupSuper(clazz);
+    private void loadConversionProps(String propsName) throws Exception {
+        InputStream is = Thread.currentThread().getContextClassLoader().getResourceAsStream(propsName);
+        Properties props = new Properties();
+        props.load(is);
 
-            if (result != null) {
-                //Register now, the next lookup will be faster
-                registerConverter(className, result);
+        for (Iterator iterator = props.entrySet().iterator();
+                iterator.hasNext();) {
+            Map.Entry entry = (Map.Entry) iterator.next();
+            String key = (String) entry.getKey();
+
+            try {
+                defaultMappings.put(key, createTypeConverter((String) entry.getValue()));
+            } catch (Exception e) {
+                LOG.error("Conversion registration error", e);
             }
         }
-        return result;
     }
 
     private TypeConverter lookupSuper(Class clazz) {
-
         TypeConverter result = null;
 
         if (clazz != null) {
             if (result == null) {
                 // Looks for direct interfaces (depth = 1 )
                 Class[] interfaces = clazz.getInterfaces();
+
                 for (int i = 0; i < interfaces.length; i++) {
                     if (defaultMappings.containsKey(interfaces[i].getName())) {
                         result = (TypeConverter) defaultMappings.get(interfaces[i].getName());
                     }
+
                     break;
                 }
 
                     result = lookupSuper(clazz.getSuperclass());
                 }
             }
-
         }
 
         return result;
     }
-
-    public TypeConverter lookup(Class clazz) {
-        return lookup(clazz.getName());
-    }
-
-    public void registerConverter(String className, TypeConverter converter) {
-        defaultMappings.put(className, converter);
-    }
-
-    protected void handleConversionException(Map context, String property, Object value, Object object) {
-        if (context.get(REPORT_CONVERSION_ERRORS) == Boolean.TRUE) {
-            String realProperty = property;
-            String fullName = (String) context.get(CONVERSION_PROPERTY_FULLNAME);
-            if (fullName != null) {
-                realProperty = fullName;
-            }
-
-            String defaultMessage = "Invalid field value for field \"" + realProperty + "\".";
-            OgnlValueStack stack = (OgnlValueStack) context.get(ActionContext.VALUE_STACK);
-
-            String getTextExpression = "getText('invalid.fieldvalue." + realProperty + "','" + defaultMessage + "')";
-            String message = (String) stack.findValue(getTextExpression);
-
-            if (message == null) {
-                message = defaultMessage;
-            }
-
-            String addFieldErrorExpression = "addFieldError('" + realProperty + "','" + message + "')";
-            stack.findValue(addFieldErrorExpression);
-        }
-    }
-
-    private TypeConverter createTypeConverter(String className) throws Exception, InstantiationException {
-        Class conversionClass = Thread.currentThread().getContextClassLoader().loadClass(className);
-
-        return (TypeConverter) conversionClass.newInstance();
-    }
-
-    private void loadConversionProps(String propsName) throws Exception {
-        InputStream is = Thread.currentThread().getContextClassLoader().getResourceAsStream(propsName);
-        Properties props = new Properties();
-        props.load(is);
-
-        for (Iterator iterator = props.entrySet().iterator();
-             iterator.hasNext();) {
-            Map.Entry entry = (Map.Entry) iterator.next();
-            String key = (String) entry.getKey();
-
-            try {
-                defaultMappings.put(key, createTypeConverter((String) entry.getValue()));
-            } catch (Exception e) {
-                LOG.error("Conversion registration error", e);
-            }
-        }
-    }
 }

src/test/com/opensymphony/xwork/interceptor/ConversionErrorInterceptorTest.java

+/*
+ * Copyright (c) 2002-2003 by OpenSymphony
+ * All rights reserved.
+ */
+package com.opensymphony.xwork.interceptor;
+
+import com.mockobjects.dynamic.Mock;
+
+import com.opensymphony.xwork.Action;
+import com.opensymphony.xwork.ActionContext;
+import com.opensymphony.xwork.ActionInvocation;
+import com.opensymphony.xwork.SimpleAction;
+import com.opensymphony.xwork.util.OgnlValueStack;
+
+import junit.framework.TestCase;
+
+import java.util.HashMap;
+import java.util.Map;
+
+
+/**
+ * ConversionErrorInterceptorTest
+ * @author Jason Carreira
+ * Date: Nov 27, 2003 4:48:09 PM
+ */
+public class ConversionErrorInterceptorTest extends TestCase {
+    //~ Instance fields ////////////////////////////////////////////////////////
+
+    protected ActionContext context;
+    protected ActionInvocation invocation;
+    protected ConversionErrorInterceptor interceptor;
+    protected Map conversionErrors;
+    protected Mock mockInvocation;
+    protected OgnlValueStack stack;
+
+    //~ Methods ////////////////////////////////////////////////////////////////
+
+    public void testFieldErrorAdded() throws Exception {
+        conversionErrors.put("foo", new Long(123));
+
+        SimpleAction action = new SimpleAction();
+        stack.push(action);
+        assertNull(action.getFieldErrors().get("foo"));
+        interceptor.intercept(invocation);
+        assertTrue(action.hasFieldErrors());
+        assertNotNull(action.getFieldErrors().get("foo"));
+    }
+
+    protected void setUp() throws Exception {
+        super.setUp();
+        interceptor = new ConversionErrorInterceptor();
+        mockInvocation = new Mock(ActionInvocation.class);
+        invocation = (ActionInvocation) mockInvocation.proxy();
+        stack = new OgnlValueStack();
+        context = new ActionContext(stack.getContext());
+        conversionErrors = new HashMap();
+        context.setConversionErrors(conversionErrors);
+        mockInvocation.matchAndReturn("getInvocationContext", context);
+        mockInvocation.expectAndReturn("invoke", Action.SUCCESS);
+    }
+}

src/test/com/opensymphony/xwork/util/OgnlValueStackTest.java

  */
 package com.opensymphony.xwork.util;
 
+import com.opensymphony.xwork.ActionContext;
+import com.opensymphony.xwork.SimpleAction;
+
 import junit.framework.TestCase;
 
 import java.io.*;
+
 import java.math.BigDecimal;
+
 import java.util.HashMap;
 import java.util.Map;
 
-import com.opensymphony.xwork.SimpleAction;
-
 
 /**
  *
         Dog dog = new Dog();
         dog.setAge(12);
         dog.setName("Rover");
-        dog.setChildAges(new int[]{1, 2});
+        dog.setChildAges(new int[] {1, 2});
 
         vs.push(dog);
         assertEquals("1, 2", vs.findValue("childAges", String.class));
         assertEquals("Rover", vs.findValue("name", String.class));
     }
 
+    public void testCallMethodThatThrowsExceptionTwice() {
+        SimpleAction action = new SimpleAction();
+        OgnlValueStack stack = new OgnlValueStack();
+        stack.push(action);
+
+        action.setThrowException(true);
+        assertNull(stack.findValue("exceptionMethod1()"));
+        action.setThrowException(false);
+        assertEquals("OK", stack.findValue("exceptionMethod()"));
+    }
+
+    public void testCallMethodWithNullArg() {
+        SimpleAction action = new SimpleAction();
+        OgnlValueStack stack = new OgnlValueStack();
+        stack.push(action);
+
+        stack.findValue("setName(blah)");
+        assertNull(action.getName());
+
+        action.setBlah("blah");
+        stack.findValue("setName(blah)");
+        assertEquals("blah", action.getName());
+    }
+
     public void testDeepProperties() {
         OgnlValueStack vs = new OgnlValueStack();
 
         Dog dog = new Dog();
         dog.setAge(12);
         dog.setName("Rover");
-        dog.setChildAges(new int[]{1, 2});
+        dog.setChildAges(new int[] {1, 2});
         dog.setHates(cat);
 
         vs.push(dog);
         assertEquals("blah:123", vs.findValue("bar", String.class));
     }
 
+    public void testGetBarAsString() {
+        Foo foo = new Foo();
+        Bar bar = new Bar();
+        bar.setTitle("bar");
+        bar.setSomethingElse(123);
+        foo.setBar(bar);
+
+        OgnlValueStack vs = new OgnlValueStack();
+        vs.push(foo);
+
+        String output = (String) vs.findValue("bar", String.class);
+        assertEquals("bar:123", output);
+    }
+
+    public void testGetComplexBarAsString() {
+        // children foo->foo->foo
+        Foo foo = new Foo();
+        Foo foo2 = new Foo();
+        foo.setChild(foo2);
+
+        Foo foo3 = new Foo();
+        foo2.setChild(foo3);
+
+        // relatives
+        Foo fooA = new Foo();
+        foo.setRelatives(new Foo[] {fooA});
+
+        Foo fooB = new Foo();
+        foo2.setRelatives(new Foo[] {fooB});
+
+        Foo fooC = new Foo();
+        foo3.setRelatives(new Foo[] {fooC});
+
+        // the bar
+        Bar bar = new Bar();
+        bar.setTitle("bar");
+        bar.setSomethingElse(123);
+
+        // now place the bar all over
+        foo.setBar(bar);
+        foo2.setBar(bar);
+        foo3.setBar(bar);
+        fooA.setBar(bar);
+        fooB.setBar(bar);
+        fooC.setBar(bar);
+
+        OgnlValueStack vs = new OgnlValueStack();
+        vs.push(foo);
+
+        vs.getContext().put("foo", foo);
+
+        assertEquals("bar:123", vs.findValue("#foo.bar", String.class));
+        assertEquals("bar:123", vs.findValue("bar", String.class));
+        assertEquals("bar:123", vs.findValue("child.bar", String.class));
+        assertEquals("bar:123", vs.findValue("child.child.bar", String.class));
+        assertEquals("bar:123", vs.findValue("relatives[0].bar", String.class));
+        assertEquals("bar:123", vs.findValue("child.relatives[0].bar", String.class));
+        assertEquals("bar:123", vs.findValue("child.child.relatives[0].bar", String.class));
+
+        vs.push(vs.findValue("child"));
+        assertEquals("bar:123", vs.findValue("bar", String.class));
+        assertEquals("bar:123", vs.findValue("child.bar", String.class));
+        assertEquals("bar:123", vs.findValue("relatives[0].bar", String.class));
+        assertEquals("bar:123", vs.findValue("child.relatives[0].bar", String.class));
+    }
+
+    public void testGetNullValue() {
+        Dog dog = new Dog();
+        OgnlValueStack stack = new OgnlValueStack();
+        stack.push(dog);
+        assertNull(stack.findValue("name"));
+    }
+
+    public void testMapEntriesAvailableByKey() {
+        Foo foo = new Foo();
+        String title = "a title";
+        foo.setTitle(title);
+
+        OgnlValueStack vs = new OgnlValueStack();
+        vs.push(foo);
+
+        Map map = new HashMap();
+        String a_key = "a";
+        String a_value = "A";
+        map.put(a_key, a_value);
+
+        String b_key = "b";
+        String b_value = "B";
+        map.put(b_key, b_value);
+
+        vs.push(map);
+
+        assertEquals(title, vs.findValue("title"));
+        assertEquals(a_value, vs.findValue(a_key));
+        assertEquals(b_value, vs.findValue(b_key));
+    }
+
     public void testMethodCalls() {
         OgnlValueStack vs = new OgnlValueStack();
 
 
         assertEquals("Jack", vs.findValue("name"));
         assertEquals("Rover", vs.findValue("[1].name"));
+
         //hates will be null
-        assertEquals(Boolean.TRUE,vs.findValue("nullSafeMethod(hates)"));
+        assertEquals(Boolean.TRUE, vs.findValue("nullSafeMethod(hates)"));
     }
 
-    public void testSerializable() throws IOException, ClassNotFoundException {
+    public void testNullEntry() {
         OgnlValueStack vs = new OgnlValueStack();
 
         Dog dog = new Dog();
-        dog.setAge(12);
         dog.setName("Rover");
 
         vs.push(dog);
         assertEquals("Rover", vs.findValue("name", String.class));
 
-        ByteArrayOutputStream baos = new ByteArrayOutputStream();
-        ObjectOutputStream oos = new ObjectOutputStream(baos);
-
-        oos.writeObject(vs);
-        oos.flush();
-
-        ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
-        ObjectInputStream ois = new ObjectInputStream(bais);
-
-        OgnlValueStack newVs = (OgnlValueStack) ois.readObject();
-        assertEquals("Rover", newVs.findValue("name", String.class));
+        vs.push(null);
+        assertEquals("Rover", vs.findValue("name", String.class));
     }
 
-    public void testSettingDogGender() {
-        OgnlValueStack vs = new OgnlValueStack();
-
+    public void testNullMethod() {
         Dog dog = new Dog();
-        vs.push(dog);
-
-        vs.setValue("male", "false");
-
-        assertEquals(false, dog.isMale());
+        OgnlValueStack stack = new OgnlValueStack();
+        stack.push(dog);
+        assertNull(stack.findValue("nullMethod()"));
+        assertNull(stack.findValue("@com.opensymphony.xwork.util.OgnlValueStackTest@staticNullMethod()"));
     }
 
-    public void testStatics() {
-        OgnlValueStack vs = new OgnlValueStack();
-
+    public void testPetSoarBug() {
         Cat cat = new Cat();
-        vs.push(cat);
-
-        Dog dog = new Dog();
-        dog.setAge(12);
-        dog.setName("Rover");
-        vs.push(dog);
+        cat.setFoo(new Foo());
 
-        assertEquals("Canine", vs.findValue("@vs@SCIENTIFIC_NAME"));
-        assertEquals("Canine", vs.findValue("@vs1@SCIENTIFIC_NAME"));
-        assertEquals("Feline", vs.findValue("@vs2@SCIENTIFIC_NAME"));
-        assertEquals(new Integer(BigDecimal.ROUND_HALF_DOWN), vs.findValue("@java.math.BigDecimal@ROUND_HALF_DOWN"));
-        assertNull(vs.findValue("@vs3@BLAH"));
-        assertNull(vs.findValue("@com.nothing.here.Nothing@BLAH"));
-    }
+        Bar bar = new Bar();
+        bar.setTitle("bar");
+        bar.setSomethingElse(123);
+        cat.getFoo().setBar(bar);
 
-    public void testTop() {
         OgnlValueStack vs = new OgnlValueStack();
+        vs.push(cat);
 
-        Dog dog1 = new Dog();
-        dog1.setAge(12);
-        dog1.setName("Rover");
+        assertEquals("bar:123", vs.findValue("foo.bar", String.class));
+    }
 
-        Dog dog2 = new Dog();
-        dog2.setAge(1);
-        dog2.setName("Jack");
-        vs.push(dog1);
-        vs.push(dog2);
+    public void testPrimitiveSettingWithInvalidValueAddsFieldError() {
+        SimpleAction action = new SimpleAction();
+        OgnlValueStack stack = new OgnlValueStack();
+        stack.getContext().put(XWorkConverter.REPORT_CONVERSION_ERRORS, Boolean.TRUE);
+        stack.push(action);
+        stack.setValue("bar", "3x");
 
-        assertEquals(dog2, vs.findValue("top"));
-        assertEquals("Jack", vs.findValue("top.name"));
+        Map conversionErrors = (Map) stack.getContext().get(ActionContext.CONVERSION_ERRORS);
+        assertTrue(conversionErrors.containsKey("bar"));
+        assertEquals(0, action.getBar());
     }
 
-    public void testTopNull() {
+    public void testSerializable() throws IOException, ClassNotFoundException {
         OgnlValueStack vs = new OgnlValueStack();
 
-        assertNull(vs.findValue("top"));
-    }
+        Dog dog = new Dog();
+        dog.setAge(12);
+        dog.setName("Rover");
 
-    public void testTwoDogs() {
-        OgnlValueStack vs = new OgnlValueStack();
+        vs.push(dog);
+        assertEquals("Rover", vs.findValue("name", String.class));
 
-        Dog dog1 = new Dog();
-        dog1.setAge(12);
-        dog1.setName("Rover");
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        ObjectOutputStream oos = new ObjectOutputStream(baos);
 
-        Dog dog2 = new Dog();
-        dog2.setAge(1);
-        dog2.setName("Jack");
-        vs.push(dog1);
-        vs.push(dog2);
+        oos.writeObject(vs);
+        oos.flush();
 
-        assertEquals("Jack", vs.findValue("name"));
-        assertEquals("Rover", vs.findValue("[1].name"));
+        ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
+        ObjectInputStream ois = new ObjectInputStream(bais);
 
-        assertEquals(dog2, vs.pop());
-        assertEquals("Rover", vs.findValue("name"));
+        OgnlValueStack newVs = (OgnlValueStack) ois.readObject();
+        assertEquals("Rover", newVs.findValue("name", String.class));
     }
 
-
-	public void testSetBarAsString() {
+    public void testSetBarAsString() {
         Foo foo = new Foo();
 
         OgnlValueStack vs = new OgnlValueStack();
         Foo foo = new Foo();
         Foo foo2 = new Foo();
         foo.setChild(foo2);
+
         Foo foo3 = new Foo();
         foo2.setChild(foo3);
 
         assertEquals(123, foo.getChild().getChild().getBar().getSomethingElse());
     }
 
-    public void testGetBarAsString() {
-        Foo foo = new Foo();
-        Bar bar = new Bar();
-        bar.setTitle("bar");
-        bar.setSomethingElse(123);
-        foo.setBar(bar);
-
+    public void testSettingDogGender() {
         OgnlValueStack vs = new OgnlValueStack();
-        vs.push(foo);
 
-        String output = (String) vs.findValue("bar", String.class);
-        assertEquals("bar:123", output);
-    }
-
-    public void testGetComplexBarAsString() {
-        // children foo->foo->foo
-        Foo foo = new Foo();
-        Foo foo2 = new Foo();
-        foo.setChild(foo2);
-        Foo foo3 = new Foo();
-        foo2.setChild(foo3);
-
-        // relatives
-        Foo fooA = new Foo();
-        foo.setRelatives(new Foo[]{fooA});
-        Foo fooB = new Foo();
-        foo2.setRelatives(new Foo[]{fooB});
-        Foo fooC = new Foo();
-        foo3.setRelatives(new Foo[]{fooC});
+        Dog dog = new Dog();
+        vs.push(dog);
 
-        // the bar
-        Bar bar = new Bar();
-        bar.setTitle("bar");
-        bar.setSomethingElse(123);
+        vs.setValue("male", "false");
 
-        // now place the bar all over
-        foo.setBar(bar);
-        foo2.setBar(bar);
-        foo3.setBar(bar);
-        fooA.setBar(bar);
-        fooB.setBar(bar);
-        fooC.setBar(bar);
+        assertEquals(false, dog.isMale());
+    }
 
+    public void testStatics() {
         OgnlValueStack vs = new OgnlValueStack();
-        vs.push(foo);
-
-        vs.getContext().put("foo", foo);
-
-        assertEquals("bar:123", vs.findValue("#foo.bar", String.class));
-        assertEquals("bar:123", vs.findValue("bar", String.class));
-        assertEquals("bar:123", vs.findValue("child.bar", String.class));
-        assertEquals("bar:123", vs.findValue("child.child.bar", String.class));
-        assertEquals("bar:123", vs.findValue("relatives[0].bar", String.class));
-        assertEquals("bar:123", vs.findValue("child.relatives[0].bar", String.class));
-        assertEquals("bar:123", vs.findValue("child.child.relatives[0].bar", String.class));
 
-        vs.push(vs.findValue("child"));
-        assertEquals("bar:123", vs.findValue("bar", String.class));
-        assertEquals("bar:123", vs.findValue("child.bar", String.class));
-        assertEquals("bar:123", vs.findValue("relatives[0].bar", String.class));
-        assertEquals("bar:123", vs.findValue("child.relatives[0].bar", String.class));
-    }
-
-    public void testPetSoarBug() {
         Cat cat = new Cat();
-        cat.setFoo(new Foo());
-        Bar bar = new Bar();
-        bar.setTitle("bar");
-        bar.setSomethingElse(123);
-        cat.getFoo().setBar(bar);
-
-        OgnlValueStack vs = new OgnlValueStack();
         vs.push(cat);
 
-        assertEquals("bar:123", vs.findValue("foo.bar", String.class));
-    }
-
-    public void testMapEntriesAvailableByKey() {
-        Foo foo = new Foo();
-        String title = "a title";
-        foo.setTitle(title);
-        OgnlValueStack vs = new OgnlValueStack();
-        vs.push(foo);
-
-        Map map = new HashMap();
-        String a_key = "a";
-        String a_value = "A";
-        map.put(a_key, a_value);
-        String b_key = "b";
-        String b_value = "B";
-        map.put(b_key, b_value);
-
-        vs.push(map);
-
-        assertEquals(title, vs.findValue("title"));
-        assertEquals(a_value, vs.findValue(a_key));
-        assertEquals(b_value, vs.findValue(b_key));
-    }
-
-    public void testNullEntry() {
-        OgnlValueStack vs = new OgnlValueStack();
-
         Dog dog = new Dog();
+        dog.setAge(12);
         dog.setName("Rover");
-
         vs.push(dog);
-        assertEquals("Rover", vs.findValue("name", String.class));
 
-        vs.push(null);
-        assertEquals("Rover", vs.findValue("name", String.class));
+        assertEquals("Canine", vs.findValue("@vs@SCIENTIFIC_NAME"));
+        assertEquals("Canine", vs.findValue("@vs1@SCIENTIFIC_NAME"));
+        assertEquals("Feline", vs.findValue("@vs2@SCIENTIFIC_NAME"));
+        assertEquals(new Integer(BigDecimal.ROUND_HALF_DOWN), vs.findValue("@java.math.BigDecimal@ROUND_HALF_DOWN"));
+        assertNull(vs.findValue("@vs3@BLAH"));
+        assertNull(vs.findValue("@com.nothing.here.Nothing@BLAH"));
     }
 
-    public void testPrimitiveSettingWithInvalidValueAddsFieldError() {
-        SimpleAction action = new SimpleAction();
-        OgnlValueStack stack = new OgnlValueStack();
-        stack.getContext().put(XWorkConverter.REPORT_CONVERSION_ERRORS,Boolean.TRUE);
-        stack.push(action);
-        stack.setValue("bar","3x");
+    public void testTop() {
+        OgnlValueStack vs = new OgnlValueStack();
 
-        assertTrue(action.getFieldErrors().containsKey("bar"));
-        assertEquals(0, action.getBar());
+        Dog dog1 = new Dog();
+        dog1.setAge(12);
+        dog1.setName("Rover");
+
+        Dog dog2 = new Dog();
+        dog2.setAge(1);
+        dog2.setName("Jack");
+        vs.push(dog1);
+        vs.push(dog2);
+
+        assertEquals(dog2, vs.findValue("top"));
+        assertEquals("Jack", vs.findValue("top.name"));
     }
 
-    public void testCallMethodThatThrowsExceptionTwice() {
-        SimpleAction action = new SimpleAction();
-        OgnlValueStack stack = new OgnlValueStack();
-        stack.push(action);
+    public void testTopNull() {
+        OgnlValueStack vs = new OgnlValueStack();
 
-        action.setThrowException(true);
-        assertNull(stack.findValue("exceptionMethod1()"));
-        action.setThrowException(false);
-        assertEquals("OK", stack.findValue("exceptionMethod()"));
+        assertNull(vs.findValue("top"));
     }
 
-    public void testCallMethodWithNullArg() {
-        SimpleAction action = new SimpleAction();
-        OgnlValueStack stack = new OgnlValueStack();
-        stack.push(action);
+    public void testTwoDogs() {
+        OgnlValueStack vs = new OgnlValueStack();
 
-        stack.findValue("setName(blah)");
-        assertNull(action.getName());
+        Dog dog1 = new Dog();
+        dog1.setAge(12);
+        dog1.setName("Rover");
 
-        action.setBlah("blah");
-        stack.findValue("setName(blah)");
-        assertEquals("blah", action.getName());
-    }
+        Dog dog2 = new Dog();
+        dog2.setAge(1);
+        dog2.setName("Jack");
+        vs.push(dog1);
+        vs.push(dog2);
 
-    public void testGetNullValue() {
-        Dog dog = new Dog();
-        OgnlValueStack stack = new OgnlValueStack();
-        stack.push(dog);
-        assertNull(stack.findValue("name"));
-    }
+        assertEquals("Jack", vs.findValue("name"));
+        assertEquals("Rover", vs.findValue("[1].name"));
 
-    public void testNullMethod() {
-        Dog dog = new Dog();
-        OgnlValueStack stack = new OgnlValueStack();
-        stack.push(dog);
-        assertNull(stack.findValue("nullMethod()"));
-        assertNull(stack.findValue("@com.opensymphony.xwork.util.OgnlValueStackTest@staticNullMethod()"));
+        assertEquals(dog2, vs.pop());
+        assertEquals("Rover", vs.findValue("name"));
     }
-
 }

src/test/com/opensymphony/xwork/util/XWorkConverterTest.java

 
 import ognl.Ognl;
 import ognl.OgnlException;
-import ognl.OgnlRuntime;
 
 import java.math.BigDecimal;
 import java.math.BigInteger;
         Map context = stack.getContext();
         context.put(XWorkConverter.REPORT_CONVERSION_ERRORS, Boolean.TRUE);
         context.put(XWorkConverter.CONVERSION_PROPERTY_FULLNAME, "bean.birth");
-        assertEquals("Conversion should have failed.", null, converter.convertValue(context, action.getBean(), null, "birth", new String[] {
-                    "invalid date"
-                }, Date.class));
+
+        String[] value = new String[] {"invalid date"};
+        assertEquals("Conversion should have failed.", null, converter.convertValue(context, action.getBean(), null, "birth", value, Date.class));
         stack.pop();
-        assertTrue(action.hasFieldErrors());
-        assertNotNull(action.getFieldErrors().get("bean.birth"));
-        assertEquals("Invalid field value for field \"bean.birth\".", ((List) action.getFieldErrors().get("bean.birth")).get(0));
+
+        Map conversionErrors = (Map) stack.getContext().get(ActionContext.CONVERSION_ERRORS);
+        assertNotNull(conversionErrors);
+        assertTrue(conversionErrors.size() == 1);
+        assertEquals(value, conversionErrors.get("bean.birth"));
     }
 
     public void testFieldErrorMessageAddedWhenConversionFails() {
 
         Map context = stack.getContext();
         context.put(XWorkConverter.REPORT_CONVERSION_ERRORS, Boolean.TRUE);
-        assertEquals("Conversion should have failed.", null, converter.convertValue(context, action, null, "date", new String[] {
-                    "invalid date"
-                }, Date.class));
+
+        String[] value = new String[] {"invalid date"};
+        assertEquals("Conversion should have failed.", null, converter.convertValue(context, action, null, "date", value, Date.class));
         stack.pop();
-        assertTrue(action.hasFieldErrors());
-        assertNotNull(action.getFieldErrors().get("date"));
-        assertEquals("Invalid field value for field \"date\".", ((List) action.getFieldErrors().get("date")).get(0));
+
+        Map conversionErrors = (Map) context.get(ActionContext.CONVERSION_ERRORS);
+        assertNotNull(conversionErrors);
+        assertEquals(1, conversionErrors.size());
+        assertNotNull(conversionErrors.get("date"));
+        assertEquals(value, conversionErrors.get("date"));
     }
 
     public void testFieldErrorMessageAddedWhenConversionFailsOnModelDriven() {
 
         Map context = stack.getContext();
         context.put(XWorkConverter.REPORT_CONVERSION_ERRORS, Boolean.TRUE);
-        assertEquals("Conversion should have failed.", null, converter.convertValue(context, action, null, "birth", new String[] {
-                    "invalid date"
-                }, Date.class));
+
+        String[] value = new String[] {"invalid date"};
+        assertEquals("Conversion should have failed.", null, converter.convertValue(context, action, null, "birth", value, Date.class));
         stack.pop();
         stack.pop();
-        assertTrue(action.hasFieldErrors());
-        assertNotNull(action.getFieldErrors().get("birth"));
-        assertEquals("Invalid date for birth.", ((List) action.getFieldErrors().get("birth")).get(0));
+
+        Map conversionErrors = (Map) context.get(ActionContext.CONVERSION_ERRORS);
+        assertNotNull(conversionErrors);
+        assertEquals(1, conversionErrors.size());
+        assertNotNull(conversionErrors.get("birth"));
+        assertEquals(value, conversionErrors.get("birth"));
+    }
+
+    public void testFindConversionErrorMessage() {
+        ModelDrivenAction action = new ModelDrivenAction();
+        OgnlValueStack stack = new OgnlValueStack();
+        stack.push(action);
+        stack.push(action.getModel());
+
+        String message = XWorkConverter.getConversionErrorMessage("birth", stack);
+        assertNotNull(message);
+        assertEquals("Invalid date for birth.", message);
+
+        message = XWorkConverter.getConversionErrorMessage("foo", stack);
+        assertNotNull(message);
+        assertEquals("Invalid field value for field \"foo\".", message);
     }
 
     public void testStringArrayToCollection() {
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.