Author: tschneider
Date: Fri Nov 9 18:47:29 2007
New Revision: 593725
URL: http://svn.apache.org/viewvc?rev=593725&view=rev
Log:
adding juel plugin as uel plugin
Added:
struts/sandbox/trunk/struts2-uel-plugin/
struts/sandbox/trunk/struts2-uel-plugin/pom.xml
struts/sandbox/trunk/struts2-uel-plugin/src/
struts/sandbox/trunk/struts2-uel-plugin/src/main/
struts/sandbox/trunk/struts2-uel-plugin/src/main/java/
struts/sandbox/trunk/struts2-uel-plugin/src/main/java/org/
struts/sandbox/trunk/struts2-uel-plugin/src/main/java/org/apache/
struts/sandbox/trunk/struts2-uel-plugin/src/main/java/org/apache/struts2/
struts/sandbox/trunk/struts2-uel-plugin/src/main/java/org/apache/struts2/uelplugin/
struts/sandbox/trunk/struts2-uel-plugin/src/main/java/org/apache/struts2/uelplugin/CompoundRootELContext.java
struts/sandbox/trunk/struts2-uel-plugin/src/main/java/org/apache/struts2/uelplugin/UelReflectionContextFactory.java
struts/sandbox/trunk/struts2-uel-plugin/src/main/java/org/apache/struts2/uelplugin/UelReflectionProvider.java
struts/sandbox/trunk/struts2-uel-plugin/src/main/java/org/apache/struts2/uelplugin/UelValueStack.java
struts/sandbox/trunk/struts2-uel-plugin/src/main/java/org/apache/struts2/uelplugin/UelValueStackFactory.java
struts/sandbox/trunk/struts2-uel-plugin/src/main/java/org/apache/struts2/uelplugin/contextlistener/
struts/sandbox/trunk/struts2-uel-plugin/src/main/java/org/apache/struts2/uelplugin/contextlistener/UelServletContextListener.java
struts/sandbox/trunk/struts2-uel-plugin/src/main/java/org/apache/struts2/uelplugin/elresolvers/
struts/sandbox/trunk/struts2-uel-plugin/src/main/java/org/apache/struts2/uelplugin/elresolvers/CompoundRootELResolver.java
struts/sandbox/trunk/struts2-uel-plugin/src/main/java/org/apache/struts2/uelplugin/elresolvers/XWorkBeanELResolver.java
struts/sandbox/trunk/struts2-uel-plugin/src/main/resources/
struts/sandbox/trunk/struts2-uel-plugin/src/main/resources/struts-plugin.xml
struts/sandbox/trunk/struts2-uel-plugin/src/test/
struts/sandbox/trunk/struts2-uel-plugin/src/test/java/
struts/sandbox/trunk/struts2-uel-plugin/src/test/java/org/
struts/sandbox/trunk/struts2-uel-plugin/src/test/java/org/apache/
struts/sandbox/trunk/struts2-uel-plugin/src/test/java/org/apache/struts2/
struts/sandbox/trunk/struts2-uel-plugin/src/test/java/org/apache/struts2/uelplugin/
struts/sandbox/trunk/struts2-uel-plugin/src/test/java/org/apache/struts2/uelplugin/UelTest.java
Added: struts/sandbox/trunk/struts2-uel-plugin/pom.xml
URL:
http://svn.apache.org/viewvc/struts/sandbox/trunk/struts2-uel-plugin/pom.xml?rev=593725&view=auto
==============================================================================
--- struts/sandbox/trunk/struts2-uel-plugin/pom.xml (added)
+++ struts/sandbox/trunk/struts2-uel-plugin/pom.xml Fri Nov 9 18:47:29 2007
@@ -0,0 +1,82 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>org.apache.struts2juel</groupId>
+ <artifactId>struts2-uel-plugin</artifactId>
+ <packaging>jar</packaging>
+ <name>Struts 2 Unified EL Plugin</name>
+ <version>1.0.0-SNAPSHOT</version>
+ <build>
+ <plugins>
+ <plugin>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <configuration>
+ <source>1.5</source>
+ <target>1.5</target>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+ <scm>
+ <connection>
+
scm:svn:https://svn.apache.org/repos/asf/struts/sandbox/trunk/struts2-uel-plugin
+ </connection>
+ <developerConnection>
+
scm:svn:https://svn.apache.org/repos/asf/struts/sandbox/trunk/struts2-uel-plugin
+ </developerConnection>
+
<url>http://https://svn.apache.org/repos/asf/struts/sandbox/trunk/struts2-uel-plugin</url>
+ </scm>
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.struts</groupId>
+ <artifactId>struts2-core</artifactId>
+ <version>2.1.1-SNAPSHOT</version>
+ <exclusions>
+ <exclusion>
+ <groupId>javax.servlet</groupId>
+ <artifactId>servlet-api</artifactId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <version>4.4</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>de.odysseus.juel</groupId>
+ <artifactId>juel</artifactId>
+ <version>2.1.0</version>
+ <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>
+ <version>20030211.134440</version>
+ </dependency>
+ <dependency>
+ <groupId>commons-collections</groupId>
+ <artifactId>commons-collections</artifactId>
+ <version>20040616</version>
+ </dependency>
+ <dependency>
+ <groupId>commons-logging</groupId>
+ <artifactId>commons-logging</artifactId>
+ <version>1.1</version>
+ <exclusions>
+ <exclusion>
+ <groupId>javax.servlet</groupId>
+ <artifactId>servlet-api</artifactId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+ </dependencies>
+</project>
\ No newline at end of file
Added:
struts/sandbox/trunk/struts2-uel-plugin/src/main/java/org/apache/struts2/uelplugin/CompoundRootELContext.java
URL:
http://svn.apache.org/viewvc/struts/sandbox/trunk/struts2-uel-plugin/src/main/java/org/apache/struts2/uelplugin/CompoundRootELContext.java?rev=593725&view=auto
==============================================================================
---
struts/sandbox/trunk/struts2-uel-plugin/src/main/java/org/apache/struts2/uelplugin/CompoundRootELContext.java
(added)
+++
struts/sandbox/trunk/struts2-uel-plugin/src/main/java/org/apache/struts2/uelplugin/CompoundRootELContext.java
Fri Nov 9 18:47:29 2007
@@ -0,0 +1,51 @@
+package org.apache.struts2.uelplugin;
+
+import javax.el.ArrayELResolver;
+import javax.el.CompositeELResolver;
+import javax.el.ELContext;
+import javax.el.ELResolver;
+import javax.el.FunctionMapper;
+import javax.el.ListELResolver;
+import javax.el.MapELResolver;
+import javax.el.ResourceBundleELResolver;
+import javax.el.VariableMapper;
+
+import org.apache.struts2.uelplugin.elresolvers.CompoundRootELResolver;
+import org.apache.struts2.uelplugin.elresolvers.XWorkBeanELResolver;
+
+
+/**
+ * An implementation of SimpleContext that knows about the ValueStack's
+ * CompoundRoot.
+ */
+public class CompoundRootELContext extends ELContext {
+ private ELResolver DEFAULT_RESOLVER_READ_WRITE;
+
+ 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());
+ }
+ };
+ }
+
+ @Override
+ public VariableMapper getVariableMapper() {
+ return null;
+ }
+
+ @Override
+ public ELResolver getELResolver() {
+ return DEFAULT_RESOLVER_READ_WRITE;
+ }
+
+ @Override
+ public FunctionMapper getFunctionMapper() {
+ return null;
+ }
+}
Added:
struts/sandbox/trunk/struts2-uel-plugin/src/main/java/org/apache/struts2/uelplugin/UelReflectionContextFactory.java
URL:
http://svn.apache.org/viewvc/struts/sandbox/trunk/struts2-uel-plugin/src/main/java/org/apache/struts2/uelplugin/UelReflectionContextFactory.java?rev=593725&view=auto
==============================================================================
---
struts/sandbox/trunk/struts2-uel-plugin/src/main/java/org/apache/struts2/uelplugin/UelReflectionContextFactory.java
(added)
+++
struts/sandbox/trunk/struts2-uel-plugin/src/main/java/org/apache/struts2/uelplugin/UelReflectionContextFactory.java
Fri Nov 9 18:47:29 2007
@@ -0,0 +1,15 @@
+package org.apache.struts2.uelplugin;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import com.opensymphony.xwork2.util.reflection.ReflectionContextFactory;
+
+/**
+ * ReflectionContextFactory for Unified EL.
+ */
+public class UelReflectionContextFactory implements ReflectionContextFactory {
+ public Map createDefaultContext(Object root) {
+ return new HashMap();
+ }
+}
Added:
struts/sandbox/trunk/struts2-uel-plugin/src/main/java/org/apache/struts2/uelplugin/UelReflectionProvider.java
URL:
http://svn.apache.org/viewvc/struts/sandbox/trunk/struts2-uel-plugin/src/main/java/org/apache/struts2/uelplugin/UelReflectionProvider.java?rev=593725&view=auto
==============================================================================
---
struts/sandbox/trunk/struts2-uel-plugin/src/main/java/org/apache/struts2/uelplugin/UelReflectionProvider.java
(added)
+++
struts/sandbox/trunk/struts2-uel-plugin/src/main/java/org/apache/struts2/uelplugin/UelReflectionProvider.java
Fri Nov 9 18:47:29 2007
@@ -0,0 +1,58 @@
+package org.apache.struts2.uelplugin;
+
+import java.util.Map;
+
+import javax.el.ELContext;
+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;
+
+/**
+ * A OgnlReflectionProvider based on Unified EL.
+ */
+public class UelReflectionProvider extends OgnlReflectionProvider {
+ private ExpressionFactory factory;
+ private XWorkConverter xworkConverter;
+
+ @Inject
+ public void setXWorkConverter(XWorkConverter conv) {
+ this.xworkConverter = conv;
+ }
+
+ public void initExpressionFactory() {
+ if (factory == null) {
+ factory = ExpressionFactory.newInstance();
+ }
+ }
+
+ @Override
+ public Object getValue(String expr, Map context, Object root) throws
ReflectionException {
+ initExpressionFactory();
+ CompoundRoot compoundRoot = new CompoundRoot();
+ compoundRoot.add(root);
+ ELContext elContext = new CompoundRootELContext();
+ elContext.putContext(XWorkConverter.class, xworkConverter);
+ // parse our expression
+ ValueExpression valueExpr = factory.createValueExpression(elContext,
+ expr, String.class);
+ return (String) valueExpr.getValue(elContext);
+ }
+
+ @Override
+ public void setValue(String expr, Map context, Object root, Object value)
throws ReflectionException {
+ initExpressionFactory();
+ CompoundRoot compoundRoot = new CompoundRoot();
+ compoundRoot.add(root);
+ ELContext elContext = new CompoundRootELContext();
+ elContext.putContext(XWorkConverter.class, xworkConverter);
+ // parse our expression
+ ValueExpression valueExpr = factory.createValueExpression(elContext,
+ expr, String.class);
+ valueExpr.setValue(elContext, value);
+ }
+}
Added:
struts/sandbox/trunk/struts2-uel-plugin/src/main/java/org/apache/struts2/uelplugin/UelValueStack.java
URL:
http://svn.apache.org/viewvc/struts/sandbox/trunk/struts2-uel-plugin/src/main/java/org/apache/struts2/uelplugin/UelValueStack.java?rev=593725&view=auto
==============================================================================
---
struts/sandbox/trunk/struts2-uel-plugin/src/main/java/org/apache/struts2/uelplugin/UelValueStack.java
(added)
+++
struts/sandbox/trunk/struts2-uel-plugin/src/main/java/org/apache/struts2/uelplugin/UelValueStack.java
Fri Nov 9 18:47:29 2007
@@ -0,0 +1,168 @@
+package org.apache.struts2.uelplugin;
+
+import java.util.Map;
+import java.util.TreeMap;
+
+import javax.el.ELContext;
+import javax.el.ELException;
+import javax.el.ExpressionFactory;
+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;
+
+/**
+ * A ValueStack that uses Unified EL as the underlying Expression Language.
+ */
+public class UelValueStack implements ValueStack {
+ private CompoundRoot root = new CompoundRoot();
+ private transient Map context;
+ private Class defaultType;
+ private Map overrides;
+ private XWorkConverter xworkConverter;
+
+ private ExpressionFactory factory;
+
+ private ELContext elContext;
+
+ public UelValueStack(ExpressionFactory factory,
+ XWorkConverter xworkConverter) {
+ this(factory, xworkConverter, new CompoundRoot());
+ }
+
+ public UelValueStack(ExpressionFactory factory,
+ XWorkConverter xworkConverter, ValueStack vs) {
+ this(factory, xworkConverter, new CompoundRoot(vs.getRoot()));
+ }
+
+ public UelValueStack(ExpressionFactory factory,
+ XWorkConverter xworkConverter, CompoundRoot root) {
+ this.xworkConverter = xworkConverter;
+ this.factory = factory;
+ setRoot(new CompoundRoot());
+ }
+
+ public String findString(String expr) {
+ return (String) findValue(expr, String.class);
+ }
+
+ public Object findValue(String expr) {
+ return findValue(expr, Object.class);
+ }
+
+ public Object findValue(String expr, Class asType) {
+ try {
+ if (expr != null && expr.startsWith("#") &&
!expr.startsWith("#{")) {
+ int firstDot = expr.indexOf('.');
+ String key = expr.substring(1, firstDot);
+ String value = expr.substring(firstDot + 1);
+ Map map = (Map) context.get(key);
+ return map.get(value);
+ }
+ if ((overrides != null) && overrides.containsKey(expr))
{
+ expr = (String) overrides.get(expr);
+ }
+ if (expr != null && expr.startsWith("%{")) {
+ // replace %{ with ${
+ expr = "#" + expr.substring(1);
+ }
+ if (expr != null && !expr.startsWith("${")
+ && !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);
+ Object retVal = valueExpr.getValue(elContext);
+ if (!Object.class.equals(asType)) {
+ retVal = xworkConverter.convertValue(null,
retVal, asType);
+ }
+ return retVal;
+ } catch (PropertyNotFoundException e) {
+ // property not found
+ return null;
+ } catch (ELException e) {
+ // fail silently so we don't mess things up
+ return null;
+ }
+ }
+
+ public Map getContext() {
+ return context;
+ }
+
+ public Map getExprOverrides() {
+ return overrides;
+ }
+
+ public CompoundRoot getRoot() {
+ return root;
+ }
+
+ public Object peek() {
+ return root.peek();
+ }
+
+ public Object pop() {
+ return root.pop();
+ }
+
+ public void push(Object o) {
+ root.push(o);
+ }
+
+ public void setDefaultType(Class defaultType) {
+ this.defaultType = defaultType;
+ }
+
+ public void setExprOverrides(Map overrides) {
+ if (this.overrides == null) {
+ this.overrides = overrides;
+ } else {
+ this.overrides.putAll(overrides);
+ }
+ }
+
+ public void set(String key, Object o) {
+ overrides.put(key, o);
+ }
+
+ public void setValue(String expr, Object value) {
+ setValue(expr, value, false);
+ }
+
+ public void setValue(String expr, Object value,
+ boolean throwExceptionOnFailure) {
+ try {
+ if (expr != null && !expr.startsWith("${")
+ && !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);
+ valueExpr.setValue(elContext, value);
+ } catch (ELException e) {
+ if (throwExceptionOnFailure) {
+ throw e;
+ }
+ }
+ }
+
+ public int size() {
+ return root.size();
+ }
+
+ protected void setRoot(CompoundRoot root) {
+ this.context = new TreeMap();
+ context.put(VALUE_STACK, this);
+ this.root = root;
+ elContext = new CompoundRootELContext();
+ }
+}
Added:
struts/sandbox/trunk/struts2-uel-plugin/src/main/java/org/apache/struts2/uelplugin/UelValueStackFactory.java
URL:
http://svn.apache.org/viewvc/struts/sandbox/trunk/struts2-uel-plugin/src/main/java/org/apache/struts2/uelplugin/UelValueStackFactory.java?rev=593725&view=auto
==============================================================================
---
struts/sandbox/trunk/struts2-uel-plugin/src/main/java/org/apache/struts2/uelplugin/UelValueStackFactory.java
(added)
+++
struts/sandbox/trunk/struts2-uel-plugin/src/main/java/org/apache/struts2/uelplugin/UelValueStackFactory.java
Fri Nov 9 18:47:29 2007
@@ -0,0 +1,38 @@
+package org.apache.struts2.uelplugin;
+
+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;
+
+/**
+ * Creates JuelValueStacks.
+ */
+public class UelValueStackFactory implements ValueStackFactory {
+ private ExpressionFactory factory;
+
+ private XWorkConverter xworkConverter;
+
+ @Inject
+ public void setXWorkConverter(XWorkConverter conv) {
+ this.xworkConverter = conv;
+ }
+
+ public void initExpressionFactory() {
+ if (factory == null) {
+ factory = ExpressionFactory.newInstance();
+ }
+ }
+
+ public ValueStack createValueStack() {
+ initExpressionFactory();
+ return new UelValueStack(factory, xworkConverter);
+ }
+
+ public ValueStack createValueStack(ValueStack stack) {
+ initExpressionFactory();
+ return new UelValueStack(factory, xworkConverter, stack);
+ }
+}
Added:
struts/sandbox/trunk/struts2-uel-plugin/src/main/java/org/apache/struts2/uelplugin/contextlistener/UelServletContextListener.java
URL:
http://svn.apache.org/viewvc/struts/sandbox/trunk/struts2-uel-plugin/src/main/java/org/apache/struts2/uelplugin/contextlistener/UelServletContextListener.java?rev=593725&view=auto
==============================================================================
---
struts/sandbox/trunk/struts2-uel-plugin/src/main/java/org/apache/struts2/uelplugin/contextlistener/UelServletContextListener.java
(added)
+++
struts/sandbox/trunk/struts2-uel-plugin/src/main/java/org/apache/struts2/uelplugin/contextlistener/UelServletContextListener.java
Fri Nov 9 18:47:29 2007
@@ -0,0 +1,30 @@
+package org.apache.struts2.uelplugin.contextlistener;
+
+import javax.servlet.ServletContext;
+import javax.servlet.ServletContextEvent;
+import javax.servlet.ServletContextListener;
+import javax.servlet.jsp.JspApplicationContext;
+import javax.servlet.jsp.JspFactory;
+
+import org.apache.struts2.uelplugin.elresolvers.CompoundRootELResolver;
+import org.apache.struts2.uelplugin.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-uel-plugin/src/main/java/org/apache/struts2/uelplugin/elresolvers/CompoundRootELResolver.java
URL:
http://svn.apache.org/viewvc/struts/sandbox/trunk/struts2-uel-plugin/src/main/java/org/apache/struts2/uelplugin/elresolvers/CompoundRootELResolver.java?rev=593725&view=auto
==============================================================================
---
struts/sandbox/trunk/struts2-uel-plugin/src/main/java/org/apache/struts2/uelplugin/elresolvers/CompoundRootELResolver.java
(added)
+++
struts/sandbox/trunk/struts2-uel-plugin/src/main/java/org/apache/struts2/uelplugin/elresolvers/CompoundRootELResolver.java
Fri Nov 9 18:47:29 2007
@@ -0,0 +1,203 @@
+package org.apache.struts2.uelplugin.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;
+ }
+}
Added:
struts/sandbox/trunk/struts2-uel-plugin/src/main/java/org/apache/struts2/uelplugin/elresolvers/XWorkBeanELResolver.java
URL:
http://svn.apache.org/viewvc/struts/sandbox/trunk/struts2-uel-plugin/src/main/java/org/apache/struts2/uelplugin/elresolvers/XWorkBeanELResolver.java?rev=593725&view=auto
==============================================================================
---
struts/sandbox/trunk/struts2-uel-plugin/src/main/java/org/apache/struts2/uelplugin/elresolvers/XWorkBeanELResolver.java
(added)
+++
struts/sandbox/trunk/struts2-uel-plugin/src/main/java/org/apache/struts2/uelplugin/elresolvers/XWorkBeanELResolver.java
Fri Nov 9 18:47:29 2007
@@ -0,0 +1,57 @@
+package org.apache.struts2.uelplugin.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);
+ }
+
+ /**
+ * 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
+ public void setValue(ELContext context, Object base, Object property,
+ Object value) {
+ XWorkConverter converter = (XWorkConverter) context
+ .getContext(XWorkConverter.class);
+ try {
+ if (converter != null && base != null) {
+ Class propType =
PropertyUtils.getPropertyType(base, property
+ .toString());
+ value = converter.convertValue(null, 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);
+ }
+ }
+}
Added:
struts/sandbox/trunk/struts2-uel-plugin/src/main/resources/struts-plugin.xml
URL:
http://svn.apache.org/viewvc/struts/sandbox/trunk/struts2-uel-plugin/src/main/resources/struts-plugin.xml?rev=593725&view=auto
==============================================================================
---
struts/sandbox/trunk/struts2-uel-plugin/src/main/resources/struts-plugin.xml
(added)
+++
struts/sandbox/trunk/struts2-uel-plugin/src/main/resources/struts-plugin.xml
Fri Nov 9 18:47:29 2007
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+
+<!DOCTYPE struts PUBLIC
+ "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
+ "http://struts.apache.org/dtds/struts-2.0.dtd">
+
+<struts>
+ <bean type="com.opensymphony.xwork2.util.ValueStackFactory" name="uel"
class=" org.apache.struts2.uelplugin.UelValueStackFactory" />
+ <bean type="com.opensymphony.xwork2.util.reflection.ReflectionProvider"
name="uel" class="org.apache.struts2.uelplugin.UelReflectionProvider" />
+ <bean
type="com.opensymphony.xwork2.util.reflection.ReflectionContextFactory"
name="uel" class=" org.apache.struts2.uelplugin.UelReflectionContextFactory" />
+
+ <constant name="struts.valueStackFactory" value="uel" />
+ <constant name="struts.reflectionProvider" value="uel" />
+ <constant name="struts.reflectionContextFactory" value="uel" />
+</struts>
\ No newline at end of file
Added:
struts/sandbox/trunk/struts2-uel-plugin/src/test/java/org/apache/struts2/uelplugin/UelTest.java
URL:
http://svn.apache.org/viewvc/struts/sandbox/trunk/struts2-uel-plugin/src/test/java/org/apache/struts2/uelplugin/UelTest.java?rev=593725&view=auto
==============================================================================
---
struts/sandbox/trunk/struts2-uel-plugin/src/test/java/org/apache/struts2/uelplugin/UelTest.java
(added)
+++
struts/sandbox/trunk/struts2-uel-plugin/src/test/java/org/apache/struts2/uelplugin/UelTest.java
Fri Nov 9 18:47:29 2007
@@ -0,0 +1,217 @@
+package org.apache.struts2.uelplugin;
+
+import java.lang.reflect.InvocationTargetException;
+import java.text.DateFormat;
+import java.text.ParseException;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.el.ExpressionFactory;
+
+import org.apache.struts2.uelplugin.UelValueStack;
+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 UelTest extends XWorkTestCase {
+ private ExpressionFactory factory = ExpressionFactory.newInstance();
+ private XWorkConverter converter;
+ private DateFormat format = DateFormat.getDateInstance();
+
+ private class DateConverter extends StrutsTypeConverter {
+
+ @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);
+ }
+
+ }
+
+ 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);
+ UelValueStack stack = new UelValueStack(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 testSetStringArray() throws IllegalAccessException,
+ InvocationTargetException, NoSuchMethodException {
+ CompoundRoot root = new CompoundRoot();
+ TestObject obj = new TestObject();
+ root.add(obj);
+ UelValueStack stack = new UelValueStack(factory, converter);
+ stack.setRoot(root);
+ stack.setValue("${value}", new String[] { "Hello World" });
+ String value = stack.findString("${value}");
+ assertEquals("Hello World", value);
+
+ stack.setValue("${age}", new String[] { "67" });
+ assertEquals(new Integer(67), stack.findValue("${age}"));
+ }
+
+ public void testDeferredFind() throws IllegalAccessException,
+ InvocationTargetException, NoSuchMethodException {
+ CompoundRoot root = new CompoundRoot();
+ TestObject obj = new TestObject();
+ root.add(obj);
+
+ UelValueStack stack = new UelValueStack(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);
+
+ stack.setValue("#{date}", new Date());
+ 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);
+
+ UelValueStack stack = new UelValueStack(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();
+ TestObject obj = new TestObject();
+ TestObject nestedObj = new TestObject();
+ obj.setInner(nestedObj);
+ root.add(obj);
+ UelValueStack stack = new UelValueStack(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);
+ UelValueStack stack = new UelValueStack(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}"),
format.format(obj.getDate()));
+ }
+
+ public void testNotFound() throws IllegalAccessException,
+ InvocationTargetException, NoSuchMethodException {
+ CompoundRoot root = new CompoundRoot();
+ TestObject obj = new TestObject();
+ root.add(obj);
+ UelValueStack stack = new UelValueStack(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;
+ private Map parameters;
+
+ 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;
+ }
+
+ public Map getParameters() {
+ return parameters;
+ }
+
+ public void setParameters(Map parameters) {
+ this.parameters = parameters;
+ }
+ }
+}