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/10 03:03:40 UTC

svn commit: r593714 - in /struts/sandbox/trunk/struts2-juel-plugin: ./ src/main/java/com/googlecode/struts2juel/ src/main/java/com/googlecode/struts2juel/contextlistener/ src/main/java/com/googlecode/struts2juel/elresolvers/ src/main/resources/ src/tes...

Author: tschneider
Date: Fri Nov  9 18:03:32 2007
New Revision: 593714

URL: http://svn.apache.org/viewvc?rev=593714&view=rev
Log: (empty)

Added:
    struts/sandbox/trunk/struts2-juel-plugin/src/main/java/com/googlecode/struts2juel/UelReflectionContextFactory.java
      - copied, changed from r593000, struts/sandbox/trunk/struts2-juel-plugin/src/main/java/com/googlecode/struts2juel/UELReflectionContextFactory.java
    struts/sandbox/trunk/struts2-juel-plugin/src/main/java/com/googlecode/struts2juel/contextlistener/
    struts/sandbox/trunk/struts2-juel-plugin/src/main/java/com/googlecode/struts2juel/contextlistener/UelServletContextListener.java
    struts/sandbox/trunk/struts2-juel-plugin/src/main/java/com/googlecode/struts2juel/elresolvers/CompoundRootELResolver.java
Removed:
    struts/sandbox/trunk/struts2-juel-plugin/src/main/java/com/googlecode/struts2juel/CompoundRootVariableMapper.java
    struts/sandbox/trunk/struts2-juel-plugin/src/main/java/com/googlecode/struts2juel/NullFunctionMapper.java
    struts/sandbox/trunk/struts2-juel-plugin/src/main/java/com/googlecode/struts2juel/PropertyValueExpression.java
    struts/sandbox/trunk/struts2-juel-plugin/src/main/java/com/googlecode/struts2juel/UELReflectionContextFactory.java
Modified:
    struts/sandbox/trunk/struts2-juel-plugin/pom.xml
    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/elresolvers/XWorkBeanELResolver.java
    struts/sandbox/trunk/struts2-juel-plugin/src/main/resources/struts-plugin.xml
    struts/sandbox/trunk/struts2-juel-plugin/src/test/java/com/googlecode/struts2juel/UelTest.java

Modified: struts/sandbox/trunk/struts2-juel-plugin/pom.xml
URL: http://svn.apache.org/viewvc/struts/sandbox/trunk/struts2-juel-plugin/pom.xml?rev=593714&r1=593713&r2=593714&view=diff
==============================================================================
--- struts/sandbox/trunk/struts2-juel-plugin/pom.xml (original)
+++ struts/sandbox/trunk/struts2-juel-plugin/pom.xml Fri Nov  9 18:03:32 2007
@@ -49,7 +49,14 @@
 			<groupId>de.odysseus.juel</groupId>
 			<artifactId>juel</artifactId>
 			<version>2.1.0</version>
-			</dependency>
+			<scope>provided</scope>
+		</dependency>
+		<dependency>
+			<groupId>org.mortbay.jetty</groupId>
+			<artifactId>jsp-2.1</artifactId>
+			<version>6.1.3</version>
+			<scope>provided</scope>
+		</dependency>
 		<dependency>
 			<groupId>commons-beanutils</groupId>
 			<artifactId>commons-beanutils</artifactId>

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=593714&r1=593713&r2=593714&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 Fri Nov  9 18:03:32 2007
@@ -10,35 +10,32 @@
 import javax.el.ResourceBundleELResolver;
 import javax.el.VariableMapper;
 
+import com.googlecode.struts2juel.elresolvers.CompoundRootELResolver;
 import com.googlecode.struts2juel.elresolvers.XWorkBeanELResolver;
-import com.opensymphony.xwork2.util.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 ELResolver DEFAULT_RESOLVER_READ_WRITE;
 
-	public CompoundRootELContext(CompoundRoot root) {
-		variableMapper = new CompoundRootVariableMapper(root);
+	public CompoundRootELContext() {
 		DEFAULT_RESOLVER_READ_WRITE = new CompositeELResolver() {
 			{
+				add(new CompoundRootELResolver());
 				add(new ArrayELResolver(false));
 				add(new ListELResolver(false));
 				add(new MapELResolver(false));
 				add(new ResourceBundleELResolver());
-				add(new XWorkBeanELResolver(false));
+				add(new XWorkBeanELResolver());
 			}
 		};
 	}
 
 	@Override
 	public VariableMapper getVariableMapper() {
-		return variableMapper;
+		return null;
 	}
 
 	@Override
@@ -48,6 +45,6 @@
 
 	@Override
 	public FunctionMapper getFunctionMapper() {
-		return functionMapper;
+		return null;
 	}
 }

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=593714&r1=593713&r2=593714&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 Fri Nov  9 18:03:32 2007
@@ -35,7 +35,7 @@
     	initExpressionFactory();
         CompoundRoot compoundRoot = new CompoundRoot();
         compoundRoot.add(root);
-        ELContext elContext = new CompoundRootELContext(compoundRoot);
+        ELContext elContext = new CompoundRootELContext();
         elContext.putContext(XWorkConverter.class, xworkConverter);
         // parse our expression
         ValueExpression valueExpr = factory.createValueExpression(elContext,
@@ -48,7 +48,7 @@
     	initExpressionFactory();
         CompoundRoot compoundRoot = new CompoundRoot();
         compoundRoot.add(root);
-        ELContext elContext = new CompoundRootELContext(compoundRoot);
+        ELContext elContext = new CompoundRootELContext();
         elContext.putContext(XWorkConverter.class, xworkConverter);
         // parse our expression
         ValueExpression valueExpr = factory.createValueExpression(elContext,

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=593714&r1=593713&r2=593714&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 Fri Nov  9 18:03:32 2007
@@ -72,6 +72,8 @@
 					&& !expr.startsWith("#{")) {
 				expr = "#{" + expr + "}";
 			}
+	        elContext.putContext(XWorkConverter.class, xworkConverter);
+	        elContext.putContext(CompoundRoot.class, root);
 			// parse our expression
 			ValueExpression valueExpr = factory.createValueExpression(
 					elContext, expr, Object.class);
@@ -140,6 +142,8 @@
 					&& !expr.startsWith("#{")) {
 				expr = "#{" + expr + "}";
 			}
+	        elContext.putContext(XWorkConverter.class, xworkConverter);
+	        elContext.putContext(CompoundRoot.class, root);
 			// parse our expression
 			ValueExpression valueExpr = factory.createValueExpression(
 					elContext, expr, Object.class);
@@ -159,7 +163,6 @@
 		this.context = new TreeMap();
 		context.put(VALUE_STACK, this);
 		this.root = root;
-		elContext = new CompoundRootELContext(root);
-        elContext.putContext(XWorkConverter.class, xworkConverter);
+		elContext = new CompoundRootELContext();
 	}
 }

Copied: struts/sandbox/trunk/struts2-juel-plugin/src/main/java/com/googlecode/struts2juel/UelReflectionContextFactory.java (from r593000, struts/sandbox/trunk/struts2-juel-plugin/src/main/java/com/googlecode/struts2juel/UELReflectionContextFactory.java)
URL: http://svn.apache.org/viewvc/struts/sandbox/trunk/struts2-juel-plugin/src/main/java/com/googlecode/struts2juel/UelReflectionContextFactory.java?p2=struts/sandbox/trunk/struts2-juel-plugin/src/main/java/com/googlecode/struts2juel/UelReflectionContextFactory.java&p1=struts/sandbox/trunk/struts2-juel-plugin/src/main/java/com/googlecode/struts2juel/UELReflectionContextFactory.java&r1=593000&r2=593714&rev=593714&view=diff
==============================================================================
--- struts/sandbox/trunk/struts2-juel-plugin/src/main/java/com/googlecode/struts2juel/UELReflectionContextFactory.java (original)
+++ struts/sandbox/trunk/struts2-juel-plugin/src/main/java/com/googlecode/struts2juel/UelReflectionContextFactory.java Fri Nov  9 18:03:32 2007
@@ -6,9 +6,9 @@
 import com.opensymphony.xwork2.util.reflection.ReflectionContextFactory;
 
 /**
- * ReflectionContextFactory for Juel.
+ * ReflectionContextFactory for Unified EL.
  */
-public class UELReflectionContextFactory implements ReflectionContextFactory {
+public class UelReflectionContextFactory implements ReflectionContextFactory {
     public Map createDefaultContext(Object root) {
         return new HashMap();
     }

Added: struts/sandbox/trunk/struts2-juel-plugin/src/main/java/com/googlecode/struts2juel/contextlistener/UelServletContextListener.java
URL: http://svn.apache.org/viewvc/struts/sandbox/trunk/struts2-juel-plugin/src/main/java/com/googlecode/struts2juel/contextlistener/UelServletContextListener.java?rev=593714&view=auto
==============================================================================
--- struts/sandbox/trunk/struts2-juel-plugin/src/main/java/com/googlecode/struts2juel/contextlistener/UelServletContextListener.java (added)
+++ struts/sandbox/trunk/struts2-juel-plugin/src/main/java/com/googlecode/struts2juel/contextlistener/UelServletContextListener.java Fri Nov  9 18:03:32 2007
@@ -0,0 +1,29 @@
+package com.googlecode.struts2juel.contextlistener;
+
+import javax.servlet.ServletContext;
+import javax.servlet.ServletContextEvent;
+import javax.servlet.ServletContextListener;
+import javax.servlet.jsp.JspApplicationContext;
+import javax.servlet.jsp.JspFactory;
+
+import com.googlecode.struts2juel.elresolvers.CompoundRootELResolver;
+import com.googlecode.struts2juel.elresolvers.XWorkBeanELResolver;
+
+/**
+ * Responsible for registering the ELResolvers.
+ */
+public class UelServletContextListener implements ServletContextListener {
+
+	public void contextInitialized(ServletContextEvent contextEvent) {
+		ServletContext servletContext = contextEvent.getServletContext();
+		JspApplicationContext jspApplicationContext = JspFactory
+				.getDefaultFactory().getJspApplicationContext(servletContext);
+		jspApplicationContext.addELResolver(new CompoundRootELResolver());
+		jspApplicationContext.addELResolver(new XWorkBeanELResolver());
+		contextEvent.getServletContext().log(
+				"CompoundRootELResolver and XWorkBeanELResolver registered");
+	}
+
+	public void contextDestroyed(ServletContextEvent contextEvent) {
+	}
+}

Added: struts/sandbox/trunk/struts2-juel-plugin/src/main/java/com/googlecode/struts2juel/elresolvers/CompoundRootELResolver.java
URL: http://svn.apache.org/viewvc/struts/sandbox/trunk/struts2-juel-plugin/src/main/java/com/googlecode/struts2juel/elresolvers/CompoundRootELResolver.java?rev=593714&view=auto
==============================================================================
--- struts/sandbox/trunk/struts2-juel-plugin/src/main/java/com/googlecode/struts2juel/elresolvers/CompoundRootELResolver.java (added)
+++ struts/sandbox/trunk/struts2-juel-plugin/src/main/java/com/googlecode/struts2juel/elresolvers/CompoundRootELResolver.java Fri Nov  9 18:03:32 2007
@@ -0,0 +1,203 @@
+package com.googlecode.struts2juel.elresolvers;
+
+import java.beans.BeanInfo;
+import java.beans.FeatureDescriptor;
+import java.beans.Introspector;
+import java.beans.PropertyDescriptor;
+import java.lang.reflect.InvocationTargetException;
+import java.util.ArrayList;
+import java.util.Iterator;
+
+import javax.el.ELContext;
+import javax.el.ELResolver;
+
+import org.apache.commons.beanutils.BeanUtils;
+import org.apache.commons.beanutils.PropertyUtils;
+
+import com.opensymphony.xwork2.conversion.impl.XWorkConverter;
+import com.opensymphony.xwork2.util.CompoundRoot;
+
+/**
+ * An ELResolver that is capable of resolving properties against the
+ * CompoundRoot if available in the ELContext.
+ */
+public class CompoundRootELResolver extends ELResolver {
+
+	@Override
+	public Class<?> getCommonPropertyType(ELContext context, Object base) {
+		if (base == null) {
+			return null;
+		}
+
+		return String.class;
+	}
+
+	@Override
+	public Iterator<FeatureDescriptor> getFeatureDescriptors(ELContext context,
+			Object base) {
+		// only resolve at the root of the context
+		if (base != null) {
+			return null;
+		}
+
+		CompoundRoot root = (CompoundRoot) context
+				.getContext(CompoundRoot.class);
+		if (root == null) {
+			return null;
+		}
+
+		ArrayList<FeatureDescriptor> list = new ArrayList<FeatureDescriptor>();
+		if (root.size() > 0) {
+			FeatureDescriptor descriptor = new FeatureDescriptor();
+			descriptor.setValue("type", root.get(0).getClass());
+			descriptor.setValue("resolvableAtDesignTime", Boolean.FALSE);
+			list.add(descriptor);
+		}
+
+		for (Object bean : root) {
+			BeanInfo info = null;
+			try {
+				info = Introspector.getBeanInfo(base.getClass());
+			} catch (Exception ex) {
+			}
+			if (info != null) {
+				for (PropertyDescriptor pd : info.getPropertyDescriptors()) {
+					pd.setValue("type", pd.getPropertyType());
+					pd.setValue("resolvableAtDesignTime", Boolean.FALSE);
+					list.add(pd);
+				}
+			}
+		}
+		return list.iterator();
+	}
+
+	@Override
+	public Class<?> getType(ELContext context, Object base, Object property) {
+		// only resolve at the root of the context
+		if (base != null) {
+			return null;
+		}
+
+		CompoundRoot root = (CompoundRoot) context
+				.getContext(CompoundRoot.class);
+		if (root == null) {
+			return null;
+		}
+		String propertyName = (String) property;
+		Object bean = findObjectForProperty(root, propertyName);
+		if (bean == null) {
+			return null;
+		}
+		try {
+			Class type = determineType(bean, propertyName);
+			context.setPropertyResolved(true);
+			return type;
+		} catch (IllegalAccessException e) {
+			throw new RuntimeException(e);
+		} catch (InvocationTargetException e) {
+			throw new RuntimeException(e);
+		} catch (NoSuchMethodException e) {
+			throw new RuntimeException(e);
+		}
+	}
+
+	@Override
+	public Object getValue(ELContext context, Object base, Object property) {
+		if (context == null) {
+			throw new NullPointerException();
+		}
+		// only resolve at the root of the context
+		if (base != null) {
+			return null;
+		}
+
+		CompoundRoot root = (CompoundRoot) context
+				.getContext(CompoundRoot.class);
+		if (root == null) {
+			return null;
+		}
+		String propertyName = (String) property;
+		if ("top".equals(propertyName) && root.size() > 0) {
+			return root.get(0);
+		}
+		try {
+			Object bean = findObjectForProperty(root, propertyName);
+			if (bean != null) {
+				Object retVal = PropertyUtils.getProperty(bean, propertyName); 
+				context.setPropertyResolved(true);
+				return retVal;
+			}
+		} catch (IllegalAccessException e) {
+			throw new RuntimeException(e);
+		} catch (InvocationTargetException e) {
+			throw new RuntimeException(e);
+		} catch (NoSuchMethodException e) {
+			throw new RuntimeException(e);
+		}
+		return null;
+	}
+
+	@Override
+	public boolean isReadOnly(ELContext context, Object base, Object property) {
+		if (context == null) {
+			throw new NullPointerException();
+		}
+
+		return false;
+	}
+
+	@Override
+	public void setValue(ELContext context, Object base, Object property,
+			Object value) {
+		if (context == null) {
+			throw new NullPointerException();
+		}
+		// only resolve at the root of the context
+		if (base != null) {
+			return;
+		}
+
+		CompoundRoot root = (CompoundRoot) context
+				.getContext(CompoundRoot.class);
+		String propertyName = (String) property;
+		try {
+			if (base == null && property != null && root != null) {
+				Object bean = findObjectForProperty(root, propertyName);
+				if (bean != null) {
+					XWorkConverter converter = (XWorkConverter) context
+							.getContext(XWorkConverter.class);
+					if (converter != null && root != null) {
+						Class propType = determineType(bean, propertyName);
+						value = converter.convertValue(null, value, propType);
+					}
+					BeanUtils.setProperty(bean, propertyName, value);
+					context.setPropertyResolved(true);
+				}
+			}
+		} catch (IllegalAccessException e) {
+			throw new RuntimeException(e);
+		} catch (InvocationTargetException e) {
+			throw new RuntimeException(e);
+		} catch (NoSuchMethodException e) {
+			throw new RuntimeException(e);
+		}
+	}
+
+	protected Class<?> determineType(Object bean, String property)
+			throws IllegalAccessException, InvocationTargetException, NoSuchMethodException {
+		return PropertyUtils.getPropertyType(bean, property);
+	}
+
+	protected Object findObjectForProperty(CompoundRoot root, String propertyName) {
+		if ("top".equals(propertyName) && root.size() > 0) {
+			return root.get(0);
+		}
+		for (int i = 0; i < root.size(); i++) {
+			if (PropertyUtils.isReadable(root.get(i), propertyName)
+					|| PropertyUtils.isWriteable(root.get(i), propertyName)) {
+				return root.get(i);
+			}
+		}
+		return null;
+	}
+}

Modified: struts/sandbox/trunk/struts2-juel-plugin/src/main/java/com/googlecode/struts2juel/elresolvers/XWorkBeanELResolver.java
URL: http://svn.apache.org/viewvc/struts/sandbox/trunk/struts2-juel-plugin/src/main/java/com/googlecode/struts2juel/elresolvers/XWorkBeanELResolver.java?rev=593714&r1=593713&r2=593714&view=diff
==============================================================================
--- struts/sandbox/trunk/struts2-juel-plugin/src/main/java/com/googlecode/struts2juel/elresolvers/XWorkBeanELResolver.java (original)
+++ struts/sandbox/trunk/struts2-juel-plugin/src/main/java/com/googlecode/struts2juel/elresolvers/XWorkBeanELResolver.java Fri Nov  9 18:03:32 2007
@@ -1,16 +1,37 @@
 package com.googlecode.struts2juel.elresolvers;
 
+import java.lang.reflect.InvocationTargetException;
+
 import javax.el.BeanELResolver;
 import javax.el.ELContext;
 
+import org.apache.commons.beanutils.PropertyUtils;
+
 import com.opensymphony.xwork2.conversion.impl.XWorkConverter;
 
 public class XWorkBeanELResolver extends BeanELResolver {
+
 	public XWorkBeanELResolver() {
+		super(false);
 	}
 
-	public XWorkBeanELResolver(boolean isReadOnly) {
-		super(isReadOnly);
+	/**
+	 * Re-implement this to always return Object. We don't want unified EL to do
+	 * type conversion, we do that in the setter using xwork type conversion
+	 * framework.
+	 */
+	@Override
+	public Class<?> getType(ELContext context, Object base, Object property) {
+		if (context == null) {
+			throw new NullPointerException();
+		}
+
+		if (base == null || property == null) {
+			return null;
+		}
+
+		context.setPropertyResolved(true);
+		return Object.class;
 	}
 
 	@Override
@@ -18,10 +39,19 @@
 			Object value) {
 		XWorkConverter converter = (XWorkConverter) context
 				.getContext(XWorkConverter.class);
-		if (converter != null && base != null) {
-			Class propType = getType(context, base, property);
-			value = converter.convertValue(value, propType);
+		try {
+			if (converter != null && base != null) {
+				Class propType = PropertyUtils.getPropertyType(base, property
+						.toString());
+				value = converter.convertValue(value, propType);
+			}
+			super.setValue(context, base, property, value);
+		} catch (IllegalAccessException e) {
+			throw new RuntimeException(e);
+		} catch (InvocationTargetException e) {
+			throw new RuntimeException(e);
+		} catch (NoSuchMethodException e) {
+			throw new RuntimeException(e);
 		}
-		super.setValue(context, base, property, value);
 	}
 }

Modified: struts/sandbox/trunk/struts2-juel-plugin/src/main/resources/struts-plugin.xml
URL: http://svn.apache.org/viewvc/struts/sandbox/trunk/struts2-juel-plugin/src/main/resources/struts-plugin.xml?rev=593714&r1=593713&r2=593714&view=diff
==============================================================================
--- struts/sandbox/trunk/struts2-juel-plugin/src/main/resources/struts-plugin.xml (original)
+++ struts/sandbox/trunk/struts2-juel-plugin/src/main/resources/struts-plugin.xml Fri Nov  9 18:03:32 2007
@@ -7,7 +7,7 @@
 <struts>
 	<bean type="com.opensymphony.xwork2.util.ValueStackFactory" name="uel" class="com.googlecode.struts2juel.JuelValueStackFactory" />
 	<bean type="com.opensymphony.xwork2.util.reflection.ReflectionProvider" name="uel" class="com.googlecode.struts2juel.JuelReflectionProvider" />	
-	<bean type="com.opensymphony.xwork2.util.reflection.ReflectionContextFactory" name="uel" class="com.googlecode.struts2juel.UELReflectionContextFactory" />
+	<bean type="com.opensymphony.xwork2.util.reflection.ReflectionContextFactory" name="uel" class="com.googlecode.struts2juel.UelReflectionContextFactory" />
 
     <constant name="struts.valueStackFactory" value="uel" />
     <constant name="struts.reflectionProvider" value="uel" />

Modified: struts/sandbox/trunk/struts2-juel-plugin/src/test/java/com/googlecode/struts2juel/UelTest.java
URL: http://svn.apache.org/viewvc/struts/sandbox/trunk/struts2-juel-plugin/src/test/java/com/googlecode/struts2juel/UelTest.java?rev=593714&r1=593713&r2=593714&view=diff
==============================================================================
--- struts/sandbox/trunk/struts2-juel-plugin/src/test/java/com/googlecode/struts2juel/UelTest.java (original)
+++ struts/sandbox/trunk/struts2-juel-plugin/src/test/java/com/googlecode/struts2juel/UelTest.java Fri Nov  9 18:03:32 2007
@@ -4,6 +4,7 @@
 import java.text.DateFormat;
 import java.text.ParseException;
 import java.util.Date;
+import java.util.HashMap;
 import java.util.Map;
 
 import javax.el.ExpressionFactory;
@@ -81,6 +82,7 @@
 		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");
@@ -95,6 +97,22 @@
 		assertEquals(stack.findString("#{date}"), format.format(obj.getDate()));
 	}
 
+	public void testMap() throws IllegalAccessException,
+			InvocationTargetException, NoSuchMethodException {
+		CompoundRoot root = new CompoundRoot();
+		HashMap map = new HashMap();
+		map.put("nameValue", "Musachy");
+		TestObject obj = new TestObject();
+		obj.setParameters(map);
+		root.add(obj);
+
+		JuelValueStack stack = new JuelValueStack(factory, converter);
+		stack.setRoot(root);
+		String value = (String) stack.findValue("parameters.nameValue",
+				String.class);
+		assertEquals("Musachy", value);
+	}
+
 	public void test2LevelSet() throws IllegalAccessException,
 			InvocationTargetException, NoSuchMethodException {
 		CompoundRoot root = new CompoundRoot();
@@ -153,6 +171,7 @@
 		private int age;
 		private Date date;
 		private TestObject inner;
+		private Map parameters;
 
 		public String getValue() {
 			return value;
@@ -186,5 +205,12 @@
 			this.inner = inner;
 		}
 
+		public Map getParameters() {
+			return parameters;
+		}
+
+		public void setParameters(Map parameters) {
+			this.parameters = parameters;
+		}
 	}
 }