You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@commons.apache.org by po...@apache.org on 2005/01/28 13:36:24 UTC

svn commit: r148883 - in jakarta/commons/proper/jelly/trunk/jelly-tags/xml: src/java/org/apache/commons/jelly/tags/xml src/test/org/apache/commons/jelly/tags/xml xdocs

Author: polx
Date: Fri Jan 28 04:36:23 2005
New Revision: 148883

URL: http://svn.apache.org/viewcvs?view=rev&rev=148883
Log:
Applying Michael Schuerig's patch.
jelly:xml is starting to get a really nifty fully-featured biest!
paul


Modified:
   jakarta/commons/proper/jelly/trunk/jelly-tags/xml/src/java/org/apache/commons/jelly/tags/xml/SetTag.java
   jakarta/commons/proper/jelly/trunk/jelly-tags/xml/src/test/org/apache/commons/jelly/tags/xml/suite.jelly
   jakarta/commons/proper/jelly/trunk/jelly-tags/xml/xdocs/changes.xml

Modified: jakarta/commons/proper/jelly/trunk/jelly-tags/xml/src/java/org/apache/commons/jelly/tags/xml/SetTag.java
Url: http://svn.apache.org/viewcvs/jakarta/commons/proper/jelly/trunk/jelly-tags/xml/src/java/org/apache/commons/jelly/tags/xml/SetTag.java?view=diff&rev=148883&p1=jakarta/commons/proper/jelly/trunk/jelly-tags/xml/src/java/org/apache/commons/jelly/tags/xml/SetTag.java&r1=148882&p2=jakarta/commons/proper/jelly/trunk/jelly-tags/xml/src/java/org/apache/commons/jelly/tags/xml/SetTag.java&r2=148883
==============================================================================
--- jakarta/commons/proper/jelly/trunk/jelly-tags/xml/src/java/org/apache/commons/jelly/tags/xml/SetTag.java	(original)
+++ jakarta/commons/proper/jelly/trunk/jelly-tags/xml/src/java/org/apache/commons/jelly/tags/xml/SetTag.java	Fri Jan 28 04:36:23 2005
@@ -30,6 +30,7 @@
 import org.jaxen.JaxenException;
 
 import java.util.ArrayList;
+import java.util.Iterator;
 import java.util.List;
 import java.util.Collections;
 
@@ -44,6 +45,12 @@
   */
 public class SetTag extends XPathTagSupport {
 
+    private static final int RETURN_NODE_LIST = 0;
+    private static final int RETURN_FIRST_NODE = 1;
+    private static final int RETURN_STRING_LIST = 2;
+    private static final int RETURN_DELIMITED_STRING_LIST = 3;
+    private static final int RETURN_FIRST_AS_STRING = 4;
+    
     /** The Log to which logging calls will be made. */
     private Log log = LogFactory.getLog(SetTag.class);
 
@@ -60,6 +67,8 @@
     
     private Boolean asString = null;
 
+    private String delim = null;
+
     public SetTag() {
 
     }
@@ -86,36 +95,30 @@
         catch (JaxenException e) {
             throw new JellyTagException(e);
         }
-
+        
         if (value instanceof List) {
             // sort the list if xpCmp is set.
             if (xpCmp != null && (xpCmp.getXpath() != null)) {
                 Collections.sort((List)value, xpCmp);
             }
         }
-        if (single!=null) {
-            if (single.booleanValue()==true) {
-                if(value instanceof List) {
-                    List l = (List) value;
-                    if (l.size()==0)
-                        value=null;
-                    else
-                        value=l.get(0);
-                }
-                if(asString!=null && asString.booleanValue() && value instanceof Node)
-                    value = ((Node) value).getStringValue();
-            } else { // single == false
-                if(! (value instanceof List) ) {
-                    List l = null;
-                    if (value==null) {
-                        l = new ArrayList(0);
-                    } else {
-                        l = new ArrayList(1);
-                        l.add(value);
-                    }
-                    value = l;
-                }
-            }
+
+        switch ( determineReturnType() ) {
+        case RETURN_NODE_LIST:
+            value = valueAsList(value);
+            break;
+        case RETURN_FIRST_NODE:
+            value = valueAsSingle(value);
+            break;
+        case RETURN_STRING_LIST:
+            value = nodeListToStringList(valueAsList(value));
+            break;
+        case RETURN_DELIMITED_STRING_LIST:
+            value = joinDelimitedElements(nodeListToStringList(valueAsList(value)));
+            break;
+        case RETURN_FIRST_AS_STRING:
+            value = singleValueAsString(valueAsSingle(value));
+            break;
         }
 
         //log.info( "Evaluated xpath: " + select + " as: " + value + " of type: " + value.getClass().getName() );
@@ -123,6 +126,84 @@
         context.setVariable(var, value);
     }
 
+    private List valueAsList( final Object value ) {
+        if (value instanceof List) {
+            return (List)value;
+        } else {
+            if (value == null) {
+                return Collections.EMPTY_LIST;
+            } else {
+                return Collections.singletonList(value);
+            }
+        }
+    }
+
+    private Object valueAsSingle( final Object value ) {
+        if (value instanceof List) {
+            List l = (List) value;
+            if (l.isEmpty())
+                return null;
+            else
+                return l.get(0);
+        } else {
+            return value;
+        }
+    }
+    
+    private String singleValueAsString( final Object value ) {
+        if (value instanceof Node) {
+            return ((Node) value).getStringValue();
+        } else {
+            return null;
+        }
+    }
+
+    private List nodeListToStringList( final List values ) {
+        List l = new ArrayList(values.size());
+        for (Iterator it = values.iterator(); it.hasNext(); ) {
+            Object v = it.next();
+            String s = singleValueAsString(v);
+            if (s != null) {
+                l.add(s);
+            }
+        }
+        return l;
+    }
+
+    private String joinDelimitedElements( final List values ) {
+        StringBuffer sb = new StringBuffer();
+        int sz = values.size();
+        for (int i = 0; i < sz; i++) {
+            String s = (String)values.get(i); 
+            sb.append(s);
+            if (i < sz - 1)
+                sb.append(delim);
+        }
+        return sb.toString();
+    }
+
+    private int determineReturnType() {
+        int resultType;
+        if (single != null && single.booleanValue()) { // first node
+            if (asString != null && asString.booleanValue()) {
+                resultType = RETURN_FIRST_AS_STRING;
+            } else {
+                resultType = RETURN_FIRST_NODE;
+            }
+        } else { // all nodes
+            if (asString != null && asString.booleanValue()) {
+                if (delim != null) {
+                    resultType = RETURN_DELIMITED_STRING_LIST;
+                } else {
+                    resultType = RETURN_STRING_LIST;
+                }
+            } else {
+                resultType = RETURN_NODE_LIST;
+            }
+        }
+        return resultType;
+    }
+
     // Properties
     //-------------------------------------------------------------------------
 
@@ -138,11 +219,11 @@
     }
 
     /** If set to true will only take the first element matching.
-        If set to false, guarantees that a list is returned.
         It then guarantees that the result is of type
         {@link org.dom4j.Node} thereby making sure that, for example,
         when an element is selected, one can directly call such methods
         as setAttribute.
+        If set to false, guarantees that a list is returned.
         */
     public void setSingle(boolean single) {
         this.single = new Boolean(single);
@@ -157,12 +238,15 @@
       * attribute to true.
       */
     public void setAsString(boolean asString) {
-        if(asString)
-            this.single = new Boolean(asString);
         this.asString = new Boolean(asString);
     }
 
-
+    /** If set, returns a string delimited by this delimiter.
+     */
+    public void setDelim(String delim) {
+        this.delim  = delim;
+    }
+        
     /** Sets the xpath expression to use to sort selected nodes.
      *  Ignored if single is true.
      */

Modified: jakarta/commons/proper/jelly/trunk/jelly-tags/xml/src/test/org/apache/commons/jelly/tags/xml/suite.jelly
Url: http://svn.apache.org/viewcvs/jakarta/commons/proper/jelly/trunk/jelly-tags/xml/src/test/org/apache/commons/jelly/tags/xml/suite.jelly?view=diff&rev=148883&p1=jakarta/commons/proper/jelly/trunk/jelly-tags/xml/src/test/org/apache/commons/jelly/tags/xml/suite.jelly&r1=148882&p2=jakarta/commons/proper/jelly/trunk/jelly-tags/xml/src/test/org/apache/commons/jelly/tags/xml/suite.jelly&r2=148883
==============================================================================
--- jakarta/commons/proper/jelly/trunk/jelly-tags/xml/src/test/org/apache/commons/jelly/tags/xml/suite.jelly	(original)
+++ jakarta/commons/proper/jelly/trunk/jelly-tags/xml/src/test/org/apache/commons/jelly/tags/xml/suite.jelly	Fri Jan 28 04:36:23 2005
@@ -300,11 +300,36 @@
         <x:set var="blip" select="$blopElements/root/blip" single="false"/>
         <j:invokeStatic var="listClass" className="java.lang.Class" method="forName"><j:arg value="java.util.List"/></j:invokeStatic>
         <test:assert test="${listClass.isAssignableFrom(blip.getClass())}"/>
-        <!-- check if selecting blop/@id asString returns a string -->
-        <x:set var="blopId" select="$blopElements/root/blop/@id" asString="true"/>
+        <!-- check if selecting blop/@id asString and single returns a string -->
+        <x:set var="blopId" select="$blopElements/root/blop/@id" asString="true" single="true"/>
         <j:invokeStatic var="stringClass" className="java.lang.Class" method="forName"><j:arg value="java.lang.String"/></j:invokeStatic>
         <test:assert test="${stringClass.isAssignableFrom(blopId.getClass())}"/>
   </test:case>
+
+
+  <test:case name="testSetStringLists">
+        <j:invokeStatic var="listClass" className="java.lang.Class" method="forName"><j:arg value="java.util.List"/></j:invokeStatic>
+        <j:invokeStatic var="stringClass" className="java.lang.Class" method="forName"><j:arg value="java.lang.String"/></j:invokeStatic>
+
+        <x:parse var="blopElements">
+          <root>
+            <blop>blop1</blop>
+            <blip/>
+            <blop id="bla">blop0</blop></root>
+        </x:parse>
+
+        <!-- check if selecting root/blop asString returns a list of strings -->
+        <x:set var="blopList" select="$blopElements/root/blop" asString="true" />
+        <test:assert test="${listClass.isAssignableFrom(blopList.getClass())}"/>
+        <test:assert test="${stringClass.isAssignableFrom(blopList.get(0).getClass())}"/>
+        <test:assertEquals expected="blop1" actual="${blopList.get(0)}"/>
+
+        <!-- check if selecting root/blop asString + delim returns a delimited string -->
+        <x:set var="blopString" select="$blopElements/root/blop" asString="true" delim=","/>
+        <test:assert test="${stringClass.isAssignableFrom(blopString.getClass())}"/>
+        <test:assertEquals expected="blop1,blop0" actual="${blopString}"/>
+  </test:case>
+
    
   <test:case name="testEntities">
     <x:parse var="doc" xml="entity.xml"/> 

Modified: jakarta/commons/proper/jelly/trunk/jelly-tags/xml/xdocs/changes.xml
Url: http://svn.apache.org/viewcvs/jakarta/commons/proper/jelly/trunk/jelly-tags/xml/xdocs/changes.xml?view=diff&rev=148883&p1=jakarta/commons/proper/jelly/trunk/jelly-tags/xml/xdocs/changes.xml&r1=148882&p2=jakarta/commons/proper/jelly/trunk/jelly-tags/xml/xdocs/changes.xml&r2=148883
==============================================================================
--- jakarta/commons/proper/jelly/trunk/jelly-tags/xml/xdocs/changes.xml	(original)
+++ jakarta/commons/proper/jelly/trunk/jelly-tags/xml/xdocs/changes.xml	Fri Jan 28 04:36:23 2005
@@ -24,6 +24,10 @@
     <author email="dion@apache.org">dIon Gillard</author>
   </properties>
   <body>
+		<release version="1.1" date="in CVS">
+			<action dev="polx" type="add" issue="JELLY-200" due-to="Michael Schuerig"
+				>xml:set can now return XPath strings and comma-separated strings</action>
+			</release>
     <release version="1.0" date="2004-09-11">
       <action dev="dion" type="add">Initial release</action>
     </release>

---------------------------------------------------------------------
To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: commons-dev-help@jakarta.apache.org