You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commons-dev@ws.apache.org by aj...@apache.org on 2006/03/20 14:12:52 UTC

svn commit: r387209 - in /webservices/commons/modules/axiom/src/org/apache/ws/commons/om/impl/llom: builder/StAXBuilder.java serialize/StreamingOMSerializer.java

Author: ajith
Date: Mon Mar 20 05:12:50 2006
New Revision: 387209

URL: http://svn.apache.org/viewcvs?rev=387209&view=rev
Log:
Fixing a few issues with attribute handling
1. Updated the StreamingOMSerializer.java to handle attributes that do not have declared namespaces. 
2. Changed the order of serializing attributes and namespaces so that namespace serializing comes first
3. StAXBuilder ignores the attribute namespace if it cannot find it through the findnamespace method. This is changed so that the namespace is declared if it is not found.

All these issues arise when using a third party pull parser such as the XMLbeans pull parser (XmlObject.newXmlStreamReader()). I'm not so keen in adding an Xbeans dependency to axiom so my guess is a relevant test case is more suitable inside Axis2 rather than Axiom!

Modified:
    webservices/commons/modules/axiom/src/org/apache/ws/commons/om/impl/llom/builder/StAXBuilder.java
    webservices/commons/modules/axiom/src/org/apache/ws/commons/om/impl/llom/serialize/StreamingOMSerializer.java

Modified: webservices/commons/modules/axiom/src/org/apache/ws/commons/om/impl/llom/builder/StAXBuilder.java
URL: http://svn.apache.org/viewcvs/webservices/commons/modules/axiom/src/org/apache/ws/commons/om/impl/llom/builder/StAXBuilder.java?rev=387209&r1=387208&r2=387209&view=diff
==============================================================================
--- webservices/commons/modules/axiom/src/org/apache/ws/commons/om/impl/llom/builder/StAXBuilder.java (original)
+++ webservices/commons/modules/axiom/src/org/apache/ws/commons/om/impl/llom/builder/StAXBuilder.java Mon Mar 20 05:12:50 2006
@@ -129,11 +129,18 @@
             OMNamespace ns = null;
             String uri = parser.getAttributeNamespace(i);
             String prefix = parser.getAttributePrefix(i);
+
             if (uri != null && uri.hashCode() != 0) {
                 ns = node.findNamespace(uri, prefix);
+                if (ns== null) {
+                    ns = node.declareNamespace(uri, prefix);
+                }
             }
+
+
             // todo if the attributes are supposed to namespace qualified all the time
             // todo then this should throw an exception here
+           
             node.addAttribute(parser.getAttributeLocalName(i),
                     parser.getAttributeValue(i), ns);
         }
@@ -353,7 +360,7 @@
     public Object getParser() {
         if (parserAccessed){
             throw new IllegalStateException(
-                    "Parser already accessed!");  
+                    "Parser already accessed!");
         }
         if (!cache) {
             parserAccessed = true;
@@ -395,7 +402,7 @@
 
     /**
      * @return Returns short.
-     */ 
+     */
     public short getBuilderType() {
         return OMConstants.PULL_TYPE_BUILDER;
     }

Modified: webservices/commons/modules/axiom/src/org/apache/ws/commons/om/impl/llom/serialize/StreamingOMSerializer.java
URL: http://svn.apache.org/viewcvs/webservices/commons/modules/axiom/src/org/apache/ws/commons/om/impl/llom/serialize/StreamingOMSerializer.java?rev=387209&r1=387208&r2=387209&view=diff
==============================================================================
--- webservices/commons/modules/axiom/src/org/apache/ws/commons/om/impl/llom/serialize/StreamingOMSerializer.java (original)
+++ webservices/commons/modules/axiom/src/org/apache/ws/commons/om/impl/llom/serialize/StreamingOMSerializer.java Mon Mar 20 05:12:50 2006
@@ -23,18 +23,22 @@
 import javax.xml.stream.XMLStreamException;
 import javax.xml.stream.XMLStreamReader;
 import javax.xml.stream.XMLStreamWriter;
+import javax.xml.namespace.NamespaceContext;
 
 /**
  * Class StreamingOMSerializer
  */
 public class StreamingOMSerializer implements XMLStreamConstants, OMSerializer {
 
+    private static int namespaceSuffix = 0;
+    public static final String NAMESPACE_PREFIX = "ns";
+
     /*
-     * The behavior of the serializer is such that it returns when it encounters the
-     * starting element for the second time. The depth variable tracks the depth of the
-     * serilizer and tells it when to return.
-     * Note that it is assumed that this serialization starts on an Element.
-     */
+    * The behavior of the serializer is such that it returns when it encounters the
+    * starting element for the second time. The depth variable tracks the depth of the
+    * serilizer and tells it when to return.
+    * Note that it is assumed that this serialization starts on an Element.
+    */
 
     /**
      * Field depth
@@ -94,7 +98,10 @@
             } else if (event == END_ELEMENT) {
                 serializeEndElement(writer);
                 depth--;
+            }else if (event == START_DOCUMENT) {
+                depth++; //if a start document is found then increment the depth
             } else if (event == END_DOCUMENT) {
+                if (depth!=0) depth--;  //for the end document - reduce the depth
                 try {
                     serializeEndElement(writer);
                 } catch (Exception e) {
@@ -138,8 +145,6 @@
             writer.writeStartElement(reader.getLocalName());
         }
 
-        // add attributes
-        serializeAttributes(reader, writer);
 
         // add the namespaces
         int count = reader.getNamespaceCount();
@@ -148,10 +153,14 @@
             namespacePrefix = reader.getNamespacePrefix(i);
             if(namespacePrefix != null && namespacePrefix.length()==0)
                 continue;
-            
+
             serializeNamespace(namespacePrefix,
                     reader.getNamespaceURI(i), writer);
         }
+
+        // add attributes
+        serializeAttributes(reader, writer);
+
     }
 
     /**
@@ -213,23 +222,66 @@
         int count = reader.getAttributeCount();
         String prefix = null;
         String namespaceName = null;
+        String writerPrefix=null;
         for (int i = 0; i < count; i++) {
             prefix = reader.getAttributePrefix(i);
             namespaceName = reader.getAttributeNamespace(i);
-            if ((prefix != null) && !namespaceName.equals("")) {
-                writer.writeAttribute(prefix, namespaceName,
-                        reader.getAttributeLocalName(i),
-                        reader.getAttributeValue(i));
-            } else {
+            writerPrefix =writer.getNamespaceContext().getPrefix(namespaceName);
+
+            if (!"".equals(namespaceName)){
+                //prefix has already being declared but this particular attrib has a
+                //no prefix attached. So use the prefix provided by the writer
+                if (writerPrefix!=null && (prefix==null || prefix.equals(""))){
+                    writer.writeAttribute(writerPrefix, namespaceName,
+                            reader.getAttributeLocalName(i),
+                            reader.getAttributeValue(i));
+
+                    //writer prefix is available but different from the current
+                    //prefix of the attrib. We should be decalring the new prefix
+                    //as a namespace declaration
+                }else if (prefix!=null && !"".equals(prefix)&& !prefix.equals(writerPrefix)){
+                    writer.writeNamespace(prefix,namespaceName);
+                    writer.writeAttribute(prefix, namespaceName,
+                            reader.getAttributeLocalName(i),
+                            reader.getAttributeValue(i));
+
+                    //prefix is null (or empty), but the namespace name is valid! it has not
+                    //being written previously also. So we need to generate a prefix
+                    //here
+                }else{
+                    prefix = generateUniquePrefix(writer.getNamespaceContext());
+                    writer.writeNamespace(prefix,namespaceName);
+                    writer.writeAttribute(prefix, namespaceName,
+                            reader.getAttributeLocalName(i),
+                            reader.getAttributeValue(i));
+                }
+            }else{
+                //empty namespace is equal to no namespace!
                 writer.writeAttribute(reader.getAttributeLocalName(i),
                         reader.getAttributeValue(i));
             }
+
+
         }
     }
 
     /**
+     * Generates a unique namespace prefix that is not in the
+     * scope of the NamespaceContext
+     * @param nsCtxt
+     * @return
+     */
+    private String generateUniquePrefix(NamespaceContext nsCtxt){
+        String prefix = NAMESPACE_PREFIX + namespaceSuffix++;
+        //null should be returned if the prefix is not bound!
+        while(nsCtxt.getNamespaceURI(prefix)!=null){
+            prefix = NAMESPACE_PREFIX + namespaceSuffix++;
+        }
+
+        return prefix;
+    }
+    /**
      * Method serializeNamespace.
-     *
      * @param prefix
      * @param URI
      * @param writer



Re: svn commit: r387209 - in /webservices/commons/modules/axiom/src/org/apache/ws/commons/om/impl/llom: builder/StAXBuilder.java serialize/StreamingOMSerializer.java

Posted by Sanjiva Weerawarana <sa...@opensource.lk>.
On Mon, 2006-03-20 at 13:12 +0000, ajith@apache.org wrote:
> Author: ajith
> Date: Mon Mar 20 05:12:50 2006
> New Revision: 387209
> 
> URL: http://svn.apache.org/viewcvs?rev=387209&view=rev Log: Fixing a
>  few issues with attribute handling 1. Updated the
>  StreamingOMSerializer.java to handle attributes that do not have
>  declared namespaces. 2. Changed the order of serializing attributes
>  and namespaces so that namespace serializing comes first

Note that this should not be necessary .. namespace declarations are
spsed to be processed first, whether they appear earlier than first for
qualified attributes or later. 

> 
> All these issues arise when using a third party pull parser such as the
>  XMLbeans pull parser (XmlObject.newXmlStreamReader()). I'm not so keen
>  in adding an Xbeans dependency to axiom so my guess is a relevant test
>  case is more suitable inside Axis2 rather than Axiom!

+1.

Sanjiva.