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/30 08:47:06 UTC

svn commit: r149113 - /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

Author: polx
Date: Sat Jan 29 23:47:05 2005
New Revision: 149113

URL: http://svn.apache.org/viewcvs?view=rev&rev=149113
Log:
x:set was returning empty-list in case of empty results whereas it used
to return a null (which becomes an empty string often in jexl or jelly).
Fixed so that when asString, single, and delim attributes are not set,
it is backwards compatible.
Reverted to the multi-slot evaluation-style as opposed to the single
policy introduced by Michael Schuerig.
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

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=149113&p1=jakarta/commons/proper/jelly/trunk/jelly-tags/xml/src/java/org/apache/commons/jelly/tags/xml/SetTag.java&r1=149112&p2=jakarta/commons/proper/jelly/trunk/jelly-tags/xml/src/java/org/apache/commons/jelly/tags/xml/SetTag.java&r2=149113
==============================================================================
--- 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	Sat Jan 29 23:47:05 2005
@@ -30,9 +30,10 @@
 import org.jaxen.JaxenException;
 
 import java.util.ArrayList;
+import java.util.Collections;
 import java.util.Iterator;
 import java.util.List;
-import java.util.Collections;
+import java.util.ListIterator;
 
 /** A tag which defines a variable from an XPath expression.
   * This function creates a variable of type {@link List} or {@link org.dom4j.Node}
@@ -66,6 +67,8 @@
     private Boolean single = null;
     
     private Boolean asString = null;
+    
+    private String delimiter = null;
 
     private String delim = null;
 
@@ -86,7 +89,7 @@
         Object xpathContext = getXPathContext();
         Object value = null;
         try {
-            if(single!=null && single.booleanValue()==true) {
+            if( single != null && single.booleanValue() == true ) {
                 value = select.selectSingleNode(xpathContext);
             } else {
                 value = select.evaluate(xpathContext);
@@ -97,29 +100,74 @@
         }
         
         if (value instanceof List) {
+            List list = (List) value;
             // sort the list if xpCmp is set.
             if (xpCmp != null && (xpCmp.getXpath() != null)) {
-                Collections.sort((List)value, xpCmp);
+                Collections.sort(list, xpCmp);
+            }
+            if(list.isEmpty()) {
+                value = null;
             }
         }
+        
 
-        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;
+        // handle single
+        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);
+                }
+            } 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;
+                }
+            }
+        }
+        
+        // now convert the result(s) to string if need
+        if(asString != null && asString.booleanValue()) {
+            if(value instanceof Node) {
+                value = ((Node) value).getStringValue();
+            } else if(value instanceof List) {
+                for(ListIterator it = ((List) value).listIterator(); it.hasNext(); ) {
+                    Object v = it.next();
+                    if(v instanceof Node) {
+                        v = ((Node) v).getStringValue();
+                        it.set(v);
+                    }
+                }
+            }
         }
+        
+        // finally convert the result to a concatenated string if delimiter is defined
+        if(delimiter != null && value instanceof List) {
+            StringBuffer buff = new StringBuffer();
+            for(Iterator it = ((List) value).iterator(); it.hasNext(); ) {
+                Object v = it.next();
+                if (v instanceof Node) {
+                    buff.append( ((Node) v).getStringValue());
+                } else {
+                    buff.append(v.toString());
+                }
+                if(it.hasNext()) {
+                    buff.append(delimiter);
+                }
+            }
+            buff.setLength(buff.length());
+            value = buff.toString();
+        }
+        
 
         //log.info( "Evaluated xpath: " + select + " as: " + value + " of type: " + value.getClass().getName() );
 
@@ -222,7 +270,8 @@
         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.
+        as setAttribute.<br/>
+        If set to false, guarantees that a list is returned.
         If set to false, guarantees that a list is returned.
         */
     public void setSingle(boolean single) {
@@ -234,19 +283,21 @@
       * itself.
       * This ensures that, thereafter, string manipulations
       * can be performed on the result.
-      * Setting this attribute to true will also set the single
-      * attribute to true.
       */
     public void setAsString(boolean asString) {
         this.asString = new Boolean(asString);
     }
 
     /** If set, returns a string delimited by this delimiter.
-     */
+      * Implies <code>asString</code> to be true.
+      */
     public void setDelim(String delim) {
-        this.delim  = delim;
+        this.delimiter = delim;
+        if( delim!=null ) {
+            this.asString = Boolean.TRUE;
+        }
     }
-        
+
     /** 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=149113&p1=jakarta/commons/proper/jelly/trunk/jelly-tags/xml/src/test/org/apache/commons/jelly/tags/xml/suite.jelly&r1=149112&p2=jakarta/commons/proper/jelly/trunk/jelly-tags/xml/src/test/org/apache/commons/jelly/tags/xml/suite.jelly&r2=149113
==============================================================================
--- 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	Sat Jan 29 23:47:05 2005
@@ -290,20 +290,37 @@
             <blip/>
             <blop id="bla">blop0</blop></root>
         </x:parse>
-        <x:set var="blopSingle" select="$blopElements/root/blop" single="true"/>
         <!-- should return the second -->
+        <x:set var="blopSingle" select="$blopElements/root/blop" single="true"/>
         <j:invokeStatic var="eltClass" className="java.lang.Class" method="forName"><j:arg value="org.dom4j.Element"/></j:invokeStatic>
         <test:assert test="${eltClass.isAssignableFrom(blopSingle.getClass())}"/>
+
         <j:set var="blopSingleText"><x:expr select="$blopSingle/text()"/></j:set>
         <test:assertEquals actual="${blopSingleText}" expected="blop1"/>
+
         <!-- check if selecting root/blip returns a list -->
         <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 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())}"/>
+				
+				<!-- check if select blop/blurp with false single returns an empty list -->
+        <x:set var="blurp" select="$blopElements/root/blurp" 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 select blop/blurp with no single or asString returns null -->
+        <x:set var="blurp" select="$blopElements/root/blurp"/>
+        <j:invokeStatic var="listClass" className="java.lang.Class" method="forName"><j:arg value="java.util.List"/></j:invokeStatic>
+				<j:set var="blurpAndX" value="${blurp}X"/>
+				blurp=${blurp}, blurpAndX=${blurpAndX}
+        <test:assert test="${'X' eq blurpAndX}"/>
+				
+				
   </test:case>
 
 

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


Re: svn commit: r149113 - /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

Posted by Paul Libbrecht <pa...@activemath.org>.
You must also have changed maven to svn... but the web-page still  
speaks about cvs! Or ?

paul


Le 31 janv. 05, à 13:22, Brett Porter a écrit :
> This fixed the original issue. I have another issue (as I mentioned  
> before), if you run "maven -e xdoc" on maven-1/plugins/trunk/ashkelon  
> you can see it. I'll investigate when I can, but hold off on that  
> release in the mean time :)
>
> - Brett
>
> polx@apache.org wrote:
>
>> Author: polx
>> Date: Sat Jan 29 23:47:05 2005
>> New Revision: 149113
>>
>> URL: http://svn.apache.org/viewcvs?view=rev&rev=149113
>> Log:
>> x:set was returning empty-list in case of empty results whereas it  
>> used
>> to return a null (which becomes an empty string often in jexl or  
>> jelly).
>> Fixed so that when asString, single, and delim attributes are not set,
>> it is backwards compatible.
>> Reverted to the multi-slot evaluation-style as opposed to the single
>> policy introduced by Michael Schuerig.
>> 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
>>
>> 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=149113&p1=jakarta/commons/proper/jelly/ 
>> trunk/jelly-tags/xml/src/java/org/apache/commons/jelly/tags/xml/ 
>> SetTag.java&r1=149112&p2=jakarta/commons/proper/jelly/trunk/jelly- 
>> tags/xml/src/java/org/apache/commons/jelly/tags/xml/ 
>> SetTag.java&r2=149113
>> ====================================================================== 
>> ========
>> ---  
>> 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	Sat Jan 29 23:47:05 2005
>> @@ -30,9 +30,10 @@
>> import org.jaxen.JaxenException;
>> import java.util.ArrayList;
>> +import java.util.Collections;
>> import java.util.Iterator;
>> import java.util.List;
>> -import java.util.Collections;
>> +import java.util.ListIterator;
>> /** A tag which defines a variable from an XPath expression.
>>   * This function creates a variable of type {@link List} or {@link  
>> org.dom4j.Node}
>> @@ -66,6 +67,8 @@
>>     private Boolean single = null;
>>         private Boolean asString = null;
>> +    +    private String delimiter = null;
>>     private String delim = null;
>> @@ -86,7 +89,7 @@
>>         Object xpathContext = getXPathContext();
>>         Object value = null;
>>         try {
>> -            if(single!=null && single.booleanValue()==true) {
>> +            if( single != null && single.booleanValue() == true ) {
>>                 value = select.selectSingleNode(xpathContext);
>>             } else {
>>                 value = select.evaluate(xpathContext);
>> @@ -97,29 +100,74 @@
>>         }
>>                 if (value instanceof List) {
>> +            List list = (List) value;
>>             // sort the list if xpCmp is set.
>>             if (xpCmp != null && (xpCmp.getXpath() != null)) {
>> -                Collections.sort((List)value, xpCmp);
>> +                Collections.sort(list, xpCmp);
>> +            }
>> +            if(list.isEmpty()) {
>> +                value = null;
>>             }
>>         }
>> +        -        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;
>> +        // handle single
>> +        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);
>> +                }
>> +            } 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;
>> +                }
>> +            }
>> +        }
>> +        +        // now convert the result(s) to string if need
>> +        if(asString != null && asString.booleanValue()) {
>> +            if(value instanceof Node) {
>> +                value = ((Node) value).getStringValue();
>> +            } else if(value instanceof List) {
>> +                for(ListIterator it = ((List) value).listIterator();  
>> it.hasNext(); ) {
>> +                    Object v = it.next();
>> +                    if(v instanceof Node) {
>> +                        v = ((Node) v).getStringValue();
>> +                        it.set(v);
>> +                    }
>> +                }
>> +            }
>>         }
>> +        +        // finally convert the result to a concatenated  
>> string if delimiter is defined
>> +        if(delimiter != null && value instanceof List) {
>> +            StringBuffer buff = new StringBuffer();
>> +            for(Iterator it = ((List) value).iterator();  
>> it.hasNext(); ) {
>> +                Object v = it.next();
>> +                if (v instanceof Node) {
>> +                    buff.append( ((Node) v).getStringValue());
>> +                } else {
>> +                    buff.append(v.toString());
>> +                }
>> +                if(it.hasNext()) {
>> +                    buff.append(delimiter);
>> +                }
>> +            }
>> +            buff.setLength(buff.length());
>> +            value = buff.toString();
>> +        }
>> +                //log.info( "Evaluated xpath: " + select + " as: " +  
>> value + " of type: " + value.getClass().getName() );
>> @@ -222,7 +270,8 @@
>>         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.
>> +        as setAttribute.<br/>
>> +        If set to false, guarantees that a list is returned.
>>         If set to false, guarantees that a list is returned.
>>         */
>>     public void setSingle(boolean single) {
>> @@ -234,19 +283,21 @@
>>       * itself.
>>       * This ensures that, thereafter, string manipulations
>>       * can be performed on the result.
>> -      * Setting this attribute to true will also set the single
>> -      * attribute to true.
>>       */
>>     public void setAsString(boolean asString) {
>>         this.asString = new Boolean(asString);
>>     }
>>     /** If set, returns a string delimited by this delimiter.
>> -     */
>> +      * Implies <code>asString</code> to be true.
>> +      */
>>     public void setDelim(String delim) {
>> -        this.delim  = delim;
>> +        this.delimiter = delim;
>> +        if( delim!=null ) {
>> +            this.asString = Boolean.TRUE;
>> +        }
>>     }
>> -        +
>>     /** 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=149113&p1=jakarta/commons/proper/jelly/ 
>> trunk/jelly-tags/xml/src/test/org/apache/commons/jelly/tags/xml/ 
>> suite.jelly&r1=149112&p2=jakarta/commons/proper/jelly/trunk/jelly- 
>> tags/xml/src/test/org/apache/commons/jelly/tags/xml/ 
>> suite.jelly&r2=149113
>> ====================================================================== 
>> ========
>> ---  
>> 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	Sat Jan 29 23:47:05 2005
>> @@ -290,20 +290,37 @@
>>             <blip/>
>>             <blop id="bla">blop0</blop></root>
>>         </x:parse>
>> -        <x:set var="blopSingle" select="$blopElements/root/blop"  
>> single="true"/>
>>         <!-- should return the second -->
>> +        <x:set var="blopSingle" select="$blopElements/root/blop"  
>> single="true"/>
>>         <j:invokeStatic var="eltClass" className="java.lang.Class"  
>> method="forName"><j:arg value="org.dom4j.Element"/></j:invokeStatic>
>>         <test:assert  
>> test="${eltClass.isAssignableFrom(blopSingle.getClass())}"/>
>> +
>>         <j:set var="blopSingleText"><x:expr  
>> select="$blopSingle/text()"/></j:set>
>>         <test:assertEquals actual="${blopSingleText}"  
>> expected="blop1"/>
>> +
>>         <!-- check if selecting root/blip returns a list -->
>>         <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 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())}"/>
>> +				
>> +				<!-- check if select blop/blurp with false single returns an  
>> empty list -->
>> +        <x:set var="blurp" select="$blopElements/root/blurp"  
>> 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 select blop/blurp with no single or asString  
>> returns null -->
>> +        <x:set var="blurp" select="$blopElements/root/blurp"/>
>> +        <j:invokeStatic var="listClass" className="java.lang.Class"  
>> method="forName"><j:arg value="java.util.List"/></j:invokeStatic>
>> +				<j:set var="blurpAndX" value="${blurp}X"/>
>> +				blurp=${blurp}, blurpAndX=${blurpAndX}
>> +        <test:assert test="${'X' eq blurpAndX}"/>
>> +				
>> +				
>>   </test:case>
>>
>> ---------------------------------------------------------------------
>> To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
>> For additional commands, e-mail: commons-dev-help@jakarta.apache.org
>>
>>
>>
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
> For additional commands, e-mail: commons-dev-help@jakarta.apache.org
>


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


Re: [jelly] x:set null pointer exception

Posted by Paul Libbrecht <pa...@activemath.org>.
I fear this used to be treated as "exception eater".
More precisely: it throwed if it could not parse the xpath.
But it just gave null if there were some other exceptions...
So the easy thing would probably be to return null if there was an 
exception at evaluating XPath... (I think this is what most processors 
do anyways).

paul


Le 2 févr. 05, à 09:58, Brett Porter a écrit :

> Hi Paul,
>
> The issue I was having was a null pointer exception resulting from 
> running the following:
>
> <x:parse var="navXML" xml="" />
> <x:set var="nav" value="$navXML/body" />
>
> I think in the past, this used to set "nav" to null (presumably 
> because navXML was an empty document, where now it is a null 
> document?)
>
> I'm now just skipping this code when xml is empty in the script.
>
> Any thoughts on how this should be handled?
>
> - Brett
>
> Brett Porter wrote:
>
>> Hi Paul,
>>
>> This fixed the original issue. I have another issue (as I mentioned 
>> before), if you run "maven -e xdoc" on maven-1/plugins/trunk/ashkelon 
>> you can see it. I'll investigate when I can, but hold off on that 
>> release in the mean time :)
>>
>> - Brett
>>
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
> For additional commands, e-mail: commons-dev-help@jakarta.apache.org
>


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


[jelly] x:set null pointer exception

Posted by Brett Porter <br...@apache.org>.
Hi Paul,

The issue I was having was a null pointer exception resulting from 
running the following:

<x:parse var="navXML" xml="" />
<x:set var="nav" value="$navXML/body" />

I think in the past, this used to set "nav" to null (presumably because 
navXML was an empty document, where now it is a null document?)

I'm now just skipping this code when xml is empty in the script.

Any thoughts on how this should be handled?

- Brett

Brett Porter wrote:

> Hi Paul,
>
> This fixed the original issue. I have another issue (as I mentioned 
> before), if you run "maven -e xdoc" on maven-1/plugins/trunk/ashkelon 
> you can see it. I'll investigate when I can, but hold off on that 
> release in the mean time :)
>
> - Brett
>


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


Re: svn commit: r149113 - /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

Posted by Brett Porter <br...@apache.org>.
Hi Paul,

This fixed the original issue. I have another issue (as I mentioned 
before), if you run "maven -e xdoc" on maven-1/plugins/trunk/ashkelon 
you can see it. I'll investigate when I can, but hold off on that 
release in the mean time :)

- Brett

polx@apache.org wrote:

>Author: polx
>Date: Sat Jan 29 23:47:05 2005
>New Revision: 149113
>
>URL: http://svn.apache.org/viewcvs?view=rev&rev=149113
>Log:
>x:set was returning empty-list in case of empty results whereas it used
>to return a null (which becomes an empty string often in jexl or jelly).
>Fixed so that when asString, single, and delim attributes are not set,
>it is backwards compatible.
>Reverted to the multi-slot evaluation-style as opposed to the single
>policy introduced by Michael Schuerig.
>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
>
>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=149113&p1=jakarta/commons/proper/jelly/trunk/jelly-tags/xml/src/java/org/apache/commons/jelly/tags/xml/SetTag.java&r1=149112&p2=jakarta/commons/proper/jelly/trunk/jelly-tags/xml/src/java/org/apache/commons/jelly/tags/xml/SetTag.java&r2=149113
>==============================================================================
>--- 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	Sat Jan 29 23:47:05 2005
>@@ -30,9 +30,10 @@
> import org.jaxen.JaxenException;
> 
> import java.util.ArrayList;
>+import java.util.Collections;
> import java.util.Iterator;
> import java.util.List;
>-import java.util.Collections;
>+import java.util.ListIterator;
> 
> /** A tag which defines a variable from an XPath expression.
>   * This function creates a variable of type {@link List} or {@link org.dom4j.Node}
>@@ -66,6 +67,8 @@
>     private Boolean single = null;
>     
>     private Boolean asString = null;
>+    
>+    private String delimiter = null;
> 
>     private String delim = null;
> 
>@@ -86,7 +89,7 @@
>         Object xpathContext = getXPathContext();
>         Object value = null;
>         try {
>-            if(single!=null && single.booleanValue()==true) {
>+            if( single != null && single.booleanValue() == true ) {
>                 value = select.selectSingleNode(xpathContext);
>             } else {
>                 value = select.evaluate(xpathContext);
>@@ -97,29 +100,74 @@
>         }
>         
>         if (value instanceof List) {
>+            List list = (List) value;
>             // sort the list if xpCmp is set.
>             if (xpCmp != null && (xpCmp.getXpath() != null)) {
>-                Collections.sort((List)value, xpCmp);
>+                Collections.sort(list, xpCmp);
>+            }
>+            if(list.isEmpty()) {
>+                value = null;
>             }
>         }
>+        
> 
>-        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;
>+        // handle single
>+        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);
>+                }
>+            } 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;
>+                }
>+            }
>+        }
>+        
>+        // now convert the result(s) to string if need
>+        if(asString != null && asString.booleanValue()) {
>+            if(value instanceof Node) {
>+                value = ((Node) value).getStringValue();
>+            } else if(value instanceof List) {
>+                for(ListIterator it = ((List) value).listIterator(); it.hasNext(); ) {
>+                    Object v = it.next();
>+                    if(v instanceof Node) {
>+                        v = ((Node) v).getStringValue();
>+                        it.set(v);
>+                    }
>+                }
>+            }
>         }
>+        
>+        // finally convert the result to a concatenated string if delimiter is defined
>+        if(delimiter != null && value instanceof List) {
>+            StringBuffer buff = new StringBuffer();
>+            for(Iterator it = ((List) value).iterator(); it.hasNext(); ) {
>+                Object v = it.next();
>+                if (v instanceof Node) {
>+                    buff.append( ((Node) v).getStringValue());
>+                } else {
>+                    buff.append(v.toString());
>+                }
>+                if(it.hasNext()) {
>+                    buff.append(delimiter);
>+                }
>+            }
>+            buff.setLength(buff.length());
>+            value = buff.toString();
>+        }
>+        
> 
>         //log.info( "Evaluated xpath: " + select + " as: " + value + " of type: " + value.getClass().getName() );
> 
>@@ -222,7 +270,8 @@
>         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.
>+        as setAttribute.<br/>
>+        If set to false, guarantees that a list is returned.
>         If set to false, guarantees that a list is returned.
>         */
>     public void setSingle(boolean single) {
>@@ -234,19 +283,21 @@
>       * itself.
>       * This ensures that, thereafter, string manipulations
>       * can be performed on the result.
>-      * Setting this attribute to true will also set the single
>-      * attribute to true.
>       */
>     public void setAsString(boolean asString) {
>         this.asString = new Boolean(asString);
>     }
> 
>     /** If set, returns a string delimited by this delimiter.
>-     */
>+      * Implies <code>asString</code> to be true.
>+      */
>     public void setDelim(String delim) {
>-        this.delim  = delim;
>+        this.delimiter = delim;
>+        if( delim!=null ) {
>+            this.asString = Boolean.TRUE;
>+        }
>     }
>-        
>+
>     /** 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=149113&p1=jakarta/commons/proper/jelly/trunk/jelly-tags/xml/src/test/org/apache/commons/jelly/tags/xml/suite.jelly&r1=149112&p2=jakarta/commons/proper/jelly/trunk/jelly-tags/xml/src/test/org/apache/commons/jelly/tags/xml/suite.jelly&r2=149113
>==============================================================================
>--- 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	Sat Jan 29 23:47:05 2005
>@@ -290,20 +290,37 @@
>             <blip/>
>             <blop id="bla">blop0</blop></root>
>         </x:parse>
>-        <x:set var="blopSingle" select="$blopElements/root/blop" single="true"/>
>         <!-- should return the second -->
>+        <x:set var="blopSingle" select="$blopElements/root/blop" single="true"/>
>         <j:invokeStatic var="eltClass" className="java.lang.Class" method="forName"><j:arg value="org.dom4j.Element"/></j:invokeStatic>
>         <test:assert test="${eltClass.isAssignableFrom(blopSingle.getClass())}"/>
>+
>         <j:set var="blopSingleText"><x:expr select="$blopSingle/text()"/></j:set>
>         <test:assertEquals actual="${blopSingleText}" expected="blop1"/>
>+
>         <!-- check if selecting root/blip returns a list -->
>         <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 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())}"/>
>+				
>+				<!-- check if select blop/blurp with false single returns an empty list -->
>+        <x:set var="blurp" select="$blopElements/root/blurp" 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 select blop/blurp with no single or asString returns null -->
>+        <x:set var="blurp" select="$blopElements/root/blurp"/>
>+        <j:invokeStatic var="listClass" className="java.lang.Class" method="forName"><j:arg value="java.util.List"/></j:invokeStatic>
>+				<j:set var="blurpAndX" value="${blurp}X"/>
>+				blurp=${blurp}, blurpAndX=${blurpAndX}
>+        <test:assert test="${'X' eq blurpAndX}"/>
>+				
>+				
>   </test:case>
> 
> 
>
>---------------------------------------------------------------------
>To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
>For additional commands, e-mail: commons-dev-help@jakarta.apache.org
>
>
>  
>


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