Author: djencks Date: Thu Feb 24 13:14:04 2005 New Revision: 155249 URL: http://svn.apache.org/viewcvs?view=rev&rev=155249 Log: partial implementation of java-xml mapping support that sets up axis TypeDesc objects
Added: geronimo/trunk/modules/axis-builder/src/java/org/apache/geronimo/axis/builder/SchemaTypeKey.java geronimo/trunk/modules/axis-builder/src/test-resources/schema/ geronimo/trunk/modules/axis-builder/src/test-resources/schema/schema1.xsd geronimo/trunk/modules/axis-builder/src/test/org/apache/geronimo/axis/builder/ParsingTest.java Modified: geronimo/trunk/modules/axis-builder/src/java/org/apache/geronimo/axis/builder/AxisBuilder.java geronimo/trunk/modules/axis-builder/src/java/org/apache/geronimo/axis/builder/WSDescriptorParser.java geronimo/trunk/modules/axis-builder/src/test/org/apache/geronimo/axis/builder/ServiceReferenceTest.java geronimo/trunk/modules/axis/src/java/org/apache/geronimo/axis/client/SEIFactoryImpl.java geronimo/trunk/modules/axis/src/test/org/apache/geronimo/axis/preconditions/DynamicEJBDeploymentTest.java geronimo/trunk/modules/axis/src/test/org/apache/geronimo/axis/testUtils/TestingUtils.java Modified: geronimo/trunk/modules/axis-builder/src/java/org/apache/geronimo/axis/builder/AxisBuilder.java URL: http://svn.apache.org/viewcvs/geronimo/trunk/modules/axis-builder/src/java/org/apache/geronimo/axis/builder/AxisBuilder.java?view=diff&r1=155248&r2=155249 ============================================================================== --- geronimo/trunk/modules/axis-builder/src/java/org/apache/geronimo/axis/builder/AxisBuilder.java (original) +++ geronimo/trunk/modules/axis-builder/src/java/org/apache/geronimo/axis/builder/AxisBuilder.java Thu Feb 24 13:14:04 2005 @@ -32,7 +32,11 @@ import java.util.List; import java.util.Map; import java.util.Set; +import java.util.Collections; import java.util.jar.JarFile; +import java.beans.PropertyDescriptor; +import java.beans.Introspector; +import java.beans.IntrospectionException; import javax.wsdl.Binding; import javax.wsdl.BindingInput; import javax.wsdl.BindingOperation; @@ -63,6 +67,10 @@ import org.apache.axis.description.FaultDesc; import org.apache.axis.description.OperationDesc; import org.apache.axis.description.ParameterDesc; +import org.apache.axis.description.TypeDesc; +import org.apache.axis.description.FieldDesc; +import org.apache.axis.description.AttributeDesc; +import org.apache.axis.description.ElementDesc; import org.apache.axis.encoding.ser.ArrayDeserializerFactory; import org.apache.axis.encoding.ser.ArraySerializerFactory; import org.apache.axis.encoding.ser.BeanDeserializerFactory; @@ -97,6 +105,8 @@ import org.apache.geronimo.xbeans.j2ee.ServiceEndpointMethodMappingType; import org.apache.geronimo.xbeans.j2ee.WsdlMessageMappingType; import org.apache.geronimo.xbeans.j2ee.WsdlReturnValueMappingType; +import org.apache.geronimo.xbeans.j2ee.VariableMappingType; +import org.apache.xmlbeans.SchemaType; import org.objectweb.asm.Type; import org.w3.x2001.xmlSchema.ComplexType; import org.w3.x2001.xmlSchema.ExplicitGroup; @@ -113,7 +123,7 @@ //WebServiceBuilder public void configurePOJO(GBeanData targetGBean, Object portInfoObject, String seiClassName) throws DeploymentException { - PortInfo portInfo = (PortInfo)portInfoObject; + PortInfo portInfo = (PortInfo) portInfoObject; System.out.println("NOT CONFIGURING WEB SERVICE " + portInfo.getPortName()); } @@ -211,6 +221,7 @@ Map complexTypeMap = WSDescriptorParser.getComplexTypesInWsdl(definition); Map exceptionMap = WSDescriptorParser.getExceptionMap(mapping); + Map schemaTypeKeyToSchemaTypeMap = WSDescriptorParser.buildSchemaTypeKeyToSchemaTypeMap(definition); for (Iterator iterator = wsdlPortMap.entrySet().iterator(); iterator.hasNext();) { Map.Entry entry = (Map.Entry) iterator.next(); @@ -254,8 +265,9 @@ OperationInfo operationInfo = buildOperationInfoLightweight(method, bindingOperation, portStyle, soapVersion); operationInfos[i++] = operationInfo; } - List typeMappings = new ArrayList(); - seiFactory = createSEIFactory(portName, enhancedServiceEndpointClass, serviceImpl, typeMappings, location, operationInfos, handlerInfos, context, classLoader); + List typeMappings = Collections.EMPTY_LIST; + Map typeDescriptors = Collections.EMPTY_MAP; + seiFactory = createSEIFactory(portName, enhancedServiceEndpointClass, serviceImpl, typeMappings, typeDescriptors, location, operationInfos, handlerInfos, context, classLoader); } else { //complete jaxrpc mapping file supplied QName portTypeQName = portType.getQName(); @@ -280,6 +292,7 @@ } JavaXmlTypeMappingType[] javaXmlTypeMappings = mapping.getJavaXmlTypeMappingArray(); List typeMappings = new ArrayList(); + Map typeDescriptors = new HashMap(); for (int j = 0; j < javaXmlTypeMappings.length; j++) { JavaXmlTypeMappingType javaXmlTypeMapping = javaXmlTypeMappings[j]; //default settings @@ -299,10 +312,15 @@ deserializerFactoryClass = ArrayDeserializerFactory.class; } + QName typeName; + SchemaTypeKey key; TypeMappingInfo typeMappingInfo = null; + boolean isElement = javaXmlTypeMapping.getQnameScope().getStringValue().equals("element"); + boolean isSimpleType = javaXmlTypeMapping.getQnameScope().getStringValue().equals("simpleType"); if (javaXmlTypeMapping.isSetRootTypeQname()) { - QName typeName = javaXmlTypeMapping.getRootTypeQname().getQNameValue(); + typeName = javaXmlTypeMapping.getRootTypeQname().getQNameValue(); typeMappingInfo = new TypeMappingInfo(clazz, typeName, serializerFactoryClass, deserializerFactoryClass); + key = new SchemaTypeKey(typeName, isElement, isSimpleType, false); } else if (javaXmlTypeMapping.isSetAnonymousTypeQname()) { String anonTypeQNameString = javaXmlTypeMapping.getAnonymousTypeQname().getStringValue(); int pos = anonTypeQNameString.lastIndexOf(":"); @@ -310,20 +328,95 @@ throw new DeploymentException("anon QName is invalid, no final ':' " + anonTypeQNameString); } //this appears to be ignored... - QName typeName = new QName(anonTypeQNameString.substring(0, pos), anonTypeQNameString.substring(pos + 1)); + typeName = new QName(anonTypeQNameString.substring(0, pos), anonTypeQNameString.substring(pos + 1)); typeMappingInfo = new TypeMappingInfo(clazz, typeName, serializerFactoryClass, deserializerFactoryClass); + key = new SchemaTypeKey(typeName, isElement, isSimpleType, true); + } else { + throw new DeploymentException("either root type qname or anonymous type qname must be set"); } typeMappings.add(typeMappingInfo); + SchemaType schemaType = (SchemaType) schemaTypeKeyToSchemaTypeMap.get(key); + if (schemaType == null) { + throw new DeploymentException("Schema type key " + key + " not found in analyzed schema: " + schemaTypeKeyToSchemaTypeMap); + } + TypeDesc typeDesc = getTypeDescriptor(clazz, typeName, javaXmlTypeMapping, schemaType); + typeDescriptors.put(clazz, typeDesc); } - seiFactory = createSEIFactory(portName, enhancedServiceEndpointClass, serviceImpl, typeMappings, location, operationInfos, handlerInfos, context, classLoader); + seiFactory = createSEIFactory(portName, enhancedServiceEndpointClass, serviceImpl, typeMappings, typeDescriptors, location, operationInfos, handlerInfos, context, classLoader); } seiPortNameToFactoryMap.put(portName, seiFactory); seiClassNameToFactoryMap.put(serviceEndpointInterface.getName(), seiFactory); } } + private TypeDesc getTypeDescriptor(Class javaClass, QName typeQName, JavaXmlTypeMappingType javaXmlTypeMapping, SchemaType schemaType) throws DeploymentException { + boolean isRestriction = schemaType.getDerivationType() == SchemaType.DT_RESTRICTION; + TypeDesc typeDesc = new TypeDesc(javaClass, !isRestriction); + //TODO typeQName may be a 'anonymous" QName like construct. Is this what axis expects? + typeDesc.setXmlType(typeQName); + VariableMappingType[] variableMappings = javaXmlTypeMapping.getVariableMappingArray(); + FieldDesc[] fields = new FieldDesc[variableMappings.length]; + + PropertyDescriptor[] propertyDescriptors = new java.beans.PropertyDescriptor[0]; + try { + propertyDescriptors = Introspector.getBeanInfo(javaClass).getPropertyDescriptors(); + } catch (IntrospectionException e) { + throw new DeploymentException("Class " + javaClass + " is not a valid javabean", e); + } + Map properties = new HashMap(); + for (int i = 0; i < propertyDescriptors.length; i++) { + PropertyDescriptor propertyDescriptor = propertyDescriptors[i]; + properties.put(propertyDescriptor.getName(), propertyDescriptor.getPropertyType()); + } + for (int i = 0; i < variableMappings.length; i++) { + VariableMappingType variableMapping = variableMappings[i]; + String fieldName = variableMapping.getJavaVariableName().getStringValue().trim(); + + if (variableMapping.isSetXmlAttributeName()) { + AttributeDesc attributeDesc = new AttributeDesc(); + //setting attribute name sets the xmlName with "" namespace, so don't do it +// attributeDesc.setAttributeName(fieldName); + attributeDesc.setFieldName(fieldName); + Class javaType = (Class) properties.get(fieldName); + if (javaType == null) { + throw new DeploymentException("field name " + fieldName + " not found in " + properties); + } + attributeDesc.setJavaType(javaType); + //TODO correct namespace??? + String namespace = ""; + QName xmlName = new QName(namespace, variableMapping.getXmlAttributeName().getStringValue().trim()); + attributeDesc.setXmlName(xmlName); + QName xmlType = schemaType.getName(); + attributeDesc.setXmlType(xmlType); + fields[i] = attributeDesc; + } else { + ElementDesc elementDesc = new ElementDesc(); + elementDesc.setFieldName(fieldName); + Class javaType = (Class) properties.get(fieldName); + if (javaType == null) { + throw new DeploymentException("field name " + fieldName + " not found in " + properties); + } + elementDesc.setJavaType(javaType); + //TODO correct namespace??? + String namespace = ""; + QName xmlName = new QName(namespace, variableMapping.getXmlElementName().getStringValue().trim()); + elementDesc.setXmlName(xmlName); + QName xmlType = schemaType.getName(); + elementDesc.setXmlType(xmlType); + //TODO figure out how to find these: +// elementDesc.setArrayType(null); +// elementDesc.setMinOccurs(0); +// elementDesc.setMaxOccurs(0); +// elementDesc.setNillable(false); + fields[i] = elementDesc; + } + } + typeDesc.setFields(fields); + return typeDesc; + } + private Method getMethodForOperation(Class enhancedServiceEndpointClass, Operation operation) throws DeploymentException { Method[] methods = enhancedServiceEndpointClass.getMethods(); String opName = operation.getName(); @@ -360,10 +453,10 @@ } - public SEIFactory createSEIFactory(String portName, Class enhancedServiceEndpointClass, Object serviceImpl, List typeMappings, URL location, OperationInfo[] operationInfos, List handlerInfoInfos, DeploymentContext deploymentContext, ClassLoader classLoader) throws DeploymentException { + public SEIFactory createSEIFactory(String portName, Class enhancedServiceEndpointClass, Object serviceImpl, List typeMappings, Map typeDescriptors, URL location, OperationInfo[] operationInfos, List handlerInfoInfos, DeploymentContext deploymentContext, ClassLoader classLoader) throws DeploymentException { List handlerInfos = buildHandlerInfosForPort(portName, handlerInfoInfos); try { - SEIFactory factory = new SEIFactoryImpl(portName, enhancedServiceEndpointClass, operationInfos, serviceImpl, typeMappings, location, handlerInfos, classLoader); + SEIFactory factory = new SEIFactoryImpl(portName, enhancedServiceEndpointClass, operationInfos, serviceImpl, typeMappings, typeDescriptors, location, handlerInfos, classLoader); return factory; } catch (ClassNotFoundException e) { throw new DeploymentException("Could not load GenericServiceEndpoint from application classloader", e); @@ -739,7 +832,6 @@ OperationInfo operationInfo = new OperationInfo(operationDesc, usesSOAPAction, soapActionURI, soapVersion, operationQName, methodName, methodDesc); return operationInfo; } - private static class ByteArrayRetrievingGeneratorStrategy extends DefaultGeneratorStrategy { Added: geronimo/trunk/modules/axis-builder/src/java/org/apache/geronimo/axis/builder/SchemaTypeKey.java URL: http://svn.apache.org/viewcvs/geronimo/trunk/modules/axis-builder/src/java/org/apache/geronimo/axis/builder/SchemaTypeKey.java?view=auto&rev=155249 ============================================================================== --- geronimo/trunk/modules/axis-builder/src/java/org/apache/geronimo/axis/builder/SchemaTypeKey.java (added) +++ geronimo/trunk/modules/axis-builder/src/java/org/apache/geronimo/axis/builder/SchemaTypeKey.java Thu Feb 24 13:14:04 2005 @@ -0,0 +1,93 @@ +/** + * + * Copyright 2003-2004 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.geronimo.axis.builder; + +import javax.xml.namespace.QName; + +/** + * @version $Rev: $ $Date: $ + */ +public final class SchemaTypeKey { + public static final String QNAME_SCOPE_COMPLEX_TYPE = "complexType"; + public static final String QNAME_SCOPE_SIMPLE_TYPE = "simpleType"; + public static final String QNAME_SCOPE_ELEMENT = "element"; + + private final QName qName; + private final String qNameScope; + private final boolean isElement; + private final boolean isSimpleType; + private final boolean isAnonymous; + + + public SchemaTypeKey(QName qName, boolean element, boolean isSimpleType, boolean anonymous) { + assert qName != null; + this.qName = qName; + isElement = element; + this.isSimpleType = isSimpleType; + isAnonymous = anonymous; + if (isElement) { + qNameScope = QNAME_SCOPE_ELEMENT; + } else if (isSimpleType) { + qNameScope = QNAME_SCOPE_SIMPLE_TYPE; + } else { + qNameScope = QNAME_SCOPE_COMPLEX_TYPE; + } + } + + public QName getqName() { + return qName; + } + + public boolean isElement() { + return isElement; + } + + public boolean isSimpleType() { + return isSimpleType; + } + + public boolean isAnonymous() { + return isAnonymous; + } + + public String getqNameScope() { + return qNameScope; + } + + public int hashCode() { + return qName.hashCode(); + } + + public boolean equals(Object other) { + if (!(other instanceof SchemaTypeKey)) { + return false; + } + SchemaTypeKey key = (SchemaTypeKey) other; + return isElement == key.isElement && isSimpleType == key.isSimpleType && isAnonymous == key.isAnonymous && qName.equals(key.qName); + } + + public String toString() { + StringBuffer buf = new StringBuffer("SchemaTypeKey: scope: ").append(qNameScope); + buf.append(" isElement: ").append(isElement); + buf.append(" isAnonymous: ").append(isAnonymous); + buf.append(" isSimpleType: ").append(isSimpleType); + buf.append(" QName: ").append(qName); + return buf.toString(); + } + + +} Modified: geronimo/trunk/modules/axis-builder/src/java/org/apache/geronimo/axis/builder/WSDescriptorParser.java URL: http://svn.apache.org/viewcvs/geronimo/trunk/modules/axis-builder/src/java/org/apache/geronimo/axis/builder/WSDescriptorParser.java?view=diff&r1=155248&r2=155249 ============================================================================== --- geronimo/trunk/modules/axis-builder/src/java/org/apache/geronimo/axis/builder/WSDescriptorParser.java (original) +++ geronimo/trunk/modules/axis-builder/src/java/org/apache/geronimo/axis/builder/WSDescriptorParser.java Thu Feb 24 13:14:04 2005 @@ -23,7 +23,9 @@ import java.net.URI; import java.net.URISyntaxException; import java.net.URL; +import java.util.ArrayList; import java.util.Calendar; +import java.util.Collection; import java.util.HashMap; import java.util.Iterator; import java.util.List; @@ -33,7 +35,6 @@ import javax.wsdl.Types; import javax.wsdl.WSDLException; import javax.wsdl.extensions.ExtensibilityElement; -import javax.wsdl.extensions.UnknownExtensibilityElement; import javax.wsdl.extensions.schema.Schema; import javax.wsdl.factory.WSDLFactory; import javax.wsdl.xml.WSDLLocator; @@ -76,9 +77,16 @@ import org.apache.geronimo.xbeans.j2ee.WebserviceDescriptionType; import org.apache.geronimo.xbeans.j2ee.WebservicesDocument; import org.apache.geronimo.xbeans.j2ee.WebservicesType; +import org.apache.xmlbeans.SchemaType; +import org.apache.xmlbeans.SchemaTypeSystem; +import org.apache.xmlbeans.XmlBeans; import org.apache.xmlbeans.XmlCursor; import org.apache.xmlbeans.XmlException; import org.apache.xmlbeans.XmlObject; +import org.apache.xmlbeans.XmlOptions; +import org.apache.xmlbeans.SchemaField; +import org.apache.xmlbeans.SchemaParticle; +import org.apache.xmlbeans.SchemaGlobalElement; import org.w3.x2001.xmlSchema.ComplexType; import org.w3.x2001.xmlSchema.SchemaDocument; import org.w3c.dom.Element; @@ -130,7 +138,7 @@ String seiInterfaceName = portComponent.getServiceEndpointInterface().getStringValue().trim(); ServiceImplBeanType serviceImplBeanType = portComponent.getServiceImplBean(); if (isEJB == serviceImplBeanType.isSetServletLink()) { - throw new DeploymentException("Wrong kind of web service described in web service descriptor: expected " + (isEJB? "EJB": "POJO(Servlet)")); + throw new DeploymentException("Wrong kind of web service described in web service descriptor: expected " + (isEJB ? "EJB" : "POJO(Servlet)")); } String linkName; if (serviceImplBeanType.isSetServletLink()) { @@ -186,17 +194,13 @@ return definition; } - /** - * Find all the top level complex types in the schemas in the definitions' types. - * Put them in a map from complex type QName to schema fragment. - * TODO it is not clear what happens with included schemas. - * - * @param definition - * @return - * @throws DeploymentException - */ - public static Map getComplexTypesInWsdl(Definition definition) throws DeploymentException { - Map complexTypeMap = new HashMap(); + public static Map buildSchemaTypeKeyToSchemaTypeMap(Definition definition) throws DeploymentException { + SchemaTypeSystem schemaTypeSystem = compileSchemaTypeSystem(definition); + return buildSchemaTypeKeyToSchemaTypeMap(schemaTypeSystem); + } + + public static SchemaTypeSystem compileSchemaTypeSystem(Definition definition) throws DeploymentException { + List schemaList = new ArrayList(); Types types = definition.getTypes(); Map namespaceMap = definition.getNamespaces(); if (types != null) { @@ -220,27 +224,155 @@ } finally { cursor.dispose(); } - SchemaDocument schemaDoc = (SchemaDocument) xmlObject.changeType(SchemaDocument.type); - SchemaConversionUtils.validateDD(schemaDoc); - SchemaDocument.Schema schema = schemaDoc.getSchema(); - String targetNamespace = schema.getTargetNamespace(); - ComplexType[] complexTypes = schema.getComplexTypeArray(); - for (int j = 0; j < complexTypes.length; j++) { - ComplexType complexType = complexTypes[j]; - String complexTypeName = complexType.getName(); - QName complexTypeQName = new QName(targetNamespace, complexTypeName); - complexTypeMap.put(complexTypeQName, complexType); - } + schemaList.add(xmlObject); } catch (XmlException e) { - throw new DeploymentException("Invalid schema in wsdl", e); + throw new DeploymentException("Could not parse schema element", e); } - } else { - //problems?? } - } else if (o instanceof UnknownExtensibilityElement) { - //This is apparently obsolete as of axis-wsdl4j-1.2-RC3.jar which includes the Schema extension above. - //I'm leaving this in in case this Schema class is not really part of a spec, even though its in javax. - UnknownExtensibilityElement unknownExtensibilityElement = (UnknownExtensibilityElement) o; + } + } + } + Collection errors = new ArrayList(); + XmlOptions xmlOptions = new XmlOptions(); + xmlOptions.setErrorListener(errors); + XmlObject[] schemas = (XmlObject[]) schemaList.toArray(new XmlObject[schemaList.size()]); + try { + SchemaTypeSystem schemaTypeSystem = XmlBeans.compileXsd(schemas, XmlBeans.getBuiltinTypeSystem(), xmlOptions); + if (errors.size() > 0) { + throw new DeploymentException("Could not compile schema type system: errors: " + errors); + } + return schemaTypeSystem; + } catch (XmlException e) { + throw new DeploymentException("Could not compile schema type system", e); + } + } + + /** + * builds a map of SchemaTypeKey containing jaxrpc-style fake QName and context info to xmlbeans SchemaType object. + * + * @param schemaTypeSystem + * @return + */ + public static Map buildSchemaTypeKeyToSchemaTypeMap(SchemaTypeSystem schemaTypeSystem) { + Map qnameMap = new HashMap(); + SchemaType[] globalTypes = schemaTypeSystem.globalTypes(); + for (int i = 0; i < globalTypes.length; i++) { + SchemaType globalType = globalTypes[i]; + QName typeQName = globalType.getName(); + addSchemaType(typeQName, globalType, false, qnameMap); + } + SchemaGlobalElement[] globalElements = schemaTypeSystem.globalElements(); + for (int i = 0; i < globalElements.length; i++) { + SchemaGlobalElement globalElement = globalElements[i]; + addElement(globalElement, null, qnameMap); + } + return qnameMap; + } + + private static void addElement(SchemaField element, SchemaTypeKey key, Map qnameMap) { + //TODO is this null if element is a ref? + QName elementName = element.getName(); + String elementNamespace = elementName.getNamespaceURI(); + if (elementNamespace == null || elementNamespace.equals("")) { + elementNamespace = key.getqName().getNamespaceURI(); + } + String elementQNameLocalName; + SchemaTypeKey elementKey = null; + if (key == null) { + //top level. rule 2.a, + elementQNameLocalName = elementName.getLocalPart(); + elementKey = new SchemaTypeKey(elementName, true, false, false); + } else { + //not top level. rule 2.b, key will be for enclosing Type. + QName enclosingTypeQName = key.getqName(); + String enclosingTypeLocalName = enclosingTypeQName.getLocalPart(); + elementQNameLocalName = enclosingTypeLocalName + ">" + elementName.getLocalPart(); + QName subElementName = new QName(elementNamespace, elementQNameLocalName); + elementKey = new SchemaTypeKey(subElementName, true, false, true); + } + SchemaType schemaType = element.getType(); + qnameMap.put(elementKey, schemaType); + //check if it's an array + if (element.getMaxOccurs() != null && element.getMaxOccurs().intValue() > 1) { + //this is at least rule 3.a. If refs get the element name from the ref, it will handle 3.b also. + int minOccurs = element.getMinOccurs() == null ? 1 : element.getMinOccurs().intValue(); + int maxOccurs = element.getMaxOccurs().intValue(); + String arrayQNameLocalName = elementQNameLocalName + "[" + minOccurs + "," + maxOccurs + "]"; + QName arrayName = new QName(elementNamespace, arrayQNameLocalName); + SchemaTypeKey arrayKey = new SchemaTypeKey(arrayName, true, false, true); + //TODO not clear we want the schemaType as the value + qnameMap.put(arrayKey, schemaType); + } + //now, name for type. Rule 1.b, type inside an element + String typeQNameLocalPart = ">" + elementQNameLocalName; + QName typeQName = new QName(elementNamespace, typeQNameLocalPart); + boolean isAnonymous = true; + addSchemaType(typeQName, schemaType, isAnonymous, qnameMap); + } + + private static void addSchemaType(QName typeQName, SchemaType schemaType, boolean anonymous, Map qnameMap) { + SchemaTypeKey typeKey = new SchemaTypeKey(typeQName, false, schemaType.isSimpleType(), anonymous); + qnameMap.put(typeKey, schemaType); + //TODO xmlbeans recommends using summary info from getElementProperties and getAttributeProperties instead of traversing the content model by hand. + SchemaParticle schemaParticle = schemaType.getContentModel(); + if (schemaParticle != null) { + addSchemaParticle(schemaParticle, typeKey, qnameMap); + } + } + + + private static void addSchemaParticle(SchemaParticle schemaParticle, SchemaTypeKey key, Map qnameMap) { + if (schemaParticle.getParticleType() == SchemaParticle.ELEMENT) { + SchemaType elementType = schemaParticle.getType(); + SchemaField element = elementType.getContainerField(); + //element will be null if the type is defined elsewhere, such as a built in type. + if (element != null) { + addElement(element, key, qnameMap); + } else { + //it may be a ref or a built in type. If it's an array (maxOccurs >1) form a type for it. + int maxOccurs = schemaParticle.getMaxOccurs() == null ? 1 : schemaParticle.getMaxOccurs().intValue(); + if (maxOccurs > 1) { + int minOccurs = schemaParticle.getMinOccurs() == null ? 1 : schemaParticle.getMinOccurs().intValue(); + QName elementName = schemaParticle.getName(); + String arrayQNameLocalName = elementName.getLocalPart() + "[" + minOccurs + "," + maxOccurs + "]"; + String elementNamespace = elementName.getNamespaceURI(); + if (elementNamespace == null || elementNamespace.equals("")) { + elementNamespace = key.getqName().getNamespaceURI(); + } + QName arrayName = new QName(elementNamespace, arrayQNameLocalName); + SchemaTypeKey arrayKey = new SchemaTypeKey(arrayName, true, false, true); + //TODO not clear we want the schemaType as the value + qnameMap.put(arrayKey, elementType); + } + } + } else { + SchemaParticle[] children = schemaParticle.getParticleChildren(); + for (int i = 0; i < children.length; i++) { + SchemaParticle child = children[i]; + addSchemaParticle(child, key, qnameMap); + } + } + } + + /** + * Find all the top level complex types in the schemas in the definitions' types. + * Put them in a map from complex type QName to schema fragment. + * TODO it is not clear what happens with included schemas. + * + * @param definition + * @return + * @throws DeploymentException + */ + public static Map getComplexTypesInWsdl(Definition definition) throws DeploymentException { + Map complexTypeMap = new HashMap(); + Types types = definition.getTypes(); + Map namespaceMap = definition.getNamespaces(); + if (types != null) { + List schemas = types.getExtensibilityElements(); + for (Iterator iterator = schemas.iterator(); iterator.hasNext();) { + Object o = iterator.next(); + if (o instanceof Schema) { + Schema unknownExtensibilityElement = (Schema) o; QName elementType = unknownExtensibilityElement.getElementType(); if (new QName("http://www.w3.org/2001/XMLSchema", "schema").equals(elementType)) { Element element = unknownExtensibilityElement.getElement(); Added: geronimo/trunk/modules/axis-builder/src/test-resources/schema/schema1.xsd URL: http://svn.apache.org/viewcvs/geronimo/trunk/modules/axis-builder/src/test-resources/schema/schema1.xsd?view=auto&rev=155249 ============================================================================== --- geronimo/trunk/modules/axis-builder/src/test-resources/schema/schema1.xsd (added) +++ geronimo/trunk/modules/axis-builder/src/test-resources/schema/schema1.xsd Thu Feb 24 13:14:04 2005 @@ -0,0 +1,25 @@ +<xsd:schema + xmlns:xsd="http://www.w3.org/2001/XMLSchema" + xmlns:foo="bar" + targetNamespace="bar"> + <xsd:complexType name="root"> + <xsd:sequence> + <xsd:element name="data" type="xsd:string"/> + </xsd:sequence> + </xsd:complexType> + <xsd:element name="root"> + <xsd:complexType> + <xsd:sequence> + <xsd:element name="inside" maxOccurs="10"> + <xsd:complexType> + <xsd:sequence> + <xsd:element name="data2" type="xsd:string"/> + </xsd:sequence> + </xsd:complexType> + </xsd:element> + <xsd:element ref="foo:someOtherElement" maxOccurs="20"/> + </xsd:sequence> + </xsd:complexType> + </xsd:element> + <xsd:element name="someOtherElement" type="xsd:int"/> +</xsd:schema> \ No newline at end of file Added: geronimo/trunk/modules/axis-builder/src/test/org/apache/geronimo/axis/builder/ParsingTest.java URL: http://svn.apache.org/viewcvs/geronimo/trunk/modules/axis-builder/src/test/org/apache/geronimo/axis/builder/ParsingTest.java?view=auto&rev=155249 ============================================================================== --- geronimo/trunk/modules/axis-builder/src/test/org/apache/geronimo/axis/builder/ParsingTest.java (added) +++ geronimo/trunk/modules/axis-builder/src/test/org/apache/geronimo/axis/builder/ParsingTest.java Thu Feb 24 13:14:04 2005 @@ -0,0 +1,65 @@ +/** + * + * Copyright 2003-2004 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.geronimo.axis.builder; + +import java.io.File; +import java.util.Collection; +import java.util.ArrayList; +import java.util.Map; +import java.util.Iterator; + +import junit.framework.TestCase; +import org.apache.xmlbeans.XmlObject; +import org.apache.xmlbeans.XmlOptions; +import org.apache.xmlbeans.SchemaTypeSystem; +import org.apache.xmlbeans.XmlBeans; +import org.apache.xmlbeans.XmlException; +import org.apache.xmlbeans.SchemaTypeLoader; +import org.apache.geronimo.schema.SchemaConversionUtils; +import org.apache.geronimo.common.DeploymentException; + +/** + * @version $Rev: $ $Date: $ + */ +public class ParsingTest extends TestCase { + private static final File basedir = new File(System.getProperty("basedir", System.getProperty("user.dir"))); + + public void testSchema1() throws Exception { + File schema1 = new File(basedir, "src/test-resources/schema/schema1.xsd"); + XmlObject xmlObject = SchemaConversionUtils.parse(schema1.toURL()); + Collection errors = new ArrayList(); + XmlOptions xmlOptions = new XmlOptions(); + xmlOptions.setErrorListener(errors); + XmlObject[] schemas = new XmlObject[] {xmlObject}; + SchemaTypeLoader schemaTypeLoader = XmlBeans.loadXsd(new XmlObject[] {}); + SchemaTypeSystem schemaTypeSystem; + try { + schemaTypeSystem = XmlBeans.compileXsd(schemas, schemaTypeLoader, xmlOptions); + if (errors.size() > 0) { + throw new DeploymentException("Could not compile schema type system: errors: " + errors); + } + } catch (XmlException e) { + throw new DeploymentException("Could not compile schema type system", e); + } + Map map = WSDescriptorParser.buildSchemaTypeKeyToSchemaTypeMap(schemaTypeSystem); + for (Iterator iterator = map.entrySet().iterator(); iterator.hasNext();) { + Map.Entry entry = (Map.Entry) iterator.next(); + System.out.println(entry.getKey() + " --> " + entry.getValue()); + } + assertEquals(9, map.size()); + } +} Modified: geronimo/trunk/modules/axis-builder/src/test/org/apache/geronimo/axis/builder/ServiceReferenceTest.java URL: http://svn.apache.org/viewcvs/geronimo/trunk/modules/axis-builder/src/test/org/apache/geronimo/axis/builder/ServiceReferenceTest.java?view=diff&r1=155248&r2=155249 ============================================================================== --- geronimo/trunk/modules/axis-builder/src/test/org/apache/geronimo/axis/builder/ServiceReferenceTest.java (original) +++ geronimo/trunk/modules/axis-builder/src/test/org/apache/geronimo/axis/builder/ServiceReferenceTest.java Thu Feb 24 13:14:04 2005 @@ -137,7 +137,8 @@ OperationInfo[] operationInfos = new OperationInfo[]{op}; Class serviceEndpointClass = builder.enhanceServiceEndpointInterface(MockPort.class, context, module, isolatedCl); String portName = "foo"; - SEIFactory serviceInterfaceFactory = builder.createSEIFactory(portName, serviceEndpointClass, serviceInstance, typeMappings, location, operationInfos, handlerInfos, context, isolatedCl); + Map typeDescriptors = new HashMap(); + SEIFactory serviceInterfaceFactory = builder.createSEIFactory(portName, serviceEndpointClass, serviceInstance, typeMappings, typeDescriptors, location, operationInfos, handlerInfos, context, isolatedCl); assertNotNull(serviceInterfaceFactory); Remote serviceInterface = serviceInterfaceFactory.createServiceEndpoint(); assertTrue(serviceInterface instanceof MockPort); Modified: geronimo/trunk/modules/axis/src/java/org/apache/geronimo/axis/client/SEIFactoryImpl.java URL: http://svn.apache.org/viewcvs/geronimo/trunk/modules/axis/src/java/org/apache/geronimo/axis/client/SEIFactoryImpl.java?view=diff&r1=155248&r2=155249 ============================================================================== --- geronimo/trunk/modules/axis/src/java/org/apache/geronimo/axis/client/SEIFactoryImpl.java (original) +++ geronimo/trunk/modules/axis/src/java/org/apache/geronimo/axis/client/SEIFactoryImpl.java Thu Feb 24 13:14:04 2005 @@ -22,6 +22,8 @@ import java.io.ObjectStreamException; import java.io.InvalidClassException; import java.util.List; +import java.util.Map; +import java.util.Iterator; import java.net.URL; import javax.xml.rpc.ServiceException; import javax.xml.rpc.handler.HandlerChain; @@ -35,6 +37,7 @@ import net.sf.cglib.core.Signature; import org.apache.axis.client.Service; import org.apache.axis.handlers.HandlerInfoChainFactory; +import org.apache.axis.description.TypeDesc; /** * @version $Rev: $ $Date: $ @@ -48,12 +51,13 @@ private transient final FastConstructor constructor; private final Object serviceImpl; private final List typeMappings; + private final Map typeDescriptors; private final URL location; private final List handlerInfos; private transient HandlerInfoChainFactory handlerInfoChainFactory; private transient OperationInfo[] sortedOperationInfos; - public SEIFactoryImpl(String portName, Class serviceEndpointClass, OperationInfo[] operationInfos, Object serviceImpl, List typeMappings, URL location, List handlerInfos, ClassLoader classLoader) throws ClassNotFoundException { + public SEIFactoryImpl(String portName, Class serviceEndpointClass, OperationInfo[] operationInfos, Object serviceImpl, List typeMappings, Map typeDescriptors, URL location, List handlerInfos, ClassLoader classLoader) throws ClassNotFoundException { this.portQName = new QName("", portName); this.serviceEndpointClass = serviceEndpointClass; this.operationInfos = operationInfos; @@ -62,6 +66,7 @@ this.constructor = FastClass.create(serviceEndpointClass).getConstructor(constructorTypes); this.serviceImpl = serviceImpl; this.typeMappings = typeMappings; + this.typeDescriptors = typeDescriptors; this.location = location; this.handlerInfos = handlerInfos; this.handlerInfoChainFactory = new HandlerInfoChainFactory(handlerInfos); @@ -76,6 +81,13 @@ int index = methodProxy.getSuperIndex(); sortedOperationInfos[index] = operationInfo; } + //register our type descriptors + for (Iterator iterator = typeDescriptors.entrySet().iterator(); iterator.hasNext();) { + Map.Entry entry = (Map.Entry) iterator.next(); + Class javaClass = (Class) entry.getKey(); + TypeDesc typeDesc = (TypeDesc) entry.getValue(); + TypeDesc.registerTypeDescForClass(javaClass, typeDesc); + } } public Remote createServiceEndpoint() throws ServiceException { @@ -99,7 +111,7 @@ private Object readResolve() throws ObjectStreamException { try { - return new SEIFactoryImpl(portQName.getLocalPart(), serviceEndpointClass, operationInfos, serviceImpl, typeMappings, location, handlerInfos, null); + return new SEIFactoryImpl(portQName.getLocalPart(), serviceEndpointClass, operationInfos, serviceImpl, typeMappings, typeDescriptors, location, handlerInfos, null); } catch (ClassNotFoundException e) { throw new InvalidClassException(GenericServiceEndpoint.class.getName(), "this is impossible"); } Modified: geronimo/trunk/modules/axis/src/test/org/apache/geronimo/axis/preconditions/DynamicEJBDeploymentTest.java URL: http://svn.apache.org/viewcvs/geronimo/trunk/modules/axis/src/test/org/apache/geronimo/axis/preconditions/DynamicEJBDeploymentTest.java?view=diff&r1=155248&r2=155249 ============================================================================== --- geronimo/trunk/modules/axis/src/test/org/apache/geronimo/axis/preconditions/DynamicEJBDeploymentTest.java (original) +++ geronimo/trunk/modules/axis/src/test/org/apache/geronimo/axis/preconditions/DynamicEJBDeploymentTest.java Thu Feb 24 13:14:04 2005 @@ -72,7 +72,7 @@ File jarFile = new File(outDir , "echo-jar/echo-ewsimpl.jar"); URI defaultParentId = new URI("org/apache/geronimo/Server"); - OpenEJBModuleBuilder moduleBuilder = new OpenEJBModuleBuilder(defaultParentId, null, null); + OpenEJBModuleBuilder moduleBuilder = new OpenEJBModuleBuilder(defaultParentId, null, null, null); EARConfigBuilder earConfigBuilder = Modified: geronimo/trunk/modules/axis/src/test/org/apache/geronimo/axis/testUtils/TestingUtils.java URL: http://svn.apache.org/viewcvs/geronimo/trunk/modules/axis/src/test/org/apache/geronimo/axis/testUtils/TestingUtils.java?view=diff&r1=155248&r2=155249 ============================================================================== --- geronimo/trunk/modules/axis/src/test/org/apache/geronimo/axis/testUtils/TestingUtils.java (original) +++ geronimo/trunk/modules/axis/src/test/org/apache/geronimo/axis/testUtils/TestingUtils.java Thu Feb 24 13:14:04 2005 @@ -129,7 +129,7 @@ protected static EARConfigBuilder getEARConfigBuilder() throws Exception { URI defaultParentId = new URI("org/apache/geronimo/Server"); - OpenEJBModuleBuilder moduleBuilder = new OpenEJBModuleBuilder(defaultParentId, null, null); + OpenEJBModuleBuilder moduleBuilder = new OpenEJBModuleBuilder(defaultParentId, null, null, null); EARConfigBuilder earConfigBuilder = new EARConfigBuilder(defaultParentId,