Author: dims
Date: Wed Jan 31 19:06:46 2007
New Revision: 502094
URL: http://svn.apache.org/viewvc?view=rev&rev=502094
Log:
Fix for WSCOMMONS-160 - StAXOMBuilder is stripping off namspace prefix's from
attributes that need namespace qualification
Modified:
webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/om/impl/util/OMSerializerUtil.java
webservices/commons/trunk/modules/axiom/modules/axiom-tests/src/test/java/org/apache/axiom/om/AttrNsTest.java
Modified:
webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/om/impl/util/OMSerializerUtil.java
URL:
http://svn.apache.org/viewvc/webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/om/impl/util/OMSerializerUtil.java?view=diff&rev=502094&r1=502093&r2=502094
==============================================================================
---
webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/om/impl/util/OMSerializerUtil.java
(original)
+++
webservices/commons/trunk/modules/axiom/modules/axiom-api/src/main/java/org/apache/axiom/om/impl/util/OMSerializerUtil.java
Wed Jan 31 19:06:46 2007
@@ -1,534 +1,536 @@
-/*
- * Copyright 2004,2005 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.axiom.om.impl.util;
-
-import org.apache.axiom.om.OMAttribute;
-import org.apache.axiom.om.OMElement;
-import org.apache.axiom.om.OMNamespace;
-import org.apache.axiom.om.OMNode;
-import org.apache.axiom.om.impl.OMNodeEx;
-import org.apache.axiom.om.impl.serialize.StreamingOMSerializer;
-
-import javax.xml.namespace.NamespaceContext;
-import javax.xml.stream.XMLStreamException;
-import javax.xml.stream.XMLStreamReader;
-import javax.xml.stream.XMLStreamWriter;
-import java.util.ArrayList;
-import java.util.Iterator;
-
-public class OMSerializerUtil {
-
- static long nsCounter = 0;
-
- /**
- * Method serializeEndpart.
- *
- * @param writer
- * @throws javax.xml.stream.XMLStreamException
- *
- */
- public static void serializeEndpart(XMLStreamWriter writer)
- throws XMLStreamException {
- writer.writeEndElement();
- }
-
- /**
- * Method serializeAttribute.
- *
- * @param attr
- * @param writer
- * @throws XMLStreamException
- * @deprecated use serializeStartpart instead
- */
- public static void serializeAttribute(OMAttribute attr, XMLStreamWriter
writer)
- throws XMLStreamException {
-
- // first check whether the attribute is associated with a namespace
- OMNamespace ns = attr.getNamespace();
- String prefix = null;
- String namespaceName = null;
- if (ns != null) {
-
- // add the prefix if it's availble
- prefix = ns.getPrefix();
- namespaceName = ns.getNamespaceURI();
- if (prefix != null) {
- writer.writeAttribute(prefix, namespaceName,
- attr.getLocalName(), attr.getAttributeValue());
- } else {
- writer.writeAttribute(namespaceName, attr.getLocalName(),
- attr.getAttributeValue());
- }
- } else {
- String localName = attr.getLocalName();
- String attributeValue = attr.getAttributeValue();
- writer.writeAttribute(localName, attributeValue);
- }
- }
-
- /**
- * Method serializeNamespace.
- *
- * @param namespace
- * @param writer
- * @throws XMLStreamException
- * @deprecated Use serializeStartpart instead
- */
- public static void serializeNamespace(OMNamespace namespace,
XMLStreamWriter writer)
- throws XMLStreamException {
- if (namespace == null) {
- return;
- }
- String uri = namespace.getNamespaceURI();
- String prefix = namespace.getPrefix();
-
- if (uri != null && !"".equals(uri)) {
- String prefixFromWriter = writer.getPrefix(uri);
-
- // 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(writer) : prefix;
- if (prefix != null && !prefix.equals(prefixFromWriter) &&
!checkForPrefixInTheCurrentContext(writer, uri, prefix))
- {
- writer.writeNamespace(prefix, uri);
- writer.setPrefix(prefix, uri);
- }
- }
- } else {
- // now the nsURI passed is "" or null. Meaning we gonna work with
defaultNS.
- // check whether there is a defaultNS already declared. If yes, is
it the same as this ?
- String currentDefaultNSURI =
writer.getNamespaceContext().getNamespaceURI("");
- if( (currentDefaultNSURI != null &&
!currentDefaultNSURI.equals(uri)) ||
- uri != null && !uri.equals(currentDefaultNSURI)){
- // this has not been declared earlier
- writer.writeDefaultNamespace(uri);
- writer.setDefaultNamespace(uri);
- }
- }
- }
-
- /**
- * Unfortunately there is disagreement in the user community about the
semantics of
- * setPrefix on the XMLStreamWriter. An example will explain the
difference:
- * writer.startElement("a")
- * writer.setPrefix("pre", "urn://sample")
- * writer.startElement("b")
- *
- * Some user communities (woodstox) believe that the setPrefix is
associate with the scope
- * for "a" and thus remains in scope until the end of a. The basis for
this believe is
- * XMLStreamWriter javadoc (which some would argue is incomplete).
- *
- * Some user communities believe that the setPrefix is associated with the
"b" element.
- * These communities reference an example in the specification and
historical usage of SAX.
- *
- * This method will return true if the setPrefix is associated with the
next writeStartElement.
- *
- * @param writer
- * @return true if setPrefix should be generated before startElement
- */
- public static boolean isSetPrefixBeforeStartElement(XMLStreamWriter
writer) {
- NamespaceContext nc = writer.getNamespaceContext();
- return(nc ==null || nc.getClass().getName().indexOf("wstx") == -1);
- }
-
- /**
- * Method serializeStartpart.
- * Serialize the start tag of an element.
- *
- * @param element
- * @param writer
- * @throws XMLStreamException
- */
- public static void serializeStartpart(OMElement element,
- XMLStreamWriter writer) throws XMLStreamException {
- serializeStartpart(element, element.getLocalName(), writer);
- }
-
- /**
- * Method serializeStartpart.
- * Serialize the start tag of an element.
- *
- * @param element
- * @param localName (in some cases, the caller wants to force a different
localName)
- * @param writer
- * @throws XMLStreamException
- */
- public static void serializeStartpart(OMElement element, String localName,
XMLStreamWriter writer)
- throws XMLStreamException {
-
- // Note: To serialize the start tag, we must follow the order dictated
by the JSR-173 (StAX) specification.
- // Please keep this code in sync with the code in
StreamingOMSerializer.serializeElement
-
- // The algorithm is:
- // ... generate setPrefix/setDefaultNamespace for each namespace
declaration if the prefix is unassociated.
- // ... generate setPrefix/setDefaultNamespace if the prefix of the
element is unassociated
- // ... generate setPrefix/setDefaultNamespace for each unassociated
prefix of the attributes.
- //
- // ... generate writeStartElement (See NOTE_A)
- //
- // ... generate writeNamespace/writerDefaultNamespace for the new
namespace declarations determine during the "set" processing
- // ... generate writeAttribute for each attribute
-
- // NOTE_A: To confuse matters, some StAX vendors (including woodstox),
believe that the setPrefix bindings
- // should occur after the writeStartElement. If this is the case, the
writeStartElement is generated first.
-
- ArrayList writePrefixList = null;
- ArrayList writeNSList = null;
-
- // Get the namespace and prefix of the element
- OMNamespace eOMNamespace = element.getNamespace();
- String ePrefix = null;
- String eNamespace = null;
- if (eOMNamespace != null) {
- ePrefix = eOMNamespace.getPrefix();
- eNamespace = eOMNamespace.getNamespaceURI();
- }
- ePrefix = (ePrefix != null && ePrefix.length() == 0) ? null :
ePrefix;
- eNamespace = (eNamespace != null && eNamespace.length() == 0) ?
null : eNamespace;
-
- // Write the startElement if required
- boolean setPrefixFirst = isSetPrefixBeforeStartElement(writer);
- if (!setPrefixFirst) {
- if (eNamespace != null) {
- if (ePrefix == null) {
- writer.writeStartElement("", localName,
eNamespace);
- } else {
- writer.writeStartElement(ePrefix, localName,
eNamespace);
- }
- } else {
- writer.writeStartElement(localName);
- }
- }
-
- // Generate setPrefix for the namespace declarations
- Iterator it = element.getAllDeclaredNamespaces();
- while (it != null && it.hasNext()) {
- OMNamespace omNamespace = (OMNamespace) it.next();
- String prefix = null;
- String namespace = null;
- if (omNamespace != null) {
- prefix = omNamespace.getPrefix();
- namespace = omNamespace.getNamespaceURI();
- }
- prefix = (prefix != null && prefix.length() == 0) ? null :
prefix;
- namespace = (namespace != null && namespace.length() == 0) ?
null : namespace;
-
-
- String newPrefix = generateSetPrefix(prefix, namespace, writer,
false);
- // If this is a new association, remember it so that it can
written out later
- if (newPrefix != null) {
- if (writePrefixList == null) {
- writePrefixList= new ArrayList();
- writeNSList = new ArrayList();
- }
- if (!writePrefixList.contains(newPrefix)) {
- writePrefixList.add(newPrefix);
- writeNSList.add(namespace);
- }
- }
- }
-
- // Generate setPrefix for the element
- // Get the prefix and namespace of the element. "" and null are
identical.
- String newPrefix = generateSetPrefix(ePrefix, eNamespace, writer,
false);
- // If this is a new association, remember it so that it can written out
later
- if (newPrefix != null) {
- if (writePrefixList == null) {
- writePrefixList= new ArrayList();
- writeNSList = new ArrayList();
- }
- if (!writePrefixList.contains(newPrefix)) {
- writePrefixList.add(newPrefix);
- writeNSList.add(eNamespace);
- }
- }
-
- // Now Generate setPrefix for each attribute
- Iterator attrs = element.getAllAttributes();
- while (attrs != null && attrs.hasNext()) {
- OMAttribute attr = (OMAttribute) attrs.next();
- OMNamespace omNamespace = attr.getNamespace();
- String prefix = null;
- String namespace = null;
- if (omNamespace != null) {
- prefix = omNamespace.getPrefix();
- namespace = omNamespace.getNamespaceURI();
- }
- prefix = (prefix != null && prefix.length() == 0) ? null :
prefix;
- namespace = (namespace != null && namespace.length() == 0) ?
null : namespace;
-
- // Default prefix referencing is not allowed on an attribute
- if (prefix == null && namespace != null) {
- String writerPrefix = writer.getPrefix(namespace);
- writerPrefix = (writerPrefix != null && writerPrefix.length()
== 0) ? null : writerPrefix;
- prefix = (writerPrefix != null) ?
- writerPrefix : getNextNSPrefix();
- }
- newPrefix = generateSetPrefix(prefix, namespace, writer, true);
- // If the prefix is not associated with a namespace yet, remember
it so that we can
- // write out a namespace declaration
- if (newPrefix != null) {
- if (writePrefixList == null) {
- writePrefixList= new ArrayList();
- writeNSList = new ArrayList();
- }
- if (!writePrefixList.contains(newPrefix)) {
- writePrefixList.add(newPrefix);
- writeNSList.add(namespace);
- }
- }
- }
-
- // Write the startElement if required
- if (setPrefixFirst) {
- if (eNamespace != null) {
- if (ePrefix == null) {
- writer.writeStartElement("", localName,
eNamespace);
- } else {
- writer.writeStartElement(ePrefix, localName,
eNamespace);
- }
- } else {
- writer.writeStartElement(localName);
- }
- }
-
- // Now write out the list of namespace declarations in this list that
we constructed
- // while doing the "set" processing.
- if (writePrefixList != null) {
- for (int i=0; i<writePrefixList.size(); i++) {
- String prefix = (String) writePrefixList.get(i);
- String namespace = (String) writeNSList.get(i);
- if (prefix != null) {
- if(namespace==null){
- writer.writeNamespace(prefix, "");
- } else{
- writer.writeNamespace(prefix, namespace);
- }
- } else {
- writer.writeDefaultNamespace(namespace);
- }
- }
- }
-
- // Now write the attributes
- attrs = element.getAllAttributes();
- while (attrs != null && attrs.hasNext()) {
- OMAttribute attr = (OMAttribute) attrs.next();
- OMNamespace omNamespace = attr.getNamespace();
- String prefix = null;
- String namespace = null;
- if (omNamespace != null) {
- prefix = omNamespace.getPrefix();
- namespace = omNamespace.getNamespaceURI();
- }
- prefix = (prefix != null && prefix.length() == 0) ? null :
prefix;
- namespace = (namespace != null && namespace.length() == 0) ?
null : namespace;
-
- if (prefix == null && namespace != null) {
- // Default namespaces are not allowed on an attribute reference.
- // Earlier in this code, a unique prefix was added for this
case...now obtain and use it
- prefix = writer.getPrefix(namespace);
- } else if (namespace != null) {
- // Use the writer's prefix if it is different
- String writerPrefix = writer.getPrefix(namespace);
- if (!prefix.equals(writerPrefix)) {
- prefix = writerPrefix;
- }
- }
- if (namespace != null) {
- // Qualified attribute
- writer.writeAttribute(prefix, namespace,
- attr.getLocalName(),
- attr.getAttributeValue());
- } else {
- // Unqualified attribute
- writer.writeAttribute(attr.getLocalName(),
- attr.getAttributeValue());
- }
- }
- }
-
- private static boolean checkForPrefixInTheCurrentContext(XMLStreamWriter
writer, String nameSpaceName, String prefix) throws XMLStreamException {
- Iterator prefixesIter =
writer.getNamespaceContext().getPrefixes(nameSpaceName);
- while (prefixesIter.hasNext()) {
- String prefix_w = (String) prefixesIter.next();
- if (prefix_w.equals(prefix)) {
- // if found do not declare the ns
- return true;
- }
- }
- return false;
- }
-
- /**
- * serializeNamespaces
- *
- * @param element
- * @param writer
- * @throws XMLStreamException
- * @deprecated Use serializeStartpart instead
- */
- public static void serializeNamespaces
- (OMElement
- element,
- XMLStreamWriter writer) throws XMLStreamException {
- Iterator namespaces = element.getAllDeclaredNamespaces();
- if (namespaces != null) {
- while (namespaces.hasNext()) {
- serializeNamespace((OMNamespace) namespaces.next(), writer);
- }
- }
- }
-
- /**
- * Serialize attributes
- * @param element
- * @param writer
- * @throws XMLStreamException
- * @deprecated Consider using serializeStartpart instead
- */
- public static void serializeAttributes
- (OMElement
- element,
- XMLStreamWriter writer) throws XMLStreamException {
- Iterator attributes = element.getAllAttributes();
- if (attributes != null && attributes.hasNext()) {
- while (attributes.hasNext()) {
- serializeAttribute((OMAttribute) attributes.next(),
- writer);
- }
- }
- }
-
- /**
- * Method serializeNormal.
- *
- * @param writer
- * @param cache
- * @throws XMLStreamException
- */
- public static void serializeNormal
- (OMElement
- element, XMLStreamWriter writer, boolean cache)
- throws XMLStreamException {
-
- if (cache) {
- element.build();
- }
-
- serializeStartpart(element, writer);
- OMNode firstChild = element.getFirstOMChild();
- if (firstChild != null) {
- if (cache) {
- (firstChild).serialize(writer);
- } else {
- (firstChild).serializeAndConsume(writer);
- }
- }
- serializeEndpart(writer);
- }
-
- public static void serializeByPullStream
- (OMElement
- element, XMLStreamWriter writer) throws XMLStreamException
{
- serializeByPullStream(element, writer, false);
- }
-
- public static void serializeByPullStream
- (OMElement
- element, XMLStreamWriter writer, boolean cache) throws
XMLStreamException {
- StreamingOMSerializer streamingOMSerializer = new
StreamingOMSerializer();
- if (cache) {
- streamingOMSerializer.serialize(element.getXMLStreamReader(),
- writer);
- } else {
- XMLStreamReader xmlStreamReaderWithoutCaching =
element.getXMLStreamReaderWithoutCaching();
- streamingOMSerializer.serialize(xmlStreamReaderWithoutCaching,
- writer);
- }
- }
-
- 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;
- }
-
- /**
- * Generate setPrefix/setDefaultNamespace if the prefix is not associated
- * @param prefix
- * @param namespace
- * @param writer
- * @param attr
- * @return prefix name if a setPrefix/setDefaultNamespace is performed
- */
- public static String generateSetPrefix(String prefix, String namespace,
XMLStreamWriter writer, boolean attr) throws XMLStreamException {
- // Generate setPrefix/setDefaultNamespace if the prefix is not
associated.
- String newPrefix = null;
- if (namespace != null) {
- // Qualified Namespace
-
- // Get the namespace associated with this writer
- String writerNS =
writer.getNamespaceContext().getNamespaceURI((prefix==null) ? "" : prefix);
- writerNS = (writerNS != null && writerNS.length() == 0) ? null
: writerNS;
-
- if (writerNS == null || !writerNS.equals(namespace)) {
- // Writer has not associated this namespace with a
prefix
- if (prefix == null) {
- writer.setDefaultNamespace(namespace);
- newPrefix = "";
- } else {
- writer.setPrefix(prefix, namespace);
- newPrefix = prefix;
- }
- } else {
- // No Action needed..The writer already has associated
this prefix to this namespace
- }
- } else {
- // Unqualified Namespace
-
- // Make sure the default namespace is either not used or
disabled (set to "")
- String writerNS =
writer.getNamespaceContext().getNamespaceURI("");
- if (writerNS != null && writerNS.length() > 0 && !attr) {
- // Disable the default namespace
- writer.setDefaultNamespace("");
- newPrefix = "";
- }
- }
- return newPrefix;
- }
-}
+/*
+ * Copyright 2004,2005 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.axiom.om.impl.util;
+
+import org.apache.axiom.om.OMAttribute;
+import org.apache.axiom.om.OMElement;
+import org.apache.axiom.om.OMNamespace;
+import org.apache.axiom.om.OMNode;
+import org.apache.axiom.om.impl.OMNodeEx;
+import org.apache.axiom.om.impl.serialize.StreamingOMSerializer;
+
+import javax.xml.namespace.NamespaceContext;
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.XMLStreamReader;
+import javax.xml.stream.XMLStreamWriter;
+import java.util.ArrayList;
+import java.util.Iterator;
+
+public class OMSerializerUtil {
+
+ static long nsCounter = 0;
+
+ /**
+ * Method serializeEndpart.
+ *
+ * @param writer
+ * @throws javax.xml.stream.XMLStreamException
+ *
+ */
+ public static void serializeEndpart(XMLStreamWriter writer)
+ throws XMLStreamException {
+ writer.writeEndElement();
+ }
+
+ /**
+ * Method serializeAttribute.
+ *
+ * @param attr
+ * @param writer
+ * @throws XMLStreamException
+ * @deprecated use serializeStartpart instead
+ */
+ public static void serializeAttribute(OMAttribute attr, XMLStreamWriter
writer)
+ throws XMLStreamException {
+
+ // first check whether the attribute is associated with a namespace
+ OMNamespace ns = attr.getNamespace();
+ String prefix = null;
+ String namespaceName = null;
+ if (ns != null) {
+
+ // add the prefix if it's availble
+ prefix = ns.getPrefix();
+ namespaceName = ns.getNamespaceURI();
+ if (prefix != null) {
+ writer.writeAttribute(prefix, namespaceName,
+ attr.getLocalName(), attr.getAttributeValue());
+ } else {
+ writer.writeAttribute(namespaceName, attr.getLocalName(),
+ attr.getAttributeValue());
+ }
+ } else {
+ String localName = attr.getLocalName();
+ String attributeValue = attr.getAttributeValue();
+ writer.writeAttribute(localName, attributeValue);
+ }
+ }
+
+ /**
+ * Method serializeNamespace.
+ *
+ * @param namespace
+ * @param writer
+ * @throws XMLStreamException
+ * @deprecated Use serializeStartpart instead
+ */
+ public static void serializeNamespace(OMNamespace namespace,
XMLStreamWriter writer)
+ throws XMLStreamException {
+ if (namespace == null) {
+ return;
+ }
+ String uri = namespace.getNamespaceURI();
+ String prefix = namespace.getPrefix();
+
+ if (uri != null && !"".equals(uri)) {
+ String prefixFromWriter = writer.getPrefix(uri);
+
+ // 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(writer) : prefix;
+ if (prefix != null && !prefix.equals(prefixFromWriter) &&
!checkForPrefixInTheCurrentContext(writer, uri, prefix))
+ {
+ writer.writeNamespace(prefix, uri);
+ writer.setPrefix(prefix, uri);
+ }
+ }
+ } else {
+ // now the nsURI passed is "" or null. Meaning we gonna work with
defaultNS.
+ // check whether there is a defaultNS already declared. If yes, is
it the same as this ?
+ String currentDefaultNSURI =
writer.getNamespaceContext().getNamespaceURI("");
+ if( (currentDefaultNSURI != null &&
!currentDefaultNSURI.equals(uri)) ||
+ uri != null && !uri.equals(currentDefaultNSURI)){
+ // this has not been declared earlier
+ writer.writeDefaultNamespace(uri);
+ writer.setDefaultNamespace(uri);
+ }
+ }
+ }
+
+ /**
+ * Unfortunately there is disagreement in the user community about the
semantics of
+ * setPrefix on the XMLStreamWriter. An example will explain the
difference:
+ * writer.startElement("a")
+ * writer.setPrefix("pre", "urn://sample")
+ * writer.startElement("b")
+ *
+ * Some user communities (woodstox) believe that the setPrefix is
associate with the scope
+ * for "a" and thus remains in scope until the end of a. The basis for
this believe is
+ * XMLStreamWriter javadoc (which some would argue is incomplete).
+ *
+ * Some user communities believe that the setPrefix is associated with the
"b" element.
+ * These communities reference an example in the specification and
historical usage of SAX.
+ *
+ * This method will return true if the setPrefix is associated with the
next writeStartElement.
+ *
+ * @param writer
+ * @return true if setPrefix should be generated before startElement
+ */
+ public static boolean isSetPrefixBeforeStartElement(XMLStreamWriter
writer) {
+ NamespaceContext nc = writer.getNamespaceContext();
+ return(nc ==null || nc.getClass().getName().indexOf("wstx") == -1);
+ }
+
+ /**
+ * Method serializeStartpart.
+ * Serialize the start tag of an element.
+ *
+ * @param element
+ * @param writer
+ * @throws XMLStreamException
+ */
+ public static void serializeStartpart(OMElement element,
+ XMLStreamWriter writer) throws XMLStreamException {
+ serializeStartpart(element, element.getLocalName(), writer);
+ }
+
+ /**
+ * Method serializeStartpart.
+ * Serialize the start tag of an element.
+ *
+ * @param element
+ * @param localName (in some cases, the caller wants to force a different
localName)
+ * @param writer
+ * @throws XMLStreamException
+ */
+ public static void serializeStartpart(OMElement element, String localName,
XMLStreamWriter writer)
+ throws XMLStreamException {
+
+ // Note: To serialize the start tag, we must follow the order dictated
by the JSR-173 (StAX) specification.
+ // Please keep this code in sync with the code in
StreamingOMSerializer.serializeElement
+
+ // The algorithm is:
+ // ... generate setPrefix/setDefaultNamespace for each namespace
declaration if the prefix is unassociated.
+ // ... generate setPrefix/setDefaultNamespace if the prefix of the
element is unassociated
+ // ... generate setPrefix/setDefaultNamespace for each unassociated
prefix of the attributes.
+ //
+ // ... generate writeStartElement (See NOTE_A)
+ //
+ // ... generate writeNamespace/writerDefaultNamespace for the new
namespace declarations determine during the "set" processing
+ // ... generate writeAttribute for each attribute
+
+ // NOTE_A: To confuse matters, some StAX vendors (including woodstox),
believe that the setPrefix bindings
+ // should occur after the writeStartElement. If this is the case, the
writeStartElement is generated first.
+
+ ArrayList writePrefixList = null;
+ ArrayList writeNSList = null;
+
+ // Get the namespace and prefix of the element
+ OMNamespace eOMNamespace = element.getNamespace();
+ String ePrefix = null;
+ String eNamespace = null;
+ if (eOMNamespace != null) {
+ ePrefix = eOMNamespace.getPrefix();
+ eNamespace = eOMNamespace.getNamespaceURI();
+ }
+ ePrefix = (ePrefix != null && ePrefix.length() == 0) ? null :
ePrefix;
+ eNamespace = (eNamespace != null && eNamespace.length() == 0) ?
null : eNamespace;
+
+ // Write the startElement if required
+ boolean setPrefixFirst = isSetPrefixBeforeStartElement(writer);
+ if (!setPrefixFirst) {
+ if (eNamespace != null) {
+ if (ePrefix == null) {
+ writer.writeStartElement("", localName,
eNamespace);
+ } else {
+ writer.writeStartElement(ePrefix, localName,
eNamespace);
+ }
+ } else {
+ writer.writeStartElement(localName);
+ }
+ }
+
+ // Generate setPrefix for the namespace declarations
+ Iterator it = element.getAllDeclaredNamespaces();
+ while (it != null && it.hasNext()) {
+ OMNamespace omNamespace = (OMNamespace) it.next();
+ String prefix = null;
+ String namespace = null;
+ if (omNamespace != null) {
+ prefix = omNamespace.getPrefix();
+ namespace = omNamespace.getNamespaceURI();
+ }
+ prefix = (prefix != null && prefix.length() == 0) ? null :
prefix;
+ namespace = (namespace != null && namespace.length() == 0) ?
null : namespace;
+
+
+ String newPrefix = generateSetPrefix(prefix, namespace, writer,
false);
+ // If this is a new association, remember it so that it can
written out later
+ if (newPrefix != null) {
+ if (writePrefixList == null) {
+ writePrefixList= new ArrayList();
+ writeNSList = new ArrayList();
+ }
+ if (!writePrefixList.contains(newPrefix)) {
+ writePrefixList.add(newPrefix);
+ writeNSList.add(namespace);
+ }
+ }
+ }
+
+ // Generate setPrefix for the element
+ // Get the prefix and namespace of the element. "" and null are
identical.
+ String newPrefix = generateSetPrefix(ePrefix, eNamespace, writer,
false);
+ // If this is a new association, remember it so that it can written out
later
+ if (newPrefix != null) {
+ if (writePrefixList == null) {
+ writePrefixList= new ArrayList();
+ writeNSList = new ArrayList();
+ }
+ if (!writePrefixList.contains(newPrefix)) {
+ writePrefixList.add(newPrefix);
+ writeNSList.add(eNamespace);
+ }
+ }
+
+ // Now Generate setPrefix for each attribute
+ Iterator attrs = element.getAllAttributes();
+ while (attrs != null && attrs.hasNext()) {
+ OMAttribute attr = (OMAttribute) attrs.next();
+ OMNamespace omNamespace = attr.getNamespace();
+ String prefix = null;
+ String namespace = null;
+ if (omNamespace != null) {
+ prefix = omNamespace.getPrefix();
+ namespace = omNamespace.getNamespaceURI();
+ }
+ prefix = (prefix != null && prefix.length() == 0) ? null :
prefix;
+ namespace = (namespace != null && namespace.length() == 0) ?
null : namespace;
+
+ // Default prefix referencing is not allowed on an attribute
+ if (prefix == null && namespace != null) {
+ String writerPrefix = writer.getPrefix(namespace);
+ writerPrefix = (writerPrefix != null && writerPrefix.length()
== 0) ? null : writerPrefix;
+ prefix = (writerPrefix != null) ?
+ writerPrefix : getNextNSPrefix();
+ }
+ newPrefix = generateSetPrefix(prefix, namespace, writer, true);
+ // If the prefix is not associated with a namespace yet, remember
it so that we can
+ // write out a namespace declaration
+ if (newPrefix != null) {
+ if (writePrefixList == null) {
+ writePrefixList= new ArrayList();
+ writeNSList = new ArrayList();
+ }
+ if (!writePrefixList.contains(newPrefix)) {
+ writePrefixList.add(newPrefix);
+ writeNSList.add(namespace);
+ }
+ }
+ }
+
+ // Write the startElement if required
+ if (setPrefixFirst) {
+ if (eNamespace != null) {
+ if (ePrefix == null) {
+ writer.writeStartElement("", localName,
eNamespace);
+ } else {
+ writer.writeStartElement(ePrefix, localName,
eNamespace);
+ }
+ } else {
+ writer.writeStartElement(localName);
+ }
+ }
+
+ // Now write out the list of namespace declarations in this list that
we constructed
+ // while doing the "set" processing.
+ if (writePrefixList != null) {
+ for (int i=0; i<writePrefixList.size(); i++) {
+ String prefix = (String) writePrefixList.get(i);
+ String namespace = (String) writeNSList.get(i);
+ if (prefix != null) {
+ if(namespace==null){
+ writer.writeNamespace(prefix, "");
+ } else{
+ writer.writeNamespace(prefix, namespace);
+ }
+ } else {
+ writer.writeDefaultNamespace(namespace);
+ }
+ }
+ }
+
+ // Now write the attributes
+ attrs = element.getAllAttributes();
+ while (attrs != null && attrs.hasNext()) {
+ OMAttribute attr = (OMAttribute) attrs.next();
+ OMNamespace omNamespace = attr.getNamespace();
+ String prefix = null;
+ String namespace = null;
+ if (omNamespace != null) {
+ prefix = omNamespace.getPrefix();
+ namespace = omNamespace.getNamespaceURI();
+ }
+ prefix = (prefix != null && prefix.length() == 0) ? null :
prefix;
+ namespace = (namespace != null && namespace.length() == 0) ?
null : namespace;
+
+ if (prefix == null && namespace != null) {
+ // Default namespaces are not allowed on an attribute reference.
+ // Earlier in this code, a unique prefix was added for this
case...now obtain and use it
+ prefix = writer.getPrefix(namespace);
+ } else if (namespace != null) {
+ // Use the writer's prefix if it is different, but if the
writers
+ // prefix is empty then do not replace because attributes do
not
+ // default to the default namespace like elements do.
+ String writerPrefix = writer.getPrefix(namespace);
+ if (!prefix.equals(writerPrefix) && !"".equals(writerPrefix)) {
+ prefix = writerPrefix;
+ }
+ }
+ if (namespace != null) {
+ // Qualified attribute
+ writer.writeAttribute(prefix, namespace,
+ attr.getLocalName(),
+ attr.getAttributeValue());
+ } else {
+ // Unqualified attribute
+ writer.writeAttribute(attr.getLocalName(),
+ attr.getAttributeValue());
+ }
+ }
+ }
+
+ private static boolean checkForPrefixInTheCurrentContext(XMLStreamWriter
writer, String nameSpaceName, String prefix) throws XMLStreamException {
+ Iterator prefixesIter =
writer.getNamespaceContext().getPrefixes(nameSpaceName);
+ while (prefixesIter.hasNext()) {
+ String prefix_w = (String) prefixesIter.next();
+ if (prefix_w.equals(prefix)) {
+ // if found do not declare the ns
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * serializeNamespaces
+ *
+ * @param element
+ * @param writer
+ * @throws XMLStreamException
+ * @deprecated Use serializeStartpart instead
+ */
+ public static void serializeNamespaces
+ (OMElement
+ element,
+ XMLStreamWriter writer) throws XMLStreamException {
+ Iterator namespaces = element.getAllDeclaredNamespaces();
+ if (namespaces != null) {
+ while (namespaces.hasNext()) {
+ serializeNamespace((OMNamespace) namespaces.next(), writer);
+ }
+ }
+ }
+
+ /**
+ * Serialize attributes
+ * @param element
+ * @param writer
+ * @throws XMLStreamException
+ * @deprecated Consider using serializeStartpart instead
+ */
+ public static void serializeAttributes
+ (OMElement
+ element,
+ XMLStreamWriter writer) throws XMLStreamException {
+ Iterator attributes = element.getAllAttributes();
+ if (attributes != null && attributes.hasNext()) {
+ while (attributes.hasNext()) {
+ serializeAttribute((OMAttribute) attributes.next(),
+ writer);
+ }
+ }
+ }
+
+ /**
+ * Method serializeNormal.
+ *
+ * @param writer
+ * @param cache
+ * @throws XMLStreamException
+ */
+ public static void serializeNormal
+ (OMElement
+ element, XMLStreamWriter writer, boolean cache)
+ throws XMLStreamException {
+
+ if (cache) {
+ element.build();
+ }
+
+ serializeStartpart(element, writer);
+ OMNode firstChild = element.getFirstOMChild();
+ if (firstChild != null) {
+ if (cache) {
+ (firstChild).serialize(writer);
+ } else {
+ (firstChild).serializeAndConsume(writer);
+ }
+ }
+ serializeEndpart(writer);
+ }
+
+ public static void serializeByPullStream
+ (OMElement
+ element, XMLStreamWriter writer) throws XMLStreamException
{
+ serializeByPullStream(element, writer, false);
+ }
+
+ public static void serializeByPullStream
+ (OMElement
+ element, XMLStreamWriter writer, boolean cache) throws
XMLStreamException {
+ StreamingOMSerializer streamingOMSerializer = new
StreamingOMSerializer();
+ if (cache) {
+ streamingOMSerializer.serialize(element.getXMLStreamReader(),
+ writer);
+ } else {
+ XMLStreamReader xmlStreamReaderWithoutCaching =
element.getXMLStreamReaderWithoutCaching();
+ streamingOMSerializer.serialize(xmlStreamReaderWithoutCaching,
+ writer);
+ }
+ }
+
+ 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;
+ }
+
+ /**
+ * Generate setPrefix/setDefaultNamespace if the prefix is not associated
+ * @param prefix
+ * @param namespace
+ * @param writer
+ * @param attr
+ * @return prefix name if a setPrefix/setDefaultNamespace is performed
+ */
+ public static String generateSetPrefix(String prefix, String namespace,
XMLStreamWriter writer, boolean attr) throws XMLStreamException {
+ // Generate setPrefix/setDefaultNamespace if the prefix is not
associated.
+ String newPrefix = null;
+ if (namespace != null) {
+ // Qualified Namespace
+
+ // Get the namespace associated with this writer
+ String writerNS =
writer.getNamespaceContext().getNamespaceURI((prefix==null) ? "" : prefix);
+ writerNS = (writerNS != null && writerNS.length() == 0) ? null
: writerNS;
+
+ if (writerNS == null || !writerNS.equals(namespace)) {
+ // Writer has not associated this namespace with a
prefix
+ if (prefix == null) {
+ writer.setDefaultNamespace(namespace);
+ newPrefix = "";
+ } else {
+ writer.setPrefix(prefix, namespace);
+ newPrefix = prefix;
+ }
+ } else {
+ // No Action needed..The writer already has associated
this prefix to this namespace
+ }
+ } else {
+ // Unqualified Namespace
+
+ // Make sure the default namespace is either not used or
disabled (set to "")
+ String writerNS =
writer.getNamespaceContext().getNamespaceURI("");
+ if (writerNS != null && writerNS.length() > 0 && !attr) {
+ // Disable the default namespace
+ writer.setDefaultNamespace("");
+ newPrefix = "";
+ }
+ }
+ return newPrefix;
+ }
+}
Modified:
webservices/commons/trunk/modules/axiom/modules/axiom-tests/src/test/java/org/apache/axiom/om/AttrNsTest.java
URL:
http://svn.apache.org/viewvc/webservices/commons/trunk/modules/axiom/modules/axiom-tests/src/test/java/org/apache/axiom/om/AttrNsTest.java?view=diff&rev=502094&r1=502093&r2=502094
==============================================================================
---
webservices/commons/trunk/modules/axiom/modules/axiom-tests/src/test/java/org/apache/axiom/om/AttrNsTest.java
(original)
+++
webservices/commons/trunk/modules/axiom/modules/axiom-tests/src/test/java/org/apache/axiom/om/AttrNsTest.java
Wed Jan 31 19:06:46 2007
@@ -23,8 +23,12 @@
import javax.xml.namespace.QName;
import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.stream.XMLInputFactory;
+import javax.xml.stream.XMLStreamReader;
+import javax.xml.stream.XMLStreamException;
import java.io.ByteArrayInputStream;
import java.io.IOException;
+import java.io.StringReader;
import java.util.Iterator;
public class AttrNsTest extends AbstractOMSerializationTest {
@@ -122,7 +126,36 @@
} catch (IOException e) {
fail(e.getMessage());
}
+ }
+ public void testAttributesWithNamespaceSerialization() {
+ try {
+ String xmlString = "<root xmlns='http://custom.com'><node
cust:id='123' xmlns:cust='http://custom.com' /></root>";
+ XMLStreamReader xmlStreamReader =
XMLInputFactory.newInstance().createXMLStreamReader(new
StringReader(xmlString));
+
+ // copied code from the generated stub class toOM method
+ org.apache.axiom.om.impl.builder.StAXOMBuilder builder = new
org.apache.axiom.om.impl.builder.StAXOMBuilder(xmlStreamReader);
+ org.apache.axiom.om.OMElement documentElement = builder
+ .getDocumentElement( );
+
+ ((org.apache.axiom.om.impl.OMNodeEx) documentElement).setParent(
null );
+ // end copied code
+
+ // now print the object after it has been processed
+ System.out.println( "after - '" + documentElement.toString( ) +
"'" );
+ Document document1 = newDocument(xmlString);
+ Document document2 = newDocument(documentElement.toString());
+ Diff diff = compareXML(document1, document2);
+ assertXMLEqual(diff, true);
+ } catch (ParserConfigurationException e) {
+ fail(e.getMessage());
+ } catch (SAXException e) {
+ fail(e.getMessage());
+ } catch (IOException e) {
+ fail(e.getMessage());
+ } catch (javax.xml.stream.XMLStreamException e) {
+ fail(e.getMessage());
+ }
}
}
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]