You are viewing a plain text version of this content. The canonical link for it is here.
Posted to axis-cvs@ws.apache.org by sc...@apache.org on 2007/12/03 19:58:05 UTC

svn commit: r600634 - in /webservices/axis2/trunk/java/modules/rmi: src/org/apache/axis2/rmi/databind/ test/org/apache/axis2/rmi/databind/ test/org/apache/axis2/rmi/databind/dto/

Author: scheu
Date: Mon Dec  3 10:58:02 2007
New Revision: 600634

URL: http://svn.apache.org/viewvc?rev=600634&view=rev
Log:
AXIS2-3376
Contributor: Brian Murray
The rmi XMLStreamParser code contains a flaw that is exposed when an inner element and
its container have the same name.
Brian contributed a test that demonstrates the problem and a fix to the problem.
The fix uses a new class, StatefulXMLStreamReader, which wraps that original XMLStreamReader and exposes a nesting statck.
Thanks Brian for this contribution.

Added:
    webservices/axis2/trunk/java/modules/rmi/src/org/apache/axis2/rmi/databind/StatefulXMLStreamReader.java
    webservices/axis2/trunk/java/modules/rmi/test/org/apache/axis2/rmi/databind/SameParamNameTest.java
    webservices/axis2/trunk/java/modules/rmi/test/org/apache/axis2/rmi/databind/dto/TestClass14.java
    webservices/axis2/trunk/java/modules/rmi/test/org/apache/axis2/rmi/databind/dto/TestClass15.java
Modified:
    webservices/axis2/trunk/java/modules/rmi/src/org/apache/axis2/rmi/databind/XmlStreamParser.java

Added: webservices/axis2/trunk/java/modules/rmi/src/org/apache/axis2/rmi/databind/StatefulXMLStreamReader.java
URL: http://svn.apache.org/viewvc/webservices/axis2/trunk/java/modules/rmi/src/org/apache/axis2/rmi/databind/StatefulXMLStreamReader.java?rev=600634&view=auto
==============================================================================
--- webservices/axis2/trunk/java/modules/rmi/src/org/apache/axis2/rmi/databind/StatefulXMLStreamReader.java (added)
+++ webservices/axis2/trunk/java/modules/rmi/src/org/apache/axis2/rmi/databind/StatefulXMLStreamReader.java Mon Dec  3 10:58:02 2007
@@ -0,0 +1,269 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.axis2.rmi.databind;
+
+import java.util.Stack;
+
+import javax.xml.namespace.NamespaceContext;
+import javax.xml.namespace.QName;
+import javax.xml.stream.Location;
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.XMLStreamReader;
+
+/**
+ * StatefulXMLStreamReader class that primarily delegates to the initial reader. However, in 
+ * addition to the normal functions performed by the initial reader, a stack is also maintained
+ * to determine the current state.
+ */
+public class StatefulXMLStreamReader implements XMLStreamReader {
+
+    protected XMLStreamReader delegate;
+    private Stack tagStack;
+    private boolean priorAccess;
+
+    /**
+     * Construct a StatefulXMLStreamReader.  Do not assume that the reader is being
+     * converted prior to accessed.
+     *
+     * @param reader XMLStreamReader for which a state is also needed.
+     */
+    public StatefulXMLStreamReader(XMLStreamReader reader) {
+        delegate = reader;
+        tagStack = new Stack();
+        priorAccess = true;
+    }
+    
+    /**
+     * Construct a StatefulXMLStreamReader.
+     *
+     * @param reader XMLStreamReader for which a state is also needed.
+     * @param at0 indicates whether reader has been advanced, which in turn 
+     *        indicates whether the XML parsing is at an intermediate state
+     *        prior to being converted to a StatefulXMLStreamReader
+     */
+    public StatefulXMLStreamReader(XMLStreamReader reader, boolean at0) {
+        delegate = reader;
+        tagStack = new Stack();
+        priorAccess = !at0;
+    }    
+
+    public void close() throws XMLStreamException {
+        delegate.close();
+    }
+
+    public int getAttributeCount() {
+        return delegate.getAttributeCount();
+    }
+
+    public String getAttributeLocalName(int arg0) {
+        return delegate.getAttributeLocalName(arg0);
+    }
+
+    public QName getAttributeName(int arg0) {
+        return delegate.getAttributeName(arg0);
+    }
+
+    public String getAttributeNamespace(int arg0) {
+        return delegate.getAttributeNamespace(arg0);
+    }
+
+    public String getAttributePrefix(int arg0) {
+        return delegate.getAttributePrefix(arg0);
+    }
+
+    public String getAttributeType(int arg0) {
+        return delegate.getAttributeType(arg0);
+    }
+
+    public String getAttributeValue(int arg0) {
+        return delegate.getAttributeValue(arg0);
+    }
+
+    public String getAttributeValue(String arg0, String arg1) {
+        return delegate.getAttributeValue(arg0, arg1);
+    }
+
+    public String getCharacterEncodingScheme() {
+        return delegate.getCharacterEncodingScheme();
+    }
+
+    public String getElementText() throws XMLStreamException {
+        return delegate.getElementText();
+    }
+
+    public String getEncoding() {
+        return delegate.getEncoding();
+    }
+
+    public int getEventType() {
+        return delegate.getEventType();
+    }
+
+    public String getLocalName() {
+        return delegate.getLocalName();
+    }
+
+    public Location getLocation() {
+        return delegate.getLocation();
+    }
+
+    public QName getName() {
+        return delegate.getName();
+    }
+
+    public NamespaceContext getNamespaceContext() {
+        return delegate.getNamespaceContext();
+    }
+
+    public int getNamespaceCount() {
+        return delegate.getNamespaceCount();
+    }
+
+    public String getNamespacePrefix(int arg0) {
+        return delegate.getNamespacePrefix(arg0);
+    }
+
+    public String getNamespaceURI() {
+        return delegate.getNamespaceURI();
+    }
+
+    public String getNamespaceURI(int arg0) {
+        return delegate.getNamespaceURI(arg0);
+    }
+
+    public String getNamespaceURI(String arg0) {
+        return delegate.getNamespaceURI(arg0);
+    }
+
+    public String getPIData() {
+        return delegate.getPIData();
+    }
+
+    public String getPITarget() {
+        return delegate.getPITarget();
+    }
+
+    public String getPrefix() {
+        return delegate.getPrefix();
+    }
+
+    public Object getProperty(String arg0) throws IllegalArgumentException {
+        return delegate.getProperty(arg0);
+    }
+
+    public String getText() {
+        return delegate.getText();
+    }
+
+    public char[] getTextCharacters() {
+        return delegate.getTextCharacters();
+    }
+
+    public int getTextCharacters(int arg0, char[] arg1, int arg2, int arg3)
+            throws XMLStreamException {
+        return delegate.getTextCharacters(arg0, arg1, arg2, arg3);
+    }
+
+    public int getTextLength() {
+        return delegate.getTextLength();
+    }
+
+    public int getTextStart() {
+        return delegate.getTextStart();
+    }
+
+    public String getVersion() {
+        return delegate.getVersion();
+    }
+
+    public boolean hasName() {
+        return delegate.hasName();
+    }
+
+    public boolean hasNext() throws XMLStreamException {
+        return delegate.hasNext();
+    }
+
+    public boolean hasText() {
+        return delegate.hasText();
+    }
+
+    public boolean isAttributeSpecified(int arg0) {
+        return delegate.isAttributeSpecified(arg0);
+    }
+
+    public boolean isCharacters() {
+        return delegate.isCharacters();
+    }
+
+    public boolean isEndElement() {
+        return delegate.isEndElement();
+    }
+
+    public boolean isStandalone() {
+        return delegate.isStandalone();
+    }
+
+    public boolean isStartElement() {
+        return delegate.isStartElement();
+    }
+
+    public boolean isWhiteSpace() {
+        return delegate.isWhiteSpace();
+    }
+
+    public int next() throws XMLStreamException {
+        int returnValue = delegate.next();
+        
+        if (delegate.isEndElement()) {
+            QName top = (QName) tagStack.peek();
+            if (!(delegate.getName().equals(top)) && !priorAccess) {
+                throw new IllegalStateException("The end element (" + delegate.getName() + ") does not "
+                        + "correspond to the current start element (" + top + ").");
+            }
+            if (tagStack.size() > 0) {
+                tagStack.pop();        
+            } else if (!priorAccess) {
+                throw new IllegalStateException("An end element was encountered for which "
+                        + "there was not a corresponding start element.");
+            }
+        } else if (delegate.isStartElement()) {
+            tagStack.push(delegate.getName());
+        }
+
+        return returnValue;
+    }
+
+    public int nextTag() throws XMLStreamException {
+        return delegate.nextTag();
+    }
+
+    public void require(int arg0, String arg1, String arg2) throws XMLStreamException {
+        delegate.require(arg0, arg1, arg2);
+    }
+
+    public boolean standaloneSet() {
+        return delegate.standaloneSet();
+    }
+    
+    public int getDepth() {
+        return tagStack.size();
+    }
+
+}

Modified: webservices/axis2/trunk/java/modules/rmi/src/org/apache/axis2/rmi/databind/XmlStreamParser.java
URL: http://svn.apache.org/viewvc/webservices/axis2/trunk/java/modules/rmi/src/org/apache/axis2/rmi/databind/XmlStreamParser.java?rev=600634&r1=600633&r2=600634&view=diff
==============================================================================
--- webservices/axis2/trunk/java/modules/rmi/src/org/apache/axis2/rmi/databind/XmlStreamParser.java (original)
+++ webservices/axis2/trunk/java/modules/rmi/src/org/apache/axis2/rmi/databind/XmlStreamParser.java Mon Dec  3 10:58:02 2007
@@ -1,661 +1,722 @@
-/*
- * 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.axis2.rmi.databind;
-
-import org.apache.axis2.rmi.metadata.*;
-import org.apache.axis2.rmi.metadata.impl.TypeImpl;
-import org.apache.axis2.rmi.exception.XmlParsingException;
-import org.apache.axis2.rmi.exception.MetaDataPopulateException;
-import org.apache.axis2.rmi.exception.SchemaGenerationException;
-import org.apache.axis2.rmi.util.Constants;
-import org.apache.axis2.rmi.util.JavaTypeToQNameMap;
-import org.apache.axis2.rmi.Configurator;
-import org.apache.axis2.rmi.types.MapType;
-
-import javax.xml.stream.XMLStreamReader;
-import javax.xml.stream.XMLStreamException;
-import javax.xml.namespace.QName;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Array;
-import java.lang.reflect.Method;
-import java.util.*;
-
-
-
-public class XmlStreamParser {
-
-    private Configurator configurator;
-    private Map qNameToTypeMap;
-    private SimpleTypeHandler simpleTypeHandler;
-    private Class simpleTypeHandlerClass;
-
-    public XmlStreamParser(Map processedTypeMap,
-                           Configurator configurator,
-                           Map schemaMap) {
-        this.configurator = configurator;
-        this.simpleTypeHandler = this.configurator.getSimpleTypeHandler();
-        this.simpleTypeHandlerClass = this.simpleTypeHandler.getClass();
-        try {
-            populateQNameToTypeMap(processedTypeMap, schemaMap);
-        } catch (MetaDataPopulateException e) {
-            // TODO: what to do this exceptions is not going to happen
-        } catch (SchemaGenerationException e) {
-            // TODO: what to do thsi exceptions is not going to happen
-        }
-    }
-
-    private void populateQNameToTypeMap(Map processedTypeMap, Map schemaMap)
-            throws MetaDataPopulateException,
-            SchemaGenerationException {
-        // first add all the proceced type map values
-        Set defaultTypeMapKeys = JavaTypeToQNameMap.getKeys();
-        Class typeClass;
-        for (Iterator iter = defaultTypeMapKeys.iterator(); iter.hasNext();) {
-            typeClass = (Class) iter.next();
-            if (!processedTypeMap.containsKey(typeClass)) {
-                Type newType = new TypeImpl(typeClass);
-                processedTypeMap.put(typeClass, newType);
-                newType.populateMetaData(this.configurator, processedTypeMap);
-                newType.generateSchema(this.configurator, schemaMap);
-            }
-        }
-        this.qNameToTypeMap = new HashMap();
-        Type type = null;
-        for (Iterator iter = processedTypeMap.values().iterator(); iter.hasNext();) {
-            type = (Type) iter.next();
-            this.qNameToTypeMap.put(type.getXmlType().getQname(), type);
-        }
-
-    }
-
-    public Object getOutputObject(XMLStreamReader reader,
-                                  Operation operation)
-            throws XMLStreamException, XmlParsingException {
-        Object returnObject = null;
-        // first we have to point to the reader to the begining of the element
-        while (!reader.isStartElement() && !reader.isEndElement()) {
-            reader.next();
-        }
-
-        // first check whether we have got the correct input element or not
-        if (reader.getLocalName().equals(operation.getOutPutElement().getName()) &&
-                reader.getNamespaceURI().equals(operation.getOutPutElement().getNamespace())) {
-            reader.next();
-            if (operation.getOutputParameter() != null) {
-                // i.e this is not a void return type
-                returnObject = getObjectForParameter(reader, operation.getOutputParameter());
-            }
-        }
-        return returnObject;
-    }
-
-    public Object[] getInputParameters(XMLStreamReader reader,
-                                       Operation operation)
-            throws XMLStreamException,
-            XmlParsingException {
-
-        List returnObjects = new ArrayList();
-        // first we have to point to the reader to the begining for the element
-        while (!reader.isStartElement() && !reader.isEndElement()) {
-            reader.next();
-        }
-
-        // first check whether we have got the correct input element or not
-        if (reader.getLocalName().equals(operation.getInputElement().getName()) &&
-                reader.getNamespaceURI().equals(operation.getInputElement().getNamespace())) {
-            // point the reader to parameters
-            reader.next();
-            Parameter parameter = null;
-            List inputParameters = operation.getInputParameters();
-            QName parameterQName = null;
-
-            for (Iterator iter = inputParameters.iterator(); iter.hasNext();) {
-                parameter = (Parameter) iter.next();
-                parameterQName = new QName(parameter.getNamespace(), parameter.getName());
-                returnObjects.add(getObjectForParameter(reader, parameter));
-                // if the reader is at the end of this parameter
-                // then we move it to next element.
-                if (reader.isEndElement() && reader.getName().equals(parameterQName)){
-                    reader.next();
-                }
-            }
-
-        } else {
-            throw new XmlParsingException("Unexpected Subelement " + reader.getName() + " but " +
-                    "expected " + operation.getInputElement().getName());
-        }
-        return returnObjects.toArray();
-    }
-
-    /**
-     * parameter has the same logic as the attribute. so reader pre and post conditions same.
-     *
-     * @param reader
-     * @param parameter
-     * @return
-     * @throws XMLStreamException
-     * @throws XmlParsingException
-     */
-
-    public Object getObjectForParameter(XMLStreamReader reader,
-                                        Parameter parameter)
-            throws XMLStreamException,
-            XmlParsingException {
-
-        QName parameterQName = new QName(parameter.getNamespace(), parameter.getName());
-        return getObjectForElement(reader,
-                parameterQName,
-                parameter.getType(),
-                parameter.isArray(),
-                parameter.getElement().isNillable(),
-                parameter.getElement().isMinOccurs0(),
-                parameter.getClassType(),
-                parameter.getJavaClass());
-
-    }
-
-    /**
-     * when calls to this method reader must point to the start of the type.
-     * if it is a simple type it points the the text
-     * if it is a complex type it points to the start element of the first attribute. and we returning
-     * from the method it should point to the end element of the last parameter.
-     *
-     * @param reader
-     * @param type
-     * @return
-     * @throws XMLStreamException
-     * @throws XmlParsingException
-     */
-
-
-    public Object getObjectForType(XMLStreamReader reader,
-                                   Type type)
-            throws XMLStreamException,
-            XmlParsingException {
-
-        try {
-            Object returnObject = null;
-            if (type.getXmlType().isSimpleType()) {
-                // this is a simple known type for us
-                // constructor should be able to invoke with the string.
-                if (type.getJavaClass().equals(Object.class)) {
-                    returnObject = new Object();
-                } else {
-                    // find the object for this string using converter util classs
-                    returnObject = getSimpleTypeObject(type, reader, reader.getText());
-                }
-            } else {
-                // first we have to point to the reader to the begining for the element
-                while (!reader.isStartElement() && !reader.isEndElement()) {
-                    reader.next();
-                }
-                // this is a complex type
-                returnObject = type.getJavaClass().newInstance();
-                // we have to get all the elementField and populate them
-                List elementFields = type.getAllElementFields();
-                ElementField elementField;
-                Object elementFieldObject;
-                QName elementFieldQName = null;
-
-                for (Iterator iter = elementFields.iterator(); iter.hasNext();) {
-                    elementField = (ElementField) iter.next();
-                    elementFieldObject = getObjectForElementField(reader, elementField);
-                    elementFieldQName = new QName(elementField.getNamespace(), elementField.getName());
-                    if (elementFieldObject != null) {
-                        elementField.getSetterMethod().invoke(returnObject, new Object[]{elementFieldObject});
-                    }
-                    // if the reader is at the end of this elementField
-                    // then we move it to next element.
-                    if (reader.isEndElement() && reader.getName().equals(elementFieldQName)){
-                        reader.next();
-                    }
-
-                }
-
-            }
-            return returnObject;
-        } catch (InstantiationException e) {
-            throw new XmlParsingException("Constructor invoking exception for type " + type.getName());
-        } catch (IllegalAccessException e) {
-            throw new XmlParsingException("Constructor invoking exception for type " + type.getName());
-        } catch (InvocationTargetException e) {
-            e.printStackTrace();
-            throw new XmlParsingException("Constructor invoking exception for type " + type.getName());
-        }
-
-    }
-
-    private Object getSimpleTypeObject(Type type, XMLStreamReader reader, String value)
-            throws  XmlParsingException {
-        Object returnObject;
-        String methodName = null;
-        try {
-            methodName = getMethodName(type.getJavaClass().getName());
-            Method  methodToInvoke = this.simpleTypeHandlerClass.getMethod(methodName,new Class[]{String.class});
-            returnObject = methodToInvoke.invoke(this.simpleTypeHandler,new Object[]{value});
-        } catch (NoSuchMethodException e) {
-            throw new XmlParsingException("Can not invoke the converter util class method " + methodName, e);
-        } catch (IllegalAccessException e) {
-            throw new XmlParsingException("Can not invoke the converter util class method " + methodName, e);
-        } catch (InvocationTargetException e) {
-            throw new XmlParsingException("Can not invoke the converter util class method " + methodName, e);
-        }
-        return returnObject;
-    }
-
-    private String getMethodName(String className) {
-        // first handle some exceptional casses
-        if (className.equals(Integer.class.getName())) {
-            return "convertToInt";
-        } else if (className.equals(Calendar.class.getName())) {
-            return "convertToDateTime";
-        }
-        if (className.indexOf(".") > -1) {
-            className = className.substring(className.lastIndexOf(".") + 1);
-        } else {
-            // this is a primitive type class
-            // so capitalize the firt letter
-            className = className.substring(0, 1).toUpperCase() + className.substring(1);
-        }
-        return "convertTo" + className;
-    }
-
-    /**
-     * give the relavent object for elementField.
-     *
-     * @param reader
-     * @param elementField
-     * @return
-     * @throws XMLStreamException
-     * @throws XmlParsingException
-     */
-
-    private Object getObjectForElementField(XMLStreamReader reader,
-                                            ElementField elementField)
-            throws XMLStreamException,
-            XmlParsingException {
-        QName elementFieldQName = new QName(elementField.getNamespace(), elementField.getName());
-        return getObjectForElement(reader,
-                elementFieldQName,
-                elementField.getType(),
-                elementField.isArray(),
-                elementField.getElement().isNillable(),
-                elementField.getElement().isMinOccurs0(),
-                elementField.getClassType(),
-                elementField.getPropertyDescriptor().getPropertyType());
-
-    }
-
-    /**
-     * element parser corresponds to parse the element (for an attribute or parameter) correctly.
-     * when calling to this method reader must point to the start element of the elemetnt. and when returning
-     * it should point to the corresponding end eleemnt of the element.
-     * if the element is an array it may point to the start element of the next element.
-     *
-     * @param reader
-     * @param elementQName
-     * @param elementType
-     * @param isArray
-     * @param classType
-     * @param javaClass - if this is a list javaClass for the list
-     * @return
-     * @throws XMLStreamException
-     * @throws XmlParsingException
-     */
-
-    private Object getObjectForElement(XMLStreamReader reader,
-                                       QName elementQName,
-                                       Type elementType,
-                                       boolean isArray,
-                                       boolean isNillable,
-                                       boolean isMinOccurs0,
-                                       int classType,
-                                       Class javaClass)
-            throws XMLStreamException,
-            XmlParsingException {
-        // first we have to point to the reader to the begining for the element
-        while (!reader.isStartElement() && !reader.isEndElement()) {
-            reader.next();
-        }
-
-        // first validate the attribute
-        if (reader.getName().equals(elementQName)) {
-
-            String nillble = reader.getAttributeValue(Constants.URI_DEFAULT_SCHEMA_XSI, "nil");
-            // actual element type may be different from the element type given
-            // if extensions has used.
-            Type actualElementType = elementType;
-            QName typeQName = getTypeQName(reader);
-            if ((typeQName != null) && !elementType.getXmlType().getQname().equals(typeQName)) {
-                // i.e this is an extension type
-                if (this.qNameToTypeMap.containsKey(typeQName)) {
-                    actualElementType = (Type) this.qNameToTypeMap.get(typeQName);
-                } else {
-                    throw new XmlParsingException("Unknown type found ==> " + typeQName);
-                }
-            }
-            // point to the complex type elements
-            if (isArray) {
-                Collection objectsCollection = getCollectionObject(classType, javaClass);
-
-                // read the first element
-                if ("true".equals(nillble) || "1".equals(nillble)) {
-                    // this is a nill attribute
-                    while (!reader.isEndElement()) {
-                        reader.next();
-                    }
-                    if (isNillable){
-                       objectsCollection.add(null);
-                    } else {
-                       throw new XmlParsingException("Element " + elementQName + " can not be null");
-                    }
-
-                } else {
-
-                    Object returnObject = getElementObjectFromReader(actualElementType, reader);
-                    objectsCollection.add(returnObject);
-
-                    // we have to move the cursor until the end element of this attribute
-                    while (!reader.isEndElement() || !reader.getName().equals(elementQName)) {
-                        reader.next();
-                    }
-                }
-                boolean loop = true;
-                while (loop) {
-                    while (!reader.isEndElement()) {
-                        reader.next();
-                    }
-                    reader.next();
-                    // now we are at the end element of the first element
-                    while (!reader.isStartElement() && !reader.isEndElement()) {
-                        reader.next();
-                    }
-
-                    // in this step if it is an end element we have found an end element
-                    // so have to exit from the loop
-                    if (reader.isEndElement()) {
-                        loop = false;
-                    } else {
-                        // now it should be in a start element
-                        // check whether still we read the original element attributes. otherwise return
-                        if (reader.getName().equals(elementQName)) {
-                            nillble = reader.getAttributeValue(Constants.URI_DEFAULT_SCHEMA_XSI, "nil");
-                            // since this is a new element we check for extensions
-                            actualElementType = elementType;
-                            typeQName = getTypeQName(reader);
-                            if ((typeQName != null) && !elementType.getXmlType().getQname().equals(typeQName)) {
-                                // i.e this is an extension type
-                                if (this.qNameToTypeMap.containsKey(typeQName)) {
-                                    actualElementType = (Type) this.qNameToTypeMap.get(typeQName);
-                                } else {
-                                    throw new XmlParsingException("Unknown type found ==> " + typeQName);
-                                }
-                            }
-                            if ("true".equals(nillble) || "1".equals(nillble)) {
-                                // this is a nill attribute
-                                while (!reader.isEndElement()) {
-                                    reader.next();
-                                }
-                                if (isNillable) {
-                                    objectsCollection.add(null);
-                                } else {
-                                    throw new XmlParsingException("Element " + elementQName + " can not be null");
-                                }
-                            } else {
-                                Object returnObject = getElementObjectFromReader(actualElementType, reader);
-                                objectsCollection.add(returnObject);
-
-                                // we have to move the cursor until the end element of this attribute
-                                while (!reader.isEndElement() || !reader.getName().equals(elementQName)) {
-                                    reader.next();
-                                }
-                            }
-                        } else {
-                            loop = false;
-                        }
-
-                    }
-                }
-
-                // this is very important in handling primitivs
-                // they can not have null values so if array then we have to return the
-                // array object is null
-                // for other also it is covenient to assume like that.
-                if ((Constants.OTHER_TYPE & classType) == Constants.OTHER_TYPE){
-                    // i.e this is not a collection type
-                    List objectsList = (List) objectsCollection;
-                    if ((objectsCollection.size() == 0) ||
-                            ((objectsCollection.size() == 1) && (objectsList.get(0) == null))) {
-                        return null;
-                    } else {
-                        // create an array with the original element type
-                        Object objectArray = Array.newInstance(elementType.getJavaClass(), objectsCollection.size());
-                        for (int i = 0; i < objectsCollection.size(); i++) {
-                            Array.set(objectArray, i, objectsList.get(i));
-                        }
-                        return objectArray;
-                    }
-                } else if ((Constants.COLLECTION_TYPE & classType) == Constants.COLLECTION_TYPE){
-                     if ((objectsCollection.size() == 0) ||
-                             ((objectsCollection.size() == 1) && (objectsCollection.iterator().next() == null))){
-                         return null;
-                     } else {
-                         return objectsCollection;
-                     }
-
-                } else if ((Constants.MAP_TYPE & classType) == Constants.MAP_TYPE){
-
-                    if ((objectsCollection.size() == 0) ||
-                            ((objectsCollection.size() == 1) && (objectsCollection.iterator().next() == null))) {
-                        return null;
-
-                    } else {
-                        List mapObjectsList = (List) objectsCollection;
-                        MapType mapType = null;
-                        Map mapObject = null;
-                        if (javaClass.isInterface()) {
-                            mapObject = new HashMap();
-                        } else {
-                            try {
-                                mapObject = (Map) javaClass.newInstance();
-                            } catch (InstantiationException e) {
-                                throw new XmlParsingException("Can not instantiate the java class " + javaClass.getName(), e);
-                            } catch (IllegalAccessException e) {
-                                throw new XmlParsingException("Can not instantiate the java class " + javaClass.getName(), e);
-                            }
-
-                        }
-                        for (Iterator iter = mapObjectsList.iterator(); iter.hasNext();) {
-                            mapType = (MapType) iter.next();
-                            mapObject.put(mapType.getKey(), mapType.getValue());
-                        }
-
-                        return mapObject;
-                    }
-
-                } else {
-                    throw new XmlParsingException("Unknow class type " + classType);
-                }
-
-            } else {
-                if ("true".equals(nillble) || "1".equals(nillble)) {
-                    // this is a nill attribute
-                    while (!reader.isEndElement()) {
-                        reader.next();
-                    }
-                    reader.next();
-                    if (isNillable) {
-                        return null;
-                    } else {
-                        throw new XmlParsingException("Element " + elementQName + " can not be null");
-                    }
-
-                } else {
-
-                    Object returnObject = getElementObjectFromReader(actualElementType, reader);
-                    // we have to move the cursor until the end element of this attribute
-                    while (!reader.isEndElement() || !reader.getName().equals(elementQName)) {
-                        reader.next();
-                    }
-                    return returnObject;
-                }
-            }
-        } else {
-            if (isMinOccurs0) {
-                return null;
-            } else {
-                throw new XmlParsingException("Unexpected Subelement " + reader.getName() + " but " +
-                        "expected " + elementQName.getLocalPart());
-            }
-        }
-    }
-
-    private Object getElementObjectFromReader(Type elementType,
-                                              XMLStreamReader reader)
-            throws XmlParsingException, XMLStreamException {
-        Object returnObject = null;
-        if (RMIBean.class.isAssignableFrom(elementType.getJavaClass())) {
-            // this is an rmi bean
-            // so invoke the static parse method
-            try {
-                Method parseMethod = elementType.getJavaClass().getMethod("parse", new Class[]{XMLStreamReader.class, XmlStreamParser.class});
-                returnObject = parseMethod.invoke(null, new Object[]{reader, this});
-            } catch (NoSuchMethodException e) {
-                throw new XmlParsingException("parse method has not been implemented correctly for the rmi bean "
-                        + elementType.getJavaClass().getName(), e);
-            } catch (IllegalAccessException e) {
-                throw new XmlParsingException("can not access parse method of the rmi bean "
-                        + elementType.getJavaClass().getName(), e);
-            } catch (InvocationTargetException e) {
-                throw new XmlParsingException("can not invoke parse method of the rmi bean "
-                        + elementType.getJavaClass().getName(), e);
-            }
-        } else {
-            // read the attributes.
-            Map javaMethodToValueMap = getJavaMethodValueHashMap(elementType, reader);
-            reader.next();
-            returnObject = getObjectForType(reader, elementType);
-            populateObjectAttributes(javaMethodToValueMap, returnObject);
-        }
-
-        return returnObject;
-    }
-
-    private void populateObjectAttributes(Map javaMethodToValueMap, Object returnObject) throws XmlParsingException {
-        Method javaMehtod;
-        try {
-            for (Iterator iter = javaMethodToValueMap.keySet().iterator();iter.hasNext();){
-                javaMehtod = (Method) iter.next();
-                javaMehtod.invoke(returnObject,new Object[]{javaMethodToValueMap.get(javaMehtod)});
-            }
-        } catch (IllegalAccessException e) {
-            throw new XmlParsingException("Can not set the attribute value");
-        } catch (InvocationTargetException e) {
-            throw new XmlParsingException("Can not set the attribute value");
-        }
-    }
-
-    private Map getJavaMethodValueHashMap(Type actualElementType, XMLStreamReader reader)
-            throws XmlParsingException {
-        AttributeField attributeField;
-        String attributeVlaue;
-        Object attributeObject;
-        Map javaMethodToValueMap = new HashMap();
-        for (Iterator iter = actualElementType.getAllAttributeFields().iterator();iter.hasNext();){
-            attributeField = (AttributeField) iter.next();
-            attributeVlaue = reader.getAttributeValue(attributeField.getNamespace(),
-                                                    attributeField.getName());
-            if (attributeVlaue != null) {
-                attributeObject = getSimpleTypeObject(attributeField.getType(), reader, attributeVlaue);
-                javaMethodToValueMap.put(attributeField.getSetterMethod(), attributeObject);
-            } else if (attributeField.isRequried()){
-                throw new XmlParsingException("Required attribute " + attributeField.getName() + " is missing");
-            }
-
-        }
-        return javaMethodToValueMap;
-    }
-
-    /**
-     * returtns the collection object according to the type.
-     * @param classType
-     * @param javaClass
-     * @return
-     * @throws XmlParsingException
-     */
-
-    private Collection getCollectionObject(int classType,
-                                           Class javaClass)
-            throws XmlParsingException {
-
-        Collection objectsCollection = null;
-        try {
-            if ((Constants.OTHER_TYPE & classType) == Constants.OTHER_TYPE) {
-                // i.e this is not a list or a map
-                objectsCollection = new ArrayList();
-            } else {
-                if (javaClass.isInterface()) {
-                    if ((Constants.LIST_TYPE & classType) == Constants.LIST_TYPE) {
-                       objectsCollection = new ArrayList();
-                    } else if ((Constants.SET_TYPE & classType) == Constants.SET_TYPE) {
-                       objectsCollection = new HashSet();
-                    } else if ((Constants.COLLECTION_TYPE & classType) == Constants.COLLECTION_TYPE) {
-                       objectsCollection = new ArrayList();
-                    } else if ((Constants.MAP_TYPE & classType) == Constants.MAP_TYPE) {
-                       objectsCollection = new ArrayList();
-                    }
-                } else {
-                    if ((Constants.COLLECTION_TYPE & classType) == Constants.COLLECTION_TYPE) {
-                        objectsCollection = (Collection) javaClass.newInstance();
-                    } else if ((Constants.MAP_TYPE & classType) == Constants.MAP_TYPE) {
-                        objectsCollection = new ArrayList();
-                    }
-                }
-            }
-
-        } catch (InstantiationException e) {
-            throw new XmlParsingException("Problem with instanciating the element class " +
-                        javaClass.getName() , e);
-        } catch (IllegalAccessException e) {
-            throw new XmlParsingException("Problem with instanciating the element class " +
-                        javaClass.getName() , e);
-        }
-        return objectsCollection;
-    }
-
-    /**
-     * reader must be at the start of the element
-     *
-     * @param reader
-     * @return qName for the type attribute
-     */
-    private QName getTypeQName(XMLStreamReader reader) {
-        QName typeQName = null;
-        String typeValue = reader.getAttributeValue(Constants.URI_2001_SCHEMA_XSI, "type");
-        if ((typeValue != null) && !typeValue.equals("")) {
-            int index = typeValue.indexOf(":");
-            String nsPrefix = "";
-            if (index > -1) {
-                nsPrefix = typeValue.substring(0, index);
-            }
-
-            String localPart = typeValue.substring(index + 1);
-            typeQName = new QName(reader.getNamespaceURI(nsPrefix), localPart);
-        }
-        return typeQName;
-    }
-
-}
+/*
+ * 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.axis2.rmi.databind;
+
+import org.apache.axis2.rmi.metadata.*;
+import org.apache.axis2.rmi.metadata.impl.TypeImpl;
+import org.apache.axis2.rmi.exception.XmlParsingException;
+import org.apache.axis2.rmi.exception.MetaDataPopulateException;
+import org.apache.axis2.rmi.exception.SchemaGenerationException;
+import org.apache.axis2.rmi.util.Constants;
+import org.apache.axis2.rmi.util.JavaTypeToQNameMap;
+import org.apache.axis2.rmi.Configurator;
+import org.apache.axis2.rmi.types.MapType;
+
+import javax.xml.stream.XMLStreamReader;
+import javax.xml.stream.XMLStreamException;
+import javax.xml.namespace.QName;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Array;
+import java.lang.reflect.Method;
+import java.util.*;
+
+public class XmlStreamParser {
+
+    private Configurator configurator;
+    private Map qNameToTypeMap;
+    private SimpleTypeHandler simpleTypeHandler;
+    private Class simpleTypeHandlerClass;
+    private boolean readerPriorAccess;
+    private boolean priorAccessDetermined = false;
+
+    public XmlStreamParser(Map processedTypeMap,
+                           Configurator configurator,
+                           Map schemaMap) {
+        this.configurator = configurator;
+        this.simpleTypeHandler = this.configurator.getSimpleTypeHandler();
+        this.simpleTypeHandlerClass = this.simpleTypeHandler.getClass();
+        try {
+            populateQNameToTypeMap(processedTypeMap, schemaMap);
+        } catch (MetaDataPopulateException e) {
+            // TODO: what to do this exceptions is not going to happen
+        } catch (SchemaGenerationException e) {
+            // TODO: what to do this exceptions is not going to happen
+        }
+    }
+
+    private void populateQNameToTypeMap(Map processedTypeMap, Map schemaMap)
+            throws MetaDataPopulateException,
+            SchemaGenerationException {
+        // first add all the proceced type map values
+        Set defaultTypeMapKeys = JavaTypeToQNameMap.getKeys();
+        Class typeClass;
+        for (Iterator iter = defaultTypeMapKeys.iterator(); iter.hasNext();) {
+            typeClass = (Class) iter.next();
+            if (!processedTypeMap.containsKey(typeClass)) {
+                Type newType = new TypeImpl(typeClass);
+                processedTypeMap.put(typeClass, newType);
+                newType.populateMetaData(this.configurator, processedTypeMap);
+                newType.generateSchema(this.configurator, schemaMap);
+            }
+        }
+        this.qNameToTypeMap = new HashMap();
+        Type type = null;
+        for (Iterator iter = processedTypeMap.values().iterator(); iter.hasNext();) {
+            type = (Type) iter.next();
+            this.qNameToTypeMap.put(type.getXmlType().getQname(), type);
+        }
+
+    }
+
+    public Object getOutputObject(XMLStreamReader reader_in,
+                                  Operation operation)
+            throws XMLStreamException, XmlParsingException {
+        Object returnObject = null;
+        
+        determinePriorAccess(reader_in);
+        StatefulXMLStreamReader reader = getStatefulReader(reader_in);
+        
+        advanceToFirstElement(reader);
+
+        // first check whether we have got the correct input element or not
+        if (reader.getLocalName().equals(operation.getOutPutElement().getName()) &&
+                reader.getNamespaceURI().equals(operation.getOutPutElement().getNamespace())) {
+            reader.next();
+            if (operation.getOutputParameter() != null) {
+                // i.e this is not a void return type
+                returnObject = getObjectForParameter(reader, operation.getOutputParameter());
+            }
+        }
+        return returnObject;
+    }
+
+    public Object[] getInputParameters(XMLStreamReader reader_in,
+                                       Operation operation)
+            throws XMLStreamException,
+            XmlParsingException {
+
+        determinePriorAccess(reader_in);
+        StatefulXMLStreamReader reader = getStatefulReader(reader_in);
+        
+        List returnObjects = new ArrayList();
+        advanceToFirstElement(reader);
+
+        // first check whether we have got the correct input element or not
+        if (reader.getLocalName().equals(operation.getInputElement().getName()) &&
+                reader.getNamespaceURI().equals(operation.getInputElement().getNamespace())) {
+            // point the reader to parameters
+            reader.next();
+            Parameter parameter = null;
+            List inputParameters = operation.getInputParameters();
+            QName parameterQName = null;
+            int startDepth = reader.getDepth();
+            
+            for (Iterator iter = inputParameters.iterator(); iter.hasNext();) {
+                parameter = (Parameter) iter.next();
+                parameterQName = new QName(parameter.getNamespace(), parameter.getName());
+                returnObjects.add(getObjectForParameter(reader, parameter));
+                // if the reader is at the end of this parameter
+                // then we move it to next element.
+                if (reader.isEndElement() && reader.getName().equals(parameterQName)
+                        && (readerPriorAccess || reader.getDepth() == startDepth - 1)){
+                    reader.next();
+                }
+            }
+
+        } else {
+            throw new XmlParsingException("Unexpected Subelement " + reader.getName() + " but " +
+                    "expected " + operation.getInputElement().getName());
+        }
+        return returnObjects.toArray();
+    }
+
+    /**
+     * parameter has the same logic as the attribute. so reader pre and post conditions same.
+     *
+     * @param reader
+     * @param parameter
+     * @return
+     * @throws XMLStreamException
+     * @throws XmlParsingException
+     */
+
+    public Object getObjectForParameter(XMLStreamReader reader_in,
+                                        Parameter parameter)
+            throws XMLStreamException,
+            XmlParsingException {
+
+        QName parameterQName = new QName(parameter.getNamespace(), parameter.getName());
+        
+        determinePriorAccess(reader_in);
+        StatefulXMLStreamReader reader = getStatefulReader(reader_in);
+        
+        return getObjectForElement(reader,
+                parameterQName,
+                parameter.getType(),
+                parameter.isArray(),
+                parameter.getElement().isNillable(),
+                parameter.getElement().isMinOccurs0(),
+                parameter.getClassType(),
+                parameter.getJavaClass());
+
+    }
+
+    /**
+     * when calls to this method reader must point to the start of the type.
+     * if it is a simple type it points the the text
+     * if it is a complex type it points to the start element of the first attribute. and we returning
+     * from the method it should point to the end element of the last parameter.
+     *
+     * @param reader
+     * @param type
+     * @return
+     * @throws XMLStreamException
+     * @throws XmlParsingException
+     */
+
+
+    public Object getObjectForType(XMLStreamReader reader_in,
+                                   Type type)
+            throws XMLStreamException,
+            XmlParsingException {
+
+        try {
+            determinePriorAccess(reader_in);
+            StatefulXMLStreamReader reader = getStatefulReader(reader_in);
+            
+            Object returnObject = null;
+            if (type.getXmlType().isSimpleType()) {
+                // this is a simple known type for us
+                // constructor should be able to invoke with the string.
+                if (type.getJavaClass().equals(Object.class)) {
+                    returnObject = new Object();
+                } else {
+                    // find the object for this string using converter util classes
+                    returnObject = getSimpleTypeObject(type, reader, reader.getText());
+                }
+            } else {
+                // first we have to point to the reader to the beginning for the element
+                while (!reader.isStartElement() && !reader.isEndElement()) {
+                    reader.next();
+                }
+                int startDepth = reader.getDepth();
+                // this is a complex type
+                returnObject = type.getJavaClass().newInstance();
+                // we have to get all the elementField and populate them
+                List elementFields = type.getAllElementFields();
+                ElementField elementField;
+                Object elementFieldObject;
+                QName elementFieldQName = null;
+
+                for (Iterator iter = elementFields.iterator(); iter.hasNext();) {
+                    elementField = (ElementField) iter.next();
+                    elementFieldObject = getObjectForElementField(reader, elementField);
+                    elementFieldQName = new QName(elementField.getNamespace(), elementField.getName());
+                    if (elementFieldObject != null) {
+                        elementField.getSetterMethod().invoke(returnObject, new Object[]{elementFieldObject});
+                    }
+                    // if the reader is at the end of this elementField
+                    // then we move it to next element.
+                    if (reader.isEndElement() && reader.getName().equals(elementFieldQName) 
+                            && (readerPriorAccess || reader.getDepth() == startDepth - 1)){
+                        reader.next();
+                    }
+
+                }
+
+            }
+            return returnObject;
+        } catch (InstantiationException e) {
+            throw new XmlParsingException("Constructor invoking exception for type " + type.getName());
+        } catch (IllegalAccessException e) {
+            throw new XmlParsingException("Constructor invoking exception for type " + type.getName());
+        } catch (InvocationTargetException e) {
+            e.printStackTrace();
+            throw new XmlParsingException("Constructor invoking exception for type " + type.getName());
+        }
+
+    }
+
+    private Object getSimpleTypeObject(Type type, StatefulXMLStreamReader reader, String value)
+            throws  XmlParsingException {
+        Object returnObject;
+        String methodName = null;
+        try {
+            methodName = getMethodName(type.getJavaClass().getName());
+            Method  methodToInvoke = this.simpleTypeHandlerClass.getMethod(methodName,new Class[]{String.class});
+            returnObject = methodToInvoke.invoke(this.simpleTypeHandler,new Object[]{value});
+        } catch (NoSuchMethodException e) {
+            throw new XmlParsingException("Can not invoke the converter util class method " + methodName, e);
+        } catch (IllegalAccessException e) {
+            throw new XmlParsingException("Can not invoke the converter util class method " + methodName, e);
+        } catch (InvocationTargetException e) {
+            throw new XmlParsingException("Can not invoke the converter util class method " + methodName, e);
+        }
+        return returnObject;
+    }
+
+    private String getMethodName(String className) {
+        // first handle some exceptional classes
+        if (className.equals(Integer.class.getName())) {
+            return "convertToInt";
+        } else if (className.equals(Calendar.class.getName())) {
+            return "convertToDateTime";
+        }
+        if (className.indexOf(".") > -1) {
+            className = className.substring(className.lastIndexOf(".") + 1);
+        } else {
+            // this is a primitive type class
+            // so capitalize the first letter
+            className = className.substring(0, 1).toUpperCase() + className.substring(1);
+        }
+        return "convertTo" + className;
+    }
+
+    /**
+     * give the relevant object for elementField.
+     *
+     * @param reader
+     * @param elementField
+     * @return
+     * @throws XMLStreamException
+     * @throws XmlParsingException
+     */
+
+    private Object getObjectForElementField(StatefulXMLStreamReader reader,
+                                            ElementField elementField)
+            throws XMLStreamException,
+            XmlParsingException {
+        QName elementFieldQName = new QName(elementField.getNamespace(), elementField.getName());
+        return getObjectForElement(reader,
+                elementFieldQName,
+                elementField.getType(),
+                elementField.isArray(),
+                elementField.getElement().isNillable(),
+                elementField.getElement().isMinOccurs0(),
+                elementField.getClassType(),
+                elementField.getPropertyDescriptor().getPropertyType());
+
+    }
+
+    /**
+     * element parser corresponds to parse the element (for an attribute or parameter) correctly.
+     * when calling to this method reader must point to the start element of the element. and when returning
+     * it should point to the corresponding end element of the element.
+     * if the element is an array it may point to the start element of the next element.
+     *
+     * @param reader
+     * @param elementQName
+     * @param elementType
+     * @param isArray
+     * @param classType
+     * @param javaClass - if this is a list javaClass for the list
+     * @return
+     * @throws XMLStreamException
+     * @throws XmlParsingException
+     */
+
+    private Object getObjectForElement(StatefulXMLStreamReader reader,
+                                       QName elementQName,
+                                       Type elementType,
+                                       boolean isArray,
+                                       boolean isNillable,
+                                       boolean isMinOccurs0,
+                                       int classType,
+                                       Class javaClass)
+            throws XMLStreamException,
+            XmlParsingException {
+        // first we have to point to the reader to the beginning for the element
+        while (!reader.isStartElement() && !reader.isEndElement()) {
+            reader.next();
+        }
+
+        // first validate the attribute
+        if (reader.getName().equals(elementQName)) {
+
+            String nillble = reader.getAttributeValue(Constants.URI_DEFAULT_SCHEMA_XSI, "nil");
+            // actual element type may be different from the element type given
+            // if extensions has used.
+            Type actualElementType = elementType;
+            QName typeQName = getTypeQName(reader);
+            if ((typeQName != null) && !elementType.getXmlType().getQname().equals(typeQName)) {
+                // i.e this is an extension type
+                if (this.qNameToTypeMap.containsKey(typeQName)) {
+                    actualElementType = (Type) this.qNameToTypeMap.get(typeQName);
+                } else {
+                    throw new XmlParsingException("Unknown type found ==> " + typeQName);
+                }
+            }
+            // point to the complex type elements
+            if (isArray) {
+                Collection objectsCollection = getCollectionObject(classType, javaClass);
+
+                // read the first element
+                if ("true".equals(nillble) || "1".equals(nillble)) {
+                    // this is a nill attribute
+                    while (!reader.isEndElement()) {
+                        reader.next();
+                    }
+                    if (isNillable){
+                       objectsCollection.add(null);
+                    } else {
+                       throw new XmlParsingException("Element " + elementQName + " can not be null");
+                    }
+
+                } else {
+
+                    Object returnObject = getElementObjectFromReader(actualElementType, reader);
+                    objectsCollection.add(returnObject);
+
+                    // we have to move the cursor until the end element of this attribute
+                    while (!reader.isEndElement() || !reader.getName().equals(elementQName)) {
+                        reader.next();
+                    }
+                }
+                boolean loop = true;
+                while (loop) {
+                    while (!reader.isEndElement()) {
+                        reader.next();
+                    }
+                    reader.next();
+                    // now we are at the end element of the first element
+                    while (!reader.isStartElement() && !reader.isEndElement()) {
+                        reader.next();
+                    }
+
+                    // in this step if it is an end element we have found an end element
+                    // so have to exit from the loop
+                    if (reader.isEndElement()) {
+                        loop = false;
+                    } else {
+                        // now it should be in a start element
+                        // check whether still we read the original element attributes. otherwise return
+                        if (reader.getName().equals(elementQName)) {
+                            nillble = reader.getAttributeValue(Constants.URI_DEFAULT_SCHEMA_XSI, "nil");
+                            // since this is a new element we check for extensions
+                            actualElementType = elementType;
+                            typeQName = getTypeQName(reader);
+                            if ((typeQName != null) && !elementType.getXmlType().getQname().equals(typeQName)) {
+                                // i.e this is an extension type
+                                if (this.qNameToTypeMap.containsKey(typeQName)) {
+                                    actualElementType = (Type) this.qNameToTypeMap.get(typeQName);
+                                } else {
+                                    throw new XmlParsingException("Unknown type found ==> " + typeQName);
+                                }
+                            }
+                            if ("true".equals(nillble) || "1".equals(nillble)) {
+                                // this is a nill attribute
+                                while (!reader.isEndElement()) {
+                                    reader.next();
+                                }
+                                if (isNillable) {
+                                    objectsCollection.add(null);
+                                } else {
+                                    throw new XmlParsingException("Element " + elementQName + " can not be null");
+                                }
+                            } else {
+                                Object returnObject = getElementObjectFromReader(actualElementType, reader);
+                                objectsCollection.add(returnObject);
+
+                                // we have to move the cursor until the end element of this attribute
+                                while (!reader.isEndElement() || !reader.getName().equals(elementQName)) {
+                                    reader.next();
+                                }
+                            }
+                        } else {
+                            loop = false;
+                        }
+
+                    }
+                }
+
+                // this is very important in handling primitives
+                // they can not have null values so if array then we have to return the
+                // array object is null
+                // for other also it is convenient to assume like that.
+                if ((Constants.OTHER_TYPE & classType) == Constants.OTHER_TYPE){
+                    // i.e this is not a collection type
+                    List objectsList = (List) objectsCollection;
+                    if ((objectsCollection.size() == 0) ||
+                            ((objectsCollection.size() == 1) && (objectsList.get(0) == null))) {
+                        return null;
+                    } else {
+                        // create an array with the original element type
+                        Object objectArray = Array.newInstance(elementType.getJavaClass(), objectsCollection.size());
+                        for (int i = 0; i < objectsCollection.size(); i++) {
+                            Array.set(objectArray, i, objectsList.get(i));
+                        }
+                        return objectArray;
+                    }
+                } else if ((Constants.COLLECTION_TYPE & classType) == Constants.COLLECTION_TYPE){
+                     if ((objectsCollection.size() == 0) ||
+                             ((objectsCollection.size() == 1) && (objectsCollection.iterator().next() == null))){
+                         return null;
+                     } else {
+                         return objectsCollection;
+                     }
+
+                } else if ((Constants.MAP_TYPE & classType) == Constants.MAP_TYPE){
+
+                    if ((objectsCollection.size() == 0) ||
+                            ((objectsCollection.size() == 1) && (objectsCollection.iterator().next() == null))) {
+                        return null;
+
+                    } else {
+                        List mapObjectsList = (List) objectsCollection;
+                        MapType mapType = null;
+                        Map mapObject = null;
+                        if (javaClass.isInterface()) {
+                            mapObject = new HashMap();
+                        } else {
+                            try {
+                                mapObject = (Map) javaClass.newInstance();
+                            } catch (InstantiationException e) {
+                                throw new XmlParsingException("Can not instantiate the java class " + javaClass.getName(), e);
+                            } catch (IllegalAccessException e) {
+                                throw new XmlParsingException("Can not instantiate the java class " + javaClass.getName(), e);
+                            }
+
+                        }
+                        for (Iterator iter = mapObjectsList.iterator(); iter.hasNext();) {
+                            mapType = (MapType) iter.next();
+                            mapObject.put(mapType.getKey(), mapType.getValue());
+                        }
+
+                        return mapObject;
+                    }
+
+                } else {
+                    throw new XmlParsingException("Unknow class type " + classType);
+                }
+
+            } else {
+                if ("true".equals(nillble) || "1".equals(nillble)) {
+                    // this is a nill attribute
+                    while (!reader.isEndElement()) {
+                        reader.next();
+                    }
+                    reader.next();
+                    if (isNillable) {
+                        return null;
+                    } else {
+                        throw new XmlParsingException("Element " + elementQName + " can not be null");
+                    }
+
+                } else {
+
+                    Object returnObject = getElementObjectFromReader(actualElementType, reader);
+                    // we have to move the cursor until the end element of this attribute
+                    while (!reader.isEndElement() || !reader.getName().equals(elementQName)) {
+                        reader.next();
+                    }
+                    return returnObject;
+                }
+            }
+        } else {
+            if (isMinOccurs0) {
+                return null;
+            } else {
+                throw new XmlParsingException("Unexpected Subelement " + reader.getName() + " but " +
+                        "expected " + elementQName.getLocalPart());
+            }
+        }
+    }
+
+    private Object getElementObjectFromReader(Type elementType,
+                                              StatefulXMLStreamReader reader)
+            throws XmlParsingException, XMLStreamException {
+        Object returnObject = null;
+        if (RMIBean.class.isAssignableFrom(elementType.getJavaClass())) {
+            // this is an rmi bean
+            // so invoke the static parse method
+            try {
+                Method parseMethod = elementType.getJavaClass().getMethod("parse", new Class[]{XMLStreamReader.class, XmlStreamParser.class});
+                returnObject = parseMethod.invoke(null, new Object[]{reader, this});
+            } catch (NoSuchMethodException e) {
+                throw new XmlParsingException("parse method has not been implemented correctly for the rmi bean "
+                        + elementType.getJavaClass().getName(), e);
+            } catch (IllegalAccessException e) {
+                throw new XmlParsingException("can not access parse method of the rmi bean "
+                        + elementType.getJavaClass().getName(), e);
+            } catch (InvocationTargetException e) {
+                throw new XmlParsingException("can not invoke parse method of the rmi bean "
+                        + elementType.getJavaClass().getName(), e);
+            }
+        } else {
+            // read the attributes.
+            Map javaMethodToValueMap = getJavaMethodValueHashMap(elementType, reader);
+            reader.next();
+            returnObject = getObjectForType(reader, elementType);
+            populateObjectAttributes(javaMethodToValueMap, returnObject);
+        }
+
+        return returnObject;
+    }
+
+    private void populateObjectAttributes(Map javaMethodToValueMap, Object returnObject) throws XmlParsingException {
+        Method javaMehtod;
+        try {
+            for (Iterator iter = javaMethodToValueMap.keySet().iterator();iter.hasNext();){
+                javaMehtod = (Method) iter.next();
+                javaMehtod.invoke(returnObject,new Object[]{javaMethodToValueMap.get(javaMehtod)});
+            }
+        } catch (IllegalAccessException e) {
+            throw new XmlParsingException("Can not set the attribute value");
+        } catch (InvocationTargetException e) {
+            throw new XmlParsingException("Can not set the attribute value");
+        }
+    }
+
+    private Map getJavaMethodValueHashMap(Type actualElementType, StatefulXMLStreamReader reader)
+            throws XmlParsingException {
+        AttributeField attributeField;
+        String attributeVlaue;
+        Object attributeObject;
+        Map javaMethodToValueMap = new HashMap();
+        for (Iterator iter = actualElementType.getAllAttributeFields().iterator();iter.hasNext();){
+            attributeField = (AttributeField) iter.next();
+            attributeVlaue = reader.getAttributeValue(attributeField.getNamespace(),
+                                                    attributeField.getName());
+            if (attributeVlaue != null) {
+                attributeObject = getSimpleTypeObject(attributeField.getType(), reader, attributeVlaue);
+                javaMethodToValueMap.put(attributeField.getSetterMethod(), attributeObject);
+            } else if (attributeField.isRequried()){
+                throw new XmlParsingException("Required attribute " + attributeField.getName() + " is missing");
+            }
+
+        }
+        return javaMethodToValueMap;
+    }
+
+    /**
+     * returns the collection object according to the type.
+     * @param classType
+     * @param javaClass
+     * @return
+     * @throws XmlParsingException
+     */
+
+    private Collection getCollectionObject(int classType,
+                                           Class javaClass)
+            throws XmlParsingException {
+
+        Collection objectsCollection = null;
+        try {
+            if ((Constants.OTHER_TYPE & classType) == Constants.OTHER_TYPE) {
+                // i.e this is not a list or a map
+                objectsCollection = new ArrayList();
+            } else {
+                if (javaClass.isInterface()) {
+                    if ((Constants.LIST_TYPE & classType) == Constants.LIST_TYPE) {
+                       objectsCollection = new ArrayList();
+                    } else if ((Constants.SET_TYPE & classType) == Constants.SET_TYPE) {
+                       objectsCollection = new HashSet();
+                    } else if ((Constants.COLLECTION_TYPE & classType) == Constants.COLLECTION_TYPE) {
+                       objectsCollection = new ArrayList();
+                    } else if ((Constants.MAP_TYPE & classType) == Constants.MAP_TYPE) {
+                       objectsCollection = new ArrayList();
+                    }
+                } else {
+                    if ((Constants.COLLECTION_TYPE & classType) == Constants.COLLECTION_TYPE) {
+                        objectsCollection = (Collection) javaClass.newInstance();
+                    } else if ((Constants.MAP_TYPE & classType) == Constants.MAP_TYPE) {
+                        objectsCollection = new ArrayList();
+                    }
+                }
+            }
+
+        } catch (InstantiationException e) {
+            throw new XmlParsingException("Problem with instanciating the element class " +
+                        javaClass.getName() , e);
+        } catch (IllegalAccessException e) {
+            throw new XmlParsingException("Problem with instanciating the element class " +
+                        javaClass.getName() , e);
+        }
+        return objectsCollection;
+    }
+
+    /**
+     * reader must be at the start of the element
+     *
+     * @param reader
+     * @return qName for the type attribute
+     */
+    private QName getTypeQName(StatefulXMLStreamReader reader) {
+        QName typeQName = null;
+        String typeValue = reader.getAttributeValue(Constants.URI_2001_SCHEMA_XSI, "type");
+        if ((typeValue != null) && !typeValue.equals("")) {
+            int index = typeValue.indexOf(":");
+            String nsPrefix = "";
+            if (index > -1) {
+                nsPrefix = typeValue.substring(0, index);
+            }
+
+            String localPart = typeValue.substring(index + 1);
+            typeQName = new QName(reader.getNamespaceURI(nsPrefix), localPart);
+        }
+        return typeQName;
+    }
+
+    /** 
+     * Determine if the reader has been advanced beyond its initial location, prior 
+     * to the methods within XmlStreamParser being called.
+     * 
+     * @param reader The XMLStreamReader on which the XmlStreamParser is acting.
+     * @return true if the reader has been advanced beyond its initial location, false otherwise
+     */
+    private boolean determinePriorAccess(XMLStreamReader reader) {
+        if (!priorAccessDetermined) {
+            if (reader.getLocation().getCharacterOffset() == 0)
+                readerPriorAccess = false;
+            else
+                readerPriorAccess = true;
+
+            priorAccessDetermined = true;
+        }
+        return readerPriorAccess;
+    }
+
+    /**
+     * Provide a mechanism (a stack) to track the current state of the XMLStream
+     * 
+     * @param reader_in the XMLStreamReader that the XmlStreamParser is acting on
+     * @return a StatefulXMLStreamReader to monitor the state of the XMLStreamReader
+     */
+    private StatefulXMLStreamReader getStatefulReader(XMLStreamReader reader_in) {
+        if (reader_in instanceof StatefulXMLStreamReader)            
+            return (StatefulXMLStreamReader) reader_in;
+        else
+            return new StatefulXMLStreamReader(reader_in, readerPriorAccess);
+    }
+    
+    /**
+     * Advance the reader to point to the beginning of the element
+     * @param reader the StatefulXMLStreamReader we are using to parse the XMLStream
+     */
+    
+    private void advanceToFirstElement(StatefulXMLStreamReader reader) throws XMLStreamException {
+    
+        if (readerPriorAccess) {
+            while (!reader.isStartElement() && !reader.isEndElement() && reader.hasNext()) {
+                reader.next();
+            }
+        } else {
+            while (reader.getDepth() == 0 && reader.hasNext()) {
+                reader.next();
+            }
+        }
+    }
+}

Added: webservices/axis2/trunk/java/modules/rmi/test/org/apache/axis2/rmi/databind/SameParamNameTest.java
URL: http://svn.apache.org/viewvc/webservices/axis2/trunk/java/modules/rmi/test/org/apache/axis2/rmi/databind/SameParamNameTest.java?rev=600634&view=auto
==============================================================================
--- webservices/axis2/trunk/java/modules/rmi/test/org/apache/axis2/rmi/databind/SameParamNameTest.java (added)
+++ webservices/axis2/trunk/java/modules/rmi/test/org/apache/axis2/rmi/databind/SameParamNameTest.java Mon Dec  3 10:58:02 2007
@@ -0,0 +1,117 @@
+/*
+ * 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.axis2.rmi.databind;
+
+import org.apache.axis2.rmi.databind.dto.*;
+import org.apache.axis2.rmi.metadata.Parameter;
+
+public class SameParamNameTest extends DataBindTest {
+
+    public void testElementArray() {
+        Class testClass = TestClass14.class;
+        Parameter parameter = new Parameter(testClass, "Param1");
+        TestClass14 testObject = null;
+        TestClass14 result = null;
+
+        testObject = new TestClass14();
+        result = (TestClass14) getReturnObject(parameter, testObject);
+        assertNull(result.getParam1());
+
+        testObject = new TestClass14();
+        testObject.setParam1(new TestClass9());
+        result = (TestClass14) getReturnObject(parameter, testObject);
+        assertNotNull(result.getParam1());
+
+        testObject = new TestClass14();
+        TestClass2[] testClass2Array = new TestClass2[2];
+
+        testClass2Array[0] = new TestClass2();
+        testClass2Array[0].setParam1(5);   
+        testClass2Array[0].setParam2((float) 6.1);
+        testClass2Array[0].setParam3(7.2);
+      
+        testClass2Array[1] = new TestClass2();
+        testClass2Array[1].setParam1(1);   
+        testClass2Array[1].setParam2((float) 2.1);
+        testClass2Array[1].setParam3(3.2);
+        
+        TestClass9 testClass9Object = new TestClass9();
+        
+        testClass9Object.setParam1(testClass2Array);
+        
+        testObject.setParam1(testClass9Object);
+        
+        result = (TestClass14) getReturnObject(parameter, testObject);
+        
+        assertTrue(result.getParam1().getParam1()[0].getParam1() == 5);
+        assertTrue(result.getParam1().getParam1()[0].getParam2() == 6.1f);
+        assertTrue(result.getParam1().getParam1()[0].getParam3() == 7.2);
+        
+        assertTrue(result.getParam1().getParam1()[1].getParam1() == 1);
+        assertTrue(result.getParam1().getParam1()[1].getParam2() == 2.1f);
+        assertTrue(result.getParam1().getParam1()[1].getParam3() == 3.2);
+        
+    }
+    
+    public void testElementElement() {
+    	Class testClass = TestClass15.class;
+        Parameter parameter = new Parameter(testClass, "Param1");
+        TestClass15 testObject = null;
+        TestClass15 result = null;
+
+        testObject = new TestClass15();
+        result = (TestClass15) getReturnObject(parameter, testObject);
+        assertNull(result.getParam1());
+
+        testObject = new TestClass15();
+        testObject.setParam1(new TestClass14());
+        result = (TestClass15) getReturnObject(parameter, testObject);
+        assertNotNull(result.getParam1());
+
+        testObject = new TestClass15();
+        TestClass2[] testClass2Array = new TestClass2[2];
+
+        testClass2Array[0] = new TestClass2();
+        testClass2Array[0].setParam1(5);   
+        testClass2Array[0].setParam2((float) 6.1);
+        testClass2Array[0].setParam3(7.2);
+      
+        testClass2Array[1] = new TestClass2();
+        testClass2Array[1].setParam1(1);   
+        testClass2Array[1].setParam2((float) 2.1);
+        testClass2Array[1].setParam3(3.2);
+        
+        TestClass9 testClass9Object = new TestClass9();
+        
+        testClass9Object.setParam1(testClass2Array);
+        
+        TestClass14 testClass14Object = new TestClass14();
+        testClass14Object.setParam1(testClass9Object);
+        
+        testObject.setParam1(testClass14Object);
+        
+        result = (TestClass15) getReturnObject(parameter, testObject);
+        
+        assertTrue(result.getParam1().getParam1().getParam1()[0].getParam1() == 5);
+        assertTrue(result.getParam1().getParam1().getParam1()[0].getParam2() == 6.1f);
+        assertTrue(result.getParam1().getParam1().getParam1()[0].getParam3() == 7.2);
+        
+        assertTrue(result.getParam1().getParam1().getParam1()[1].getParam1() == 1);
+        assertTrue(result.getParam1().getParam1().getParam1()[1].getParam2() == 2.1f);
+        assertTrue(result.getParam1().getParam1().getParam1()[1].getParam3() == 3.2);
+        
+    }
+}

Added: webservices/axis2/trunk/java/modules/rmi/test/org/apache/axis2/rmi/databind/dto/TestClass14.java
URL: http://svn.apache.org/viewvc/webservices/axis2/trunk/java/modules/rmi/test/org/apache/axis2/rmi/databind/dto/TestClass14.java?rev=600634&view=auto
==============================================================================
--- webservices/axis2/trunk/java/modules/rmi/test/org/apache/axis2/rmi/databind/dto/TestClass14.java (added)
+++ webservices/axis2/trunk/java/modules/rmi/test/org/apache/axis2/rmi/databind/dto/TestClass14.java Mon Dec  3 10:58:02 2007
@@ -0,0 +1,29 @@
+/*
+ * 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.axis2.rmi.databind.dto;
+
+public class TestClass14 {
+    
+    private TestClass9 param1;
+
+    public TestClass9 getParam1() {
+        return param1;
+    }
+
+    public void setParam1(TestClass9 param1) {
+        this.param1 = param1;
+    }    
+}

Added: webservices/axis2/trunk/java/modules/rmi/test/org/apache/axis2/rmi/databind/dto/TestClass15.java
URL: http://svn.apache.org/viewvc/webservices/axis2/trunk/java/modules/rmi/test/org/apache/axis2/rmi/databind/dto/TestClass15.java?rev=600634&view=auto
==============================================================================
--- webservices/axis2/trunk/java/modules/rmi/test/org/apache/axis2/rmi/databind/dto/TestClass15.java (added)
+++ webservices/axis2/trunk/java/modules/rmi/test/org/apache/axis2/rmi/databind/dto/TestClass15.java Mon Dec  3 10:58:02 2007
@@ -0,0 +1,30 @@
+/*
+ * 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.axis2.rmi.databind.dto;
+
+public class TestClass15 {
+    
+    private TestClass14 param1;
+
+    public TestClass14 getParam1() {
+        return param1;
+    }
+
+    public void setParam1(TestClass14 param1) {
+        this.param1 = param1;
+    }    
+}
+



---------------------------------------------------------------------
To unsubscribe, e-mail: axis-cvs-unsubscribe@ws.apache.org
For additional commands, e-mail: axis-cvs-help@ws.apache.org