You are viewing a plain text version of this content. The canonical link for it is here.
Posted to cvs@cocoon.apache.org by da...@apache.org on 2005/01/02 22:15:37 UTC

svn commit: r123901 - in cocoon/trunk/src/blocks/template: java/org/apache/cocoon/components java/org/apache/cocoon/components/expression java/org/apache/cocoon/components/expression/jexl test/org/apache/cocoon/components test/org/apache/cocoon/components/expression test/org/apache/cocoon/components/expression/jexl

Author: danielf
Date: Sun Jan  2 13:15:36 2005
New Revision: 123901

URL: http://svn.apache.org/viewcvs?view=rev&rev=123901
Log:
Pluggable expressions. This far only jexl and only part of the intended functionallity is supported.
Added:
   cocoon/trunk/src/blocks/template/java/org/apache/cocoon/components/
   cocoon/trunk/src/blocks/template/java/org/apache/cocoon/components/expression/
   cocoon/trunk/src/blocks/template/java/org/apache/cocoon/components/expression/Expression.java
   cocoon/trunk/src/blocks/template/java/org/apache/cocoon/components/expression/ExpressionCompiler.java
   cocoon/trunk/src/blocks/template/java/org/apache/cocoon/components/expression/ExpressionContext.java
   cocoon/trunk/src/blocks/template/java/org/apache/cocoon/components/expression/ExpressionException.java
   cocoon/trunk/src/blocks/template/java/org/apache/cocoon/components/expression/ExpressionFactory.java
   cocoon/trunk/src/blocks/template/java/org/apache/cocoon/components/expression/jexl/
   cocoon/trunk/src/blocks/template/java/org/apache/cocoon/components/expression/jexl/JexlCompiler.java
   cocoon/trunk/src/blocks/template/java/org/apache/cocoon/components/expression/jexl/JexlExpression.java
   cocoon/trunk/src/blocks/template/test/org/apache/cocoon/components/
   cocoon/trunk/src/blocks/template/test/org/apache/cocoon/components/expression/
   cocoon/trunk/src/blocks/template/test/org/apache/cocoon/components/expression/ExpressionTestCase.java
   cocoon/trunk/src/blocks/template/test/org/apache/cocoon/components/expression/ExpressionTestCase.xtest
   cocoon/trunk/src/blocks/template/test/org/apache/cocoon/components/expression/jexl/
   cocoon/trunk/src/blocks/template/test/org/apache/cocoon/components/expression/jexl/JexlTestCase.java

Added: cocoon/trunk/src/blocks/template/java/org/apache/cocoon/components/expression/Expression.java
Url: http://svn.apache.org/viewcvs/cocoon/trunk/src/blocks/template/java/org/apache/cocoon/components/expression/Expression.java?view=auto&rev=123901
==============================================================================
--- (empty file)
+++ cocoon/trunk/src/blocks/template/java/org/apache/cocoon/components/expression/Expression.java	Sun Jan  2 13:15:36 2005
@@ -0,0 +1,30 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.cocoon.components.expression;
+
+import java.util.Iterator;
+
+public interface Expression {
+    public Object evaluate(ExpressionContext context) throws ExpressionException;
+
+    public Iterator iterate(ExpressionContext context) throws ExpressionException;
+
+    public void assign(ExpressionContext context, Object value) throws ExpressionException;
+
+    public String getExpression();
+
+    public String getLanguage();
+}

Added: cocoon/trunk/src/blocks/template/java/org/apache/cocoon/components/expression/ExpressionCompiler.java
Url: http://svn.apache.org/viewcvs/cocoon/trunk/src/blocks/template/java/org/apache/cocoon/components/expression/ExpressionCompiler.java?view=auto&rev=123901
==============================================================================
--- (empty file)
+++ cocoon/trunk/src/blocks/template/java/org/apache/cocoon/components/expression/ExpressionCompiler.java	Sun Jan  2 13:15:36 2005
@@ -0,0 +1,23 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.cocoon.components.expression;
+
+public interface ExpressionCompiler {
+    public String ROLE = ExpressionCompiler.class.getName();
+
+    public Expression compile(String language, String expression)
+        throws ExpressionException;
+}

Added: cocoon/trunk/src/blocks/template/java/org/apache/cocoon/components/expression/ExpressionContext.java
Url: http://svn.apache.org/viewcvs/cocoon/trunk/src/blocks/template/java/org/apache/cocoon/components/expression/ExpressionContext.java?view=auto&rev=123901
==============================================================================
--- (empty file)
+++ cocoon/trunk/src/blocks/template/java/org/apache/cocoon/components/expression/ExpressionContext.java	Sun Jan  2 13:15:36 2005
@@ -0,0 +1,69 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.cocoon.components.expression;
+
+import java.util.HashMap;
+import java.util.Map;
+
+public class ExpressionContext extends HashMap {
+    private ExpressionContext closure;
+    private Object contextBean = null;
+
+    public ExpressionContext() {
+        this(null);
+    }
+
+    public ExpressionContext(ExpressionContext closure) {
+        this.closure = closure;
+    }
+
+    public Object getContextBean() {
+        if (contextBean != null)
+            return contextBean;
+        else if (closure != null)
+            return closure.getContextBean();
+        else
+            return null;
+    }
+
+    public void setContextBean(Object contextBean) {
+        this.contextBean = contextBean;
+    }
+
+    public Map getVars() {
+        return this;
+    }
+
+    public void setVars(Map map) {
+        clear();
+        putAll(map);
+    }
+
+    public boolean containsKey(Object key) {
+        return this.get(key) != null;
+    }
+
+    public Object get(Object key) {
+        if (key.equals("this")) {
+            return this;
+        }
+        Object result = super.get(key);
+        if (result == null && closure != null) {
+            result = closure.get(key);
+        }
+        return result;
+    }
+}

Added: cocoon/trunk/src/blocks/template/java/org/apache/cocoon/components/expression/ExpressionException.java
Url: http://svn.apache.org/viewcvs/cocoon/trunk/src/blocks/template/java/org/apache/cocoon/components/expression/ExpressionException.java?view=auto&rev=123901
==============================================================================
--- (empty file)
+++ cocoon/trunk/src/blocks/template/java/org/apache/cocoon/components/expression/ExpressionException.java	Sun Jan  2 13:15:36 2005
@@ -0,0 +1,58 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.cocoon.components.expression;
+
+import java.io.IOException;
+
+import org.apache.avalon.framework.CascadingThrowable;
+
+public class ExpressionException
+    extends IOException implements CascadingThrowable
+{
+    /**
+     * The Throwable that caused this exception to be thrown.
+     */
+    private final Throwable throwable;
+
+    /**
+     * Construct a new <code>ExpressionException</code> instance.
+     *
+     * @param message the detail message for this exception.
+     */
+    public ExpressionException(final String message) {
+        this(message, null);
+    }
+
+    /**
+     * Construct a new <code>ExpressionException</code> instance.
+     *
+     * @param message the detail message for this exception.
+     * @param throwable the root cause of the exception.
+     */
+    public ExpressionException(final String message, final Throwable throwable) {
+        super(message);
+        this.throwable = throwable;
+    }
+    
+    /**
+     * Retrieve the cause of the exception.
+     *
+     * @return the cause.
+     */
+    public final Throwable getCause() {
+        return this.throwable;
+    }
+}

Added: cocoon/trunk/src/blocks/template/java/org/apache/cocoon/components/expression/ExpressionFactory.java
Url: http://svn.apache.org/viewcvs/cocoon/trunk/src/blocks/template/java/org/apache/cocoon/components/expression/ExpressionFactory.java?view=auto&rev=123901
==============================================================================
--- (empty file)
+++ cocoon/trunk/src/blocks/template/java/org/apache/cocoon/components/expression/ExpressionFactory.java	Sun Jan  2 13:15:36 2005
@@ -0,0 +1,68 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.cocoon.components.expression;
+
+import org.apache.avalon.framework.CascadingRuntimeException;
+import org.apache.avalon.framework.activity.Disposable;
+import org.apache.avalon.framework.logger.AbstractLogEnabled;
+import org.apache.avalon.framework.service.ServiceException;
+import org.apache.avalon.framework.service.ServiceManager;
+import org.apache.avalon.framework.service.ServiceSelector;
+import org.apache.avalon.framework.service.Serviceable;
+import org.apache.avalon.framework.thread.ThreadSafe;
+
+public class ExpressionFactory
+    extends AbstractLogEnabled
+    implements Disposable, Serviceable, ThreadSafe {
+    public static String ROLE = ExpressionFactory.class.getName();
+
+    /** The component manager */
+    protected ServiceManager manager;
+
+    /** The Expression compiler selector */
+    protected ServiceSelector compilerSelector;
+
+    public void service(final ServiceManager manager)
+        throws ServiceException {
+        this.manager = manager;
+
+        this.compilerSelector =
+            (ServiceSelector)this.manager.lookup(ExpressionCompiler.ROLE + "Selector");
+    }
+
+    public void dispose() {
+        if(null != this.manager) {
+            this.manager.release(this.compilerSelector);
+            this.compilerSelector = null;
+        }
+    }
+
+    public Expression getExpression(String language, String expression)
+        throws ExpressionException {
+
+        Expression expressionImpl = null;
+        ExpressionCompiler compiler = null;
+        try {
+            compiler = (ExpressionCompiler)this.compilerSelector.select(language);
+            expressionImpl = compiler.compile(language, expression);
+        } catch(final ServiceException ce) {
+            throw new ExpressionException("Can't find a compiler for " + language);
+        } finally {
+            this.compilerSelector.release(compiler);
+        }
+        return expressionImpl;
+    }
+}

Added: cocoon/trunk/src/blocks/template/java/org/apache/cocoon/components/expression/jexl/JexlCompiler.java
Url: http://svn.apache.org/viewcvs/cocoon/trunk/src/blocks/template/java/org/apache/cocoon/components/expression/jexl/JexlCompiler.java?view=auto&rev=123901
==============================================================================
--- (empty file)
+++ cocoon/trunk/src/blocks/template/java/org/apache/cocoon/components/expression/jexl/JexlCompiler.java	Sun Jan  2 13:15:36 2005
@@ -0,0 +1,28 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.cocoon.components.expression.jexl;
+
+import org.apache.avalon.framework.thread.ThreadSafe;
+import org.apache.cocoon.components.expression.Expression;
+import org.apache.cocoon.components.expression.ExpressionCompiler;
+import org.apache.cocoon.components.expression.ExpressionException;
+
+public class JexlCompiler implements ExpressionCompiler, ThreadSafe {
+    public Expression compile(String language, String expression)
+        throws ExpressionException{
+        return new JexlExpression(language, expression);
+    }
+}

Added: cocoon/trunk/src/blocks/template/java/org/apache/cocoon/components/expression/jexl/JexlExpression.java
Url: http://svn.apache.org/viewcvs/cocoon/trunk/src/blocks/template/java/org/apache/cocoon/components/expression/jexl/JexlExpression.java?view=auto&rev=123901
==============================================================================
--- (empty file)
+++ cocoon/trunk/src/blocks/template/java/org/apache/cocoon/components/expression/jexl/JexlExpression.java	Sun Jan  2 13:15:36 2005
@@ -0,0 +1,84 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.cocoon.components.expression.jexl;
+
+import java.util.Iterator;
+import java.util.Map;
+
+import org.apache.commons.jexl.JexlContext;
+import org.apache.cocoon.components.expression.Expression;
+import org.apache.cocoon.components.expression.ExpressionCompiler;
+import org.apache.cocoon.components.expression.ExpressionContext;
+import org.apache.cocoon.components.expression.ExpressionException;
+
+public class JexlExpression implements Expression {
+
+    private final String language;
+    private final org.apache.commons.jexl.Expression compiledExpression;
+
+    public JexlExpression(String language, String expression)
+        throws ExpressionException {
+        this.language = language;
+        try {
+            this.compiledExpression =
+                org.apache.commons.jexl.ExpressionFactory.createExpression(expression);
+        } catch (Exception e) {
+            throw new ExpressionException("Couldn't create expression " + expression, e);
+        }
+    }
+
+    public Object evaluate(ExpressionContext context)
+        throws ExpressionException{
+        try {
+            return this.compiledExpression.evaluate(new ContextAdapter(context));
+        } catch (Exception e) {
+            throw new ExpressionException("Couldn't evaluate expression " +
+                                          getExpression(), e);
+        }
+    }
+
+    public Iterator iterate(ExpressionContext context)
+        throws ExpressionException {
+        return null;
+    }
+
+    public void assign(ExpressionContext context, Object value)
+        throws ExpressionException {
+    }
+
+    public String getExpression() {
+        return this.compiledExpression.getExpression();
+    }
+
+    public String getLanguage() {
+        return this.language;
+    }
+
+    static class ContextAdapter implements JexlContext {
+        private final ExpressionContext context;
+        public ContextAdapter(ExpressionContext context) {
+            this.context = context;
+        }
+
+        public Map getVars() {
+            return this.context.getVars();
+        }
+
+        public void setVars(Map map) {
+            this.context.setVars(map);
+        }
+    }
+}

Added: cocoon/trunk/src/blocks/template/test/org/apache/cocoon/components/expression/ExpressionTestCase.java
Url: http://svn.apache.org/viewcvs/cocoon/trunk/src/blocks/template/test/org/apache/cocoon/components/expression/ExpressionTestCase.java?view=auto&rev=123901
==============================================================================
--- (empty file)
+++ cocoon/trunk/src/blocks/template/test/org/apache/cocoon/components/expression/ExpressionTestCase.java	Sun Jan  2 13:15:36 2005
@@ -0,0 +1,57 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.cocoon.components.expression;
+
+import org.apache.avalon.framework.service.ServiceException;
+import org.apache.cocoon.CocoonTestCase;
+
+public class ExpressionTestCase extends CocoonTestCase {
+
+    public void testContext() {
+        ExpressionContext parentContext = new ExpressionContext();
+        parentContext.put("var1", "foo");
+        parentContext.put("var2", "bar");
+
+        ExpressionContext context = new ExpressionContext(parentContext);
+        context.put("var1", "zonk");
+
+        assertEquals("foo", parentContext.get("var1"));
+        assertEquals("bar", parentContext.get("var2"));
+        assertEquals("zonk", context.get("var1"));
+        assertEquals("bar", context.get("var2"));
+    }
+
+    public void testContextBean() {
+        ExpressionContext parentContext = new ExpressionContext();
+        parentContext.setContextBean("foo");
+
+        ExpressionContext context = new ExpressionContext(parentContext);
+        context.setContextBean("bar");
+
+        assertEquals("foo", parentContext.getContextBean());
+        assertEquals("bar", context.getContextBean());
+    }
+
+    public void testFactory() throws ExpressionException, ServiceException {
+        ExpressionFactory factory = (ExpressionFactory)this.lookup(ExpressionFactory.ROLE);
+        assertNotNull("Test lookup of expression factory", factory);
+
+        Expression expression = factory.getExpression("jexl", "1+2");
+        assertNotNull("Test expression compilation", expression);
+
+        assertEquals(new Long(3), expression.evaluate(new ExpressionContext()));
+    }
+}

Added: cocoon/trunk/src/blocks/template/test/org/apache/cocoon/components/expression/ExpressionTestCase.xtest
Url: http://svn.apache.org/viewcvs/cocoon/trunk/src/blocks/template/test/org/apache/cocoon/components/expression/ExpressionTestCase.xtest?view=auto&rev=123901
==============================================================================
--- (empty file)
+++ cocoon/trunk/src/blocks/template/test/org/apache/cocoon/components/expression/ExpressionTestCase.xtest	Sun Jan  2 13:15:36 2005
@@ -0,0 +1,34 @@
+<?xml version="1.0"?>
+<!--
+  Copyright 1999-2004 The Apache Software Foundation
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+-->
+
+<testcase>
+  <roles>
+    <role name="org.apache.cocoon.components.expression.ExpressionCompilerSelector"
+          shorthand="expression-compilers"
+          default-class="org.apache.cocoon.core.container.DefaultServiceSelector"/>
+    <role name="org.apache.cocoon.components.expression.ExpressionFactory"
+          shorthand="expression-factory"
+          default-class="org.apache.cocoon.components.expression.ExpressionFactory"/>
+  </roles>
+ 
+  <components>
+    <expression-compilers>
+      <component-instance class="org.apache.cocoon.components.expression.jexl.JexlCompiler" name="jexl"/>
+    </expression-compilers>
+  </components>
+ 
+</testcase>

Added: cocoon/trunk/src/blocks/template/test/org/apache/cocoon/components/expression/jexl/JexlTestCase.java
Url: http://svn.apache.org/viewcvs/cocoon/trunk/src/blocks/template/test/org/apache/cocoon/components/expression/jexl/JexlTestCase.java?view=auto&rev=123901
==============================================================================
--- (empty file)
+++ cocoon/trunk/src/blocks/template/test/org/apache/cocoon/components/expression/jexl/JexlTestCase.java	Sun Jan  2 13:15:36 2005
@@ -0,0 +1,40 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.cocoon.components.expression.jexl;
+
+import junit.framework.TestCase;
+import org.apache.cocoon.components.expression.Expression;
+import org.apache.cocoon.components.expression.ExpressionCompiler;
+import org.apache.cocoon.components.expression.ExpressionContext;
+import org.apache.cocoon.components.expression.ExpressionException;
+
+public class JexlTestCase extends TestCase {
+
+    public void testExpression() throws ExpressionException {
+        ExpressionCompiler compiler = new JexlCompiler();
+        Expression expression = compiler.compile("jexl", "1+2");
+        assertEquals(new Long(3), expression.evaluate(new ExpressionContext()));
+    }
+
+    public void testContextExpression() throws ExpressionException {
+        ExpressionCompiler compiler = new JexlCompiler();
+        ExpressionContext context = new ExpressionContext();
+        context.put("a", new Long(1));
+        context.put("b", new Long(2));
+        Expression expression = compiler.compile("jexl", "a+b");
+        assertEquals(new Long(3), expression.evaluate(context));
+    }
+}