You are viewing a plain text version of this content. The canonical link for it is here.
Posted to java-dev@axis.apache.org by ch...@apache.org on 2005/10/18 13:17:09 UTC

svn commit: r326085 - /webservices/axis2/trunk/java/modules/codegen/src/org/apache/axis2/databinding/utils/ADBPullParser.java

Author: chinthaka
Date: Tue Oct 18 04:16:55 2005
New Revision: 326085

URL: http://svn.apache.org/viewcvs?rev=326085&view=rev
Log:
adding namespace stuff, not yet complete

Modified:
    webservices/axis2/trunk/java/modules/codegen/src/org/apache/axis2/databinding/utils/ADBPullParser.java

Modified: webservices/axis2/trunk/java/modules/codegen/src/org/apache/axis2/databinding/utils/ADBPullParser.java
URL: http://svn.apache.org/viewcvs/webservices/axis2/trunk/java/modules/codegen/src/org/apache/axis2/databinding/utils/ADBPullParser.java?rev=326085&r1=326084&r2=326085&view=diff
==============================================================================
--- webservices/axis2/trunk/java/modules/codegen/src/org/apache/axis2/databinding/utils/ADBPullParser.java (original)
+++ webservices/axis2/trunk/java/modules/codegen/src/org/apache/axis2/databinding/utils/ADBPullParser.java Tue Oct 18 04:16:55 2005
@@ -11,6 +11,9 @@
 import javax.xml.stream.XMLStreamConstants;
 import javax.xml.stream.XMLStreamException;
 import javax.xml.stream.XMLStreamReader;
+import java.util.Stack;
+import java.util.HashMap;
+import java.util.ArrayList;
 
 /*
  * Copyright 2004,2005 The Apache Software Foundation.
@@ -35,13 +38,8 @@
     private OMAttribute[] attributes;
     private QName elementQName;
 
-    private boolean isHandlingDocumentElement;
-    private boolean isStartDocumentThrown = false;
-    private boolean isEndDocumentThrown = false;
-
-
     // Every parser can contain a reference to a pull parser of one of its children
-    private ADBPullParser childPullParser;
+    private XMLStreamReader childPullParser;
 
     // a flag for this class to know, we are currently accessing one of the children's parsers
     private boolean accessingChildPullParser = false;
@@ -62,19 +60,26 @@
     // a pointer to the children list of current location
     private int currentIndex = 0;
 
+    private ArrayList declaredNamespaces;
+
+    /**
+     * This namespace map will contain uri as the key and the prefix as the value, so that I can check
+     * whether a particular namespace is there or not easily.
+     * Element has the responsibility of removing the new namespaces he has added after the end element.
+     * Stack is the best option, but searching for a particular namespace in the stack is not that efficient
+     * we should be able to do the search more often than adding and removing namespace. So here I have to
+     * forgo the easyness of Stacks for pushing and poping over the easier searchability of HashMap.
+     * For removing newly added namespaces, element has to keep track of new namespaces he has added
+     * remove them from the namespace map, after the end element.
+     */
+    private HashMap namespaceMap;
 
-    private ADBPullParser(QName adbBeansQName, Object[] properties, OMAttribute[] attributes) {
-        this.properties = properties;
-        this.elementQName = adbBeansQName;
-        this.attributes = attributes;
-        isHandlingDocumentElement = false;
-    }
 
-    private ADBPullParser(QName adbBeansQName, Object[] properties, OMAttribute[] attributes, boolean isHandlingDocumentElement) {
+    private ADBPullParser(QName adbBeansQName, Object[] properties, OMAttribute[] attributes) {
         this.properties = properties;
         this.elementQName = adbBeansQName;
         this.attributes = attributes;
-        this.isHandlingDocumentElement = isHandlingDocumentElement;
+        namespaceMap = new HashMap();
     }
 
     /**
@@ -82,37 +87,37 @@
      * @param properties    - this should contain all the stuff that stax events should be generated.
      *                      Lets take an example of a bean.
      *                      <pre> <Person>
-     *                                                                                                                                                                                                                                                                                                                                <Name>FooOne</Name>
-     *                                                                                                                                                                                                                                                                                                                                <DependentOne>
-     *                                                                                                                                                                                                                                                                                                                                    <Name>FooTwo</Name>
-     *                                                                                                                                                                                                                                                                                                                                    <Age>25</Age>
-     *                                                                                                                                                                                                                                                                                                                                    <Sex>Male</Sex>
-     *                                                                                                                                                                                                                                                                                                                                </DependentOne>
-     *                                                                                                                                                                                                                                                                                                                            </Person>
+     *                                                                                                                                                                                                                                                                                                                                                                                                                                                              <Name>FooOne</Name>
+     *                                                                                                                                                                                                                                                                                                                                                                                                                                                              <DependentOne>
+     *                                                                                                                                                                                                                                                                                                                                                                                                                                                                  <Name>FooTwo</Name>
+     *                                                                                                                                                                                                                                                                                                                                                                                                                                                                  <Age>25</Age>
+     *                                                                                                                                                                                                                                                                                                                                                                                                                                                                  <Sex>Male</Sex>
+     *                                                                                                                                                                                                                                                                                                                                                                                                                                                              </DependentOne>
+     *                                                                                                                                                                                                                                                                                                                                                                                                                                                          </Person>
      *                      <p/>
-     *                                                                                                                                                                                                                                                                                                                            so the mapping bean for this is
-     *                                                                                                                                                                                                                                                                                                                            class Person {
-     *                                                                                                                                                                                                                                                                                                                                String Name;
-     *                                                                                                                                                                                                                                                                                                                                Dependent dependentOne;
-     *                                                                                                                                                                                                                                                                                                                            }
+     *                                                                                                                                                                                                                                                                                                                                                                                                                                                          so the mapping bean for this is
+     *                                                                                                                                                                                                                                                                                                                                                                                                                                                          class Person {
+     *                                                                                                                                                                                                                                                                                                                                                                                                                                                              String Name;
+     *                                                                                                                                                                                                                                                                                                                                                                                                                                                              Dependent dependentOne;
+     *                                                                                                                                                                                                                                                                                                                                                                                                                                                          }
      *                      <p/>
-     *                                                                                                                                                                                                                                                                                                                            class Dependent {
-     *                                                                                                                                                                                                                                                                                                                                String name;
-     *                                                                                                                                                                                                                                                                                                                                int age;
-     *                                                                                                                                                                                                                                                                                                                                String sex;
-     *                                                                                                                                                                                                                                                                                                                            }
+     *                                                                                                                                                                                                                                                                                                                                                                                                                                                          class Dependent {
+     *                                                                                                                                                                                                                                                                                                                                                                                                                                                              String name;
+     *                                                                                                                                                                                                                                                                                                                                                                                                                                                              int age;
+     *                                                                                                                                                                                                                                                                                                                                                                                                                                                              String sex;
+     *                                                                                                                                                                                                                                                                                                                                                                                                                                                          }
      *                      <p/>
-     *                                                                                                                                                                                                                                                                                                                            So if one needs to generate pull events out of a Person bean, the array he needs
-     *                                                                                                                                                                                                                                                                                                                            to pass is like this.
-     *                                                                                                                                                                                                                                                                                                                            ---------------------------------------------------------------
-     *                                                                                                                                                                                                                                                                                                                            | "Name" | "FooOne" | QName("DependentOne") | Dependent object|
-     *                                                                                                                                                                                                                                                                                                                            ---------------------------------------------------------------
-     *                                                                                                                                                                                                                                                                                                                            Remember "Name" and "FooOne" MUST be strings and DependentOne SHOULD be
-     *                                                                                                                                                                                                                                                                                                                            QName.
-     *                                                                                                                                                                                                                                                                                                                            This DependentObject can either be an ADBBean or a POJO. If its an ADBBean
-     *                                                                                                                                                                                                                                                                                                                            We directly get the pull parser from that. If not we create a reflection based
-     *                                                                                                                                                                                                                                                                                                                            pull parser for that java bean.
-     *                                                                                                                                                                                                                                                                                                        </pre>
+     *                                                                                                                                                                                                                                                                                                                                                                                                                                                          So if one needs to generate pull events out of a Person bean, the array he needs
+     *                                                                                                                                                                                                                                                                                                                                                                                                                                                          to pass is like this.
+     *                                                                                                                                                                                                                                                                                                                                                                                                                                                          ---------------------------------------------------------------
+     *                                                                                                                                                                                                                                                                                                                                                                                                                                                          | "Name" | "FooOne" | QName("DependentOne") | Dependent object|
+     *                                                                                                                                                                                                                                                                                                                                                                                                                                                          ---------------------------------------------------------------
+     *                                                                                                                                                                                                                                                                                                                                                                                                                                                          Remember "Name" and "FooOne" MUST be strings and DependentOne SHOULD be
+     *                                                                                                                                                                                                                                                                                                                                                                                                                                                          QName.
+     *                                                                                                                                                                                                                                                                                                                                                                                                                                                          This DependentObject can either be an ADBBean or a POJO. If its an ADBBean
+     *                                                                                                                                                                                                                                                                                                                                                                                                                                                          We directly get the pull parser from that. If not we create a reflection based
+     *                                                                                                                                                                                                                                                                                                                                                                                                                                                          pull parser for that java bean.
+     *                                                                                                                                                                                                                                                                                                                                                                                                                                      </pre>
      * @param attributes    - this will contain an array of OMAttributes
      * @return XMLStreamReader
      */
@@ -121,7 +126,7 @@
     }
 
     public static XMLStreamReader createPullParser(QName adbBeansQName, Object[] properties, OMAttribute[] attributes, boolean isDocumentElement) {
-        return new ADBPullParser(adbBeansQName, properties, attributes, isDocumentElement);
+        return new ADBPullParser(adbBeansQName, properties, attributes);
     }
 
     public boolean isCompleted() {
@@ -130,36 +135,27 @@
 
     // ----------- XMLStreamReader Methods -------------------------------------------//
     public Object getProperty(String string) throws IllegalArgumentException {
-        return null;  //To change body of implemented methods use File | Settings | File Templates.
+        return null;
     }
 
     public int next() throws XMLStreamException {
-        int event = 0;
 
-        // First check whether the parser has already has completed. currentIndex starts with 0. But
-        // but the first emulated event is the start element of the given element. The same index pointer
-        // is used to point to the elements in the Array. Since we allocate index 0 to the current element,
-        // currentIndex is always ahead one step from the location of the array which is currently being processed.
-        // so when you check for completeness you have to check for currentIndex >= array length + 2
-
-        if (isHandlingDocumentElement && !isStartDocumentThrown) {
-            isStartDocumentThrown = true;
-            return XMLStreamConstants.START_DOCUMENT;
-        }
+        /** First check whether the parser has already has completed. currentIndex starts with 0. But
+         but the first emulated event is the start element of the given element. The same index pointer
+         is used to point to the elements in the Array. Since we allocate index 0 to the current element,
+         currentIndex is always ahead one step from the location of the array which is currently being processed.
+         so when you check for completeness you have to check for currentIndex >= array length + 2
+         */
 
         // terminate condition.
         // if properties are set check we have traversed all of them. If there are no properties, then
         // check whether we have already thrown the END Element.
-        if ( ( properties != null &&  currentIndex >= properties.length + 2) || (properties == null && isEndElementFinished)) {
-            if (isHandlingDocumentElement && isEndDocumentThrown) {
-                isEndDocumentThrown = true;
-                return XMLStreamConstants.END_DOCUMENT;
-            }
+        if ((properties != null && currentIndex >= properties.length + 2) || (properties == null && isEndElementFinished)) {
             throw new XMLStreamException("End of elements has already been reached. Can not go beyond that");
         }
 
         if (accessingChildPullParser) {
-            if (!childPullParser.isCompleted()) {
+            if (childPullParser instanceof ADBPullParser && !((ADBPullParser) childPullParser).isCompleted()) {
                 return childPullParser.next();
             } else {
                 accessingChildPullParser = false;
@@ -177,8 +173,10 @@
             // then this is just the start element
             currentIndex++;
             parserInformation = new ParserInformation(this.elementQName);
+            namespaceMap.put(elementQName.getNamespaceURI(), elementQName.getPrefix());
+            handleAttributes();
             return XMLStreamConstants.START_ELEMENT;
-        } else if ( properties == null || properties.length + 1 == currentIndex) {
+        } else if (properties == null || properties.length + 1 == currentIndex) {
             // this is the end of this element
             currentIndex++;
             isEndElementFinished = true;
@@ -193,11 +191,13 @@
                 Object object = properties[currentIndex];
                 if (object instanceof ADBBean) {
                     ADBBean adbBean = (ADBBean) object;
-                    childPullParser = (ADBPullParser) adbBean.getPullParser((QName) o);
+                    ADBPullParser adbPullParser = (ADBPullParser) adbBean.getPullParser((QName) o);
+                    adbPullParser.setNamespaceMap(this.namespaceMap);
+                    childPullParser = adbPullParser;
                 } else if (object instanceof OMElement) {
 //                   childPullParser = (OMElement) ;
                 } else {
-                    childPullParser = (ADBPullParser) BeanSerializerUtil.getPullParser(object, (QName) o);
+                    childPullParser = BeanSerializerUtil.getPullParser(object, (QName) o);
                 }
                 accessingChildPullParser = true;
                 return this.next();
@@ -213,14 +213,28 @@
 
     }
 
+    private void handleAttributes() {
+        // by this time all the attributes related methods can be called.
+        // now need to extract namespace from them and attach them to the element itself.
+        if (attributes != null) {
+            for (int i = 0; i < attributes.length; i++) {
+                OMAttribute attribute = attributes[i];
+                if (namespaceMap.get(attribute.getQName().getNamespaceURI()) == null) {
+                    namespaceMap.put(attribute.getQName().getNamespaceURI(), attribute.getQName().getPrefix());
+                    
+                }
+            }
+        }
+    }
+
 
     public boolean hasNext() throws XMLStreamException {
         return !isEndElementFinished;
     }
 
     public String getElementText() throws XMLStreamException {
-        ParserInformation parserInfo = getCorrectParserInformation();
-        return parserInfo != null ? parserInfo.getText() : "";
+        if (accessingChildPullParser) return childPullParser.getElementText();
+        return parserInformation != null ? parserInformation.getText() : "";
     }
 
 
@@ -235,38 +249,38 @@
     }
 
     public String getText() {
-        ParserInformation parserInfo = getCorrectParserInformation();
-        return parserInfo != null ? parserInfo.getText() : "";
+        if (accessingChildPullParser) return childPullParser.getText();
+        return parserInformation != null ? parserInformation.getText() : "";
     }
 
     public boolean hasText() {
-        ParserInformation parserInfo = getCorrectParserInformation();
-        return parserInfo != null && parserInfo.getText() != null && !"".equals(parserInformation.getText());
+        if (accessingChildPullParser) return childPullParser.hasText();
+        return parserInformation != null && parserInformation.getText() != null && !"".equals(parserInformation.getText());
     }
 
     public QName getName() {
-        ParserInformation parserInfo = getCorrectParserInformation();
-        return parserInfo != null ? parserInfo.getName() : null;
+        if (accessingChildPullParser) return childPullParser.getName();
+        return parserInformation != null ? parserInformation.getName() : null;
     }
 
     public String getLocalName() {
-        ParserInformation parserInfo = getCorrectParserInformation();
-        return parserInfo != null ? parserInfo.getName().getLocalPart() : null;
+        if (accessingChildPullParser) return childPullParser.getLocalName();
+        return parserInformation != null ? parserInformation.getName().getLocalPart() : null;
     }
 
     public boolean hasName() {
-        ParserInformation parserInfo = getCorrectParserInformation();
-        return parserInfo != null && parserInfo.getName() != null;
+        if (accessingChildPullParser) return childPullParser.hasName();
+        return parserInformation != null && parserInformation.getName() != null;
     }
 
     public String getNamespaceURI() {
-        ParserInformation parserInfo = getCorrectParserInformation();
-        return parserInfo != null && parserInfo.getName() != null ? parserInfo.getName().getNamespaceURI() : "";
+        if (accessingChildPullParser) return childPullParser.getNamespaceURI();
+        return parserInformation != null && parserInformation.getName() != null ? parserInformation.getName().getNamespaceURI() : "";
     }
 
     public String getPrefix() {
-        ParserInformation parserInfo = getCorrectParserInformation();
-        return parserInfo != null ? parserInfo.getName().getPrefix() : null;
+        if (accessingChildPullParser) return childPullParser.getPrefix();
+        return parserInformation != null ? parserInformation.getName().getPrefix() : null;
     }
 
     public String getAttributeValue(String namespaceURI, String localName) {
@@ -479,23 +493,20 @@
         return event;
     }
 
-    /**
-     * This will returns the parser information
-     */
-    public ParserInformation getParserInformation() {
-        return accessingChildPullParser ? childPullParser.getParserInformation() : this.parserInformation;
+    public HashMap getNamespaceMap() {
+        return namespaceMap;
     }
 
-    private ADBPullParser.ParserInformation getCorrectParserInformation() {
-        return accessingChildPullParser ? childPullParser.getParserInformation() : this.parserInformation;
+    public void setNamespaceMap(HashMap namespaceMap) {
+        this.namespaceMap = namespaceMap;
     }
 
 // --------------------------------------------------------------------------------------------------//
 
     /**
-     * Inner class which holds stuff for the parser to pick data
+     * Inner class which holds stuff for the parser to pick data.
      * This hold the information the parser will hold when user request for data. Every ADBPullParser
-     * hold this kind of object inside it and within the methods of ADBPullParser, they refer to the
+     * holds this kind of object inside it and within the methods of ADBPullParser, they refer to the
      * fields inside this class. So if user needs to change what parser returns, he just need to
      * change parser information object.
      */
@@ -530,4 +541,6 @@
             this.name = name;
         }
     }
+
+
 }