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/07/19 19:34:02 UTC
svn commit: r219726 - in /jakarta/commons/proper/jelly/trunk:
jelly-tags/xml/ jelly-tags/xml/src/java/org/apache/commons/jelly/tags/xml/
jelly-tags/xml/src/test/org/apache/commons/jelly/tags/xml/
src/java/org/apache/commons/jelly/ src/java/org/apache/c...
Author: polx
Date: Tue Jul 19 10:34:00 2005
New Revision: 219726
URL: http://svn.apache.org/viewcvs?rev=219726&view=rev
Log:
Fixing treatment of namespaced-qualified attributes in XML taglib and
in the xml-output.
This fixes JELLY-213 and JELLY-214.
paul
Added:
jakarta/commons/proper/jelly/trunk/jelly-tags/xml/src/java/org/apache/commons/jelly/tags/xml/ReplaceNamespaceTag.java
jakarta/commons/proper/jelly/trunk/jelly-tags/xml/src/test/org/apache/commons/jelly/tags/xml/attributeNameSpace.jelly
jakarta/commons/proper/jelly/trunk/jelly-tags/xml/src/test/org/apache/commons/jelly/tags/xml/attributeNameSpaceDefaultNS.jelly
jakarta/commons/proper/jelly/trunk/jelly-tags/xml/src/test/org/apache/commons/jelly/tags/xml/attributeNameSpaceDuplicatedNS.jelly
jakarta/commons/proper/jelly/trunk/jelly-tags/xml/src/test/org/apache/commons/jelly/tags/xml/attributeNameSpaceWithInnerElements.jelly
jakarta/commons/proper/jelly/trunk/jelly-tags/xml/src/test/org/apache/commons/jelly/tags/xml/elementWithNameSpace.jelly
jakarta/commons/proper/jelly/trunk/jelly-tags/xml/src/test/org/apache/commons/jelly/tags/xml/elementWithNameSpaceError.jelly
jakarta/commons/proper/jelly/trunk/jelly-tags/xml/src/test/org/apache/commons/jelly/tags/xml/namespaceReplace.jelly
jakarta/commons/proper/jelly/trunk/src/test/org/apache/commons/jelly/testStaticNamespacedAttributes.jelly
Modified:
jakarta/commons/proper/jelly/trunk/jelly-tags/xml/project.xml
jakarta/commons/proper/jelly/trunk/jelly-tags/xml/src/java/org/apache/commons/jelly/tags/xml/AttributeTag.java
jakarta/commons/proper/jelly/trunk/jelly-tags/xml/src/java/org/apache/commons/jelly/tags/xml/ElementTag.java
jakarta/commons/proper/jelly/trunk/jelly-tags/xml/src/java/org/apache/commons/jelly/tags/xml/XMLTagLibrary.java
jakarta/commons/proper/jelly/trunk/jelly-tags/xml/src/test/org/apache/commons/jelly/tags/xml/TestXMLTags.java
jakarta/commons/proper/jelly/trunk/src/java/org/apache/commons/jelly/XMLOutput.java
jakarta/commons/proper/jelly/trunk/src/java/org/apache/commons/jelly/impl/StaticTag.java
jakarta/commons/proper/jelly/trunk/src/java/org/apache/commons/jelly/impl/StaticTagScript.java
jakarta/commons/proper/jelly/trunk/src/java/org/apache/commons/jelly/impl/TagScript.java
jakarta/commons/proper/jelly/trunk/src/java/org/apache/commons/jelly/parser/XMLParser.java
jakarta/commons/proper/jelly/trunk/src/test/org/apache/commons/jelly/TestCoreTags.java
jakarta/commons/proper/jelly/trunk/src/test/org/apache/commons/jelly/core/TestFileTag.java
Modified: jakarta/commons/proper/jelly/trunk/jelly-tags/xml/project.xml
URL: http://svn.apache.org/viewcvs/jakarta/commons/proper/jelly/trunk/jelly-tags/xml/project.xml?rev=219726&r1=219725&r2=219726&view=diff
==============================================================================
--- jakarta/commons/proper/jelly/trunk/jelly-tags/xml/project.xml (original)
+++ jakarta/commons/proper/jelly/trunk/jelly-tags/xml/project.xml Tue Jul 19 10:34:00 2005
@@ -20,7 +20,7 @@
<extend>${basedir}/../tag-project.xml</extend>
<id>commons-jelly-tags-xml</id>
<name>commons-jelly-tags-xml</name>
- <currentVersion>1.1</currentVersion>
+ <currentVersion>1.2-dev</currentVersion>
<package>org.apache.commons.jelly.tags.xml</package>
<description>The Jelly XML Tag Library</description>
<shortDescription>Commons Jelly XML Tag Library</shortDescription>
@@ -37,6 +37,11 @@
</version>
</versions>
<dependencies>
+ <dependency>
+ <id>commons-jelly</id>
+ <version>SNAPSHOT</version>
+ </dependency>
+
<!-- run time / in testing-->
<dependency>
Modified: jakarta/commons/proper/jelly/trunk/jelly-tags/xml/src/java/org/apache/commons/jelly/tags/xml/AttributeTag.java
URL: http://svn.apache.org/viewcvs/jakarta/commons/proper/jelly/trunk/jelly-tags/xml/src/java/org/apache/commons/jelly/tags/xml/AttributeTag.java?rev=219726&r1=219725&r2=219726&view=diff
==============================================================================
--- jakarta/commons/proper/jelly/trunk/jelly-tags/xml/src/java/org/apache/commons/jelly/tags/xml/AttributeTag.java (original)
+++ jakarta/commons/proper/jelly/trunk/jelly-tags/xml/src/java/org/apache/commons/jelly/tags/xml/AttributeTag.java Tue Jul 19 10:34:00 2005
@@ -26,6 +26,8 @@
* @version $Revision$
*/
public class AttributeTag extends TagSupport {
+ /** The namespace URI. */
+ private String namespace;
/** the name of the attribute. */
private String name;
@@ -38,10 +40,11 @@
//-------------------------------------------------------------------------
public void doTag(XMLOutput output) throws JellyTagException {
ElementTag tag = (ElementTag) findAncestorWithClass( ElementTag.class );
- if ( tag == null ) {
- throw new JellyTagException( "<attribute> tag must be enclosed inside an <element> tag" );
+ if (tag == null) {
+ throw new JellyTagException(
+ "<attribute> tag must be enclosed inside an <element> tag" );
}
- tag.setAttributeValue( getName(), getBodyText( false ) );
+ tag.setAttributeValue(getName(), getBodyText(false), getURI());
}
// Properties
@@ -53,10 +56,25 @@
public String getName() {
return name;
}
+
/**
- * Sets the name of the attribute
+ * Sets the name of the attribute.
*/
public void setName(String name) {
this.name = name;
+ }
+
+ /**
+ * @return the namespace URI of the element
+ */
+ public String getURI() {
+ return namespace;
+ }
+
+ /**
+ * Sets the namespace URI of the element
+ */
+ public void setURI(String namespace) {
+ this.namespace = namespace;
}
}
Modified: jakarta/commons/proper/jelly/trunk/jelly-tags/xml/src/java/org/apache/commons/jelly/tags/xml/ElementTag.java
URL: http://svn.apache.org/viewcvs/jakarta/commons/proper/jelly/trunk/jelly-tags/xml/src/java/org/apache/commons/jelly/tags/xml/ElementTag.java?rev=219726&r1=219725&r2=219726&view=diff
==============================================================================
--- jakarta/commons/proper/jelly/trunk/jelly-tags/xml/src/java/org/apache/commons/jelly/tags/xml/ElementTag.java (original)
+++ jakarta/commons/proper/jelly/trunk/jelly-tags/xml/src/java/org/apache/commons/jelly/tags/xml/ElementTag.java Tue Jul 19 10:34:00 2005
@@ -15,6 +15,7 @@
*/
package org.apache.commons.jelly.tags.xml;
+import org.apache.commons.jelly.JellyException;
import org.apache.commons.jelly.JellyTagException;
import org.apache.commons.jelly.TagSupport;
import org.apache.commons.jelly.XMLOutput;
@@ -22,8 +23,6 @@
import org.xml.sax.SAXException;
import org.xml.sax.helpers.AttributesImpl;
-import java.io.IOException;
-
/** A tag to produce an XML element which can contain other attributes
* or elements like the <code><xsl:element></code> tag.
*
@@ -32,16 +31,16 @@
*/
public class ElementTag extends TagSupport {
- /** The namespace URI */
+ /** The namespace URI. */
private String namespace;
- /** The qualified name */
+ /** The qualified name. */
private String name;
- /** The XML Attributes */
+ /** The XML Attributes. */
private AttributesImpl attributes = new AttributesImpl();
- /** flag set if attributes are output */
+ /** flag set if attributes are output. */
private boolean outputAttributes;
public ElementTag() {
@@ -52,11 +51,12 @@
*
* @param name of the attribute
* @param value of the attribute
- * @throws JellyException if the start element has already been output.
+ * @param uri namespace of the attribute
+ * @throws JellyTagException 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 JellyTagException {
+ public void setAttributeValue(String name, String value, String uri) throws JellyTagException {
if (outputAttributes) {
throw new JellyTagException(
"Cannot set the value of attribute: "
@@ -67,13 +67,22 @@
// ### we'll assume that all attributes are in no namespace!
// ### this is severely limiting!
// ### we should be namespace aware
- int index = attributes.getIndex("", name);
+ // NAMESPACE FIXED:
+ int idx = name.indexOf(':');
+ final String localName = (idx >= 0)
+ ? name.substring(idx + 1)
+ : name;
+ final String nsUri = (uri != null)
+ ? uri
+ : "";
+
+ int index = attributes.getIndex(nsUri, localName);
if (index >= 0) {
attributes.removeAttribute(index);
}
// treat null values as no attribute
if (value != null) {
- attributes.addAttribute("", name, name, "CDATA", value);
+ attributes.addAttribute(nsUri, localName, name, "CDATA", value);
}
}
@@ -107,22 +116,21 @@
super.endElement(uri, localName, qName);
}
- public void characters(char ch[], int start, int length) throws SAXException {
+ 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)
+ public void ignorableWhitespace(char[] ch, int start, int length)
throws SAXException {
initialize();
super.ignorableWhitespace(ch, start, length);
}
public void objectData(Object object)
- throws SAXException
- {
+ throws SAXException {
initialize();
- super.objectData( object );
+ super.objectData(object);
}
public void processingInstruction(String target, String data)
@@ -133,7 +141,7 @@
/**
* Ensure that the outer start element is generated
- * before any content is output
+ * before any content is output.
*/
protected void initialize() throws SAXException {
if (!outputAttributes) {
Added: jakarta/commons/proper/jelly/trunk/jelly-tags/xml/src/java/org/apache/commons/jelly/tags/xml/ReplaceNamespaceTag.java
URL: http://svn.apache.org/viewcvs/jakarta/commons/proper/jelly/trunk/jelly-tags/xml/src/java/org/apache/commons/jelly/tags/xml/ReplaceNamespaceTag.java?rev=219726&view=auto
==============================================================================
--- jakarta/commons/proper/jelly/trunk/jelly-tags/xml/src/java/org/apache/commons/jelly/tags/xml/ReplaceNamespaceTag.java (added)
+++ jakarta/commons/proper/jelly/trunk/jelly-tags/xml/src/java/org/apache/commons/jelly/tags/xml/ReplaceNamespaceTag.java Tue Jul 19 10:34:00 2005
@@ -0,0 +1,128 @@
+/*
+ * Copyright 2002,2004 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.commons.jelly.tags.xml;
+
+import org.apache.commons.jelly.JellyTagException;
+import org.apache.commons.jelly.MissingAttributeException;
+import org.apache.commons.jelly.TagSupport;
+import org.apache.commons.jelly.XMLOutput;
+
+import org.xml.sax.Attributes;
+import org.xml.sax.SAXException;
+import org.xml.sax.helpers.AttributesImpl;
+
+/**
+ * Replace namespace is a filter to change the namespace of any
+ * elemement attribute passing through it.
+ *
+ * @author Diogo Quintela <dq...@gmail.com>
+ */
+public class ReplaceNamespaceTag extends TagSupport {
+ private String fromNamespace;
+ private String toNamespace;
+
+ public ReplaceNamespaceTag() {
+ }
+
+ // Tag interface
+ //-------------------------------------------------------------------------
+ public void doTag(XMLOutput output) throws MissingAttributeException, JellyTagException {
+ final String fromURI = (fromNamespace != null) ? fromNamespace : "";
+ final String toURI = (toNamespace != null) ? toNamespace : "";
+ XMLOutput newOutput = output;
+
+ if (!toURI.equals(fromURI)) {
+ newOutput = new XMLOutput(output) {
+ public void startElement(String uri, String localName, String qName, Attributes atts)
+ throws SAXException {
+ super.startElement(replaceURI(uri), localName, qName, replaceURI(atts));
+ }
+
+ public void endElement(String uri, String localName, String qName)
+ throws SAXException {
+ super.endElement(replaceURI(uri), localName, qName);
+ }
+
+ public void startPrefixMapping(String prefix, String uri)
+ throws SAXException {
+ super.startPrefixMapping(prefix, replaceURI(uri));
+ }
+
+ private String replaceURI(String uri) {
+ String newUri = uri;
+
+ if (fromURI.equals((uri != null) ? uri : "")) {
+ newUri = toURI;
+ }
+
+ return newUri;
+ }
+
+ private Attributes replaceURI(Attributes atts) {
+ AttributesImpl newAttsImpl = new AttributesImpl();
+
+ for (int i = 0; i < atts.getLength(); i++) {
+ // Normally attributes don't have namespaces
+ // But may have (only if on form prefix:attr) ?
+ // So, we'll only replace if needed
+ String QName = atts.getQName(i);
+ String newUri = atts.getURI(i);
+ int idx = QName.indexOf(':');
+
+ if (idx >= 0) {
+ newUri = replaceURI(newUri);
+ }
+
+ newAttsImpl.addAttribute(newUri, atts.getLocalName(i), atts.getQName(i),
+ atts.getType(i), atts.getValue(i));
+ }
+
+ return newAttsImpl;
+ }
+ };
+ }
+
+ invokeBody(newOutput);
+ }
+
+ /**
+ * @return the source namespace URI to replace
+ */
+ public String getFromURI() {
+ return fromNamespace;
+ }
+
+ /**
+ * Sets the source namespace URI to replace.
+ */
+ public void setFromURI(String namespace) {
+ this.fromNamespace = namespace;
+ }
+
+ /**
+ * @return the destination namespace URI to replace
+ */
+ public String getToURI() {
+ return toNamespace;
+ }
+
+ /**
+ * Sets the destination namespace URI to replace.
+ */
+ public void setToURI(String namespace) {
+ this.toNamespace = namespace;
+ }
+}
\ No newline at end of file
Modified: jakarta/commons/proper/jelly/trunk/jelly-tags/xml/src/java/org/apache/commons/jelly/tags/xml/XMLTagLibrary.java
URL: http://svn.apache.org/viewcvs/jakarta/commons/proper/jelly/trunk/jelly-tags/xml/src/java/org/apache/commons/jelly/tags/xml/XMLTagLibrary.java?rev=219726&r1=219725&r2=219726&view=diff
==============================================================================
--- jakarta/commons/proper/jelly/trunk/jelly-tags/xml/src/java/org/apache/commons/jelly/tags/xml/XMLTagLibrary.java (original)
+++ jakarta/commons/proper/jelly/trunk/jelly-tags/xml/src/java/org/apache/commons/jelly/tags/xml/XMLTagLibrary.java Tue Jul 19 10:34:00 2005
@@ -53,6 +53,7 @@
registerTag("expr", ExprTag.class);
registerTag("element", ElementTag.class);
registerTag("attribute", AttributeTag.class);
+ registerTag("replaceNamespace", ReplaceNamespaceTag.class);
registerTag("copy", CopyTag.class);
registerTag("copyOf", CopyOfTag.class);
registerTag("comment", CommentTag.class);
Modified: jakarta/commons/proper/jelly/trunk/jelly-tags/xml/src/test/org/apache/commons/jelly/tags/xml/TestXMLTags.java
URL: http://svn.apache.org/viewcvs/jakarta/commons/proper/jelly/trunk/jelly-tags/xml/src/test/org/apache/commons/jelly/tags/xml/TestXMLTags.java?rev=219726&r1=219725&r2=219726&view=diff
==============================================================================
--- jakarta/commons/proper/jelly/trunk/jelly-tags/xml/src/test/org/apache/commons/jelly/tags/xml/TestXMLTags.java (original)
+++ jakarta/commons/proper/jelly/trunk/jelly-tags/xml/src/test/org/apache/commons/jelly/tags/xml/TestXMLTags.java Tue Jul 19 10:34:00 2005
@@ -19,15 +19,20 @@
import java.io.FileInputStream;
import java.io.InputStream;
import java.io.StringWriter;
+import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import junit.framework.Assert;
import junit.framework.Test;
import junit.framework.TestCase;
import junit.framework.TestSuite;
import junit.textui.TestRunner;
import org.apache.commons.jelly.JellyContext;
+import org.apache.commons.jelly.JellyException;
import org.apache.commons.jelly.Script;
import org.apache.commons.jelly.XMLOutput;
import org.apache.commons.jelly.parser.XMLParser;
@@ -36,6 +41,8 @@
import org.dom4j.Document;
import org.dom4j.DocumentHelper;
import org.dom4j.Node;
+import org.dom4j.io.SAXContentHandler;
+import org.dom4j.io.XMLWriter;
/** Tests the parser, the engine and the XML tags
*
@@ -84,57 +91,158 @@
log.debug("Evaluated script as...");
log.debug(text);
}
- assertEquals("Produces the correct output", "It works!", text);
+ assertEquals("Should produce the correct output", "It works!", text);
+ }
+
+ public void testElementWithNameSpace() throws Exception {
+ String text = evaluteScriptAsText(testBaseDir + "/elementWithNameSpace.jelly");
+ assertEquals("Should produce the correct output",
+ "<env:Envelope "+
+ "xmlns:env=\"http://schemas.xmlsoap.org/soap/envelope/\" "+
+ "env:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\">"+
+ "</env:Envelope>", text);
+ }
+
+ public void testElementWithNameSpaceError() throws Exception {
+ try {
+ evaluteScriptAsText(testBaseDir + "/elementWithNameSpaceError.jelly");
+ Assert.fail("We should have bailed out with an JellyException");
+ } catch (JellyException jex) {
+ assertTrue(jex.getReason().startsWith("Cannot set same prefix to diferent URI in same node"));
+ }
+ }
+
+ public void testNamespaceReplace() throws Exception {
+ // For this test when we not set "ns" var with expected namespace, it
+ // is expected to repeat the same two times
+ String text = evaluteScriptAsText(testBaseDir + "/namespaceReplace.jelly");
+ String repeatingText = "<test-subnode attr=\"test\"><test-anotherSubNode></test-anotherSubNode><test-anotherSubNodeAgain xmlns:other=\"\" other:abc=\"testValue\"></test-anotherSubNodeAgain></test-subnode>";
+ assertEquals("Should produce the correct output",
+ "<test-node xmlns:test=\"http://apache/testNS\" test:abc=\"testValue\">"+
+ repeatingText + repeatingText +
+ "</test-node>", text);
+
+ Map ctxVars = new HashMap();
+ ctxVars.put("ns", "http://java/ns");
+
+ text = evaluteScriptAsText(testBaseDir + "/namespaceReplace.jelly", ctxVars);
+
+ String firstTrunk =
+ "<test-subnode xmlns=\"\" attr=\"test\">" +
+ "<test-anotherSubNode>" +
+ "</test-anotherSubNode>" +
+ "<test-anotherSubNodeAgain xmlns:other=\"http://java/ns\" xmlns=\"http://java/ns\" other:abc=\"testValue\">" +
+ "</test-anotherSubNodeAgain>" +
+ "</test-subnode>";
+
+ String secondTrunk =
+ "<test-subnode attr=\"test\">" +
+ "<test-anotherSubNode>" +
+ "</test-anotherSubNode>" +
+ "<test-anotherSubNodeAgain xmlns:other=\"http://java/ns\" other:abc=\"testValue\">" +
+ "</test-anotherSubNodeAgain>" +
+ "</test-subnode>";
+
+ System.out.println("TestXMLTags.testNamespaceReplace() text="+text);
+ assertEquals("Should produce the correct output",
+ "<test-node xmlns:test=\"http://apache/testNS\" xmlns=\"http://java/ns\" test:abc=\"testValue\">"+
+ firstTrunk + secondTrunk +
+ "</test-node>", text);
+ }
+
+ public void testAttributeNameSpaceDuplicatedNS() throws Exception {
+ try {
+ evaluteScriptAsText(testBaseDir + "/attributeNameSpaceDuplicatedNS.jelly");
+ Assert.fail("We should have bailed out with an JellyException");
+ } catch (JellyException jex) {
+ assertTrue(jex.getReason().startsWith("Cannot set same prefix to diferent URI in same node"));
+ }
+ }
+
+ public void testAttributeNameSpace() throws Exception {
+ String text = evaluteScriptAsText(testBaseDir + "/attributeNameSpace.jelly");
+ System.out.println(text);
+ assertEquals("Should produce the correct output",
+ "<top-node xmlns=\"abc\">"+
+ "<test-node xmlns:test=\"http://apache/testNS\" xmlns=\"http://apache/trueNS\" test:abc=\"testValue\" abc2=\"testValue\" abc3=\"testValue\">"+
+ "<test:test-subnode><node-at-same-ns-as-top xmlns=\"abc\">"+
+ "</node-at-same-ns-as-top>"+
+ "</test:test-subnode>"+
+ "</test-node>"+
+ "</top-node>", text);
+ }
+
+ public void testAttributeNameSpaceDefaultNS() throws Exception {
+ String text = evaluteScriptAsText(testBaseDir + "/attributeNameSpaceDefaultNS.jelly");
+ System.out.println(text);
+ assertEquals("Should produce the correct output",
+ "<top-node>"+
+ "<test-node xmlns:test=\"http://apache/testNS\" xmlns=\"http://apache/trueNS\" test:abc=\"testValue\" abc2=\"testValue\" abc3=\"testValue\">"+
+ "<test:test-subnode><node-at-same-ns-as-top xmlns=\"\">"+
+ "</node-at-same-ns-as-top>"+
+ "</test:test-subnode>"+
+ "</test-node>"+
+ "</top-node>", text);
+ }
+
+ public void testAttributeNameSpaceWithInnerElements() throws Exception {
+ String text = evaluteScriptAsText(testBaseDir + "/attributeNameSpaceWithInnerElements.jelly");
+ assertEquals("Should produce the correct output",
+ "<test-node xmlns:test=\"http://apache/testNS\" test:abc=\"testValue\" abc2=\"testValue\" abc3=\"testValue\">"+
+ "<test-sub-node xmlns:test2=\"http://apache/testNS\" xmlns:test3=\"http://apache/anotherNS\" test:abc=\"testValue\" test2:abc2=\"testValue\" test3:abc3=\"testValue\">"+
+ "</test-sub-node>"+
+ "</test-node>"
+ , text);
}
public void testTransform() throws Exception {
String text = evaluteScriptAsText(testBaseDir + "/transformExample.jelly");
- assertEquals("Produces the correct output", "It works!", text);
+ assertEquals("Should produce the correct output", "It works!", text);
}
public void testTransformAllInLine() throws Exception {
String text = evaluteScriptAsText(testBaseDir + "/transformExampleAllInLine.jelly");
- assertEquals("Produces the correct output", "It works!", text);
+ assertEquals("Should produce the correct output", "It works!", text);
}
public void testTransformParams() throws Exception {
String text = evaluteScriptAsText(testBaseDir + "/transformParamExample.jelly");
- assertEquals("Produces the correct output", "It works!", text);
+ assertEquals("Should produce the correct output", "It works!", text);
}
public void testTransformParamsInLine() throws Exception {
String text = evaluteScriptAsText(testBaseDir + "/transformParamExample2.jelly");
- assertEquals("Produces the correct output", "It works!", text);
+ assertEquals("Should produce the correct output", "It works!", text);
}
public void testTransformSAXOutput() throws Exception {
String text = evaluteScriptAsText(testBaseDir + "/transformExampleSAXOutput.jelly");
- assertEquals("Produces the correct output", "It works!", text);
+ assertEquals("Should produce the correct output", "It works!", text);
}
public void testTransformSAXOutputNestedTransforms() throws Exception {
String text = evaluteScriptAsText(testBaseDir +
"/transformExampleSAXOutputNestedTransforms.jelly");
- assertEquals("Produces the correct output", "It works!", text);
+ assertEquals("Should produce the correct output", "It works!", text);
}
public void testTransformSchematron() throws Exception {
String text = evaluteScriptAsText(testBaseDir +
"/schematron/transformSchematronExample.jelly");
- assertEquals("Produces the correct output", "Report count=1:assert count=2", text);
+ assertEquals("Should produce the correct output", "Report count=1:assert count=2", text);
}
public void testTransformXmlVar() throws Exception {
String text = evaluteScriptAsText(testBaseDir +
"/transformExampleXmlVar.jelly");
- assertEquals("Produces the correct output", "It works!", text);
+ assertEquals("Should produce the correct output", "It works!", text);
}
public void testDoctype() throws Exception {
String text = evaluteScriptAsText(testBaseDir +
"/testDoctype.jelly");
- assertEquals("Produces the correct output", "<!DOCTYPE foo PUBLIC \"publicID\" \"foo.dtd\">\n<foo></foo>", text);
+ assertEquals("Should produce the correct output", "<!DOCTYPE foo PUBLIC \"publicID\" \"foo.dtd\">\n<foo></foo>", text);
}
public void runUnitTest(String name) throws Exception {
@@ -172,7 +280,23 @@
* returns the whitespace trimmed output as text
*/
protected String evaluteScriptAsText(String fileName) throws Exception {
+ return evaluteScriptAsText(fileName, null);
+ }
+
+ /**
+ * Evaluates the script by the given file name and
+ * returns the whitespace trimmed output as text
+ */
+ protected String evaluteScriptAsText(String fileName, Map ctxVars) throws Exception {
JellyContext context = new JellyContext();
+ if (ctxVars != null) {
+ Set keys = ctxVars.keySet();
+ for (Iterator iterator = keys.iterator(); iterator.hasNext();) {
+ String key = (String) iterator.next();
+ Object value = ctxVars.get(key);
+ context.setVariable(key, value);
+ }
+ }
// allow scripts to refer to any resource inside this project
// using an absolute URI like /src/test/org/apache/foo.xml
@@ -190,4 +314,49 @@
}
return text;
}
+
+ protected String evaluteScriptAsTextUsingSaxContentHandler(String fileName, Map ctxVars) throws Exception {
+ org.dom4j.io.OutputFormat outputFormat = new org.dom4j.io.OutputFormat();
+ outputFormat.setSuppressDeclaration(true);
+ outputFormat.setNewlines(false);
+ outputFormat.setIndent(false);
+ outputFormat.setExpandEmptyElements(true);
+ //outputFormat.setIndentSize(4);
+
+ StringWriter buffer = new StringWriter();
+ XMLWriter xmlWriter = new XMLWriter(buffer, outputFormat);
+ // xmlWriter.setEscapeText(false);
+
+ SAXContentHandler saxHandler = new SAXContentHandler();
+ XMLOutput output = new XMLOutput(saxHandler);
+
+ // now run a script using a URL
+ JellyContext context = new JellyContext();
+ if (ctxVars != null) {
+ Set keys = ctxVars.keySet();
+ for (Iterator iterator = keys.iterator(); iterator.hasNext();) {
+ String key = (String) iterator.next();
+ Object value = ctxVars.get(key);
+ context.setVariable(key, value);
+ }
+ }
+
+ // allow scripts to refer to any resource inside this project
+ // using an absolute URI like /src/test/org/apache/foo.xml
+ context.setRootURL(new File(".").toURL());
+
+ output.startDocument();
+ context.runScript(new File(fileName), output);
+ output.endDocument();
+ xmlWriter.write(saxHandler.getDocument());
+ xmlWriter.flush();
+
+ String text = buffer.toString().trim();
+ if (log.isDebugEnabled()) {
+ log.debug("Evaluated script as...");
+ log.debug(text);
+ }
+ return text;
+ }
+
}
Added: jakarta/commons/proper/jelly/trunk/jelly-tags/xml/src/test/org/apache/commons/jelly/tags/xml/attributeNameSpace.jelly
URL: http://svn.apache.org/viewcvs/jakarta/commons/proper/jelly/trunk/jelly-tags/xml/src/test/org/apache/commons/jelly/tags/xml/attributeNameSpace.jelly?rev=219726&view=auto
==============================================================================
--- jakarta/commons/proper/jelly/trunk/jelly-tags/xml/src/test/org/apache/commons/jelly/tags/xml/attributeNameSpace.jelly (added)
+++ jakarta/commons/proper/jelly/trunk/jelly-tags/xml/src/test/org/apache/commons/jelly/tags/xml/attributeNameSpace.jelly Tue Jul 19 10:34:00 2005
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<j:jelly xmlns:j="jelly:core" xmlns:x="jelly:xml" xmlns="abc">
+ <top-node>
+ <x:element URI="http://apache/trueNS" name="test-node">
+ <x:attribute URI="http://apache/testNS" name="test:abc" trim="true">testValue</x:attribute>
+ <!-- attributes without ':' should not have namespace -->
+ <x:attribute URI="http://apache/testNS" name="abc2" trim="true">testValue</x:attribute>
+ <x:attribute name="abc3" trim="true">testValue</x:attribute>
+ <x:element URI="http://apache/testNS" name="test:test-subnode">
+ <node-at-same-ns-as-top/>
+ </x:element>
+ </x:element>
+ </top-node>
+</j:jelly>
+
Added: jakarta/commons/proper/jelly/trunk/jelly-tags/xml/src/test/org/apache/commons/jelly/tags/xml/attributeNameSpaceDefaultNS.jelly
URL: http://svn.apache.org/viewcvs/jakarta/commons/proper/jelly/trunk/jelly-tags/xml/src/test/org/apache/commons/jelly/tags/xml/attributeNameSpaceDefaultNS.jelly?rev=219726&view=auto
==============================================================================
--- jakarta/commons/proper/jelly/trunk/jelly-tags/xml/src/test/org/apache/commons/jelly/tags/xml/attributeNameSpaceDefaultNS.jelly (added)
+++ jakarta/commons/proper/jelly/trunk/jelly-tags/xml/src/test/org/apache/commons/jelly/tags/xml/attributeNameSpaceDefaultNS.jelly Tue Jul 19 10:34:00 2005
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<j:jelly xmlns:j="jelly:core" xmlns:x="jelly:xml">
+ <top-node>
+ <x:element URI="http://apache/trueNS" name="test-node">
+ <x:attribute URI="http://apache/testNS" name="test:abc" trim="true">testValue</x:attribute>
+ <!-- attributes without ':' should not have namespace -->
+ <x:attribute URI="http://apache/testNS" name="abc2" trim="true">testValue</x:attribute>
+ <x:attribute name="abc3" trim="true">testValue</x:attribute>
+ <x:element URI="http://apache/testNS" name="test:test-subnode">
+ <node-at-same-ns-as-top/>
+ </x:element>
+ </x:element>
+ </top-node>
+</j:jelly>
+
Added: jakarta/commons/proper/jelly/trunk/jelly-tags/xml/src/test/org/apache/commons/jelly/tags/xml/attributeNameSpaceDuplicatedNS.jelly
URL: http://svn.apache.org/viewcvs/jakarta/commons/proper/jelly/trunk/jelly-tags/xml/src/test/org/apache/commons/jelly/tags/xml/attributeNameSpaceDuplicatedNS.jelly?rev=219726&view=auto
==============================================================================
--- jakarta/commons/proper/jelly/trunk/jelly-tags/xml/src/test/org/apache/commons/jelly/tags/xml/attributeNameSpaceDuplicatedNS.jelly (added)
+++ jakarta/commons/proper/jelly/trunk/jelly-tags/xml/src/test/org/apache/commons/jelly/tags/xml/attributeNameSpaceDuplicatedNS.jelly Tue Jul 19 10:34:00 2005
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<j:jelly xmlns:j="jelly:core" xmlns:x="jelly:xml">
+ <x:element name="test-node">
+ <x:attribute URI="http://apache/testNS" name="test:abc" trim="true">testValue</x:attribute>
+ <x:attribute URI="http://apache/anotherNS" name="test:abc2" trim="true">testValue</x:attribute>
+ </x:element>
+</j:jelly>
+
Added: jakarta/commons/proper/jelly/trunk/jelly-tags/xml/src/test/org/apache/commons/jelly/tags/xml/attributeNameSpaceWithInnerElements.jelly
URL: http://svn.apache.org/viewcvs/jakarta/commons/proper/jelly/trunk/jelly-tags/xml/src/test/org/apache/commons/jelly/tags/xml/attributeNameSpaceWithInnerElements.jelly?rev=219726&view=auto
==============================================================================
--- jakarta/commons/proper/jelly/trunk/jelly-tags/xml/src/test/org/apache/commons/jelly/tags/xml/attributeNameSpaceWithInnerElements.jelly (added)
+++ jakarta/commons/proper/jelly/trunk/jelly-tags/xml/src/test/org/apache/commons/jelly/tags/xml/attributeNameSpaceWithInnerElements.jelly Tue Jul 19 10:34:00 2005
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<j:jelly xmlns:j="jelly:core" xmlns:x="jelly:xml">
+ <x:element name="test-node">
+ <x:attribute URI="http://apache/testNS" name="test:abc" trim="true">testValue</x:attribute>
+ <!-- attributes without ':' should not have namespace -->
+ <x:attribute URI="http://apache/testNS" name="abc2" trim="true">testValue</x:attribute>
+ <x:attribute name="abc3" trim="true">testValue</x:attribute>
+
+ <x:element name="test-sub-node">
+ <x:attribute URI="http://apache/testNS" name="test:abc" trim="true">testValue</x:attribute>
+ <x:attribute URI="http://apache/testNS" name="test2:abc2" trim="true">testValue</x:attribute>
+ <x:attribute URI="http://apache/anotherNS" name="test3:abc3" trim="true">testValue</x:attribute>
+ </x:element>
+ </x:element>
+</j:jelly>
+
Added: jakarta/commons/proper/jelly/trunk/jelly-tags/xml/src/test/org/apache/commons/jelly/tags/xml/elementWithNameSpace.jelly
URL: http://svn.apache.org/viewcvs/jakarta/commons/proper/jelly/trunk/jelly-tags/xml/src/test/org/apache/commons/jelly/tags/xml/elementWithNameSpace.jelly?rev=219726&view=auto
==============================================================================
--- jakarta/commons/proper/jelly/trunk/jelly-tags/xml/src/test/org/apache/commons/jelly/tags/xml/elementWithNameSpace.jelly (added)
+++ jakarta/commons/proper/jelly/trunk/jelly-tags/xml/src/test/org/apache/commons/jelly/tags/xml/elementWithNameSpace.jelly Tue Jul 19 10:34:00 2005
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<j:jelly xmlns:j="jelly:core" xmlns:x="jelly:xml">
+ <x:element URI="http://schemas.xmlsoap.org/soap/envelope/" name="env:Envelope">
+ <x:attribute URI="http://schemas.xmlsoap.org/soap/envelope/"
+ name="env:encodingStyle" trim="true">
+ http://schemas.xmlsoap.org/soap/encoding/
+ </x:attribute>
+ </x:element>
+</j:jelly>
+
Added: jakarta/commons/proper/jelly/trunk/jelly-tags/xml/src/test/org/apache/commons/jelly/tags/xml/elementWithNameSpaceError.jelly
URL: http://svn.apache.org/viewcvs/jakarta/commons/proper/jelly/trunk/jelly-tags/xml/src/test/org/apache/commons/jelly/tags/xml/elementWithNameSpaceError.jelly?rev=219726&view=auto
==============================================================================
--- jakarta/commons/proper/jelly/trunk/jelly-tags/xml/src/test/org/apache/commons/jelly/tags/xml/elementWithNameSpaceError.jelly (added)
+++ jakarta/commons/proper/jelly/trunk/jelly-tags/xml/src/test/org/apache/commons/jelly/tags/xml/elementWithNameSpaceError.jelly Tue Jul 19 10:34:00 2005
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<j:jelly xmlns:j="jelly:core" xmlns:x="jelly:xml">
+ <x:element URI="http://schemas.xmlsoap.org/soap/envelope/" name="env:Envelope">
+ <x:attribute name="env:encodingStyle" trim="true">
+ http://schemas.xmlsoap.org/soap/encoding/
+ </x:attribute>
+ </x:element>
+</j:jelly>
+
Added: jakarta/commons/proper/jelly/trunk/jelly-tags/xml/src/test/org/apache/commons/jelly/tags/xml/namespaceReplace.jelly
URL: http://svn.apache.org/viewcvs/jakarta/commons/proper/jelly/trunk/jelly-tags/xml/src/test/org/apache/commons/jelly/tags/xml/namespaceReplace.jelly?rev=219726&view=auto
==============================================================================
--- jakarta/commons/proper/jelly/trunk/jelly-tags/xml/src/test/org/apache/commons/jelly/tags/xml/namespaceReplace.jelly (added)
+++ jakarta/commons/proper/jelly/trunk/jelly-tags/xml/src/test/org/apache/commons/jelly/tags/xml/namespaceReplace.jelly Tue Jul 19 10:34:00 2005
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<j:jelly xmlns:j="jelly:core" xmlns:x="jelly:xml">
+ <x:element URI="${ns}" name="test-node">
+ <x:attribute URI="http://apache/testNS" name="test:abc" trim="true">testValue</x:attribute>
+
+ <test-subnode attr="test">
+ <test-anotherSubNode />
+ <x:element URI="${ns}" name="test-anotherSubNodeAgain">
+ <x:attribute URI="${ns}" name="other:abc" trim="true">testValue</x:attribute>
+ </x:element>
+ </test-subnode>
+
+ <x:replaceNamespace toURI="${ns}">
+ <test-subnode attr="test">
+ <test-anotherSubNode />
+ <x:element URI="${ns}" name="test-anotherSubNodeAgain">
+ <x:attribute URI="${ns}" name="other:abc" trim="true">testValue</x:attribute>
+ </x:element>
+ </test-subnode>
+ </x:replaceNamespace>
+ </x:element>
+</j:jelly>
+
Modified: jakarta/commons/proper/jelly/trunk/src/java/org/apache/commons/jelly/XMLOutput.java
URL: http://svn.apache.org/viewcvs/jakarta/commons/proper/jelly/trunk/src/java/org/apache/commons/jelly/XMLOutput.java?rev=219726&r1=219725&r2=219726&view=diff
==============================================================================
--- jakarta/commons/proper/jelly/trunk/src/java/org/apache/commons/jelly/XMLOutput.java (original)
+++ jakarta/commons/proper/jelly/trunk/src/java/org/apache/commons/jelly/XMLOutput.java Tue Jul 19 10:34:00 2005
@@ -20,6 +20,11 @@
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.io.Writer;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
@@ -44,29 +49,35 @@
public class XMLOutput implements ContentHandler, LexicalHandler {
protected static final String[] LEXICAL_HANDLER_NAMES =
- {
- "http://xml.org/sax/properties/lexical-handler",
- "http://xml.org/sax/handlers/LexicalHandler" };
+ {
+ "http://xml.org/sax/properties/lexical-handler",
+ "http://xml.org/sax/handlers/LexicalHandler" };
- /** empty attributes */
+ /** Empty attributes. */
private static final Attributes EMPTY_ATTRIBUTES = new AttributesImpl();
/** The Log to which logging calls will be made. */
private static final Log log = LogFactory.getLog(XMLOutput.class);
- /** the default for escaping of text */
+ /** the default for escaping of text. */
private static final boolean DEFAULT_ESCAPE_TEXT = false;
- /** The SAX ContentHandler that output goes to */
+ /** The SAX ContentHandler that output goes to. */
private ContentHandler contentHandler;
- /** The SAX LexicalHandler that output goes to */
+ /** The SAX LexicalHandler that output goes to. */
private LexicalHandler lexicalHandler;
+ /** Stack of kown namespaces. */
+ private NamespaceStack namespaceStack = new NamespaceStack();
public XMLOutput() {
}
+ /** The XML-output will relay the SAX events to the indicated
+ * contentHandler.
+ * @param contentHandler
+ */
public XMLOutput(ContentHandler contentHandler) {
this.contentHandler = contentHandler;
// often classes will implement LexicalHandler as well
@@ -75,6 +86,11 @@
}
}
+ /** The XML-output will relay the SAX events to the indicated
+ * content-handler lexical-handler.
+ * @param contentHandler
+ * @param lexicalHandler
+ */
public XMLOutput(
ContentHandler contentHandler,
LexicalHandler lexicalHandler) {
@@ -92,16 +108,25 @@
}
/**
- * Provides a useful hook that implementations can use to close the
- * underlying OutputStream or Writer
+ * Provides a useful hook that implementations
+ * can use to close the
+ * underlying OutputStream or Writer.
+ *
+ * @throws IOException
*/
public void close() throws IOException {
}
+ /** Flushes the underlying stream if {@link XMLWriter}
+ * or {@link XMLOutput}.
+ *
+ * @throws IOException
+ */
public void flush() throws IOException {
- if( contentHandler instanceof XMLWriter )
- {
+ if (contentHandler instanceof XMLWriter) {
((XMLWriter)contentHandler).flush();
+ } else if (contentHandler instanceof XMLOutput) {
+ ((XMLOutput)contentHandler).flush();
}
}
@@ -109,7 +134,7 @@
//-------------------------------------------------------------------------
/**
- * Creates an XMLOutput from an existing SAX XMLReader
+ * Creates an XMLOutput from an existing SAX XMLReader.
*/
public static XMLOutput createXMLOutput(XMLReader xmlReader) {
XMLOutput output = new XMLOutput(xmlReader.getContentHandler());
@@ -122,10 +147,11 @@
output.setLexicalHandler((LexicalHandler) value);
break;
}
- }
- catch (Exception e) {
+ } catch (Exception e) {
// ignore any unsupported-operation exceptions
- if (log.isDebugEnabled()) log.debug("error setting lexical handler properties", e);
+ if (log.isDebugEnabled()) {
+ log.debug("error setting lexical handler properties", e);
+ }
}
}
return output;
@@ -145,10 +171,9 @@
*
* @param writer is the writer to output to
* @param escapeText is whether or not text output will be escaped. This must be true
- * if the underlying output is XML or could be false if the underlying output is textual.
+ * if the underlying output is XML or could be false if the underlying output is textual.
*/
- public static XMLOutput createXMLOutput(Writer writer, boolean escapeText)
- {
+ public static XMLOutput createXMLOutput(Writer writer, boolean escapeText) {
XMLWriter xmlWriter = new XMLWriter(writer);
xmlWriter.setEscapeText(escapeText);
return createXMLOutput(xmlWriter);
@@ -169,8 +194,11 @@
* @param out is the output stream to write
* @param escapeText is whether or not text output will be escaped. This must be true
* if the underlying output is XML or could be false if the underlying output is textual.
+ * @throws UnsupportedEncodingException if the underlying write could not
+ * be created.
*/
- public static XMLOutput createXMLOutput(OutputStream out, boolean escapeText) throws UnsupportedEncodingException {
+ public static XMLOutput createXMLOutput(OutputStream out, boolean escapeText)
+ throws UnsupportedEncodingException {
XMLWriter xmlWriter = new XMLWriter(out);
xmlWriter.setEscapeText(escapeText);
return createXMLOutput(xmlWriter);
@@ -193,7 +221,7 @@
/**
* Outputs the given String as a piece of valid text in the
* XML event stream.
- * Any special XML characters should be properly escaped.
+ * Any special XML characters should come out properly escaped.
*/
public void write(String text) throws SAXException {
char[] ch = text.toCharArray();
@@ -212,7 +240,7 @@
}
/**
- * Outputs a comment to the XML stream
+ * Outputs a comment to the XML stream.
*/
public void writeComment(String text) throws SAXException {
char[] ch = text.toCharArray();
@@ -220,21 +248,24 @@
}
/**
- * Helper method for outputting a start element event for an element in no namespace
+ * Helper method for outputting a start element event
+ * for an element in no namespace.
*/
public void startElement(String localName) throws SAXException {
startElement("", localName, localName, EMPTY_ATTRIBUTES);
}
/**
- * Helper method for outputting a start element event for an element in no namespace
+ * Helper method for outputting a start element event
+ * for an element in no namespace.
*/
public void startElement(String localName, Attributes attributes) throws SAXException {
startElement("", localName, localName, attributes);
}
/**
- * Helper method for outputting an end element event for an element in no namespace
+ * Helper method for outputting an end element event
+ * for an element in no namespace.
*/
public void endElement(String localName) throws SAXException {
endElement("", localName, localName);
@@ -344,7 +375,9 @@
* @see #startElement
*/
public void startPrefixMapping(String prefix, String uri) throws SAXException {
- contentHandler.startPrefixMapping(prefix, uri);
+ namespaceStack.pushNamespace(prefix, uri);
+ // contentHandler.startPrefixMapping(prefix, uri) will be called if needed
+ // in pushNamespace
}
/**
@@ -364,7 +397,9 @@
* @see #endElement
*/
public void endPrefixMapping(String prefix) throws SAXException {
- contentHandler.endPrefixMapping(prefix);
+ namespaceStack.popNamespace(prefix);
+ // End prefix mapping was already called after endElement
+ // contentHandler.endPrefixMapping(prefix);
}
/**
@@ -435,7 +470,28 @@
String qName,
Attributes atts)
throws SAXException {
+
+ int idx = qName.indexOf(':');
+ String attNsPrefix = "";
+ if (idx >= 0) {
+ attNsPrefix = qName.substring(0, idx);
+ }
+ namespaceStack.pushNamespace(attNsPrefix, uri);
+ for (int i = 0; i < atts.getLength(); i++) {
+ String attQName = atts.getQName(i);
+ // An attribute only has an namespace if has a prefix
+ // If not, stays in namespace of containing node
+ idx = attQName.indexOf(':');
+ if (idx >= 0) {
+ attNsPrefix = attQName.substring(0, idx);
+ String attUri = atts.getURI(i);
+ namespaceStack.pushNamespace(attNsPrefix, attUri);
+ }
+ }
+
contentHandler.startElement(uri, localName, qName, atts);
+ // Inform namespaceStack of a new depth
+ namespaceStack.increaseLevel();
}
/**
@@ -462,6 +518,9 @@
public void endElement(String uri, String localName, String qName)
throws SAXException {
contentHandler.endElement(uri, localName, qName);
+ // Inform namespaceStack to return to previous depth
+ namespaceStack.decreaseLevel();
+ namespaceStack.popNamespaces();
}
/**
@@ -507,7 +566,7 @@
* @see #ignorableWhitespace
* @see org.xml.sax.Locator
*/
- public void characters(char ch[], int start, int length) throws SAXException {
+ public void characters(char[] ch, int start, int length) throws SAXException {
contentHandler.characters(ch, start, length);
}
@@ -535,7 +594,7 @@
* wrapping another exception.
* @see #characters
*/
- public void ignorableWhitespace(char ch[], int start, int length)
+ public void ignorableWhitespace(char[] ch, int start, int length)
throws SAXException {
contentHandler.ignorableWhitespace(ch, start, length);
}
@@ -855,4 +914,127 @@
return answer;
}
+ private final class NamespaceStack {
+ /** A list of maps: Each map contains prefix->uri mapping */
+ private List nsStack;
+
+ private NamespaceStack() {
+ this.nsStack = new ArrayList();
+ this.nsStack.add(new HashMap());
+ }
+
+ private boolean isRootNodeDefaultNs(String prefix, String uri) {
+ return ("".equals(prefix) && "".equals(uri) && nsStack.size() == 1);
+ }
+
+ public void pushNamespace(String prefix, String uri) throws SAXException {
+ Map prefixUriMap;
+
+ if (prefix == null) {
+ prefix = "";
+ }
+ if (uri == null) {
+ uri = "";
+ }
+
+ if ("xml".equals(prefix)) {
+ // We should ignore setting 'xml' prefix
+ // As declared in java of ContentHandler#startPrefixMapping
+ return;
+ }
+
+
+ // Lets find out if we already declared this same prefix,
+ // if not declare in current depth map (the first of list)
+ // and call contentHandler.startPrefixMapping(prefix, uri);
+ boolean isNew = true;
+ for (Iterator iter = nsStack.iterator(); iter.hasNext();) {
+ prefixUriMap = (Map) iter.next();
+ if (prefixUriMap.containsKey(prefix)) {
+ if (uri.equals(prefixUriMap.get(prefix))) {
+ // Its an active namespace already
+ // System.out.println(">>>"+XMLOutput.this.hashCode()+">NamespaceStack.pushNamespace() IS NOT NEW prefix="+prefix+",uri="+uri);
+ isNew = false;
+ }
+ // We found it in stack
+ // If it was exacly the same, we won't bother
+ break;
+ }
+ }
+
+ if (isNew) {
+ // not declared sometime before
+ prefixUriMap = (Map) nsStack.get(0); // Current depth map
+ // Sanity check: Don't let two prefixes for diferent uris in
+ // same depth
+ if (prefixUriMap.containsKey(prefix)) {
+ if (!uri.equals(prefixUriMap.get(prefix))) {
+ throw new SAXException("Cannot set same prefix to diferent URI in same node: trying to add prefix \""
+ + prefix + "\" for uri \""+uri+"\" whereas the declared ones are " + prefixUriMap);
+ }
+ } else {
+ prefixUriMap.put(prefix, uri);
+
+ // To avoid setting xmlns="" for top node (not very nice :D)
+ // We need to especificaly check this condition
+ if (!isRootNodeDefaultNs(prefix, uri)) {
+// System.out.println(">>>"+XMLOutput.this.hashCode()+">NamespaceStack.pushNamespace() prefix="+prefix+",uri="+uri);
+ contentHandler.startPrefixMapping(prefix, uri);
+ }
+ }
+ }
+ }
+
+ public void popNamespaces() throws SAXException {
+ Map prefixUriMap = (Map)nsStack.get(0);
+ for (Iterator iter = prefixUriMap.keySet().iterator();iter.hasNext();) {
+ String prefix = (String)iter.next();
+ String uri = (String) prefixUriMap.get(prefix);
+ iter.remove();
+
+ // If we havent called startPrefixMapping for root node if we wanted to avoid xmlns=""
+ // We aren't going to call endPrefixMapping neither
+ if (!isRootNodeDefaultNs(prefix, uri)) {
+// System.out.println(">>>"+XMLOutput.this.hashCode()+">NamespaceStack.popNamespaces() prefix="+prefix);
+ contentHandler.endPrefixMapping(prefix);
+ }
+ }
+ }
+
+ public void popNamespace(String prefix) throws SAXException {
+ Map prefixUriMap = (Map)nsStack.get(0);
+
+ if (prefix == null) {
+ prefix = "";
+ }
+
+ if ("xml".equals(prefix)) {
+ // We should ignore setting 'xml' prefix
+ // As declared in java of ContentHandler#startPrefixMapping
+ return;
+ }
+
+ if (prefixUriMap.containsKey(prefix)) {
+ String uri = (String) prefixUriMap.get(prefix);
+ prefixUriMap.remove(prefix);
+ // If we havent called startPrefixMapping for root node if we wanted to avoid xmlns=""
+ // We aren't going to call endPrefixMapping neither
+ if (!isRootNodeDefaultNs(prefix, uri)) {
+// System.out.println(">>>"+XMLOutput.this.hashCode()+">NamespaceStack.popNamespace() prefix="+prefix);
+ contentHandler.endPrefixMapping(prefix);
+ }
+ }/* else {
+ improper nesting ? or already removed in popNamespaces
+ }
+ */
+ }
+
+ public void decreaseLevel() {
+ nsStack.remove(0);
+ }
+
+ public void increaseLevel() {
+ nsStack.add(0, new HashMap());
+ }
+ }
}
Modified: jakarta/commons/proper/jelly/trunk/src/java/org/apache/commons/jelly/impl/StaticTag.java
URL: http://svn.apache.org/viewcvs/jakarta/commons/proper/jelly/trunk/src/java/org/apache/commons/jelly/impl/StaticTag.java?rev=219726&r1=219725&r2=219726&view=diff
==============================================================================
--- jakarta/commons/proper/jelly/trunk/src/java/org/apache/commons/jelly/impl/StaticTag.java (original)
+++ jakarta/commons/proper/jelly/trunk/src/java/org/apache/commons/jelly/impl/StaticTag.java Tue Jul 19 10:34:00 2005
@@ -69,6 +69,15 @@
}
}
+ public void setAttribute(String name, String prefix, String nsURI, Object value) {
+ if(value==null)
+ return;
+ if(prefix!=null && prefix.length()>0)
+ attributes.addAttribute(nsURI,name,prefix+":"+name,"CDATA",value.toString());
+ else
+ attributes.addAttribute("",name,name,"CDATA",value.toString());
+ }
+
// DynaTag interface
//-------------------------------------------------------------------------
public void setAttribute(String name, Object value) throws JellyTagException {
Modified: jakarta/commons/proper/jelly/trunk/src/java/org/apache/commons/jelly/impl/StaticTagScript.java
URL: http://svn.apache.org/viewcvs/jakarta/commons/proper/jelly/trunk/src/java/org/apache/commons/jelly/impl/StaticTagScript.java?rev=219726&r1=219725&r2=219726&view=diff
==============================================================================
--- jakarta/commons/proper/jelly/trunk/src/java/org/apache/commons/jelly/impl/StaticTagScript.java (original)
+++ jakarta/commons/proper/jelly/trunk/src/java/org/apache/commons/jelly/impl/StaticTagScript.java Tue Jul 19 10:34:00 2005
@@ -86,7 +86,10 @@
for (Iterator iter = attributes.entrySet().iterator(); iter.hasNext();) {
Map.Entry entry = (Map.Entry) iter.next();
String name = (String) entry.getKey();
- Expression expression = (Expression) entry.getValue();
+ if(name.indexOf(':')!=-1)
+ name = name.substring(name.indexOf(':')+1);
+ ExpressionAttribute expat = (ExpressionAttribute) entry.getValue();
+ Expression expression = expat.exp;
Object value = null;
@@ -96,7 +99,10 @@
value = expression.evaluate(context);
}
- dynaTag.setAttribute(name, value);
+ if(expat.prefix!=null || expat.prefix.length()>0 && tag instanceof StaticTag)
+ ((StaticTag) dynaTag).setAttribute(name,expat.prefix, expat.nsURI,value);
+ else
+ dynaTag.setAttribute(name, value);
}
tag.doTag(output);
Modified: jakarta/commons/proper/jelly/trunk/src/java/org/apache/commons/jelly/impl/TagScript.java
URL: http://svn.apache.org/viewcvs/jakarta/commons/proper/jelly/trunk/src/java/org/apache/commons/jelly/impl/TagScript.java?rev=219726&r1=219725&r2=219726&view=diff
==============================================================================
--- jakarta/commons/proper/jelly/trunk/src/java/org/apache/commons/jelly/impl/TagScript.java (original)
+++ jakarta/commons/proper/jelly/trunk/src/java/org/apache/commons/jelly/impl/TagScript.java Tue Jul 19 10:34:00 2005
@@ -170,7 +170,19 @@
if (log.isDebugEnabled()) {
log.debug("adding attribute name: " + name + " expression: " + expression);
}
- attributes.put(name, expression);
+ attributes.put(name, new ExpressionAttribute(name,expression));
+ }
+
+ /** Add an initialization attribute for the tag.
+ * This method must be called after the setTag() method
+ */
+ public void addAttribute(String name, String prefix, String nsURI, Expression expression) {
+ if (log.isDebugEnabled()) {
+ log.debug("adding attribute name: " + name + " expression: " + expression);
+ }
+ if(name.indexOf(':')==-1)
+ name = prefix + ':' + name;
+ attributes.put(name, new ExpressionAttribute(name,prefix,nsURI,expression));
}
/**
@@ -206,7 +218,7 @@
for (Iterator iter = attributes.entrySet().iterator(); iter.hasNext();) {
Map.Entry entry = (Map.Entry) iter.next();
String name = (String) entry.getKey();
- Expression expression = (Expression) entry.getValue();
+ Expression expression = ((ExpressionAttribute) entry.getValue()).exp;
Class type = dynaTag.getAttributeType(name);
Object value = null;
@@ -225,7 +237,7 @@
for (Iterator iter = attributes.entrySet().iterator(); iter.hasNext();) {
Map.Entry entry = (Map.Entry) iter.next();
String name = (String) entry.getKey();
- Expression expression = (Expression) entry.getValue();
+ Expression expression = ((ExpressionAttribute) entry.getValue()).exp;
DynaProperty property = dynaBean.getDynaClass().getDynaProperty(name);
if (property == null) {
@@ -690,3 +702,21 @@
throw new JellyTagException(e, fileName, elementName, columnNumber, lineNumber);
}
}
+
+
+class ExpressionAttribute {
+ public ExpressionAttribute(String name, Expression exp) {
+ this(name,"","",exp);
+ }
+ public ExpressionAttribute(String name, String prefix, String nsURI, Expression exp) {
+ this.name = name;
+ this.prefix = prefix;
+ this.nsURI = nsURI;
+ this.exp = exp;
+ }
+
+ String name;
+ String prefix;
+ String nsURI;
+ Expression exp;
+}
\ No newline at end of file
Modified: jakarta/commons/proper/jelly/trunk/src/java/org/apache/commons/jelly/parser/XMLParser.java
URL: http://svn.apache.org/viewcvs/jakarta/commons/proper/jelly/trunk/src/java/org/apache/commons/jelly/parser/XMLParser.java?rev=219726&r1=219725&r2=219726&view=diff
==============================================================================
--- jakarta/commons/proper/jelly/trunk/src/java/org/apache/commons/jelly/parser/XMLParser.java (original)
+++ jakarta/commons/proper/jelly/trunk/src/java/org/apache/commons/jelly/parser/XMLParser.java Tue Jul 19 10:34:00 2005
@@ -1066,7 +1066,12 @@
attributeValue, getExpressionFactory()
);
String attrQName = list.getQName(i);
- script.addAttribute(attrQName, expression);
+ int p = attrQName.indexOf(':');
+ String prefix = p>=0 ?
+ attrQName.substring(0,p):
+ "";
+ script.addAttribute(list.getLocalName(i),
+ prefix, list.getURI(i), expression);
}
return script;
}
Modified: jakarta/commons/proper/jelly/trunk/src/test/org/apache/commons/jelly/TestCoreTags.java
URL: http://svn.apache.org/viewcvs/jakarta/commons/proper/jelly/trunk/src/test/org/apache/commons/jelly/TestCoreTags.java?rev=219726&r1=219725&r2=219726&view=diff
==============================================================================
--- jakarta/commons/proper/jelly/trunk/src/test/org/apache/commons/jelly/TestCoreTags.java (original)
+++ jakarta/commons/proper/jelly/trunk/src/test/org/apache/commons/jelly/TestCoreTags.java Tue Jul 19 10:34:00 2005
@@ -105,4 +105,24 @@
textScript.trimStartWhitespace();
assertEquals("foo", textScript.getText());
}
+
+
+ public void testStaticNamespacedAttributes() throws Exception {
+ InputStream in = new FileInputStream("src/test/org/apache/commons/jelly/testStaticNamespacedAttributes.jelly");
+ XMLParser parser = new XMLParser();
+ Script script = parser.parse(in);
+ script = script.compile();
+ log.debug("Found: " + script);
+ JellyContext context = new JellyContext();
+ StringWriter buffer = new StringWriter();
+ script.run(context, XMLOutput.createXMLOutput(buffer));
+ String text = buffer.toString().trim();
+ if (log.isDebugEnabled()) {
+ log.debug("Evaluated script as...");
+ log.debug(text);
+ }
+ assertEquals("Should produces the correct output",
+ "<blip xmlns:blop=\"blop\" blop:x=\"blip\"></blip>",
+ text);
+ }
}
Modified: jakarta/commons/proper/jelly/trunk/src/test/org/apache/commons/jelly/core/TestFileTag.java
URL: http://svn.apache.org/viewcvs/jakarta/commons/proper/jelly/trunk/src/test/org/apache/commons/jelly/core/TestFileTag.java?rev=219726&r1=219725&r2=219726&view=diff
==============================================================================
--- jakarta/commons/proper/jelly/trunk/src/test/org/apache/commons/jelly/core/TestFileTag.java (original)
+++ jakarta/commons/proper/jelly/trunk/src/test/org/apache/commons/jelly/core/TestFileTag.java Tue Jul 19 10:34:00 2005
@@ -55,7 +55,7 @@
//FIXME This doesn't take into account attribute ordering
assertEquals("fully qualified attributes not passed",
- "<html xmlns=\"http://www.w3.org/1999/xhtml\" xml:lang=\"en\" lang=\"en\"></html>",
+ "<html xmlns=\"http://www.w3.org/1999/xhtml\" lang=\"en\" xml:lang=\"en\"></html>",
data);
}
Added: jakarta/commons/proper/jelly/trunk/src/test/org/apache/commons/jelly/testStaticNamespacedAttributes.jelly
URL: http://svn.apache.org/viewcvs/jakarta/commons/proper/jelly/trunk/src/test/org/apache/commons/jelly/testStaticNamespacedAttributes.jelly?rev=219726&view=auto
==============================================================================
--- jakarta/commons/proper/jelly/trunk/src/test/org/apache/commons/jelly/testStaticNamespacedAttributes.jelly (added)
+++ jakarta/commons/proper/jelly/trunk/src/test/org/apache/commons/jelly/testStaticNamespacedAttributes.jelly Tue Jul 19 10:34:00 2005
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<j:jelly xmlns:j="jelly:core">
+ <blip xmlns:blop="blop" blop:x="blip"/>
+</j:jelly>
---------------------------------------------------------------------
To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: commons-dev-help@jakarta.apache.org
Re: svn commit: r219726 - in /jakarta/commons/proper/jelly/trunk: jelly-tags/xml/ jelly-tags/xml/src/java/org/apache/commons/jelly/tags/xml/ jelly-tags/xml/src/test/org/apache/commons/jelly/tags/xml/ src/java/org/apache/commons/jelly/ src/java/org/ap
Posted by Paul Libbrecht <pa...@activemath.org>.
Le 20 juil. 05, à 01:08, Dion Gillard a écrit :
> could you make the <version> tag 1.2-SNAPSHOT instead of -dev? That
> keeps it all consistent.
I wanted to ask about this.
Actually, I've also made 1.1-dev into jelly's project.xml.
Isn't SNAPSHOT supposed to be a (fake but complete) version number?
What we want is something else, or ?
> And how about an update to the changes.xml file?
Sure, that soon.
Also, how could I upload the snapshot at some point?
thanks
paul
---------------------------------------------------------------------
To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: commons-dev-help@jakarta.apache.org
Re: svn commit: r219726 - in /jakarta/commons/proper/jelly/trunk: jelly-tags/xml/ jelly-tags/xml/src/java/org/apache/commons/jelly/tags/xml/ jelly-tags/xml/src/test/org/apache/commons/jelly/tags/xml/ src/java/org/apache/commons/jelly/ src/java/org/ap
Posted by Dion Gillard <di...@gmail.com>.
Hi Paul,
could you make the <version> tag 1.2-SNAPSHOT instead of -dev? That
keeps it all consistent.
And how about an update to the changes.xml file?
On 7/20/05, polx@apache.org <po...@apache.org> wrote:
> Author: polx
> Date: Tue Jul 19 10:34:00 2005
> New Revision: 219726
>
> URL: http://svn.apache.org/viewcvs?rev=219726&view=rev
> Log:
> Fixing treatment of namespaced-qualified attributes in XML taglib and
> in the xml-output.
> This fixes JELLY-213 and JELLY-214.
> paul
>
> Added:
> jakarta/commons/proper/jelly/trunk/jelly-tags/xml/src/java/org/apache/commons/jelly/tags/xml/ReplaceNamespaceTag.java
> jakarta/commons/proper/jelly/trunk/jelly-tags/xml/src/test/org/apache/commons/jelly/tags/xml/attributeNameSpace.jelly
> jakarta/commons/proper/jelly/trunk/jelly-tags/xml/src/test/org/apache/commons/jelly/tags/xml/attributeNameSpaceDefaultNS.jelly
> jakarta/commons/proper/jelly/trunk/jelly-tags/xml/src/test/org/apache/commons/jelly/tags/xml/attributeNameSpaceDuplicatedNS.jelly
> jakarta/commons/proper/jelly/trunk/jelly-tags/xml/src/test/org/apache/commons/jelly/tags/xml/attributeNameSpaceWithInnerElements.jelly
> jakarta/commons/proper/jelly/trunk/jelly-tags/xml/src/test/org/apache/commons/jelly/tags/xml/elementWithNameSpace.jelly
> jakarta/commons/proper/jelly/trunk/jelly-tags/xml/src/test/org/apache/commons/jelly/tags/xml/elementWithNameSpaceError.jelly
> jakarta/commons/proper/jelly/trunk/jelly-tags/xml/src/test/org/apache/commons/jelly/tags/xml/namespaceReplace.jelly
> jakarta/commons/proper/jelly/trunk/src/test/org/apache/commons/jelly/testStaticNamespacedAttributes.jelly
> Modified:
> jakarta/commons/proper/jelly/trunk/jelly-tags/xml/project.xml
> jakarta/commons/proper/jelly/trunk/jelly-tags/xml/src/java/org/apache/commons/jelly/tags/xml/AttributeTag.java
> jakarta/commons/proper/jelly/trunk/jelly-tags/xml/src/java/org/apache/commons/jelly/tags/xml/ElementTag.java
> jakarta/commons/proper/jelly/trunk/jelly-tags/xml/src/java/org/apache/commons/jelly/tags/xml/XMLTagLibrary.java
> jakarta/commons/proper/jelly/trunk/jelly-tags/xml/src/test/org/apache/commons/jelly/tags/xml/TestXMLTags.java
> jakarta/commons/proper/jelly/trunk/src/java/org/apache/commons/jelly/XMLOutput.java
> jakarta/commons/proper/jelly/trunk/src/java/org/apache/commons/jelly/impl/StaticTag.java
> jakarta/commons/proper/jelly/trunk/src/java/org/apache/commons/jelly/impl/StaticTagScript.java
> jakarta/commons/proper/jelly/trunk/src/java/org/apache/commons/jelly/impl/TagScript.java
> jakarta/commons/proper/jelly/trunk/src/java/org/apache/commons/jelly/parser/XMLParser.java
> jakarta/commons/proper/jelly/trunk/src/test/org/apache/commons/jelly/TestCoreTags.java
> jakarta/commons/proper/jelly/trunk/src/test/org/apache/commons/jelly/core/TestFileTag.java
>
> Modified: jakarta/commons/proper/jelly/trunk/jelly-tags/xml/project.xml
> URL: http://svn.apache.org/viewcvs/jakarta/commons/proper/jelly/trunk/jelly-tags/xml/project.xml?rev=219726&r1=219725&r2=219726&view=diff
> ==============================================================================
> --- jakarta/commons/proper/jelly/trunk/jelly-tags/xml/project.xml (original)
> +++ jakarta/commons/proper/jelly/trunk/jelly-tags/xml/project.xml Tue Jul 19 10:34:00 2005
> @@ -20,7 +20,7 @@
> <extend>${basedir}/../tag-project.xml</extend>
> <id>commons-jelly-tags-xml</id>
> <name>commons-jelly-tags-xml</name>
> - <currentVersion>1.1</currentVersion>
> + <currentVersion>1.2-dev</currentVersion>
> <package>org.apache.commons.jelly.tags.xml</package>
> <description>The Jelly XML Tag Library</description>
> <shortDescription>Commons Jelly XML Tag Library</shortDescription>
> @@ -37,6 +37,11 @@
> </version>
> </versions>
> <dependencies>
> + <dependency>
> + <id>commons-jelly</id>
> + <version>SNAPSHOT</version>
> + </dependency>
> +
> <!-- run time / in testing-->
>
> <dependency>
>
> Modified: jakarta/commons/proper/jelly/trunk/jelly-tags/xml/src/java/org/apache/commons/jelly/tags/xml/AttributeTag.java
> URL: http://svn.apache.org/viewcvs/jakarta/commons/proper/jelly/trunk/jelly-tags/xml/src/java/org/apache/commons/jelly/tags/xml/AttributeTag.java?rev=219726&r1=219725&r2=219726&view=diff
> ==============================================================================
> --- jakarta/commons/proper/jelly/trunk/jelly-tags/xml/src/java/org/apache/commons/jelly/tags/xml/AttributeTag.java (original)
> +++ jakarta/commons/proper/jelly/trunk/jelly-tags/xml/src/java/org/apache/commons/jelly/tags/xml/AttributeTag.java Tue Jul 19 10:34:00 2005
> @@ -26,6 +26,8 @@
> * @version $Revision$
> */
> public class AttributeTag extends TagSupport {
> + /** The namespace URI. */
> + private String namespace;
>
> /** the name of the attribute. */
> private String name;
> @@ -38,10 +40,11 @@
> //-------------------------------------------------------------------------
> public void doTag(XMLOutput output) throws JellyTagException {
> ElementTag tag = (ElementTag) findAncestorWithClass( ElementTag.class );
> - if ( tag == null ) {
> - throw new JellyTagException( "<attribute> tag must be enclosed inside an <element> tag" );
> + if (tag == null) {
> + throw new JellyTagException(
> + "<attribute> tag must be enclosed inside an <element> tag" );
> }
> - tag.setAttributeValue( getName(), getBodyText( false ) );
> + tag.setAttributeValue(getName(), getBodyText(false), getURI());
> }
>
> // Properties
> @@ -53,10 +56,25 @@
> public String getName() {
> return name;
> }
> +
> /**
> - * Sets the name of the attribute
> + * Sets the name of the attribute.
> */
> public void setName(String name) {
> this.name = name;
> + }
> +
> + /**
> + * @return the namespace URI of the element
> + */
> + public String getURI() {
> + return namespace;
> + }
> +
> + /**
> + * Sets the namespace URI of the element
> + */
> + public void setURI(String namespace) {
> + this.namespace = namespace;
> }
> }
>
> Modified: jakarta/commons/proper/jelly/trunk/jelly-tags/xml/src/java/org/apache/commons/jelly/tags/xml/ElementTag.java
> URL: http://svn.apache.org/viewcvs/jakarta/commons/proper/jelly/trunk/jelly-tags/xml/src/java/org/apache/commons/jelly/tags/xml/ElementTag.java?rev=219726&r1=219725&r2=219726&view=diff
> ==============================================================================
> --- jakarta/commons/proper/jelly/trunk/jelly-tags/xml/src/java/org/apache/commons/jelly/tags/xml/ElementTag.java (original)
> +++ jakarta/commons/proper/jelly/trunk/jelly-tags/xml/src/java/org/apache/commons/jelly/tags/xml/ElementTag.java Tue Jul 19 10:34:00 2005
> @@ -15,6 +15,7 @@
> */
> package org.apache.commons.jelly.tags.xml;
>
> +import org.apache.commons.jelly.JellyException;
> import org.apache.commons.jelly.JellyTagException;
> import org.apache.commons.jelly.TagSupport;
> import org.apache.commons.jelly.XMLOutput;
> @@ -22,8 +23,6 @@
> import org.xml.sax.SAXException;
> import org.xml.sax.helpers.AttributesImpl;
>
> -import java.io.IOException;
> -
> /** A tag to produce an XML element which can contain other attributes
> * or elements like the <code><xsl:element></code> tag.
> *
> @@ -32,16 +31,16 @@
> */
> public class ElementTag extends TagSupport {
>
> - /** The namespace URI */
> + /** The namespace URI. */
> private String namespace;
>
> - /** The qualified name */
> + /** The qualified name. */
> private String name;
>
> - /** The XML Attributes */
> + /** The XML Attributes. */
> private AttributesImpl attributes = new AttributesImpl();
>
> - /** flag set if attributes are output */
> + /** flag set if attributes are output. */
> private boolean outputAttributes;
>
> public ElementTag() {
> @@ -52,11 +51,12 @@
> *
> * @param name of the attribute
> * @param value of the attribute
> - * @throws JellyException if the start element has already been output.
> + * @param uri namespace of the attribute
> + * @throws JellyTagException 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 JellyTagException {
> + public void setAttributeValue(String name, String value, String uri) throws JellyTagException {
> if (outputAttributes) {
> throw new JellyTagException(
> "Cannot set the value of attribute: "
> @@ -67,13 +67,22 @@
> // ### we'll assume that all attributes are in no namespace!
> // ### this is severely limiting!
> // ### we should be namespace aware
> - int index = attributes.getIndex("", name);
> + // NAMESPACE FIXED:
> + int idx = name.indexOf(':');
> + final String localName = (idx >= 0)
> + ? name.substring(idx + 1)
> + : name;
> + final String nsUri = (uri != null)
> + ? uri
> + : "";
> +
> + int index = attributes.getIndex(nsUri, localName);
> if (index >= 0) {
> attributes.removeAttribute(index);
> }
> // treat null values as no attribute
> if (value != null) {
> - attributes.addAttribute("", name, name, "CDATA", value);
> + attributes.addAttribute(nsUri, localName, name, "CDATA", value);
> }
> }
>
> @@ -107,22 +116,21 @@
> super.endElement(uri, localName, qName);
> }
>
> - public void characters(char ch[], int start, int length) throws SAXException {
> + 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)
> + public void ignorableWhitespace(char[] ch, int start, int length)
> throws SAXException {
> initialize();
> super.ignorableWhitespace(ch, start, length);
> }
>
> public void objectData(Object object)
> - throws SAXException
> - {
> + throws SAXException {
> initialize();
> - super.objectData( object );
> + super.objectData(object);
> }
>
> public void processingInstruction(String target, String data)
> @@ -133,7 +141,7 @@
>
> /**
> * Ensure that the outer start element is generated
> - * before any content is output
> + * before any content is output.
> */
> protected void initialize() throws SAXException {
> if (!outputAttributes) {
>
> Added: jakarta/commons/proper/jelly/trunk/jelly-tags/xml/src/java/org/apache/commons/jelly/tags/xml/ReplaceNamespaceTag.java
> URL: http://svn.apache.org/viewcvs/jakarta/commons/proper/jelly/trunk/jelly-tags/xml/src/java/org/apache/commons/jelly/tags/xml/ReplaceNamespaceTag.java?rev=219726&view=auto
> ==============================================================================
> --- jakarta/commons/proper/jelly/trunk/jelly-tags/xml/src/java/org/apache/commons/jelly/tags/xml/ReplaceNamespaceTag.java (added)
> +++ jakarta/commons/proper/jelly/trunk/jelly-tags/xml/src/java/org/apache/commons/jelly/tags/xml/ReplaceNamespaceTag.java Tue Jul 19 10:34:00 2005
> @@ -0,0 +1,128 @@
> +/*
> + * Copyright 2002,2004 The Apache Software Foundation.
> + *
> + * Licensed under the Apache License, Version 2.0 (the "License");
> + * you may not use this file except in compliance with the License.
> + * You may obtain a copy of the License at
> + *
> + * http://www.apache.org/licenses/LICENSE-2.0
> + *
> + * Unless required by applicable law or agreed to in writing, software
> + * distributed under the License is distributed on an "AS IS" BASIS,
> + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
> + * See the License for the specific language governing permissions and
> + * limitations under the License.
> + */
> +package org.apache.commons.jelly.tags.xml;
> +
> +import org.apache.commons.jelly.JellyTagException;
> +import org.apache.commons.jelly.MissingAttributeException;
> +import org.apache.commons.jelly.TagSupport;
> +import org.apache.commons.jelly.XMLOutput;
> +
> +import org.xml.sax.Attributes;
> +import org.xml.sax.SAXException;
> +import org.xml.sax.helpers.AttributesImpl;
> +
> +/**
> + * Replace namespace is a filter to change the namespace of any
> + * elemement attribute passing through it.
> + *
> + * @author Diogo Quintela <dq...@gmail.com>
> + */
> +public class ReplaceNamespaceTag extends TagSupport {
> + private String fromNamespace;
> + private String toNamespace;
> +
> + public ReplaceNamespaceTag() {
> + }
> +
> + // Tag interface
> + //-------------------------------------------------------------------------
> + public void doTag(XMLOutput output) throws MissingAttributeException, JellyTagException {
> + final String fromURI = (fromNamespace != null) ? fromNamespace : "";
> + final String toURI = (toNamespace != null) ? toNamespace : "";
> + XMLOutput newOutput = output;
> +
> + if (!toURI.equals(fromURI)) {
> + newOutput = new XMLOutput(output) {
> + public void startElement(String uri, String localName, String qName, Attributes atts)
> + throws SAXException {
> + super.startElement(replaceURI(uri), localName, qName, replaceURI(atts));
> + }
> +
> + public void endElement(String uri, String localName, String qName)
> + throws SAXException {
> + super.endElement(replaceURI(uri), localName, qName);
> + }
> +
> + public void startPrefixMapping(String prefix, String uri)
> + throws SAXException {
> + super.startPrefixMapping(prefix, replaceURI(uri));
> + }
> +
> + private String replaceURI(String uri) {
> + String newUri = uri;
> +
> + if (fromURI.equals((uri != null) ? uri : "")) {
> + newUri = toURI;
> + }
> +
> + return newUri;
> + }
> +
> + private Attributes replaceURI(Attributes atts) {
> + AttributesImpl newAttsImpl = new AttributesImpl();
> +
> + for (int i = 0; i < atts.getLength(); i++) {
> + // Normally attributes don't have namespaces
> + // But may have (only if on form prefix:attr) ?
> + // So, we'll only replace if needed
> + String QName = atts.getQName(i);
> + String newUri = atts.getURI(i);
> + int idx = QName.indexOf(':');
> +
> + if (idx >= 0) {
> + newUri = replaceURI(newUri);
> + }
> +
> + newAttsImpl.addAttribute(newUri, atts.getLocalName(i), atts.getQName(i),
> + atts.getType(i), atts.getValue(i));
> + }
> +
> + return newAttsImpl;
> + }
> + };
> + }
> +
> + invokeBody(newOutput);
> + }
> +
> + /**
> + * @return the source namespace URI to replace
> + */
> + public String getFromURI() {
> + return fromNamespace;
> + }
> +
> + /**
> + * Sets the source namespace URI to replace.
> + */
> + public void setFromURI(String namespace) {
> + this.fromNamespace = namespace;
> + }
> +
> + /**
> + * @return the destination namespace URI to replace
> + */
> + public String getToURI() {
> + return toNamespace;
> + }
> +
> + /**
> + * Sets the destination namespace URI to replace.
> + */
> + public void setToURI(String namespace) {
> + this.toNamespace = namespace;
> + }
> +}
> \ No newline at end of file
>
> Modified: jakarta/commons/proper/jelly/trunk/jelly-tags/xml/src/java/org/apache/commons/jelly/tags/xml/XMLTagLibrary.java
> URL: http://svn.apache.org/viewcvs/jakarta/commons/proper/jelly/trunk/jelly-tags/xml/src/java/org/apache/commons/jelly/tags/xml/XMLTagLibrary.java?rev=219726&r1=219725&r2=219726&view=diff
> ==============================================================================
> --- jakarta/commons/proper/jelly/trunk/jelly-tags/xml/src/java/org/apache/commons/jelly/tags/xml/XMLTagLibrary.java (original)
> +++ jakarta/commons/proper/jelly/trunk/jelly-tags/xml/src/java/org/apache/commons/jelly/tags/xml/XMLTagLibrary.java Tue Jul 19 10:34:00 2005
> @@ -53,6 +53,7 @@
> registerTag("expr", ExprTag.class);
> registerTag("element", ElementTag.class);
> registerTag("attribute", AttributeTag.class);
> + registerTag("replaceNamespace", ReplaceNamespaceTag.class);
> registerTag("copy", CopyTag.class);
> registerTag("copyOf", CopyOfTag.class);
> registerTag("comment", CommentTag.class);
>
> Modified: jakarta/commons/proper/jelly/trunk/jelly-tags/xml/src/test/org/apache/commons/jelly/tags/xml/TestXMLTags.java
> URL: http://svn.apache.org/viewcvs/jakarta/commons/proper/jelly/trunk/jelly-tags/xml/src/test/org/apache/commons/jelly/tags/xml/TestXMLTags.java?rev=219726&r1=219725&r2=219726&view=diff
> ==============================================================================
> --- jakarta/commons/proper/jelly/trunk/jelly-tags/xml/src/test/org/apache/commons/jelly/tags/xml/TestXMLTags.java (original)
> +++ jakarta/commons/proper/jelly/trunk/jelly-tags/xml/src/test/org/apache/commons/jelly/tags/xml/TestXMLTags.java Tue Jul 19 10:34:00 2005
> @@ -19,15 +19,20 @@
> import java.io.FileInputStream;
> import java.io.InputStream;
> import java.io.StringWriter;
> +import java.util.HashMap;
> import java.util.Iterator;
> import java.util.List;
> +import java.util.Map;
> +import java.util.Set;
>
> +import junit.framework.Assert;
> import junit.framework.Test;
> import junit.framework.TestCase;
> import junit.framework.TestSuite;
> import junit.textui.TestRunner;
>
> import org.apache.commons.jelly.JellyContext;
> +import org.apache.commons.jelly.JellyException;
> import org.apache.commons.jelly.Script;
> import org.apache.commons.jelly.XMLOutput;
> import org.apache.commons.jelly.parser.XMLParser;
> @@ -36,6 +41,8 @@
> import org.dom4j.Document;
> import org.dom4j.DocumentHelper;
> import org.dom4j.Node;
> +import org.dom4j.io.SAXContentHandler;
> +import org.dom4j.io.XMLWriter;
>
> /** Tests the parser, the engine and the XML tags
> *
> @@ -84,57 +91,158 @@
> log.debug("Evaluated script as...");
> log.debug(text);
> }
> - assertEquals("Produces the correct output", "It works!", text);
> + assertEquals("Should produce the correct output", "It works!", text);
> + }
> +
> + public void testElementWithNameSpace() throws Exception {
> + String text = evaluteScriptAsText(testBaseDir + "/elementWithNameSpace.jelly");
> + assertEquals("Should produce the correct output",
> + "<env:Envelope "+
> + "xmlns:env=\"http://schemas.xmlsoap.org/soap/envelope/\" "+
> + "env:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\">"+
> + "</env:Envelope>", text);
> + }
> +
> + public void testElementWithNameSpaceError() throws Exception {
> + try {
> + evaluteScriptAsText(testBaseDir + "/elementWithNameSpaceError.jelly");
> + Assert.fail("We should have bailed out with an JellyException");
> + } catch (JellyException jex) {
> + assertTrue(jex.getReason().startsWith("Cannot set same prefix to diferent URI in same node"));
> + }
> + }
> +
> + public void testNamespaceReplace() throws Exception {
> + // For this test when we not set "ns" var with expected namespace, it
> + // is expected to repeat the same two times
> + String text = evaluteScriptAsText(testBaseDir + "/namespaceReplace.jelly");
> + String repeatingText = "<test-subnode attr=\"test\"><test-anotherSubNode></test-anotherSubNode><test-anotherSubNodeAgain xmlns:other=\"\" other:abc=\"testValue\"></test-anotherSubNodeAgain></test-subnode>";
> + assertEquals("Should produce the correct output",
> + "<test-node xmlns:test=\"http://apache/testNS\" test:abc=\"testValue\">"+
> + repeatingText + repeatingText +
> + "</test-node>", text);
> +
> + Map ctxVars = new HashMap();
> + ctxVars.put("ns", "http://java/ns");
> +
> + text = evaluteScriptAsText(testBaseDir + "/namespaceReplace.jelly", ctxVars);
> +
> + String firstTrunk =
> + "<test-subnode xmlns=\"\" attr=\"test\">" +
> + "<test-anotherSubNode>" +
> + "</test-anotherSubNode>" +
> + "<test-anotherSubNodeAgain xmlns:other=\"http://java/ns\" xmlns=\"http://java/ns\" other:abc=\"testValue\">" +
> + "</test-anotherSubNodeAgain>" +
> + "</test-subnode>";
> +
> + String secondTrunk =
> + "<test-subnode attr=\"test\">" +
> + "<test-anotherSubNode>" +
> + "</test-anotherSubNode>" +
> + "<test-anotherSubNodeAgain xmlns:other=\"http://java/ns\" other:abc=\"testValue\">" +
> + "</test-anotherSubNodeAgain>" +
> + "</test-subnode>";
> +
> + System.out.println("TestXMLTags.testNamespaceReplace() text="+text);
> + assertEquals("Should produce the correct output",
> + "<test-node xmlns:test=\"http://apache/testNS\" xmlns=\"http://java/ns\" test:abc=\"testValue\">"+
> + firstTrunk + secondTrunk +
> + "</test-node>", text);
> + }
> +
> + public void testAttributeNameSpaceDuplicatedNS() throws Exception {
> + try {
> + evaluteScriptAsText(testBaseDir + "/attributeNameSpaceDuplicatedNS.jelly");
> + Assert.fail("We should have bailed out with an JellyException");
> + } catch (JellyException jex) {
> + assertTrue(jex.getReason().startsWith("Cannot set same prefix to diferent URI in same node"));
> + }
> + }
> +
> + public void testAttributeNameSpace() throws Exception {
> + String text = evaluteScriptAsText(testBaseDir + "/attributeNameSpace.jelly");
> + System.out.println(text);
> + assertEquals("Should produce the correct output",
> + "<top-node xmlns=\"abc\">"+
> + "<test-node xmlns:test=\"http://apache/testNS\" xmlns=\"http://apache/trueNS\" test:abc=\"testValue\" abc2=\"testValue\" abc3=\"testValue\">"+
> + "<test:test-subnode><node-at-same-ns-as-top xmlns=\"abc\">"+
> + "</node-at-same-ns-as-top>"+
> + "</test:test-subnode>"+
> + "</test-node>"+
> + "</top-node>", text);
> + }
> +
> + public void testAttributeNameSpaceDefaultNS() throws Exception {
> + String text = evaluteScriptAsText(testBaseDir + "/attributeNameSpaceDefaultNS.jelly");
> + System.out.println(text);
> + assertEquals("Should produce the correct output",
> + "<top-node>"+
> + "<test-node xmlns:test=\"http://apache/testNS\" xmlns=\"http://apache/trueNS\" test:abc=\"testValue\" abc2=\"testValue\" abc3=\"testValue\">"+
> + "<test:test-subnode><node-at-same-ns-as-top xmlns=\"\">"+
> + "</node-at-same-ns-as-top>"+
> + "</test:test-subnode>"+
> + "</test-node>"+
> + "</top-node>", text);
> + }
> +
> + public void testAttributeNameSpaceWithInnerElements() throws Exception {
> + String text = evaluteScriptAsText(testBaseDir + "/attributeNameSpaceWithInnerElements.jelly");
> + assertEquals("Should produce the correct output",
> + "<test-node xmlns:test=\"http://apache/testNS\" test:abc=\"testValue\" abc2=\"testValue\" abc3=\"testValue\">"+
> + "<test-sub-node xmlns:test2=\"http://apache/testNS\" xmlns:test3=\"http://apache/anotherNS\" test:abc=\"testValue\" test2:abc2=\"testValue\" test3:abc3=\"testValue\">"+
> + "</test-sub-node>"+
> + "</test-node>"
> + , text);
> }
>
> public void testTransform() throws Exception {
> String text = evaluteScriptAsText(testBaseDir + "/transformExample.jelly");
> - assertEquals("Produces the correct output", "It works!", text);
> + assertEquals("Should produce the correct output", "It works!", text);
> }
>
> public void testTransformAllInLine() throws Exception {
> String text = evaluteScriptAsText(testBaseDir + "/transformExampleAllInLine.jelly");
> - assertEquals("Produces the correct output", "It works!", text);
> + assertEquals("Should produce the correct output", "It works!", text);
> }
>
> public void testTransformParams() throws Exception {
> String text = evaluteScriptAsText(testBaseDir + "/transformParamExample.jelly");
> - assertEquals("Produces the correct output", "It works!", text);
> + assertEquals("Should produce the correct output", "It works!", text);
> }
>
> public void testTransformParamsInLine() throws Exception {
>
> String text = evaluteScriptAsText(testBaseDir + "/transformParamExample2.jelly");
> - assertEquals("Produces the correct output", "It works!", text);
> + assertEquals("Should produce the correct output", "It works!", text);
> }
>
> public void testTransformSAXOutput() throws Exception {
> String text = evaluteScriptAsText(testBaseDir + "/transformExampleSAXOutput.jelly");
> - assertEquals("Produces the correct output", "It works!", text);
> + assertEquals("Should produce the correct output", "It works!", text);
> }
>
> public void testTransformSAXOutputNestedTransforms() throws Exception {
> String text = evaluteScriptAsText(testBaseDir +
> "/transformExampleSAXOutputNestedTransforms.jelly");
> - assertEquals("Produces the correct output", "It works!", text);
> + assertEquals("Should produce the correct output", "It works!", text);
> }
>
> public void testTransformSchematron() throws Exception {
> String text = evaluteScriptAsText(testBaseDir +
> "/schematron/transformSchematronExample.jelly");
> - assertEquals("Produces the correct output", "Report count=1:assert count=2", text);
> + assertEquals("Should produce the correct output", "Report count=1:assert count=2", text);
> }
>
> public void testTransformXmlVar() throws Exception {
> String text = evaluteScriptAsText(testBaseDir +
> "/transformExampleXmlVar.jelly");
> - assertEquals("Produces the correct output", "It works!", text);
> + assertEquals("Should produce the correct output", "It works!", text);
> }
>
> public void testDoctype() throws Exception {
> String text = evaluteScriptAsText(testBaseDir +
> "/testDoctype.jelly");
> - assertEquals("Produces the correct output", "<!DOCTYPE foo PUBLIC \"publicID\" \"foo.dtd\">\n<foo></foo>", text);
> + assertEquals("Should produce the correct output", "<!DOCTYPE foo PUBLIC \"publicID\" \"foo.dtd\">\n<foo></foo>", text);
> }
>
> public void runUnitTest(String name) throws Exception {
> @@ -172,7 +280,23 @@
> * returns the whitespace trimmed output as text
> */
> protected String evaluteScriptAsText(String fileName) throws Exception {
> + return evaluteScriptAsText(fileName, null);
> + }
> +
> + /**
> + * Evaluates the script by the given file name and
> + * returns the whitespace trimmed output as text
> + */
> + protected String evaluteScriptAsText(String fileName, Map ctxVars) throws Exception {
> JellyContext context = new JellyContext();
> + if (ctxVars != null) {
> + Set keys = ctxVars.keySet();
> + for (Iterator iterator = keys.iterator(); iterator.hasNext();) {
> + String key = (String) iterator.next();
> + Object value = ctxVars.get(key);
> + context.setVariable(key, value);
> + }
> + }
>
> // allow scripts to refer to any resource inside this project
> // using an absolute URI like /src/test/org/apache/foo.xml
> @@ -190,4 +314,49 @@
> }
> return text;
> }
> +
> + protected String evaluteScriptAsTextUsingSaxContentHandler(String fileName, Map ctxVars) throws Exception {
> + org.dom4j.io.OutputFormat outputFormat = new org.dom4j.io.OutputFormat();
> + outputFormat.setSuppressDeclaration(true);
> + outputFormat.setNewlines(false);
> + outputFormat.setIndent(false);
> + outputFormat.setExpandEmptyElements(true);
> + //outputFormat.setIndentSize(4);
> +
> + StringWriter buffer = new StringWriter();
> + XMLWriter xmlWriter = new XMLWriter(buffer, outputFormat);
> + // xmlWriter.setEscapeText(false);
> +
> + SAXContentHandler saxHandler = new SAXContentHandler();
> + XMLOutput output = new XMLOutput(saxHandler);
> +
> + // now run a script using a URL
> + JellyContext context = new JellyContext();
> + if (ctxVars != null) {
> + Set keys = ctxVars.keySet();
> + for (Iterator iterator = keys.iterator(); iterator.hasNext();) {
> + String key = (String) iterator.next();
> + Object value = ctxVars.get(key);
> + context.setVariable(key, value);
> + }
> + }
> +
> + // allow scripts to refer to any resource inside this project
> + // using an absolute URI like /src/test/org/apache/foo.xml
> + context.setRootURL(new File(".").toURL());
> +
> + output.startDocument();
> + context.runScript(new File(fileName), output);
> + output.endDocument();
> + xmlWriter.write(saxHandler.getDocument());
> + xmlWriter.flush();
> +
> + String text = buffer.toString().trim();
> + if (log.isDebugEnabled()) {
> + log.debug("Evaluated script as...");
> + log.debug(text);
> + }
> + return text;
> + }
> +
> }
>
> Added: jakarta/commons/proper/jelly/trunk/jelly-tags/xml/src/test/org/apache/commons/jelly/tags/xml/attributeNameSpace.jelly
> URL: http://svn.apache.org/viewcvs/jakarta/commons/proper/jelly/trunk/jelly-tags/xml/src/test/org/apache/commons/jelly/tags/xml/attributeNameSpace.jelly?rev=219726&view=auto
> ==============================================================================
> --- jakarta/commons/proper/jelly/trunk/jelly-tags/xml/src/test/org/apache/commons/jelly/tags/xml/attributeNameSpace.jelly (added)
> +++ jakarta/commons/proper/jelly/trunk/jelly-tags/xml/src/test/org/apache/commons/jelly/tags/xml/attributeNameSpace.jelly Tue Jul 19 10:34:00 2005
> @@ -0,0 +1,15 @@
> +<?xml version="1.0" encoding="UTF-8"?>
> +<j:jelly xmlns:j="jelly:core" xmlns:x="jelly:xml" xmlns="abc">
> + <top-node>
> + <x:element URI="http://apache/trueNS" name="test-node">
> + <x:attribute URI="http://apache/testNS" name="test:abc" trim="true">testValue</x:attribute>
> + <!-- attributes without ':' should not have namespace -->
> + <x:attribute URI="http://apache/testNS" name="abc2" trim="true">testValue</x:attribute>
> + <x:attribute name="abc3" trim="true">testValue</x:attribute>
> + <x:element URI="http://apache/testNS" name="test:test-subnode">
> + <node-at-same-ns-as-top/>
> + </x:element>
> + </x:element>
> + </top-node>
> +</j:jelly>
> +
>
> Added: jakarta/commons/proper/jelly/trunk/jelly-tags/xml/src/test/org/apache/commons/jelly/tags/xml/attributeNameSpaceDefaultNS.jelly
> URL: http://svn.apache.org/viewcvs/jakarta/commons/proper/jelly/trunk/jelly-tags/xml/src/test/org/apache/commons/jelly/tags/xml/attributeNameSpaceDefaultNS.jelly?rev=219726&view=auto
> ==============================================================================
> --- jakarta/commons/proper/jelly/trunk/jelly-tags/xml/src/test/org/apache/commons/jelly/tags/xml/attributeNameSpaceDefaultNS.jelly (added)
> +++ jakarta/commons/proper/jelly/trunk/jelly-tags/xml/src/test/org/apache/commons/jelly/tags/xml/attributeNameSpaceDefaultNS.jelly Tue Jul 19 10:34:00 2005
> @@ -0,0 +1,15 @@
> +<?xml version="1.0" encoding="UTF-8"?>
> +<j:jelly xmlns:j="jelly:core" xmlns:x="jelly:xml">
> + <top-node>
> + <x:element URI="http://apache/trueNS" name="test-node">
> + <x:attribute URI="http://apache/testNS" name="test:abc" trim="true">testValue</x:attribute>
> + <!-- attributes without ':' should not have namespace -->
> + <x:attribute URI="http://apache/testNS" name="abc2" trim="true">testValue</x:attribute>
> + <x:attribute name="abc3" trim="true">testValue</x:attribute>
> + <x:element URI="http://apache/testNS" name="test:test-subnode">
> + <node-at-same-ns-as-top/>
> + </x:element>
> + </x:element>
> + </top-node>
> +</j:jelly>
> +
>
> Added: jakarta/commons/proper/jelly/trunk/jelly-tags/xml/src/test/org/apache/commons/jelly/tags/xml/attributeNameSpaceDuplicatedNS.jelly
> URL: http://svn.apache.org/viewcvs/jakarta/commons/proper/jelly/trunk/jelly-tags/xml/src/test/org/apache/commons/jelly/tags/xml/attributeNameSpaceDuplicatedNS.jelly?rev=219726&view=auto
> ==============================================================================
> --- jakarta/commons/proper/jelly/trunk/jelly-tags/xml/src/test/org/apache/commons/jelly/tags/xml/attributeNameSpaceDuplicatedNS.jelly (added)
> +++ jakarta/commons/proper/jelly/trunk/jelly-tags/xml/src/test/org/apache/commons/jelly/tags/xml/attributeNameSpaceDuplicatedNS.jelly Tue Jul 19 10:34:00 2005
> @@ -0,0 +1,8 @@
> +<?xml version="1.0" encoding="UTF-8"?>
> +<j:jelly xmlns:j="jelly:core" xmlns:x="jelly:xml">
> + <x:element name="test-node">
> + <x:attribute URI="http://apache/testNS" name="test:abc" trim="true">testValue</x:attribute>
> + <x:attribute URI="http://apache/anotherNS" name="test:abc2" trim="true">testValue</x:attribute>
> + </x:element>
> +</j:jelly>
> +
>
> Added: jakarta/commons/proper/jelly/trunk/jelly-tags/xml/src/test/org/apache/commons/jelly/tags/xml/attributeNameSpaceWithInnerElements.jelly
> URL: http://svn.apache.org/viewcvs/jakarta/commons/proper/jelly/trunk/jelly-tags/xml/src/test/org/apache/commons/jelly/tags/xml/attributeNameSpaceWithInnerElements.jelly?rev=219726&view=auto
> ==============================================================================
> --- jakarta/commons/proper/jelly/trunk/jelly-tags/xml/src/test/org/apache/commons/jelly/tags/xml/attributeNameSpaceWithInnerElements.jelly (added)
> +++ jakarta/commons/proper/jelly/trunk/jelly-tags/xml/src/test/org/apache/commons/jelly/tags/xml/attributeNameSpaceWithInnerElements.jelly Tue Jul 19 10:34:00 2005
> @@ -0,0 +1,16 @@
> +<?xml version="1.0" encoding="UTF-8"?>
> +<j:jelly xmlns:j="jelly:core" xmlns:x="jelly:xml">
> + <x:element name="test-node">
> + <x:attribute URI="http://apache/testNS" name="test:abc" trim="true">testValue</x:attribute>
> + <!-- attributes without ':' should not have namespace -->
> + <x:attribute URI="http://apache/testNS" name="abc2" trim="true">testValue</x:attribute>
> + <x:attribute name="abc3" trim="true">testValue</x:attribute>
> +
> + <x:element name="test-sub-node">
> + <x:attribute URI="http://apache/testNS" name="test:abc" trim="true">testValue</x:attribute>
> + <x:attribute URI="http://apache/testNS" name="test2:abc2" trim="true">testValue</x:attribute>
> + <x:attribute URI="http://apache/anotherNS" name="test3:abc3" trim="true">testValue</x:attribute>
> + </x:element>
> + </x:element>
> +</j:jelly>
> +
>
> Added: jakarta/commons/proper/jelly/trunk/jelly-tags/xml/src/test/org/apache/commons/jelly/tags/xml/elementWithNameSpace.jelly
> URL: http://svn.apache.org/viewcvs/jakarta/commons/proper/jelly/trunk/jelly-tags/xml/src/test/org/apache/commons/jelly/tags/xml/elementWithNameSpace.jelly?rev=219726&view=auto
> ==============================================================================
> --- jakarta/commons/proper/jelly/trunk/jelly-tags/xml/src/test/org/apache/commons/jelly/tags/xml/elementWithNameSpace.jelly (added)
> +++ jakarta/commons/proper/jelly/trunk/jelly-tags/xml/src/test/org/apache/commons/jelly/tags/xml/elementWithNameSpace.jelly Tue Jul 19 10:34:00 2005
> @@ -0,0 +1,10 @@
> +<?xml version="1.0" encoding="UTF-8"?>
> +<j:jelly xmlns:j="jelly:core" xmlns:x="jelly:xml">
> + <x:element URI="http://schemas.xmlsoap.org/soap/envelope/" name="env:Envelope">
> + <x:attribute URI="http://schemas.xmlsoap.org/soap/envelope/"
> + name="env:encodingStyle" trim="true">
> + http://schemas.xmlsoap.org/soap/encoding/
> + </x:attribute>
> + </x:element>
> +</j:jelly>
> +
>
> Added: jakarta/commons/proper/jelly/trunk/jelly-tags/xml/src/test/org/apache/commons/jelly/tags/xml/elementWithNameSpaceError.jelly
> URL: http://svn.apache.org/viewcvs/jakarta/commons/proper/jelly/trunk/jelly-tags/xml/src/test/org/apache/commons/jelly/tags/xml/elementWithNameSpaceError.jelly?rev=219726&view=auto
> ==============================================================================
> --- jakarta/commons/proper/jelly/trunk/jelly-tags/xml/src/test/org/apache/commons/jelly/tags/xml/elementWithNameSpaceError.jelly (added)
> +++ jakarta/commons/proper/jelly/trunk/jelly-tags/xml/src/test/org/apache/commons/jelly/tags/xml/elementWithNameSpaceError.jelly Tue Jul 19 10:34:00 2005
> @@ -0,0 +1,9 @@
> +<?xml version="1.0" encoding="UTF-8"?>
> +<j:jelly xmlns:j="jelly:core" xmlns:x="jelly:xml">
> + <x:element URI="http://schemas.xmlsoap.org/soap/envelope/" name="env:Envelope">
> + <x:attribute name="env:encodingStyle" trim="true">
> + http://schemas.xmlsoap.org/soap/encoding/
> + </x:attribute>
> + </x:element>
> +</j:jelly>
> +
>
> Added: jakarta/commons/proper/jelly/trunk/jelly-tags/xml/src/test/org/apache/commons/jelly/tags/xml/namespaceReplace.jelly
> URL: http://svn.apache.org/viewcvs/jakarta/commons/proper/jelly/trunk/jelly-tags/xml/src/test/org/apache/commons/jelly/tags/xml/namespaceReplace.jelly?rev=219726&view=auto
> ==============================================================================
> --- jakarta/commons/proper/jelly/trunk/jelly-tags/xml/src/test/org/apache/commons/jelly/tags/xml/namespaceReplace.jelly (added)
> +++ jakarta/commons/proper/jelly/trunk/jelly-tags/xml/src/test/org/apache/commons/jelly/tags/xml/namespaceReplace.jelly Tue Jul 19 10:34:00 2005
> @@ -0,0 +1,23 @@
> +<?xml version="1.0" encoding="UTF-8"?>
> +<j:jelly xmlns:j="jelly:core" xmlns:x="jelly:xml">
> + <x:element URI="${ns}" name="test-node">
> + <x:attribute URI="http://apache/testNS" name="test:abc" trim="true">testValue</x:attribute>
> +
> + <test-subnode attr="test">
> + <test-anotherSubNode />
> + <x:element URI="${ns}" name="test-anotherSubNodeAgain">
> + <x:attribute URI="${ns}" name="other:abc" trim="true">testValue</x:attribute>
> + </x:element>
> + </test-subnode>
> +
> + <x:replaceNamespace toURI="${ns}">
> + <test-subnode attr="test">
> + <test-anotherSubNode />
> + <x:element URI="${ns}" name="test-anotherSubNodeAgain">
> + <x:attribute URI="${ns}" name="other:abc" trim="true">testValue</x:attribute>
> + </x:element>
> + </test-subnode>
> + </x:replaceNamespace>
> + </x:element>
> +</j:jelly>
> +
>
> Modified: jakarta/commons/proper/jelly/trunk/src/java/org/apache/commons/jelly/XMLOutput.java
> URL: http://svn.apache.org/viewcvs/jakarta/commons/proper/jelly/trunk/src/java/org/apache/commons/jelly/XMLOutput.java?rev=219726&r1=219725&r2=219726&view=diff
> ==============================================================================
> --- jakarta/commons/proper/jelly/trunk/src/java/org/apache/commons/jelly/XMLOutput.java (original)
> +++ jakarta/commons/proper/jelly/trunk/src/java/org/apache/commons/jelly/XMLOutput.java Tue Jul 19 10:34:00 2005
> @@ -20,6 +20,11 @@
> import java.io.OutputStream;
> import java.io.UnsupportedEncodingException;
> import java.io.Writer;
> +import java.util.ArrayList;
> +import java.util.HashMap;
> +import java.util.Iterator;
> +import java.util.List;
> +import java.util.Map;
>
> import org.apache.commons.logging.Log;
> import org.apache.commons.logging.LogFactory;
> @@ -44,29 +49,35 @@
> public class XMLOutput implements ContentHandler, LexicalHandler {
>
> protected static final String[] LEXICAL_HANDLER_NAMES =
> - {
> - "http://xml.org/sax/properties/lexical-handler",
> - "http://xml.org/sax/handlers/LexicalHandler" };
> + {
> + "http://xml.org/sax/properties/lexical-handler",
> + "http://xml.org/sax/handlers/LexicalHandler" };
>
> - /** empty attributes */
> + /** Empty attributes. */
> private static final Attributes EMPTY_ATTRIBUTES = new AttributesImpl();
>
> /** The Log to which logging calls will be made. */
> private static final Log log = LogFactory.getLog(XMLOutput.class);
>
> - /** the default for escaping of text */
> + /** the default for escaping of text. */
> private static final boolean DEFAULT_ESCAPE_TEXT = false;
>
> - /** The SAX ContentHandler that output goes to */
> + /** The SAX ContentHandler that output goes to. */
> private ContentHandler contentHandler;
>
> - /** The SAX LexicalHandler that output goes to */
> + /** The SAX LexicalHandler that output goes to. */
> private LexicalHandler lexicalHandler;
>
> + /** Stack of kown namespaces. */
> + private NamespaceStack namespaceStack = new NamespaceStack();
>
> public XMLOutput() {
> }
>
> + /** The XML-output will relay the SAX events to the indicated
> + * contentHandler.
> + * @param contentHandler
> + */
> public XMLOutput(ContentHandler contentHandler) {
> this.contentHandler = contentHandler;
> // often classes will implement LexicalHandler as well
> @@ -75,6 +86,11 @@
> }
> }
>
> + /** The XML-output will relay the SAX events to the indicated
> + * content-handler lexical-handler.
> + * @param contentHandler
> + * @param lexicalHandler
> + */
> public XMLOutput(
> ContentHandler contentHandler,
> LexicalHandler lexicalHandler) {
> @@ -92,16 +108,25 @@
> }
>
> /**
> - * Provides a useful hook that implementations can use to close the
> - * underlying OutputStream or Writer
> + * Provides a useful hook that implementations
> + * can use to close the
> + * underlying OutputStream or Writer.
> + *
> + * @throws IOException
> */
> public void close() throws IOException {
> }
>
> + /** Flushes the underlying stream if {@link XMLWriter}
> + * or {@link XMLOutput}.
> + *
> + * @throws IOException
> + */
> public void flush() throws IOException {
> - if( contentHandler instanceof XMLWriter )
> - {
> + if (contentHandler instanceof XMLWriter) {
> ((XMLWriter)contentHandler).flush();
> + } else if (contentHandler instanceof XMLOutput) {
> + ((XMLOutput)contentHandler).flush();
> }
> }
>
> @@ -109,7 +134,7 @@
> //-------------------------------------------------------------------------
>
> /**
> - * Creates an XMLOutput from an existing SAX XMLReader
> + * Creates an XMLOutput from an existing SAX XMLReader.
> */
> public static XMLOutput createXMLOutput(XMLReader xmlReader) {
> XMLOutput output = new XMLOutput(xmlReader.getContentHandler());
> @@ -122,10 +147,11 @@
> output.setLexicalHandler((LexicalHandler) value);
> break;
> }
> - }
> - catch (Exception e) {
> + } catch (Exception e) {
> // ignore any unsupported-operation exceptions
> - if (log.isDebugEnabled()) log.debug("error setting lexical handler properties", e);
> + if (log.isDebugEnabled()) {
> + log.debug("error setting lexical handler properties", e);
> + }
> }
> }
> return output;
> @@ -145,10 +171,9 @@
> *
> * @param writer is the writer to output to
> * @param escapeText is whether or not text output will be escaped. This must be true
> - * if the underlying output is XML or could be false if the underlying output is textual.
> + * if the underlying output is XML or could be false if the underlying output is textual.
> */
> - public static XMLOutput createXMLOutput(Writer writer, boolean escapeText)
> - {
> + public static XMLOutput createXMLOutput(Writer writer, boolean escapeText) {
> XMLWriter xmlWriter = new XMLWriter(writer);
> xmlWriter.setEscapeText(escapeText);
> return createXMLOutput(xmlWriter);
> @@ -169,8 +194,11 @@
> * @param out is the output stream to write
> * @param escapeText is whether or not text output will be escaped. This must be true
> * if the underlying output is XML or could be false if the underlying output is textual.
> + * @throws UnsupportedEncodingException if the underlying write could not
> + * be created.
> */
> - public static XMLOutput createXMLOutput(OutputStream out, boolean escapeText) throws UnsupportedEncodingException {
> + public static XMLOutput createXMLOutput(OutputStream out, boolean escapeText)
> + throws UnsupportedEncodingException {
> XMLWriter xmlWriter = new XMLWriter(out);
> xmlWriter.setEscapeText(escapeText);
> return createXMLOutput(xmlWriter);
> @@ -193,7 +221,7 @@
> /**
> * Outputs the given String as a piece of valid text in the
> * XML event stream.
> - * Any special XML characters should be properly escaped.
> + * Any special XML characters should come out properly escaped.
> */
> public void write(String text) throws SAXException {
> char[] ch = text.toCharArray();
> @@ -212,7 +240,7 @@
> }
>
> /**
> - * Outputs a comment to the XML stream
> + * Outputs a comment to the XML stream.
> */
> public void writeComment(String text) throws SAXException {
> char[] ch = text.toCharArray();
> @@ -220,21 +248,24 @@
> }
>
> /**
> - * Helper method for outputting a start element event for an element in no namespace
> + * Helper method for outputting a start element event
> + * for an element in no namespace.
> */
> public void startElement(String localName) throws SAXException {
> startElement("", localName, localName, EMPTY_ATTRIBUTES);
> }
>
> /**
> - * Helper method for outputting a start element event for an element in no namespace
> + * Helper method for outputting a start element event
> + * for an element in no namespace.
> */
> public void startElement(String localName, Attributes attributes) throws SAXException {
> startElement("", localName, localName, attributes);
> }
>
> /**
> - * Helper method for outputting an end element event for an element in no namespace
> + * Helper method for outputting an end element event
> + * for an element in no namespace.
> */
> public void endElement(String localName) throws SAXException {
> endElement("", localName, localName);
> @@ -344,7 +375,9 @@
> * @see #startElement
> */
> public void startPrefixMapping(String prefix, String uri) throws SAXException {
> - contentHandler.startPrefixMapping(prefix, uri);
> + namespaceStack.pushNamespace(prefix, uri);
> + // contentHandler.startPrefixMapping(prefix, uri) will be called if needed
> + // in pushNamespace
> }
>
> /**
> @@ -364,7 +397,9 @@
> * @see #endElement
> */
> public void endPrefixMapping(String prefix) throws SAXException {
> - contentHandler.endPrefixMapping(prefix);
> + namespaceStack.popNamespace(prefix);
> + // End prefix mapping was already called after endElement
> + // contentHandler.endPrefixMapping(prefix);
> }
>
> /**
> @@ -435,7 +470,28 @@
> String qName,
> Attributes atts)
> throws SAXException {
> +
> + int idx = qName.indexOf(':');
> + String attNsPrefix = "";
> + if (idx >= 0) {
> + attNsPrefix = qName.substring(0, idx);
> + }
> + namespaceStack.pushNamespace(attNsPrefix, uri);
> + for (int i = 0; i < atts.getLength(); i++) {
> + String attQName = atts.getQName(i);
> + // An attribute only has an namespace if has a prefix
> + // If not, stays in namespace of containing node
> + idx = attQName.indexOf(':');
> + if (idx >= 0) {
> + attNsPrefix = attQName.substring(0, idx);
> + String attUri = atts.getURI(i);
> + namespaceStack.pushNamespace(attNsPrefix, attUri);
> + }
> + }
> +
> contentHandler.startElement(uri, localName, qName, atts);
> + // Inform namespaceStack of a new depth
> + namespaceStack.increaseLevel();
> }
>
> /**
> @@ -462,6 +518,9 @@
> public void endElement(String uri, String localName, String qName)
> throws SAXException {
> contentHandler.endElement(uri, localName, qName);
> + // Inform namespaceStack to return to previous depth
> + namespaceStack.decreaseLevel();
> + namespaceStack.popNamespaces();
> }
>
> /**
> @@ -507,7 +566,7 @@
> * @see #ignorableWhitespace
> * @see org.xml.sax.Locator
> */
> - public void characters(char ch[], int start, int length) throws SAXException {
> + public void characters(char[] ch, int start, int length) throws SAXException {
> contentHandler.characters(ch, start, length);
> }
>
> @@ -535,7 +594,7 @@
> * wrapping another exception.
> * @see #characters
> */
> - public void ignorableWhitespace(char ch[], int start, int length)
> + public void ignorableWhitespace(char[] ch, int start, int length)
> throws SAXException {
> contentHandler.ignorableWhitespace(ch, start, length);
> }
> @@ -855,4 +914,127 @@
> return answer;
> }
>
> + private final class NamespaceStack {
> + /** A list of maps: Each map contains prefix->uri mapping */
> + private List nsStack;
> +
> + private NamespaceStack() {
> + this.nsStack = new ArrayList();
> + this.nsStack.add(new HashMap());
> + }
> +
> + private boolean isRootNodeDefaultNs(String prefix, String uri) {
> + return ("".equals(prefix) && "".equals(uri) && nsStack.size() == 1);
> + }
> +
> + public void pushNamespace(String prefix, String uri) throws SAXException {
> + Map prefixUriMap;
> +
> + if (prefix == null) {
> + prefix = "";
> + }
> + if (uri == null) {
> + uri = "";
> + }
> +
> + if ("xml".equals(prefix)) {
> + // We should ignore setting 'xml' prefix
> + // As declared in java of ContentHandler#startPrefixMapping
> + return;
> + }
> +
> +
> + // Lets find out if we already declared this same prefix,
> + // if not declare in current depth map (the first of list)
> + // and call contentHandler.startPrefixMapping(prefix, uri);
> + boolean isNew = true;
> + for (Iterator iter = nsStack.iterator(); iter.hasNext();) {
> + prefixUriMap = (Map) iter.next();
> + if (prefixUriMap.containsKey(prefix)) {
> + if (uri.equals(prefixUriMap.get(prefix))) {
> + // Its an active namespace already
> + // System.out.println(">>>"+XMLOutput.this.hashCode()+">NamespaceStack.pushNamespace() IS NOT NEW prefix="+prefix+",uri="+uri);
> + isNew = false;
> + }
> + // We found it in stack
> + // If it was exacly the same, we won't bother
> + break;
> + }
> + }
> +
> + if (isNew) {
> + // not declared sometime before
> + prefixUriMap = (Map) nsStack.get(0); // Current depth map
> + // Sanity check: Don't let two prefixes for diferent uris in
> + // same depth
> + if (prefixUriMap.containsKey(prefix)) {
> + if (!uri.equals(prefixUriMap.get(prefix))) {
> + throw new SAXException("Cannot set same prefix to diferent URI in same node: trying to add prefix \""
> + + prefix + "\" for uri \""+uri+"\" whereas the declared ones are " + prefixUriMap);
> + }
> + } else {
> + prefixUriMap.put(prefix, uri);
> +
> + // To avoid setting xmlns="" for top node (not very nice :D)
> + // We need to especificaly check this condition
> + if (!isRootNodeDefaultNs(prefix, uri)) {
> +// System.out.println(">>>"+XMLOutput.this.hashCode()+">NamespaceStack.pushNamespace() prefix="+prefix+",uri="+uri);
> + contentHandler.startPrefixMapping(prefix, uri);
> + }
> + }
> + }
> + }
> +
> + public void popNamespaces() throws SAXException {
> + Map prefixUriMap = (Map)nsStack.get(0);
> + for (Iterator iter = prefixUriMap.keySet().iterator();iter.hasNext();) {
> + String prefix = (String)iter.next();
> + String uri = (String) prefixUriMap.get(prefix);
> + iter.remove();
> +
> + // If we havent called startPrefixMapping for root node if we wanted to avoid xmlns=""
> + // We aren't going to call endPrefixMapping neither
> + if (!isRootNodeDefaultNs(prefix, uri)) {
> +// System.out.println(">>>"+XMLOutput.this.hashCode()+">NamespaceStack.popNamespaces() prefix="+prefix);
> + contentHandler.endPrefixMapping(prefix);
> + }
> + }
> + }
> +
> + public void popNamespace(String prefix) throws SAXException {
> + Map prefixUriMap = (Map)nsStack.get(0);
> +
> + if (prefix == null) {
> + prefix = "";
> + }
> +
> + if ("xml".equals(prefix)) {
> + // We should ignore setting 'xml' prefix
> + // As declared in java of ContentHandler#startPrefixMapping
> + return;
> + }
> +
> + if (prefixUriMap.containsKey(prefix)) {
> + String uri = (String) prefixUriMap.get(prefix);
> + prefixUriMap.remove(prefix);
> + // If we havent called startPrefixMapping for root node if we wanted to avoid xmlns=""
> + // We aren't going to call endPrefixMapping neither
> + if (!isRootNodeDefaultNs(prefix, uri)) {
> +// System.out.println(">>>"+XMLOutput.this.hashCode()+">NamespaceStack.popNamespace() prefix="+prefix);
> + contentHandler.endPrefixMapping(prefix);
> + }
> + }/* else {
> + improper nesting ? or already removed in popNamespaces
> + }
> + */
> + }
> +
> + public void decreaseLevel() {
> + nsStack.remove(0);
> + }
> +
> + public void increaseLevel() {
> + nsStack.add(0, new HashMap());
> + }
> + }
> }
>
> Modified: jakarta/commons/proper/jelly/trunk/src/java/org/apache/commons/jelly/impl/StaticTag.java
> URL: http://svn.apache.org/viewcvs/jakarta/commons/proper/jelly/trunk/src/java/org/apache/commons/jelly/impl/StaticTag.java?rev=219726&r1=219725&r2=219726&view=diff
> ==============================================================================
> --- jakarta/commons/proper/jelly/trunk/src/java/org/apache/commons/jelly/impl/StaticTag.java (original)
> +++ jakarta/commons/proper/jelly/trunk/src/java/org/apache/commons/jelly/impl/StaticTag.java Tue Jul 19 10:34:00 2005
> @@ -69,6 +69,15 @@
> }
> }
>
> + public void setAttribute(String name, String prefix, String nsURI, Object value) {
> + if(value==null)
> + return;
> + if(prefix!=null && prefix.length()>0)
> + attributes.addAttribute(nsURI,name,prefix+":"+name,"CDATA",value.toString());
> + else
> + attributes.addAttribute("",name,name,"CDATA",value.toString());
> + }
> +
> // DynaTag interface
> //-------------------------------------------------------------------------
> public void setAttribute(String name, Object value) throws JellyTagException {
>
> Modified: jakarta/commons/proper/jelly/trunk/src/java/org/apache/commons/jelly/impl/StaticTagScript.java
> URL: http://svn.apache.org/viewcvs/jakarta/commons/proper/jelly/trunk/src/java/org/apache/commons/jelly/impl/StaticTagScript.java?rev=219726&r1=219725&r2=219726&view=diff
> ==============================================================================
> --- jakarta/commons/proper/jelly/trunk/src/java/org/apache/commons/jelly/impl/StaticTagScript.java (original)
> +++ jakarta/commons/proper/jelly/trunk/src/java/org/apache/commons/jelly/impl/StaticTagScript.java Tue Jul 19 10:34:00 2005
> @@ -86,7 +86,10 @@
> for (Iterator iter = attributes.entrySet().iterator(); iter.hasNext();) {
> Map.Entry entry = (Map.Entry) iter.next();
> String name = (String) entry.getKey();
> - Expression expression = (Expression) entry.getValue();
> + if(name.indexOf(':')!=-1)
> + name = name.substring(name.indexOf(':')+1);
> + ExpressionAttribute expat = (ExpressionAttribute) entry.getValue();
> + Expression expression = expat.exp;
>
> Object value = null;
>
> @@ -96,7 +99,10 @@
> value = expression.evaluate(context);
> }
>
> - dynaTag.setAttribute(name, value);
> + if(expat.prefix!=null || expat.prefix.length()>0 && tag instanceof StaticTag)
> + ((StaticTag) dynaTag).setAttribute(name,expat.prefix, expat.nsURI,value);
> + else
> + dynaTag.setAttribute(name, value);
> }
>
> tag.doTag(output);
>
> Modified: jakarta/commons/proper/jelly/trunk/src/java/org/apache/commons/jelly/impl/TagScript.java
> URL: http://svn.apache.org/viewcvs/jakarta/commons/proper/jelly/trunk/src/java/org/apache/commons/jelly/impl/TagScript.java?rev=219726&r1=219725&r2=219726&view=diff
> ==============================================================================
> --- jakarta/commons/proper/jelly/trunk/src/java/org/apache/commons/jelly/impl/TagScript.java (original)
> +++ jakarta/commons/proper/jelly/trunk/src/java/org/apache/commons/jelly/impl/TagScript.java Tue Jul 19 10:34:00 2005
> @@ -170,7 +170,19 @@
> if (log.isDebugEnabled()) {
> log.debug("adding attribute name: " + name + " expression: " + expression);
> }
> - attributes.put(name, expression);
> + attributes.put(name, new ExpressionAttribute(name,expression));
> + }
> +
> + /** Add an initialization attribute for the tag.
> + * This method must be called after the setTag() method
> + */
> + public void addAttribute(String name, String prefix, String nsURI, Expression expression) {
> + if (log.isDebugEnabled()) {
> + log.debug("adding attribute name: " + name + " expression: " + expression);
> + }
> + if(name.indexOf(':')==-1)
> + name = prefix + ':' + name;
> + attributes.put(name, new ExpressionAttribute(name,prefix,nsURI,expression));
> }
>
> /**
> @@ -206,7 +218,7 @@
> for (Iterator iter = attributes.entrySet().iterator(); iter.hasNext();) {
> Map.Entry entry = (Map.Entry) iter.next();
> String name = (String) entry.getKey();
> - Expression expression = (Expression) entry.getValue();
> + Expression expression = ((ExpressionAttribute) entry.getValue()).exp;
>
> Class type = dynaTag.getAttributeType(name);
> Object value = null;
> @@ -225,7 +237,7 @@
> for (Iterator iter = attributes.entrySet().iterator(); iter.hasNext();) {
> Map.Entry entry = (Map.Entry) iter.next();
> String name = (String) entry.getKey();
> - Expression expression = (Expression) entry.getValue();
> + Expression expression = ((ExpressionAttribute) entry.getValue()).exp;
>
> DynaProperty property = dynaBean.getDynaClass().getDynaProperty(name);
> if (property == null) {
> @@ -690,3 +702,21 @@
> throw new JellyTagException(e, fileName, elementName, columnNumber, lineNumber);
> }
> }
> +
> +
> +class ExpressionAttribute {
> + public ExpressionAttribute(String name, Expression exp) {
> + this(name,"","",exp);
> + }
> + public ExpressionAttribute(String name, String prefix, String nsURI, Expression exp) {
> + this.name = name;
> + this.prefix = prefix;
> + this.nsURI = nsURI;
> + this.exp = exp;
> + }
> +
> + String name;
> + String prefix;
> + String nsURI;
> + Expression exp;
> +}
> \ No newline at end of file
>
> Modified: jakarta/commons/proper/jelly/trunk/src/java/org/apache/commons/jelly/parser/XMLParser.java
> URL: http://svn.apache.org/viewcvs/jakarta/commons/proper/jelly/trunk/src/java/org/apache/commons/jelly/parser/XMLParser.java?rev=219726&r1=219725&r2=219726&view=diff
> ==============================================================================
> --- jakarta/commons/proper/jelly/trunk/src/java/org/apache/commons/jelly/parser/XMLParser.java (original)
> +++ jakarta/commons/proper/jelly/trunk/src/java/org/apache/commons/jelly/parser/XMLParser.java Tue Jul 19 10:34:00 2005
> @@ -1066,7 +1066,12 @@
> attributeValue, getExpressionFactory()
> );
> String attrQName = list.getQName(i);
> - script.addAttribute(attrQName, expression);
> + int p = attrQName.indexOf(':');
> + String prefix = p>=0 ?
> + attrQName.substring(0,p):
> + "";
> + script.addAttribute(list.getLocalName(i),
> + prefix, list.getURI(i), expression);
> }
> return script;
> }
>
> Modified: jakarta/commons/proper/jelly/trunk/src/test/org/apache/commons/jelly/TestCoreTags.java
> URL: http://svn.apache.org/viewcvs/jakarta/commons/proper/jelly/trunk/src/test/org/apache/commons/jelly/TestCoreTags.java?rev=219726&r1=219725&r2=219726&view=diff
> ==============================================================================
> --- jakarta/commons/proper/jelly/trunk/src/test/org/apache/commons/jelly/TestCoreTags.java (original)
> +++ jakarta/commons/proper/jelly/trunk/src/test/org/apache/commons/jelly/TestCoreTags.java Tue Jul 19 10:34:00 2005
> @@ -105,4 +105,24 @@
> textScript.trimStartWhitespace();
> assertEquals("foo", textScript.getText());
> }
> +
> +
> + public void testStaticNamespacedAttributes() throws Exception {
> + InputStream in = new FileInputStream("src/test/org/apache/commons/jelly/testStaticNamespacedAttributes.jelly");
> + XMLParser parser = new XMLParser();
> + Script script = parser.parse(in);
> + script = script.compile();
> + log.debug("Found: " + script);
> + JellyContext context = new JellyContext();
> + StringWriter buffer = new StringWriter();
> + script.run(context, XMLOutput.createXMLOutput(buffer));
> + String text = buffer.toString().trim();
> + if (log.isDebugEnabled()) {
> + log.debug("Evaluated script as...");
> + log.debug(text);
> + }
> + assertEquals("Should produces the correct output",
> + "<blip xmlns:blop=\"blop\" blop:x=\"blip\"></blip>",
> + text);
> + }
> }
>
> Modified: jakarta/commons/proper/jelly/trunk/src/test/org/apache/commons/jelly/core/TestFileTag.java
> URL: http://svn.apache.org/viewcvs/jakarta/commons/proper/jelly/trunk/src/test/org/apache/commons/jelly/core/TestFileTag.java?rev=219726&r1=219725&r2=219726&view=diff
> ==============================================================================
> --- jakarta/commons/proper/jelly/trunk/src/test/org/apache/commons/jelly/core/TestFileTag.java (original)
> +++ jakarta/commons/proper/jelly/trunk/src/test/org/apache/commons/jelly/core/TestFileTag.java Tue Jul 19 10:34:00 2005
> @@ -55,7 +55,7 @@
>
> //FIXME This doesn't take into account attribute ordering
> assertEquals("fully qualified attributes not passed",
> - "<html xmlns=\"http://www.w3.org/1999/xhtml\" xml:lang=\"en\" lang=\"en\"></html>",
> + "<html xmlns=\"http://www.w3.org/1999/xhtml\" lang=\"en\" xml:lang=\"en\"></html>",
> data);
> }
>
>
> Added: jakarta/commons/proper/jelly/trunk/src/test/org/apache/commons/jelly/testStaticNamespacedAttributes.jelly
> URL: http://svn.apache.org/viewcvs/jakarta/commons/proper/jelly/trunk/src/test/org/apache/commons/jelly/testStaticNamespacedAttributes.jelly?rev=219726&view=auto
> ==============================================================================
> --- jakarta/commons/proper/jelly/trunk/src/test/org/apache/commons/jelly/testStaticNamespacedAttributes.jelly (added)
> +++ jakarta/commons/proper/jelly/trunk/src/test/org/apache/commons/jelly/testStaticNamespacedAttributes.jelly Tue Jul 19 10:34:00 2005
> @@ -0,0 +1,4 @@
> +<?xml version="1.0" encoding="utf-8" ?>
> +<j:jelly xmlns:j="jelly:core">
> + <blip xmlns:blop="blop" blop:x="blip"/>
> +</j:jelly>
>
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
> For additional commands, e-mail: commons-dev-help@jakarta.apache.org
>
>
--
http://www.multitask.com.au/people/dion/
"You are going to let the fear of poverty govern your life and your
reward will be that you will eat, but you will not live." - George
Bernard Shaw
---------------------------------------------------------------------
To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: commons-dev-help@jakarta.apache.org