Uploaded image for project: 'Sling'
  1. Sling
  2. SLING-577

Patch Submission: JSP tag to evaluate JCR properties using EL

    XMLWordPrintableJSON

Details

    • New Feature
    • Status: Resolved
    • Major
    • Resolution: Won't Fix
    • None
    • None
    • Scripting
    • None

    Description

      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><sling:evalProperty></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

      {@link #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>

      Attachments

        1. evalproperty.patch
          10 kB
          David Trott

        Issue Links

          Activity

            People

              fmeschbe Felix Meschberger
              dtrott David Trott
              Votes:
              0 Vote for this issue
              Watchers:
              1 Start watching this issue

              Dates

                Created:
                Updated:
                Resolved: