Author: chinthaka
Date: Fri Apr 21 06:48:55 2006
New Revision: 395885
URL: http://svn.apache.org/viewcvs?rev=395885&view=rev
Log:
Fixing defaultNS handling in writing ns with our SerializerUtil. This had to be
done due to the non-standard way of ns handling by different XMLStreamReader
implementations
Modified:
webservices/commons/trunk/modules/axiom/src/org/apache/axiom/om/impl/builder/StAXOMBuilder.java
webservices/commons/trunk/modules/axiom/src/org/apache/axiom/om/impl/util/OMSerializerUtil.java
webservices/commons/trunk/modules/axiom/test/org/apache/axiom/om/NamespaceTest.java
Modified:
webservices/commons/trunk/modules/axiom/src/org/apache/axiom/om/impl/builder/StAXOMBuilder.java
URL:
http://svn.apache.org/viewcvs/webservices/commons/trunk/modules/axiom/src/org/apache/axiom/om/impl/builder/StAXOMBuilder.java?rev=395885&r1=395884&r2=395885&view=diff
==============================================================================
---
webservices/commons/trunk/modules/axiom/src/org/apache/axiom/om/impl/builder/StAXOMBuilder.java
(original)
+++
webservices/commons/trunk/modules/axiom/src/org/apache/axiom/om/impl/builder/StAXOMBuilder.java
Fri Apr 21 06:48:55 2006
@@ -343,7 +343,7 @@
//if the namespace is not defined already when we write the start
tag declare it
// check whether this is the default namespace and make sure we
have not declared that earlier
namespaceURIFromParser = parser.getNamespaceURI(i);
- if (nsprefix == null || "".equals(nsprefix)) {
+ if ("".equals(nsprefix) || nsprefix == null) {
node.declareDefaultNamespace(parser.getNamespaceURI(i));
} else {
node.declareNamespace(namespaceURIFromParser, nsprefix);
Modified:
webservices/commons/trunk/modules/axiom/src/org/apache/axiom/om/impl/util/OMSerializerUtil.java
URL:
http://svn.apache.org/viewcvs/webservices/commons/trunk/modules/axiom/src/org/apache/axiom/om/impl/util/OMSerializerUtil.java?rev=395885&r1=395884&r2=395885&view=diff
==============================================================================
---
webservices/commons/trunk/modules/axiom/src/org/apache/axiom/om/impl/util/OMSerializerUtil.java
(original)
+++
webservices/commons/trunk/modules/axiom/src/org/apache/axiom/om/impl/util/OMSerializerUtil.java
Fri Apr 21 06:48:55 2006
@@ -94,13 +94,22 @@
if (uri != null && !"".equals(uri)) {
String prefixFromWriter = writer.getPrefix(uri);
- // lets see whether we have default namespace now
- if (prefix != null && "".equals(prefix) && (prefixFromWriter ==
null || !prefix.equals(prefixFromWriter))) {
+
+ // Handling Default Namespaces First
+ // Case 1 :
+ // here we are trying define a default namespace. But has
this been defined in the current context.
+ // yes, there can be a default namespace, but it may have a
different URI. If its a different URI
+ // then explicitly define the default namespace here.
+ // Case 2 :
+ // The passed in namespace is a default ns, but there is a
non-default ns declared
+ // in the current scope.
+ if ( ("".equals(prefix) && "".equals(prefixFromWriter) &&
!uri.equals(writer.getNamespaceContext().getNamespaceURI(""))) ||
+ (prefix != null && "".equals(prefix) && (prefixFromWriter ==
null || !prefix.equals(prefixFromWriter)))){
// this has not been declared earlier
writer.writeDefaultNamespace(uri);
writer.setDefaultNamespace(uri);
} else {
- prefix = prefix == null ? getNextNSPrefix() : prefix;
+ prefix = prefix == null ? getNextNSPrefix(writer) : prefix;
if (prefix != null && !prefix.equals(prefixFromWriter)) {
writer.writeNamespace(prefix, uri);
writer.setPrefix(prefix, uri);
@@ -125,19 +134,75 @@
if (element.getNamespace() != null) {
nameSpaceName = element.getNamespace().getName();
prefix = element.getNamespace().getPrefix();
- if (nameSpaceName != null) {
+ if (nameSpaceName != null && !"".equals(nameSpaceName)) {
writer_prefix = writer.getPrefix(nameSpaceName);
- if (writer_prefix != null) {
- writer.writeStartElement(nameSpaceName,
- element.getLocalName());
- } else {
- prefix = (prefix == null) ? getNextNSPrefix() : prefix;
+
+ // if the writer has no prefix registered for the given
namespace, no matter what prefix the
+ // ns contains, use that to handle the ns
+ if (writer_prefix == null && !"".equals(prefix)) {
+ prefix = (prefix == null) ? getNextNSPrefix(writer) :
prefix;
writer.writeStartElement(prefix, element.getLocalName(),
nameSpaceName);
writer.writeNamespace(prefix, nameSpaceName);
writer.setPrefix(prefix, nameSpaceName);
-
+ } else if (prefix == null) {
+ // by this time prefix is null and writer_prefix is not
null
+ writer.writeStartElement(nameSpaceName,
+ element.getLocalName());
+ } else {
+ // now lets handle the case where (prefix != null &&
writer_prefix != null)
+ if ("".equals(prefix) && "".equals(writer_prefix)) {
+ // now this element is trying to use a default
namespace and at the same point
+ // exists a default namespace with the given ns URI.
+ // but the problem here is that, what if the xml is
like the following
+ // <One xmlns="one.org" >
+ // <Two xmlns="two.org">
+ // <Three xmlns="one.org" />
+ // </Two>
+ // </One>
+ //
+ // if we ask the prefix registered with one.org, the
parser will return ""
+ // which is the default ns. But if we do not declare a
new default ns explicitly here
+ // then this causes problem as element Two has already
overriden the default ns.
+ //
+ // Solution for this is to ask from the parser the
nsURI attached to "" at this
+ // moment and compare the return uri with namespace
name
+ if
(nameSpaceName.equals(writer.getNamespaceContext().getNamespaceURI("")))
+ {
+ writer.writeStartElement(nameSpaceName,
element.getLocalName());
+ } else {
+ writer.writeStartElement(prefix,
element.getLocalName(),
+ nameSpaceName);
+ writer.writeDefaultNamespace(nameSpaceName);
+ writer.setDefaultNamespace(nameSpaceName);
+ }
+ } else if (prefix.equals(writer_prefix)) {
+ writer.writeStartElement(nameSpaceName,
element.getLocalName());
+ } else if ("".equals(prefix)) {
+ writer.writeStartElement(prefix,
element.getLocalName(),
+ nameSpaceName);
+ writer.writeDefaultNamespace(nameSpaceName);
+ writer.setDefaultNamespace(nameSpaceName);
+ } else {
+ writer.writeStartElement(prefix,
element.getLocalName(),
+ nameSpaceName);
+ writer.writeNamespace(prefix, nameSpaceName);
+ writer.setPrefix(prefix, nameSpaceName);
+ }
}
+
+// if (writer_prefix != null) {
+// writer.writeStartElement(nameSpaceName,
+// element.getLocalName());
+// } else {
+// prefix = (prefix == null) ? getNextNSPrefix() : prefix;
+// writer.writeStartElement(prefix, element.getLocalName(),
+// nameSpaceName);
+// writer.writeNamespace(prefix, nameSpaceName);
+// writer.setPrefix(prefix, nameSpaceName);
+//
+// }
+
} else {
writer.writeStartElement(element.getLocalName());
}
@@ -235,5 +300,14 @@
public static String getNextNSPrefix() {
return "axis2ns" + ++nsCounter % Long.MAX_VALUE;
+ }
+
+ public static String getNextNSPrefix(XMLStreamWriter writer) {
+ String prefix = getNextNSPrefix();
+ while (writer.getNamespaceContext().getNamespaceURI(prefix) != null){
+ prefix = getNextNSPrefix();
+ }
+
+ return prefix;
}
}
Modified:
webservices/commons/trunk/modules/axiom/test/org/apache/axiom/om/NamespaceTest.java
URL:
http://svn.apache.org/viewcvs/webservices/commons/trunk/modules/axiom/test/org/apache/axiom/om/NamespaceTest.java?rev=395885&r1=395884&r2=395885&view=diff
==============================================================================
---
webservices/commons/trunk/modules/axiom/test/org/apache/axiom/om/NamespaceTest.java
(original)
+++
webservices/commons/trunk/modules/axiom/test/org/apache/axiom/om/NamespaceTest.java
Fri Apr 21 06:48:55 2006
@@ -5,6 +5,7 @@
import javax.xml.namespace.QName;
import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.stream.XMLStreamException;
import java.io.IOException;
import java.util.Iterator;
/*
@@ -72,6 +73,59 @@
OMNamespace namespace2 = elem.findNamespace("http://test2.org", null);
assertTrue(namespace2 != null && namespace2.getPrefix() != null &&
"".equals(namespace2.getPrefix()));
+ }
+
+ /**
+ * Here a namespace will be defined with a certain prefix in the root
element. But later the same ns
+ * is defined with the same uri in a child element, but this time with a
different prefix.
+ */
+ public void testNamespaceProblem() throws XMLStreamException {
+
+ /**
+ * <RootElement xmlns:ns1="http://ws.apache.org/axis2">
+ * <ns2:ChildElement xmlns:ns2="http://ws.apache.org/axis2"/>
+ * </RootElement>
+ *
+ */
+
+ OMFactory omFac = OMAbstractFactory.getOMFactory();
+
+ OMElement documentElement = omFac.createOMElement("RootElement", null);
+ documentElement.declareNamespace("http://ws.apache.org/axis2", "ns1");
+
+ OMNamespace ns = omFac.createOMNamespace("http://ws.apache.org/axis2",
"ns2");
+ omFac.createOMElement("ChildElement", ns, documentElement);
+
+
assertTrue(documentElement.toStringWithConsume().indexOf("ns2:ChildElement") >
-1);
+ }
+
+ public void testNamespaceProblem2() throws XMLStreamException {
+
+ /**
+ * <RootElement xmlns="http://one.org">
+ * <ns2:ChildElementOne xmlns:ns2="http://ws.apache.org/axis2"
xmlns="http://two.org">
+ * <ChildElementTwo xmlns="http://one.org" />
+ * </ns2:ChildElementOne>
+ * </RootElement>
+ */
+
+ OMFactory omFac = OMAbstractFactory.getOMFactory();
+
+ OMElement documentElement = omFac.createOMElement("RootElement", null);
+ documentElement.declareDefaultNamespace("http://one.org");
+
+ OMNamespace ns = omFac.createOMNamespace("http://ws.apache.org/axis2",
"ns2");
+ OMElement childOne = omFac.createOMElement("ChildElementOne", ns,
documentElement);
+ childOne.declareDefaultNamespace("http://two.org");
+
+ OMElement childTwo = omFac.createOMElement("ChildElementTwo", null,
childOne);
+ childTwo.declareDefaultNamespace("http://one.org");
+
+ StringBuffer element = new
StringBuffer(documentElement.toStringWithConsume());
+
+ int firstIndex = element.indexOf("xmlns=\"http://one.org\"");
+ assertTrue(firstIndex > -1);
+ assertTrue(element.lastIndexOf("xmlns=\"http://one.org\"") !=
firstIndex);
}