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