You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@commons.apache.org by bu...@apache.org on 2005/01/27 02:25:18 UTC

DO NOT REPLY [Bug 33259] New: - Patch for xml:set to set var to string list or delimited string

DO NOT REPLY TO THIS EMAIL, BUT PLEASE POST YOUR BUG�
RELATED COMMENTS THROUGH THE WEB INTERFACE AVAILABLE AT
<http://issues.apache.org/bugzilla/show_bug.cgi?id=33259>.
ANY REPLY MADE TO THIS MESSAGE WILL NOT BE COLLECTED AND�
INSERTED IN THE BUG DATABASE.

http://issues.apache.org/bugzilla/show_bug.cgi?id=33259

           Summary: Patch for xml:set to set var to string list or delimited
                    string
           Product: Commons
           Version: Nightly Builds
          Platform: Other
        OS/Version: Linux
            Status: NEW
          Severity: enhancement
          Priority: P2
         Component: Jelly
        AssignedTo: commons-dev@jakarta.apache.org
        ReportedBy: michael@schuerig.de


The patch below enhances the xml:set tag so that it can set its variable  
(1) to a list of strings and (2) to a single string with result node string  
delimited by a given string.  
 
Michael 
 
Index: src/java/org/apache/commons/jelly/tags/xml/SetTag.java 
=================================================================== 
RCS 
file: /home/cvspublic/jakarta-commons/jelly/jelly-tags/xml/src/java/org/apache/commons/jelly/tags/xml/SetTag.java,v 
retrieving revision 1.12 
diff -u -r1.12 SetTag.java 
--- src/java/org/apache/commons/jelly/tags/xml/SetTag.java 17 Jan 2005 
22:09:28 -0000 1.12 
+++ src/java/org/apache/commons/jelly/tags/xml/SetTag.java 27 Jan 2005 
01:10:08 -0000 
@@ -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 
     //------------------------------------------------------------------------- 
  
@@ -157,12 +238,16 @@ 
       * attribute to true. 
       */ 
     public void setAsString(boolean asString) { 
-        if(asString) 
-            this.single = new Boolean(asString); 
         this.asString = new Boolean(asString); 
     } 
  
- 
+    /** 
+     *  
+     */ 
+    public void setDelim(String delim) { 
+        this.delim  = delim; 
+    } 
+         
     /** Sets the xpath expression to use to sort selected nodes. 
      *  Ignored if single is true. 
      */ 
Index: src/test/org/apache/commons/jelly/tags/xml/suite.jelly 
=================================================================== 
RCS 
file: /home/cvspublic/jakarta-commons/jelly/jelly-tags/xml/src/test/org/apache/commons/jelly/tags/xml/suite.jelly,v 
retrieving revision 1.13 
diff -u -r1.13 suite.jelly 
--- src/test/org/apache/commons/jelly/tags/xml/suite.jelly 17 Jan 2005 
22:09:28 -0000 1.13 
+++ src/test/org/apache/commons/jelly/tags/xml/suite.jelly 27 Jan 2005 
01:10:08 -0000 
@@ -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"/>

-- 
Configure bugmail: http://issues.apache.org/bugzilla/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
You are the assignee for the bug, or are watching the assignee.

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