You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@struts.apache.org by ts...@apache.org on 2007/11/07 05:00:21 UTC

svn commit: r592605 - in /struts/sandbox/trunk/struts2-juel-plugin/src: main/java/com/googlecode/struts2juel/ test/java/com/googlecode/struts2juel/

Author: tschneider
Date: Tue Nov  6 20:00:20 2007
New Revision: 592605

URL: http://svn.apache.org/viewvc?rev=592605&view=rev
Log:
added type conversion

Modified:
    struts/sandbox/trunk/struts2-juel-plugin/src/main/java/com/googlecode/struts2juel/CompoundRootELContext.java
    struts/sandbox/trunk/struts2-juel-plugin/src/main/java/com/googlecode/struts2juel/JuelReflectionProvider.java
    struts/sandbox/trunk/struts2-juel-plugin/src/main/java/com/googlecode/struts2juel/JuelValueStack.java
    struts/sandbox/trunk/struts2-juel-plugin/src/main/java/com/googlecode/struts2juel/JuelValueStackFactory.java
    struts/sandbox/trunk/struts2-juel-plugin/src/main/java/com/googlecode/struts2juel/PropertyValueExpression.java
    struts/sandbox/trunk/struts2-juel-plugin/src/test/java/com/googlecode/struts2juel/JuelTest.java

Modified: struts/sandbox/trunk/struts2-juel-plugin/src/main/java/com/googlecode/struts2juel/CompoundRootELContext.java
URL: http://svn.apache.org/viewvc/struts/sandbox/trunk/struts2-juel-plugin/src/main/java/com/googlecode/struts2juel/CompoundRootELContext.java?rev=592605&r1=592604&r2=592605&view=diff
==============================================================================
--- struts/sandbox/trunk/struts2-juel-plugin/src/main/java/com/googlecode/struts2juel/CompoundRootELContext.java (original)
+++ struts/sandbox/trunk/struts2-juel-plugin/src/main/java/com/googlecode/struts2juel/CompoundRootELContext.java Tue Nov  6 20:00:20 2007
@@ -1,7 +1,6 @@
 package com.googlecode.struts2juel;
 
 import javax.el.ArrayELResolver;
-import javax.el.BeanELResolver;
 import javax.el.CompositeELResolver;
 import javax.el.ELContext;
 import javax.el.ELResolver;
@@ -11,33 +10,39 @@
 import javax.el.ResourceBundleELResolver;
 import javax.el.VariableMapper;
 
+import com.googlecode.struts2juel.elresolvers.XWorkBeanELResolver;
+import com.opensymphony.xwork2.conversion.impl.XWorkConverter;
 import com.opensymphony.xwork2.util.CompoundRoot;
 
 /**
- * An implementation of SimpleContext that knows about the ValueStack's CompoundRoot.
+ * An implementation of SimpleContext that knows about the ValueStack's
+ * CompoundRoot.
  */
 public class CompoundRootELContext extends ELContext {
-    private VariableMapper variableMapper;
-    private FunctionMapper functionMapper = new NullFunctionMapper();
+	private VariableMapper variableMapper;
+	private FunctionMapper functionMapper = new NullFunctionMapper();
+	private XWorkConverter xworkConverter;
 
-    private static final ELResolver DEFAULT_RESOLVER_READ_WRITE = new CompositeELResolver() {
+	private static final ELResolver DEFAULT_RESOLVER_READ_WRITE = new CompositeELResolver() {
 		{
 			add(new ArrayELResolver(false));
 			add(new ListELResolver(false));
 			add(new MapELResolver(false));
 			add(new ResourceBundleELResolver());
-			add(new BeanELResolver(false));
+			add(new XWorkBeanELResolver(false));
 		}
 	};
-    
-    public CompoundRootELContext(CompoundRoot root) {
-        variableMapper = new CompoundRootVariableMapper(root);
-    }
-
-    @Override
-    public VariableMapper getVariableMapper() {
-        return variableMapper;
-    }
+
+	public CompoundRootELContext(XWorkConverter xworkConverter,
+			CompoundRoot root) {
+		this.xworkConverter = xworkConverter;
+		variableMapper = new CompoundRootVariableMapper(root);
+	}
+
+	@Override
+	public VariableMapper getVariableMapper() {
+		return variableMapper;
+	}
 
 	@Override
 	public ELResolver getELResolver() {
@@ -47,5 +52,16 @@
 	@Override
 	public FunctionMapper getFunctionMapper() {
 		return functionMapper;
+	}
+
+	public XWorkConverter getXworkConverter() {
+		return xworkConverter;
+	}
+
+	public Object convertType(Object value, Class toType) {
+		if (toType == null) {
+			return value;
+		}
+		return xworkConverter.convertValue(null, value, toType);
 	}
 }

Modified: struts/sandbox/trunk/struts2-juel-plugin/src/main/java/com/googlecode/struts2juel/JuelReflectionProvider.java
URL: http://svn.apache.org/viewvc/struts/sandbox/trunk/struts2-juel-plugin/src/main/java/com/googlecode/struts2juel/JuelReflectionProvider.java?rev=592605&r1=592604&r2=592605&view=diff
==============================================================================
--- struts/sandbox/trunk/struts2-juel-plugin/src/main/java/com/googlecode/struts2juel/JuelReflectionProvider.java (original)
+++ struts/sandbox/trunk/struts2-juel-plugin/src/main/java/com/googlecode/struts2juel/JuelReflectionProvider.java Tue Nov  6 20:00:20 2007
@@ -6,6 +6,8 @@
 import javax.el.ExpressionFactory;
 import javax.el.ValueExpression;
 
+import com.opensymphony.xwork2.conversion.impl.XWorkConverter;
+import com.opensymphony.xwork2.inject.Inject;
 import com.opensymphony.xwork2.ognl.OgnlReflectionProvider;
 import com.opensymphony.xwork2.util.CompoundRoot;
 import com.opensymphony.xwork2.util.reflection.ReflectionException;
@@ -15,6 +17,12 @@
  */
 public class JuelReflectionProvider extends OgnlReflectionProvider {
 	private ExpressionFactory factory;
+	private XWorkConverter xworkConverter;
+
+	@Inject
+	public void setXWorkConverter(XWorkConverter conv) {
+		this.xworkConverter = conv;
+	}
 
 	public void initExpressionFactory() {
 		if (factory == null) {
@@ -27,7 +35,7 @@
     	initExpressionFactory();
         CompoundRoot compoundRoot = new CompoundRoot();
         compoundRoot.add(root);
-        ELContext elContext = new CompoundRootELContext(compoundRoot);
+        ELContext elContext = new CompoundRootELContext(xworkConverter, compoundRoot);
         // parse our expression
         ValueExpression valueExpr = factory.createValueExpression(elContext,
             expr, String.class);
@@ -39,7 +47,7 @@
     	initExpressionFactory();
         CompoundRoot compoundRoot = new CompoundRoot();
         compoundRoot.add(root);
-        ELContext elContext = new CompoundRootELContext(compoundRoot);
+        ELContext elContext = new CompoundRootELContext(xworkConverter, compoundRoot);
         // parse our expression
         ValueExpression valueExpr = factory.createValueExpression(elContext,
             expr, String.class);

Modified: struts/sandbox/trunk/struts2-juel-plugin/src/main/java/com/googlecode/struts2juel/JuelValueStack.java
URL: http://svn.apache.org/viewvc/struts/sandbox/trunk/struts2-juel-plugin/src/main/java/com/googlecode/struts2juel/JuelValueStack.java?rev=592605&r1=592604&r2=592605&view=diff
==============================================================================
--- struts/sandbox/trunk/struts2-juel-plugin/src/main/java/com/googlecode/struts2juel/JuelValueStack.java (original)
+++ struts/sandbox/trunk/struts2-juel-plugin/src/main/java/com/googlecode/struts2juel/JuelValueStack.java Tue Nov  6 20:00:20 2007
@@ -9,6 +9,7 @@
 import javax.el.PropertyNotFoundException;
 import javax.el.ValueExpression;
 
+import com.opensymphony.xwork2.conversion.impl.XWorkConverter;
 import com.opensymphony.xwork2.util.CompoundRoot;
 import com.opensymphony.xwork2.util.ValueStack;
 
@@ -20,19 +21,27 @@
 	private transient Map context;
 	private Class defaultType;
 	private Map overrides;
+	private XWorkConverter xworkConverter;
 
 	private ExpressionFactory factory;
 
 	private ELContext elContext;
 
-	public JuelValueStack(ExpressionFactory factory) {
-		this.factory = factory;
-		setRoot(new CompoundRoot());
+	public JuelValueStack(ExpressionFactory factory,
+			XWorkConverter xworkConverter) {
+		this(factory, xworkConverter, new CompoundRoot());
+	}
+
+	public JuelValueStack(ExpressionFactory factory,
+			XWorkConverter xworkConverter, ValueStack vs) {
+		this(factory, xworkConverter, new CompoundRoot(vs.getRoot()));
 	}
 
-	public JuelValueStack(ExpressionFactory factory, ValueStack vs) {
+	public JuelValueStack(ExpressionFactory factory,
+			XWorkConverter xworkConverter, CompoundRoot root) {
+		this.xworkConverter = xworkConverter;
 		this.factory = factory;
-		setRoot(new CompoundRoot(vs.getRoot()));
+		setRoot(new CompoundRoot());
 	}
 
 	public String findString(String expr) {
@@ -64,8 +73,11 @@
 			}
 			// parse our expression
 			ValueExpression valueExpr = factory.createValueExpression(
-					elContext, expr, asType);
+					elContext, expr, Object.class);
 			Object retVal = valueExpr.getValue(elContext);
+			if (!Object.class.equals(asType)) {
+				retVal = xworkConverter.convertValue(null, retVal, asType);
+			}
 			return retVal;
 		} catch (PropertyNotFoundException e) {
 			// property not found
@@ -127,7 +139,7 @@
 				expr = "${" + expr + "}";
 			}
 			// hack to allow parameters to be set back
-			// juel doesn't support setting String[] values on String properties
+			// uel doesn't support setting String[] values on String properties
 			if (value != null && value instanceof String[]
 					&& ((String[]) value).length == 1) {
 				value = ((String[]) value)[0];
@@ -151,6 +163,6 @@
 		this.context = new TreeMap();
 		context.put(VALUE_STACK, this);
 		this.root = root;
-		this.elContext = new CompoundRootELContext(root);
+		this.elContext = new CompoundRootELContext(xworkConverter, root);
 	}
 }

Modified: struts/sandbox/trunk/struts2-juel-plugin/src/main/java/com/googlecode/struts2juel/JuelValueStackFactory.java
URL: http://svn.apache.org/viewvc/struts/sandbox/trunk/struts2-juel-plugin/src/main/java/com/googlecode/struts2juel/JuelValueStackFactory.java?rev=592605&r1=592604&r2=592605&view=diff
==============================================================================
--- struts/sandbox/trunk/struts2-juel-plugin/src/main/java/com/googlecode/struts2juel/JuelValueStackFactory.java (original)
+++ struts/sandbox/trunk/struts2-juel-plugin/src/main/java/com/googlecode/struts2juel/JuelValueStackFactory.java Tue Nov  6 20:00:20 2007
@@ -2,6 +2,8 @@
 
 import javax.el.ExpressionFactory;
 
+import com.opensymphony.xwork2.conversion.impl.XWorkConverter;
+import com.opensymphony.xwork2.inject.Inject;
 import com.opensymphony.xwork2.util.ValueStack;
 import com.opensymphony.xwork2.util.ValueStackFactory;
 
@@ -11,19 +13,26 @@
 public class JuelValueStackFactory implements ValueStackFactory {
 	private ExpressionFactory factory;
 
+	private XWorkConverter xworkConverter;
+
+	@Inject
+	public void setXWorkConverter(XWorkConverter conv) {
+		this.xworkConverter = conv;
+	}
+
 	public void initExpressionFactory() {
 		if (factory == null) {
 			factory = ExpressionFactoryLocator.locateExpressFactory();
 		}
 	}
-	
-    public ValueStack createValueStack() {
-    	initExpressionFactory();
-        return new JuelValueStack(factory);
-    }
-
-    public ValueStack createValueStack(ValueStack stack) {
-    	initExpressionFactory();
-        return new JuelValueStack(factory, stack);
-    }
+
+	public ValueStack createValueStack() {
+		initExpressionFactory();
+		return new JuelValueStack(factory, xworkConverter);
+	}
+
+	public ValueStack createValueStack(ValueStack stack) {
+		initExpressionFactory();
+		return new JuelValueStack(factory, xworkConverter, stack);
+	}
 }

Modified: struts/sandbox/trunk/struts2-juel-plugin/src/main/java/com/googlecode/struts2juel/PropertyValueExpression.java
URL: http://svn.apache.org/viewvc/struts/sandbox/trunk/struts2-juel-plugin/src/main/java/com/googlecode/struts2juel/PropertyValueExpression.java?rev=592605&r1=592604&r2=592605&view=diff
==============================================================================
--- struts/sandbox/trunk/struts2-juel-plugin/src/main/java/com/googlecode/struts2juel/PropertyValueExpression.java (original)
+++ struts/sandbox/trunk/struts2-juel-plugin/src/main/java/com/googlecode/struts2juel/PropertyValueExpression.java Tue Nov  6 20:00:20 2007
@@ -7,14 +7,18 @@
 
 import org.apache.commons.beanutils.PropertyUtils;
 
+import com.opensymphony.xwork2.conversion.impl.XWorkConverter;
+
 /**
  * A value expression that uses a javabean as the root of the value expression.
  */
 public class PropertyValueExpression extends ValueExpression {
 	private Object object;
 	private String property;
+    private XWorkConverter xworkConverter;
 
 	public PropertyValueExpression(Object object, String property) {
+    	this.xworkConverter = xworkConverter;
 		this.object = object;
 		this.property = property;
 	}
@@ -33,7 +37,7 @@
 	}
 
 	@Override
-	public Class<?> getType(ELContext arg0) {
+	public Class<?> getType(ELContext context) {
 		try {
 			return PropertyUtils.getPropertyType(object, property);
 		} catch (IllegalAccessException e) {
@@ -46,7 +50,7 @@
 	}
 
 	@Override
-	public Object getValue(ELContext arg0) {
+	public Object getValue(ELContext context) {
 		try {
 			return PropertyUtils.getSimpleProperty(object, property);
 		} catch (IllegalAccessException e) {
@@ -59,14 +63,17 @@
 	}
 
 	@Override
-	public boolean isReadOnly(ELContext arg0) {
+	public boolean isReadOnly(ELContext context) {
 		return !PropertyUtils.isWriteable(object, property);
 	}
 
 	@Override
-	public void setValue(ELContext arg0, Object obj) {
+	public void setValue(ELContext context, Object value) {
 		try {
-			PropertyUtils.setSimpleProperty(object, property, obj);
+			Class propType = PropertyUtils.getPropertyType(object, property);
+			XWorkConverter xworkConverter = ((CompoundRootELContext) context).getXworkConverter();
+			Object convertedValue = xworkConverter.convertValue(value, propType);
+			PropertyUtils.setSimpleProperty(object, property, convertedValue);
 		} catch (IllegalAccessException e) {
 			throw new RuntimeException(e);
 		} catch (InvocationTargetException e) {

Modified: struts/sandbox/trunk/struts2-juel-plugin/src/test/java/com/googlecode/struts2juel/JuelTest.java
URL: http://svn.apache.org/viewvc/struts/sandbox/trunk/struts2-juel-plugin/src/test/java/com/googlecode/struts2juel/JuelTest.java?rev=592605&r1=592604&r2=592605&view=diff
==============================================================================
--- struts/sandbox/trunk/struts2-juel-plugin/src/test/java/com/googlecode/struts2juel/JuelTest.java (original)
+++ struts/sandbox/trunk/struts2-juel-plugin/src/test/java/com/googlecode/struts2juel/JuelTest.java Tue Nov  6 20:00:20 2007
@@ -1,55 +1,155 @@
 package com.googlecode.struts2juel;
 
 import java.lang.reflect.InvocationTargetException;
+import java.text.DateFormat;
+import java.text.ParseException;
+import java.util.Date;
+import java.util.Map;
 
 import javax.el.ExpressionFactory;
 
-import junit.framework.TestCase;
+import org.apache.struts2.util.StrutsTypeConverter;
 
+import com.opensymphony.xwork2.XWorkTestCase;
+import com.opensymphony.xwork2.conversion.impl.XWorkConverter;
 import com.opensymphony.xwork2.util.CompoundRoot;
 
-public class JuelTest extends TestCase {
+public class JuelTest extends XWorkTestCase {
+	private ExpressionFactory factory = new de.odysseus.el.ExpressionFactoryImpl();
+	private XWorkConverter converter;
+
+	private class DateConverter extends StrutsTypeConverter {
+		private DateFormat format = DateFormat.getDateInstance();
+		@Override
+		public Object convertFromString(Map context, String[] values,
+				Class toClass) {
+			try {
+				return format.parseObject(values[0]);
+			} catch (ParseException e) {
+				return null;
+			}
+		}
+
+		@Override
+		public String convertToString(Map context, Object o) {
+			return format.format(o);
+		}
+		
+	}
 	
-    public void testBasicFind() throws IllegalAccessException,
-        InvocationTargetException, NoSuchMethodException {
-        ExpressionFactory factory = new de.odysseus.el.ExpressionFactoryImpl();
-
-        CompoundRoot root = new CompoundRoot();
-        TestObject obj = new TestObject();
-        root.add(obj);
-        JuelValueStack stack = new JuelValueStack(factory);
-        stack.setRoot(root);
-        stack.setValue("${value}", "Hello World");
-        String value = stack.findString("${value}");
-        assertEquals("Hello World", value);
-    }
-
-    public void testNotFound() throws IllegalAccessException,
-        InvocationTargetException, NoSuchMethodException {
-        ExpressionFactory factory = new de.odysseus.el.ExpressionFactoryImpl();
-
-        CompoundRoot root = new CompoundRoot();
-        TestObject obj = new TestObject();
-        root.add(obj);
-        JuelValueStack stack = new JuelValueStack(factory);
-        stack.setRoot(root);
-        stack.setValue("${value}", "Hello World");
-        String value = stack.findString("${VALUENOTHERE}");
-        assertNull(value);
-
-        value = stack.findString("VALUENOTHERE");
-        assertNull(value);
-    }
-
-    public class TestObject {
-        private String value;
-
-        public String getValue() {
-            return value;
-        }
-
-        public void setValue(String value) {
-            this.value = value;
-        }
-    }
+	protected void setUp() throws Exception {
+		super.setUp();
+
+		converter = container.getInstance(XWorkConverter.class);
+		converter.registerConverter("java.util.Date", new DateConverter());
+	}
+
+	public void testBasicFind() throws IllegalAccessException,
+			InvocationTargetException, NoSuchMethodException {
+		CompoundRoot root = new CompoundRoot();
+		TestObject obj = new TestObject();
+		root.add(obj);
+		JuelValueStack stack = new JuelValueStack(factory, converter);
+		stack.setRoot(root);
+		stack.setValue("${value}", "Hello World");
+		String value = stack.findString("${value}");
+		assertEquals("Hello World", value);
+
+		stack.setValue("${age}", "56");
+		String age = stack.findString("${age}");
+		assertEquals("56", age);
+	}
+
+	public void test2LevelSet() throws IllegalAccessException,
+			InvocationTargetException, NoSuchMethodException {
+		CompoundRoot root = new CompoundRoot();
+		TestObject obj = new TestObject();
+		TestObject nestedObj = new TestObject();
+		obj.setInner(nestedObj);
+		root.add(obj);
+		JuelValueStack stack = new JuelValueStack(factory, converter);
+		stack.setRoot(root);
+		stack.setValue("${inner.age}", "66");
+		assertEquals(66, obj.getInner().getAge());
+	}
+
+	public void testTypeConversion() throws IllegalAccessException,
+			InvocationTargetException, NoSuchMethodException {
+
+		CompoundRoot root = new CompoundRoot();
+		TestObject obj = new TestObject();
+		TestObject inner = new TestObject();
+		obj.setInner(inner);
+		root.add(obj);
+		JuelValueStack stack = new JuelValueStack(factory, converter);
+		stack.setRoot(root);
+
+		stack.setValue("${age}", "22");
+		assertEquals(stack.findValue("${age}"), obj.getAge());
+
+		stack.setValue("${inner.value}", "George");
+		assertEquals(stack.findValue("${inner.value}"), obj.getInner()
+				.getValue());
+
+		stack.setValue("${inner.age}", "44");
+		assertEquals(stack.findValue("${inner.age}"), obj.getInner().getAge());
+
+		stack.setValue("${date}", new Date());
+		assertEquals(stack.findString("${date}"), obj.getDate());
+	}
+
+	public void testNotFound() throws IllegalAccessException,
+			InvocationTargetException, NoSuchMethodException {
+		CompoundRoot root = new CompoundRoot();
+		TestObject obj = new TestObject();
+		root.add(obj);
+		JuelValueStack stack = new JuelValueStack(factory, converter);
+		stack.setRoot(root);
+		stack.setValue("${value}", "Hello World");
+		String value = stack.findString("${VALUENOTHERE}");
+		assertNull(value);
+
+		value = stack.findString("VALUENOTHERE");
+		assertNull(value);
+	}
+
+	public class TestObject {
+		private String value;
+		private int age;
+		private Date date;
+		private TestObject inner;
+
+		public String getValue() {
+			return value;
+		}
+
+		public void setValue(String value) {
+			this.value = value;
+		}
+
+		public int getAge() {
+			return age;
+		}
+
+		public void setAge(int age) {
+			this.age = age;
+		}
+
+		public Date getDate() {
+			return date;
+		}
+
+		public void setDate(Date date) {
+			this.date = date;
+		}
+
+		public TestObject getInner() {
+			return inner;
+		}
+
+		public void setInner(TestObject inner) {
+			this.inner = inner;
+		}
+
+	}
 }