Patch Submission: JSP tag to evaluate JCR properties using EL
-------------------------------------------------------------

                 Key: SLING-577
                 URL: https://issues.apache.org/jira/browse/SLING-577
             Project: Sling
          Issue Type: New Feature
          Components: Scripting JSP
            Reporter: David Trott


Use case
========
Say you are building components in sling and you want to break the logic into 
two separate components:
-  One to fetch the data (possibly from a DB) and populate the pageContext.
-  And one to render some HTML using data in the pageContext.

 
This would allow either component to be switched out without affecting the 
other.
 

In this scenario we need a way to connect the two components together; one 
option is to use EL
Hence we could define a property of the content node for the visual component: 
rating="${dbrating}"

This assumes that the DB component has already done a 
pageContext.setAttribute("dbrating", "some value");


We can then build a JSP page which evaluates the properties, e.g:

<h1>Current Rating: '<sling:evalProperty property="rating"/>'</h1>

Hence this JSP page would form the core of the visual component.




Patch File
========

diff -Nur 
jsp-taglib-base/src/main/java/org/apache/sling/scripting/jsp/taglib/EvalPropertyTEI.java
 
jsp-taglib-update/src/main/java/org/apache/sling/scripting/jsp/taglib/EvalPropertyTEI.java
--- 
jsp-taglib-base/src/main/java/org/apache/sling/scripting/jsp/taglib/EvalPropertyTEI.java
    1969-12-31 16:00:00.000000000 -0800
+++ 
jsp-taglib-update/src/main/java/org/apache/sling/scripting/jsp/taglib/EvalPropertyTEI.java
  2008-07-22 20:25:57.000000000 -0700
@@ -0,0 +1,74 @@
+/*
+ * 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.
+ */
+package org.apache.sling.scripting.jsp.taglib;
+
+import static 
org.apache.sling.scripting.jsp.taglib.EvalPropertyTag.DEFAULT_VAR;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.servlet.jsp.tagext.TagData;
+import javax.servlet.jsp.tagext.TagExtraInfo;
+import javax.servlet.jsp.tagext.VariableInfo;
+
+/**
+ * This class defines the scripting variables that are created by the
+ * <code>EvalPropertyTag</code>.
+ */
+public class EvalPropertyTEI extends TagExtraInfo {
+
+    /**
+     * The name of the tag attribute used to define the name of the
+     * value scripting variable (value is "var").
+     */
+    public static final String ATTR_VAR = "var";
+
+    private static final String VAR_CLASS = String.class.getName();
+
+    /**
+     * Returns an Array of <code>VariableInfo</code> objects describing
+     * scripting variables.
+     *
+     * @see javax.servlet.jsp.tagext.TagExtraInfo#getVariableInfo(TagData)
+     */
+    public VariableInfo[] getVariableInfo(TagData data) {
+
+        List<VariableInfo> varInfos = new ArrayList<VariableInfo>();
+
+        addVar(varInfos, data, ATTR_VAR, DEFAULT_VAR, VAR_CLASS);
+
+        return varInfos.toArray(new VariableInfo[varInfos.size()]);
+
+    }
+
+    private void addVar(List<VariableInfo> varInfos, TagData data, String 
attrName, String defaultValue, String varClass) {
+        String value = getValue(data, attrName, defaultValue);
+
+        if (value != null && varClass != null) {
+            varInfos.add(new VariableInfo(value, varClass, true, 
VariableInfo.AT_END));
+        }
+    }
+
+    private String getValue(TagData data, String name, String defaultValue) {
+        Object value = data.getAttribute(name);
+        if (value instanceof String) {
+            return (String) value;
+        }
+
+        return defaultValue;
+    }
+}
diff -Nur 
jsp-taglib-base/src/main/java/org/apache/sling/scripting/jsp/taglib/EvalPropertyTag.java
 
jsp-taglib-update/src/main/java/org/apache/sling/scripting/jsp/taglib/EvalPropertyTag.java
--- 
jsp-taglib-base/src/main/java/org/apache/sling/scripting/jsp/taglib/EvalPropertyTag.java
    1969-12-31 16:00:00.000000000 -0800
+++ 
jsp-taglib-update/src/main/java/org/apache/sling/scripting/jsp/taglib/EvalPropertyTag.java
  2008-07-22 20:25:57.000000000 -0700
@@ -0,0 +1,137 @@
+/*
+ * 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.
+ */
+package org.apache.sling.scripting.jsp.taglib;
+
+import java.io.IOException;
+
+import javax.el.ELContext;
+import javax.el.ExpressionFactory;
+import javax.jcr.Node;
+import javax.jcr.PathNotFoundException;
+import javax.jcr.Property;
+import javax.jcr.RepositoryException;
+import javax.servlet.ServletRequest;
+import javax.servlet.jsp.JspException;
+import javax.servlet.jsp.JspFactory;
+import javax.servlet.jsp.tagext.TagSupport;
+
+import org.apache.sling.api.resource.Resource;
+import org.apache.sling.api.resource.ResourceResolver;
+import org.apache.sling.api.scripting.SlingBindings;
+import org.apache.sling.api.scripting.SlingScriptHelper;
+
+/**
+ * The <code>EvalPropertyTag</code> implements the
+ * <code>&lt;sling:evalProperty&gt;</code> custom tag.
+ */
+public class EvalPropertyTag extends TagSupport {
+
+    /**
+     * Default name for the scripting variable set to the result
+     * of the evaluation (value is null).
+     */
+    public static final String DEFAULT_VAR = null;
+
+    /**
+     * The default path if no path attribute is passed to the tag (value is 
".").
+     */
+    public static final String DEFAULT_PATH = ".";
+
+    private String var = DEFAULT_VAR;
+
+    private String path = DEFAULT_PATH;
+
+    private String property;
+
+    /**
+     * Default constructor.
+     */
+    public EvalPropertyTag() {
+    }
+
+    /**
+     * Reads a value from the performs an EL evaluation and sets a variable.
+     *
+     * @return always [EMAIL PROTECTED] #EVAL_PAGE}.
+     */
+    public int doEndTag() throws JspException {
+        try {
+            final ServletRequest request = pageContext.getRequest();
+            final SlingBindings bindings = 
(SlingBindings)request.getAttribute(SlingBindings.class.getName());
+            final SlingScriptHelper scriptHelper = bindings.getSling();
+            final Resource baseResource = 
scriptHelper.getRequest().getResource();
+            final ResourceResolver resourceResolver = 
baseResource.getResourceResolver();
+
+            final Resource resource = 
resourceResolver.getResource(baseResource, this.path);
+            if (resource == null) {
+                throw new JspException("Resource not found: " + this.path);
+            }
+
+            final Node node = resource.adaptTo(Node.class);
+            if (node == null) {
+                throw new JspException("Path is not a valid node: " + 
this.path);
+            }
+
+            final Property propNode = node.getProperty(this.property);
+            if (propNode == node) {
+                throw new JspException("Property not found: " + this.path);
+            }
+
+
+            final String elValue = propNode.getString();
+            if (elValue != null) {
+                ELContext elctx  = pageContext.getELContext();
+                String strValue = (String) 
getExpressionFactory().createValueExpression(elctx, elValue, 
String.class).getValue(elctx);
+
+                if (this.var == null || this.var.trim().equals("")) {
+                    pageContext.getOut().print(strValue);
+                } else {
+                    pageContext.setAttribute(this.var, strValue);
+                }
+            }
+
+            return EVAL_PAGE;
+        } catch (PathNotFoundException e) {
+            throw new JspException(e);
+        } catch (RepositoryException e) {
+            throw new JspException(e);
+        } catch (IOException e) {
+            throw new JspException(e);
+        }
+    }
+
+    // --------------------------< setter methods >----------------------------
+
+    public void setVar(String var) {
+        this.var = var;
+    }
+
+    public void setPath(String path) {
+        this.path = path;
+    }
+
+    public void setProperty(String property) {
+        this.property = property;
+    }
+
+    private ExpressionFactory getExpressionFactory() {
+        return JspFactory.getDefaultFactory()
+            .getJspApplicationContext(pageContext.getServletContext())
+            .getExpressionFactory();
+
+    }
+}
diff -Nur jsp-taglib-base/src/main/resources/META-INF/taglib.tld 
jsp-taglib-update/src/main/resources/META-INF/taglib.tld
--- jsp-taglib-base/src/main/resources/META-INF/taglib.tld      2008-07-22 
20:21:56.000000000 -0700
+++ jsp-taglib-update/src/main/resources/META-INF/taglib.tld    2008-07-22 
20:25:57.000000000 -0700
@@ -161,4 +161,43 @@
         </attribute>
     </tag>
 
+    <tag>
+        <description>
+            Performs an EL evaluation on the value in a JCR property.
+        </description>
+        <name>evalProperty</name>
+        <tag-class>
+            org.apache.sling.scripting.jsp.taglib.EvalPropertyTag
+        </tag-class>
+        <tei-class>
+            org.apache.sling.scripting.jsp.taglib.EvalPropertyTEI
+        </tei-class>
+        <body-content>empty</body-content>
+        <attribute>
+            <description>
+                The variable which receives the result of the evaluation.
+                If this attribute is missing or blank the result is written to 
out.
+            </description>
+            <name>var</name>
+            <required>false</required>
+            <rtexprvalue>false</rtexprvalue>
+        </attribute>
+        <attribute>
+            <description>
+                The relative path to the node which has the property to be 
evaluated.
+                If omitted the tag will use "." (current content node).
+            </description>
+            <name>path</name>
+            <required>false</required>
+            <rtexprvalue>true</rtexprvalue>
+        </attribute>
+        <attribute>
+            <description>
+                The property to be evaluated.
+            </description>
+            <name>property</name>
+            <required>true</required>
+            <rtexprvalue>true</rtexprvalue>
+        </attribute>
+    </tag>
 </taglib>


-- 
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.

Reply via email to