Author: tschneider Date: Sun Nov 4 10:50:44 2007 New Revision: 591816 URL: http://svn.apache.org/viewvc?rev=591816&view=rev Log: checking in the initial alpha version of a struts2 juel plugin
Added: struts/sandbox/trunk/struts2-juel-plugin/ struts/sandbox/trunk/struts2-juel-plugin/pom.xml struts/sandbox/trunk/struts2-juel-plugin/src/ struts/sandbox/trunk/struts2-juel-plugin/src/main/ struts/sandbox/trunk/struts2-juel-plugin/src/main/java/ struts/sandbox/trunk/struts2-juel-plugin/src/main/java/com/ struts/sandbox/trunk/struts2-juel-plugin/src/main/java/com/googlecode/ struts/sandbox/trunk/struts2-juel-plugin/src/main/java/com/googlecode/struts2juel/ 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/CompoundRootVariableMapper.java struts/sandbox/trunk/struts2-juel-plugin/src/main/java/com/googlecode/struts2juel/JuelReflectionContextFactory.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/main/resources/ struts/sandbox/trunk/struts2-juel-plugin/src/main/resources/struts-plugin.xml struts/sandbox/trunk/struts2-juel-plugin/src/test/ struts/sandbox/trunk/struts2-juel-plugin/src/test/java/ struts/sandbox/trunk/struts2-juel-plugin/src/test/java/com/ struts/sandbox/trunk/struts2-juel-plugin/src/test/java/com/googlecode/ struts/sandbox/trunk/struts2-juel-plugin/src/test/java/com/googlecode/struts2juel/ struts/sandbox/trunk/struts2-juel-plugin/src/test/java/com/googlecode/struts2juel/JuelTest.java Added: struts/sandbox/trunk/struts2-juel-plugin/pom.xml URL: http://svn.apache.org/viewvc/struts/sandbox/trunk/struts2-juel-plugin/pom.xml?rev=591816&view=auto ============================================================================== --- struts/sandbox/trunk/struts2-juel-plugin/pom.xml (added) +++ struts/sandbox/trunk/struts2-juel-plugin/pom.xml Sun Nov 4 10:50:44 2007 @@ -0,0 +1,69 @@ +<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>com.googlecode.struts2juel</groupId> + <artifactId>struts2-juel-plugin</artifactId> + <packaging>jar</packaging> + <name>Struts 2 Juel 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://struts2scopeplugin.googlecode.com/svn/trunk/ + </connection> + <developerConnection> + scm:svn:https://struts2scopeplugin.googlecode.com/svn/trunk/ + </developerConnection> + <url>http://struts2scopeplugin.googlecode.com/svn/trunk/</url> + </scm> + <dependencies> + <dependency> + <groupId>javax.servlet</groupId> + <artifactId>servlet-api</artifactId> + <version>2.4</version> + <scope>provided</scope> + </dependency> + <dependency> + <groupId>org.apache.struts</groupId> + <artifactId>struts2-core</artifactId> + <version>2.1.1-SNAPSHOT</version> + </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> + </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> + </dependency> + </dependencies> +</project> \ No newline at end of file Added: 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=591816&view=auto ============================================================================== --- struts/sandbox/trunk/struts2-juel-plugin/src/main/java/com/googlecode/struts2juel/CompoundRootELContext.java (added) +++ struts/sandbox/trunk/struts2-juel-plugin/src/main/java/com/googlecode/struts2juel/CompoundRootELContext.java Sun Nov 4 10:50:44 2007 @@ -0,0 +1,20 @@ +package com.googlecode.struts2juel; + +import javax.el.VariableMapper; + +import com.opensymphony.xwork2.util.CompoundRoot; + +import de.odysseus.el.util.SimpleContext; + +public class CompoundRootELContext extends SimpleContext { + private VariableMapper variableMapper; + + public CompoundRootELContext(CompoundRoot root) { + variableMapper = new CompoundRootVariableMapper(root); + } + + @Override + public VariableMapper getVariableMapper() { + return variableMapper; + } +} Added: struts/sandbox/trunk/struts2-juel-plugin/src/main/java/com/googlecode/struts2juel/CompoundRootVariableMapper.java URL: http://svn.apache.org/viewvc/struts/sandbox/trunk/struts2-juel-plugin/src/main/java/com/googlecode/struts2juel/CompoundRootVariableMapper.java?rev=591816&view=auto ============================================================================== --- struts/sandbox/trunk/struts2-juel-plugin/src/main/java/com/googlecode/struts2juel/CompoundRootVariableMapper.java (added) +++ struts/sandbox/trunk/struts2-juel-plugin/src/main/java/com/googlecode/struts2juel/CompoundRootVariableMapper.java Sun Nov 4 10:50:44 2007 @@ -0,0 +1,37 @@ +package com.googlecode.struts2juel; + +import javax.el.ValueExpression; +import javax.el.VariableMapper; + +import org.apache.commons.beanutils.PropertyUtils; + +import com.opensymphony.xwork2.util.CompoundRoot; + +public class CompoundRootVariableMapper extends VariableMapper { + private CompoundRoot root; + + public CompoundRootVariableMapper(CompoundRoot root) { + this.root = root; + } + + @Override + public ValueExpression resolveVariable(String variable) { + if ("top".equals(variable) && root.size() > 0) { + return new PropertyValueExpression(root.get(0), variable); + } + for (int i = 0; i < root.size(); i++) { + if (PropertyUtils.isReadable(root.get(i), variable) || + PropertyUtils.isWriteable(root.get(i), variable)) { + return new PropertyValueExpression(root.get(i), variable); + } + } + return null; + } + + @Override + public ValueExpression setVariable(String variable, ValueExpression valueExpression) { + // TODO Auto-generated method stub + return null; + } + +} Added: struts/sandbox/trunk/struts2-juel-plugin/src/main/java/com/googlecode/struts2juel/JuelReflectionContextFactory.java URL: http://svn.apache.org/viewvc/struts/sandbox/trunk/struts2-juel-plugin/src/main/java/com/googlecode/struts2juel/JuelReflectionContextFactory.java?rev=591816&view=auto ============================================================================== --- struts/sandbox/trunk/struts2-juel-plugin/src/main/java/com/googlecode/struts2juel/JuelReflectionContextFactory.java (added) +++ struts/sandbox/trunk/struts2-juel-plugin/src/main/java/com/googlecode/struts2juel/JuelReflectionContextFactory.java Sun Nov 4 10:50:44 2007 @@ -0,0 +1,13 @@ +package com.googlecode.struts2juel; + +import java.util.HashMap; +import java.util.Map; + +import com.opensymphony.xwork2.util.reflection.ReflectionContextFactory; + +public class JuelReflectionContextFactory implements ReflectionContextFactory { + + public Map createDefaultContext(Object root) { + return new HashMap(); + } +} Added: 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=591816&view=auto ============================================================================== --- struts/sandbox/trunk/struts2-juel-plugin/src/main/java/com/googlecode/struts2juel/JuelReflectionProvider.java (added) +++ struts/sandbox/trunk/struts2-juel-plugin/src/main/java/com/googlecode/struts2juel/JuelReflectionProvider.java Sun Nov 4 10:50:44 2007 @@ -0,0 +1,37 @@ +package com.googlecode.struts2juel; + +import java.util.Map; + +import javax.el.ELContext; +import javax.el.ExpressionFactory; +import javax.el.ValueExpression; + +import com.opensymphony.xwork2.ognl.OgnlReflectionProvider; +import com.opensymphony.xwork2.util.CompoundRoot; +import com.opensymphony.xwork2.util.reflection.ReflectionException; + +public class JuelReflectionProvider extends OgnlReflectionProvider { + ExpressionFactory factory = new de.odysseus.el.ExpressionFactoryImpl(); + + @Override + public Object getValue(String expr, Map context, Object root) throws ReflectionException { + CompoundRoot compoundRoot = new CompoundRoot(); + compoundRoot.add(root); + ELContext elContext = new CompoundRootELContext(compoundRoot); + // 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 { + CompoundRoot compoundRoot = new CompoundRoot(); + compoundRoot.add(root); + ELContext elContext = new CompoundRootELContext(compoundRoot); + // parse our expression + ValueExpression valueExpr = factory.createValueExpression(elContext, + expr, String.class); + valueExpr.setValue(elContext, value); + } +} Added: 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=591816&view=auto ============================================================================== --- struts/sandbox/trunk/struts2-juel-plugin/src/main/java/com/googlecode/struts2juel/JuelValueStack.java (added) +++ struts/sandbox/trunk/struts2-juel-plugin/src/main/java/com/googlecode/struts2juel/JuelValueStack.java Sun Nov 4 10:50:44 2007 @@ -0,0 +1,142 @@ +package com.googlecode.struts2juel; + +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.util.CompoundRoot; +import com.opensymphony.xwork2.util.ValueStack; + +public class JuelValueStack implements ValueStack { + private CompoundRoot root = new CompoundRoot(); + private transient Map context; + private Class defaultType; + private Map overrides; + + ExpressionFactory factory = new de.odysseus.el.ExpressionFactoryImpl(); + + ELContext elContext; + + public JuelValueStack() { + setRoot(new CompoundRoot()); + } + + public JuelValueStack(ValueStack vs) { + setRoot(new CompoundRoot(vs.getRoot())); + } + + 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("#")) { + 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(expr != null && expr.startsWith("%{")) { + // replace %{ with ${ + expr = expr.substring(1); + } + if(expr != null && !expr.startsWith("${")) { + expr = "${" + expr + "}"; + } + // parse our expression + ValueExpression valueExpr = factory.createValueExpression( + elContext, expr, asType); + Object retVal = valueExpr.getValue(elContext); + 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 set(String key, Object o) { + // TODO : what to do here? + } + + public void setDefaultType(Class defaultType) { + this.defaultType = defaultType; + } + + public void setExprOverrides(Map overrides) { + this.overrides = overrides; + } + + 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 = "${" + expr + "}"; + } + if(value != null && value instanceof String[] + && ((String[]) value).length == 1) { + value = ((String[]) value)[0]; + } + // 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; + this.elContext = new CompoundRootELContext(root); + } +} Added: 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=591816&view=auto ============================================================================== --- struts/sandbox/trunk/struts2-juel-plugin/src/main/java/com/googlecode/struts2juel/JuelValueStackFactory.java (added) +++ struts/sandbox/trunk/struts2-juel-plugin/src/main/java/com/googlecode/struts2juel/JuelValueStackFactory.java Sun Nov 4 10:50:44 2007 @@ -0,0 +1,15 @@ +package com.googlecode.struts2juel; + +import com.opensymphony.xwork2.util.ValueStack; +import com.opensymphony.xwork2.util.ValueStackFactory; + +public class JuelValueStackFactory implements ValueStackFactory { + + public ValueStack createValueStack() { + return new JuelValueStack(); + } + + public ValueStack createValueStack(ValueStack stack) { + return new JuelValueStack(stack); + } +} Added: 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=591816&view=auto ============================================================================== --- struts/sandbox/trunk/struts2-juel-plugin/src/main/java/com/googlecode/struts2juel/PropertyValueExpression.java (added) +++ struts/sandbox/trunk/struts2-juel-plugin/src/main/java/com/googlecode/struts2juel/PropertyValueExpression.java Sun Nov 4 10:50:44 2007 @@ -0,0 +1,102 @@ +package com.googlecode.struts2juel; + +import java.lang.reflect.InvocationTargetException; + +import javax.el.ELContext; +import javax.el.ValueExpression; + +import org.apache.commons.beanutils.PropertyUtils; + +public class PropertyValueExpression extends ValueExpression { + private Object object; + private String property; + + public PropertyValueExpression(Object object, String property) { + this.object = object; + this.property = property; + } + + @Override + public Class<?> getExpectedType() { + try { + return PropertyUtils.getPropertyType(object, property); + } catch(IllegalAccessException e) { + throw new RuntimeException(e); + } catch(InvocationTargetException e) { + throw new RuntimeException(e); + } catch(NoSuchMethodException e) { + throw new RuntimeException(e); + } + } + + @Override + public Class<?> getType(ELContext arg0) { + try { + return PropertyUtils.getPropertyType(object, property); + } 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 arg0) { + try { + return PropertyUtils.getSimpleProperty(object, property); + } catch(IllegalAccessException e) { + throw new RuntimeException(e); + } catch(InvocationTargetException e) { + throw new RuntimeException(e); + } catch(NoSuchMethodException e) { + throw new RuntimeException(e); + } + } + + @Override + public boolean isReadOnly(ELContext arg0) { + return PropertyUtils.isWriteable(object, property); + } + + @Override + public void setValue(ELContext arg0, Object obj) { + try { + PropertyUtils.setSimpleProperty(object, property, obj); + } catch(IllegalAccessException e) { + throw new RuntimeException(e); + } catch(InvocationTargetException e) { + throw new RuntimeException(e); + } catch(NoSuchMethodException e) { + throw new RuntimeException(e); + } + } + + @Override + public boolean equals(Object otherObject) { + if (otherObject != null && otherObject.getClass() == getClass()) { + PropertyValueExpression other = (PropertyValueExpression)otherObject; + if (property != other.property) { + return false; + } + return object == other.object || object != null && object.equals(other.object); + } + return false; + } + + @Override + public String getExpressionString() { + return null; + } + + @Override + public int hashCode() { + return property.hashCode(); + } + + @Override + public boolean isLiteralText() { + return false; + } +} Added: 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=591816&view=auto ============================================================================== --- struts/sandbox/trunk/struts2-juel-plugin/src/main/resources/struts-plugin.xml (added) +++ struts/sandbox/trunk/struts2-juel-plugin/src/main/resources/struts-plugin.xml Sun Nov 4 10:50:44 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="juel" class="com.googlecode.struts2juel.JuelValueStackFactory" /> + <bean type="com.opensymphony.xwork2.util.reflection.ReflectionProvider" name="juel" class="com.googlecode.struts2juel.JuelReflectionProvider" /> + <bean type="com.opensymphony.xwork2.util.reflection.ReflectionContextFactory" name="juel" class="com.googlecode.struts2juel.JuelReflectionContextFactory" /> + + <constant name="struts.valueStackFactory" value="juel" /> + <constant name="struts.reflectionProvider" value="juel" /> + <constant name="struts.reflectionContextFactory" value="juel" /> +</struts> \ No newline at end of file Added: 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=591816&view=auto ============================================================================== --- struts/sandbox/trunk/struts2-juel-plugin/src/test/java/com/googlecode/struts2juel/JuelTest.java (added) +++ struts/sandbox/trunk/struts2-juel-plugin/src/test/java/com/googlecode/struts2juel/JuelTest.java Sun Nov 4 10:50:44 2007 @@ -0,0 +1,54 @@ +package com.googlecode.struts2juel; + +import java.lang.reflect.InvocationTargetException; + +import javax.el.ExpressionFactory; + +import junit.framework.TestCase; + +import com.opensymphony.xwork2.util.CompoundRoot; + +public class JuelTest extends TestCase { + 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(); + 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(); + 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; + } + } +}