jstrachan    2002/11/13 11:35:16

  Modified:    jelly/src/test/org/apache/commons/jelly/xml suite.jelly
               jelly/src/java/org/apache/commons/jelly/tags/xml
                        ElementTag.java
  Log:
  Patch to fix nesting of <x:element> and <x:attribute> tags as well as new JellyUnit 
test cases to test it
  
  Revision  Changes    Path
  1.3       +22 -0     
jakarta-commons-sandbox/jelly/src/test/org/apache/commons/jelly/xml/suite.jelly
  
  Index: suite.jelly
  ===================================================================
  RCS file: 
/home/cvs/jakarta-commons-sandbox/jelly/src/test/org/apache/commons/jelly/xml/suite.jelly,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- suite.jelly       13 Nov 2002 09:03:31 -0000      1.2
  +++ suite.jelly       13 Nov 2002 19:35:14 -0000      1.3
  @@ -10,13 +10,35 @@
        <x:parse var="doc">
                <x:element name="foo">
                        <x:attribute name="x">1234</x:attribute>
  +                     
  +                     <x:element name="bar">
  +                                     <x:attribute name="y">ABC</x:attribute>
  +                                     hello
  +                             </x:element>
                </x:element>
        </x:parse>
        
                <test:assert xpath="$doc/foo"/>
                <test:assert xpath="$doc/foo[@x='1234']"/>
                <test:assert xpath="count($doc/bar) = 0"/>
  +
  +             <!-- test nested element and attributes -->             
  +             <test:assert xpath="$doc/foo[@x='1234']/bar[@y='ABC']"/>
  +             <test:assert xpath="$doc/foo[@x='1234']/bar[@y='ABC']='hello'"/>
  +  </test:case>
  +  
  +  <test:case name="testBadElementAndAttribute">
  +     
  +    <j:catch var="ex">
  +             <x:element name="foo">
  +                     some text
  +                     <x:attribute name="x">1234</x:attribute>
  +             </x:element>
  +             </j:catch>      
                
  +             <test:assert test="${ex != null}">
  +                     We should have created an exception as some text is output 
before the attributes
  +             </test:assert>
     </test:case>
     
     <test:case name="assertXPathTests">
  
  
  
  1.5       +74 -14    
jakarta-commons-sandbox/jelly/src/java/org/apache/commons/jelly/tags/xml/ElementTag.java
  
  Index: ElementTag.java
  ===================================================================
  RCS file: 
/home/cvs/jakarta-commons-sandbox/jelly/src/java/org/apache/commons/jelly/tags/xml/ElementTag.java,v
  retrieving revision 1.4
  retrieving revision 1.5
  diff -u -r1.4 -r1.5
  --- ElementTag.java   12 Nov 2002 08:39:50 -0000      1.4
  +++ ElementTag.java   13 Nov 2002 19:35:15 -0000      1.5
  @@ -67,6 +67,8 @@
   import org.apache.commons.jelly.XMLOutput;
   
   import org.xml.sax.Attributes;
  +import org.xml.sax.ContentHandler;
  +import org.xml.sax.SAXException;
   import org.xml.sax.helpers.AttributesImpl;
   
   /** A tag to produce an XML element which can contain other attributes 
  @@ -86,11 +88,25 @@
       /** The XML Attributes */
       private AttributesImpl attributes = new AttributesImpl();
   
  +     /** flag set if attributes are output */
  +     private boolean outputAttributes;
       
       public ElementTag() {
       }
   
  -    public void setAttributeValue( String name, String value ) {
  +     /**
  +      * Sets the attribute of the given name to the specified value.
  +      * 
     * @param name of the attribute
         * @param value of the 
attribute
        * @throws JellyException if the start element has already been 
output. 
  +      *   Attributes must be set on the outer element before any content 
  +      *   (child elements or text) is output
         */
  +    public void setAttributeValue( String name, String value ) throws 
JellyException {
  +     if (outputAttributes) {
  +             throw new JellyException(
  +                             "Cannot set the value of attribute: " 
  +                     + name + " as we have already output the startElement() SAX 
event"
  +                     );
  +     }
  +     
           // ### we'll assume that all attributes are in no namespace!
           // ### this is severely limiting!
           // ### we should be namespace aware
  @@ -107,22 +123,66 @@
       // Tag interface
       //-------------------------------------------------------------------------     
               
       public void doTag(XMLOutput output) throws Exception {
  -        String localName = null;
           int idx = name.indexOf(':');
  -        if (idx >= 0) {
  -            localName = name.substring(idx + 1);
  -        }
  -        else {
  -            localName = name;
  -        }
  +        final String localName = (idx >= 0) 
  +             ? name.substring(idx + 1)
  +             : name;
  +        
  +        outputAttributes = false;
           
  -        /** 
  -         * @todo we should buffer up any SAX events and replay then
  -         * inside the startElement/endElement block
         */
  -        invokeBody(output);
  -        output.startElement(namespace, localName, name, attributes);
  +        XMLOutput newOutput = new XMLOutput(output) {
  +
  +                     // add an initialize hook to the core content-generating 
methods
  +                                     
  +                 public void startElement(
  +                     String uri,
  +                     String localName,
  +                     String qName,
  +                     Attributes atts)
  +                     throws SAXException {
  +                             initialize();           
  +                     super.startElement(uri, localName, qName, atts);
  +                 }
  +             
  +                 public void endElement(String uri, String localName, String qName)
  +                     throws SAXException {
  +                             initialize();           
  +                     super.endElement(uri, localName, qName);
  +                 }
  +             
  +                 public void characters(char ch[], int start, int length) throws 
SAXException {
  +                             initialize();           
  +                     super.characters(ch, start, length);
  +                 }
  +             
  +                 public void ignorableWhitespace(char ch[], int start, int length)
  +                     throws SAXException {
  +                             initialize();           
  +                     super.ignorableWhitespace(ch, start, length);
  +                 }
  +                 public void processingInstruction(String target, String data)
  +                     throws SAXException {
  +                             initialize();           
  +                     super.processingInstruction(target, data);
  +                 }
  +             
  +             /** 
  +              * Ensure that the outer start element is generated 
  +              * before any content is output
                 */ 
  +             protected void initialize() throws SAXException {
  +                     if (!outputAttributes) {
  +                             super.startElement(namespace, localName, name, 
attributes);
  +                             outputAttributes = true;
  +                     }
  +             }
  +        };
  +        
  +        invokeBody(newOutput);
           
  -        /** @todo we should replay the cached SAX events (if any) here */
  +        if (!outputAttributes) {
  +             output.startElement(namespace, localName, name, attributes);
  +             outputAttributes = true;
  +        }
           
           output.endElement(namespace, localName, name);
           attributes.clear();
  
  
  

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

Reply via email to