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: [EMAIL PROTECTED] 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: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]