Author: cbrisson
Date: Sat Feb 21 18:54:21 2009
New Revision: 746564

URL: http://svn.apache.org/viewvc?rev=746564&view=rev
Log:
WebappUberspector to allow ,  and  control objets to share their attributes via 
standard property getters and setters

Added:
    
velocity/tools/trunk/src/main/java/org/apache/velocity/tools/view/WebappUberspector.java
Modified:
    
velocity/tools/trunk/src/main/java/org/apache/velocity/tools/view/velocity.properties

Added: 
velocity/tools/trunk/src/main/java/org/apache/velocity/tools/view/WebappUberspector.java
URL: 
http://svn.apache.org/viewvc/velocity/tools/trunk/src/main/java/org/apache/velocity/tools/view/WebappUberspector.java?rev=746564&view=auto
==============================================================================
--- 
velocity/tools/trunk/src/main/java/org/apache/velocity/tools/view/WebappUberspector.java
 (added)
+++ 
velocity/tools/trunk/src/main/java/org/apache/velocity/tools/view/WebappUberspector.java
 Sat Feb 21 18:54:21 2009
@@ -0,0 +1,241 @@
+package org.apache.velocity.tools.view;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.
+ */
+
+import org.apache.velocity.util.introspection.*;
+import org.apache.velocity.runtime.parser.node.AbstractExecutor;
+import org.apache.velocity.runtime.parser.node.SetExecutor;
+import org.apache.velocity.runtime.log.Log;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpSession;
+import javax.servlet.ServletContext;
+import java.lang.reflect.InvocationTargetException;
+
+/**
+ * <p>This custom uberspector allows getAttribute() and setAttribute() as 
standard
+ * getters and setters for the "request","session" and "application" keys.
+ * <p>It allows VTL statements like:
+ * <pre>
+ * #set($session.foo = 'youpi')
+ * session parameter 'foo' has value: $session.foo
+ * </pre>
+ * </p>
+ * <p>This uberspector requires Velocity 1.6+ ; to use it, you must specify 
<code>org.apache.velocity.tools.view.WebappUberspector</code>
+ * as the last uberspector to the <code>runtime.introspector.uberspect</code> 
property in you <code>velocity.properties</code> file.</p>
+ *
+ * <p>For instance:</p>
+ *
+ * <p><code>runtime.introspector.uberspect = 
org.apache.velocity.util.introspection.UberspectImpl,org.apache.velocity.tools.view.WebappUberspector</code></p>
+ *
+ * @author <a href="mailto:cbris...@apache.org";>Claude Brisson</a>
+ * @version $Id: WebappUberspector.java $  */
+
+public class WebappUberspector extends AbstractChainableUberspector
+{
+
+    /**
+     * Property getter
+     * @param obj
+     * @param identifier
+     * @param i
+     * @return A Velocity Getter Method.
+     * @throws Exception
+     */
+    public VelPropertyGet getPropertyGet(Object obj, String identifier, Info i)
+            throws Exception
+    {
+        VelPropertyGet ret = super.getPropertyGet(obj,identifier,i);
+        if(ret == null)
+        {
+            Class claz = obj.getClass();
+            if(obj instanceof HttpServletRequest
+                || obj instanceof HttpSession
+                || obj instanceof ServletContext)
+            {
+                AbstractExecutor executor = new GetAttributeExecutor(log, 
introspector, claz, identifier);
+                ret = executor.isAlive() ? new VelGetterImpl(executor) : null;
+            }
+        }
+        return ret;
+    }
+
+    /**
+     * init method
+     * @throws Exception
+     */
+    public void init() throws Exception
+    {
+        super.init();
+        // we need our own introspector since the inner one is hidden by the 
Uberspect interface
+        introspector = new Introspector(log);
+    }
+
+    /**
+     * Property setter
+     * @param obj
+     * @param identifier
+     * @param arg
+     * @param i
+     * @return A Velocity Setter method.
+     * @throws Exception
+     */
+    public VelPropertySet getPropertySet(Object obj, String identifier,
+                                         Object arg, Info i)
+            throws Exception
+    {
+        VelPropertySet ret = super.getPropertySet(obj,identifier,arg,i);
+        if(ret == null) {
+            Class claz = obj.getClass();
+            if(obj instanceof HttpServletRequest
+                || obj instanceof HttpSession
+                || obj instanceof ServletContext)
+            {
+                SetExecutor executor = new SetAttributeExecutor(log, 
introspector, claz, arg, identifier);
+                ret = executor.isAlive() ? new VelSetterImpl(executor) : null;
+            }
+        }
+        return ret;
+    }
+
+
+    /**
+     * Executor for getAttribute(name) method.
+     */
+    public class GetAttributeExecutor extends AbstractExecutor
+    {
+        private final Introspector introspector;
+
+        // This is still threadsafe because this object is only read except in 
the C'tor.
+        private Object [] params;
+
+        /**
+         * @param log
+         * @param introspector
+         * @param clazz
+         * @param property
+         */
+        public GetAttributeExecutor(final Log log, final Introspector 
introspector,
+                final Class clazz, final String property)
+        {
+            this.log = log;
+            this.introspector = introspector;
+            this.params = new Object[] { property };
+
+            discover(clazz);
+        }
+
+        protected void discover(final Class clazz)
+        {
+            try
+            {
+                setMethod(introspector.getMethod(clazz, "getAttribute", 
params));
+            }
+            /**
+             * pass through application level runtime exceptions
+             */
+            catch( RuntimeException e )
+            {
+                throw e;
+            }
+            catch(Exception e)
+            {
+                log.error("While looking for getAttribute('" + params[0] + "') 
method:", e);
+            }
+        }
+
+        /**
+         * @see 
org.apache.velocity.runtime.parser.node.AbstractExecutor#execute(java.lang.Object)
+         */
+        public Object execute(final Object o)
+            throws IllegalAccessException, InvocationTargetException
+        {
+            return isAlive() ? getMethod().invoke(o, params) : null;
+        }
+    }
+
+    /**
+     * Executor for setAttribute(name,value) method
+     */
+    public class SetAttributeExecutor extends SetExecutor
+    {
+        private final Introspector introspector;
+        private final String property;
+
+        /**
+         * @param log
+         * @param introspector
+         * @param clazz
+         * @param arg
+         * @param property
+         */
+        public SetAttributeExecutor(final Log log, final Introspector 
introspector,
+                final Class clazz, final Object arg, final String property)
+        {
+            this.log = log;
+            this.introspector = introspector;
+            this.property = property;
+
+            discover(clazz, arg);
+        }
+
+        /**
+         * @param clazz
+         * @param arg
+         */
+        protected void discover(final Class clazz, final Object arg)
+        {
+            Object [] params = new Object[] { property, arg };
+
+            try
+            {
+                setMethod(introspector.getMethod(clazz, "setAttribute", 
params));
+            }
+            /**
+             * pass through application level runtime exceptions
+             */
+            catch( RuntimeException e )
+            {
+                throw e;
+            }
+            catch(Exception e)
+            {
+                log.error("While looking for put('" + params[0] + "') 
method:", e);
+            }
+        }
+
+        /**
+         * @see 
org.apache.velocity.runtime.parser.node.SetExecutor#execute(java.lang.Object, 
java.lang.Object)
+         */
+        public Object execute(final Object o, final Object value)
+            throws IllegalAccessException,  InvocationTargetException
+        {
+            Object [] params;
+
+            if (isAlive())
+            {
+                params = new Object [] { property, value };
+                return getMethod().invoke(o, params);
+            }
+
+            return null;
+        }
+    }
+}

Modified: 
velocity/tools/trunk/src/main/java/org/apache/velocity/tools/view/velocity.properties
URL: 
http://svn.apache.org/viewvc/velocity/tools/trunk/src/main/java/org/apache/velocity/tools/view/velocity.properties?rev=746564&r1=746563&r2=746564&view=diff
==============================================================================
--- 
velocity/tools/trunk/src/main/java/org/apache/velocity/tools/view/velocity.properties
 (original)
+++ 
velocity/tools/trunk/src/main/java/org/apache/velocity/tools/view/velocity.properties
 Sat Feb 21 18:54:21 2009
@@ -22,3 +22,8 @@
 resource.loader = webapp,string
 webapp.resource.loader.class = 
org.apache.velocity.tools.view.WebappResourceLoader
 string.resource.loader.class = 
org.apache.velocity.runtime.resource.loader.StringResourceLoader
+
+# uncomment (or copy in your velocity.properties file) the following line if 
you have Velocity 1.6+
+# and want to access application, session and request attributes via standard 
setters, like in:
+#   #set($session.foo = 'bar') foo is: $session.foo
+#runtime.introspector.uberspect = 
org.apache.velocity.util.introspection.UberspectImpl,org.apache.velocity.tools.view.WebappUberspector


Reply via email to