/** * * 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.IOException; import java.io.InputStream; import java.net.URI; import java.net.URISyntaxException; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Stack; import java.util.jar.JarFile; import java.util.zip.ZipEntry; import javax.wsdl.Definition; import javax.wsdl.Import; import javax.wsdl.Port; import javax.wsdl.Service; import javax.wsdl.Types; import javax.wsdl.WSDLException; import javax.wsdl.extensions.ExtensibilityElement; import javax.wsdl.extensions.ExtensionRegistry; import javax.wsdl.extensions.UnknownExtensibilityElement; import javax.wsdl.extensions.schema.Schema; import javax.wsdl.extensions.soap.SOAPAddress; import javax.wsdl.factory.WSDLFactory; import javax.wsdl.xml.WSDLLocator; import javax.wsdl.xml.WSDLReader; import javax.xml.namespace.QName; import com.ibm.wsdl.extensions.PopulatedExtensionRegistry; import com.ibm.wsdl.extensions.schema.SchemaConstants; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.geronimo.axis.server.AxisWebServiceContainer; import org.apache.geronimo.common.DeploymentException; import org.apache.geronimo.schema.SchemaConversionUtils; import org.apache.geronimo.xbeans.wsdl.DefinitionsDocument; import org.apache.geronimo.xbeans.wsdl.TDefinitions; import org.apache.geronimo.xbeans.wsdl.TPort; import org.apache.geronimo.xbeans.wsdl.TService; import org.apache.geronimo.deployment.xmlbeans.XmlBeansUtil; import org.apache.geronimo.deployment.xmlbeans.XmlBeansUtil; import org.apache.xmlbeans.SchemaField; import org.apache.xmlbeans.SchemaGlobalElement; import org.apache.xmlbeans.SchemaParticle; import org.apache.xmlbeans.SchemaType; import org.apache.xmlbeans.SchemaTypeSystem; import org.apache.xmlbeans.XmlBeans; import org.apache.xmlbeans.XmlCursor; import org.apache.xmlbeans.XmlError; import org.apache.xmlbeans.XmlException; import org.apache.xmlbeans.XmlObject; import org.apache.xmlbeans.XmlOptions; import org.apache.xmlbeans.impl.xb.xsdschema.SchemaDocument; import org.w3c.dom.Element; import org.xml.sax.EntityResolver; import org.xml.sax.InputSource; import org.xml.sax.SAXException; /** * @version $Rev$ $Date$ */ public class SchemaInfoBuilder { private static final Log log = LogFactory.getLog(SchemaInfoBuilder.class); private static final SchemaTypeSystem basicTypeSystem; private static final String[] errorNames = {"Error", "Warning", "Info"}; private static final String SOAP_NS = "http://schemas.xmlsoap.org/wsdl/soap/"; private static final QName ADDRESS_QNAME = new QName(SOAP_NS, "address"); private static final QName LOCATION_QNAME = new QName("", "location"); static { InputStream is = WSDescriptorParser.class.getClassLoader().getResourceAsStream("META-INF/schema/soap_encoding_1_1.xsd"); if (is == null) { throw new RuntimeException("Could not locate soap encoding schema"); } ArrayList errors = new ArrayList(); XmlOptions xmlOptions = XmlBeansUtil.createXmlOptions(errors); try { SchemaDocument parsed = SchemaDocument.Factory.parse(is, xmlOptions); if (errors.size() != 0) { throw new XmlException(errors.toArray().toString()); } basicTypeSystem = XmlBeans.compileXsd(new XmlObject[]{parsed}, XmlBeans.getBuiltinTypeSystem(), xmlOptions); if (errors.size() > 0) { throw new RuntimeException("Could not compile schema type system: errors: " + errors); } } catch (XmlException e) { throw new RuntimeException("Could not compile schema type system", e); } catch (IOException e) { throw new RuntimeException("Could not compile schema type system", e); } } private final JarFile moduleFile; private final Definition definition; private final Stack uris = new Stack(); private final Map wsdlMap = new HashMap(); private final Map schemaTypeKeyToSchemaTypeMap; private final Map complexTypeMap; private final Map elementMap; private final Map simpleTypeMap; private final Map portMap; public SchemaInfoBuilder(JarFile moduleFile, URI wsdlUri) throws DeploymentException { this(moduleFile, wsdlUri, null, null); } public SchemaInfoBuilder(JarFile moduleFile, Definition definition) throws DeploymentException { this(moduleFile, null, definition, null); } SchemaInfoBuilder(JarFile moduleFile, URI uri, SchemaTypeSystem schemaTypeSystem) throws DeploymentException { this(moduleFile, uri, null, schemaTypeSystem); } SchemaInfoBuilder(JarFile moduleFile, URI uri, Definition definition, SchemaTypeSystem schemaTypeSystem) throws DeploymentException { this.moduleFile = moduleFile; if (uri != null) { uris.push(uri); if (definition == null && schemaTypeSystem == null) { definition = readWsdl(moduleFile, uri); } } else if (definition != null) { try { uri = new URI(definition.getDocumentBaseURI()); uris.push(uri); } catch (URISyntaxException e) { throw new DeploymentException("Could not locate definition", e); } } else { throw new DeploymentException("You must supply uri or definition"); } if (schemaTypeSystem == null) { schemaTypeSystem = compileSchemaTypeSystem(definition); } this.definition = definition; schemaTypeKeyToSchemaTypeMap = buildSchemaTypeKeyToSchemaTypeMap(schemaTypeSystem); complexTypeMap = buildComplexTypeMap(); simpleTypeMap = buildSimpleTypeMap(); elementMap = buildElementMap(); portMap = buildPortMap(); } public Map getSchemaTypeKeyToSchemaTypeMap() { return schemaTypeKeyToSchemaTypeMap; } public Definition getDefinition() { return definition; } public Map getWsdlMap() { return wsdlMap; } /** * Find all the complex types in the previously constructed schema analysis. * Put them in a map from complex type QName to schema fragment. * * @return */ public Map getComplexTypesInWsdl() { return complexTypeMap; } private Map buildComplexTypeMap() { Map complexTypeMap = new HashMap(); for (Iterator iterator = schemaTypeKeyToSchemaTypeMap.entrySet().iterator(); iterator.hasNext();) { Map.Entry entry = (Map.Entry) iterator.next(); SchemaTypeKey key = (SchemaTypeKey) entry.getKey(); if (!key.isSimpleType() && !key.isAnonymous()) { QName qName = key.getqName(); SchemaType schemaType = (SchemaType) entry.getValue(); complexTypeMap.put(qName, schemaType); } } return complexTypeMap; } public Map getElementToTypeMap() { return elementMap; } private Map buildElementMap() { Map elementToTypeMap = new HashMap(); for (Iterator iterator = schemaTypeKeyToSchemaTypeMap.entrySet().iterator(); iterator.hasNext();) { Map.Entry entry = (Map.Entry) iterator.next(); SchemaTypeKey key = (SchemaTypeKey) entry.getKey(); if (key.isElement()) { QName elementQName = key.getqName(); SchemaType schemaType = (SchemaType) entry.getValue(); QName typeQName = schemaType.getName(); elementToTypeMap.put(elementQName, typeQName); } } return elementToTypeMap; } /** * Gets a map of all the javax.wsdl.Port instance in the WSDL definition keyed by the port's QName * <p/> * WSDL 1.1 spec: 2.6 "The name attribute provides a unique name among all ports defined within in the enclosing WSDL document." * * @return */ public Map getPortMap() { return portMap; } private Map buildPortMap() { HashMap ports = new HashMap(); if (definition != null) { Collection services = definition.getServices().values(); for (Iterator iterator = services.iterator(); iterator.hasNext();) { Service service = (Service) iterator.next(); ports.putAll(service.getPorts()); } } return ports; } public Map getSimpleTypeMap() { return simpleTypeMap; } private Map buildSimpleTypeMap() { Map simpleTypeMap = new HashMap(); for (Iterator iterator = schemaTypeKeyToSchemaTypeMap.entrySet().iterator(); iterator.hasNext();) { Map.Entry entry = (Map.Entry) iterator.next(); SchemaTypeKey key = (SchemaTypeKey) entry.getKey(); if (key.isSimpleType() && !key.isAnonymous()) { QName qName = key.getqName(); SchemaType schemaType = (SchemaType) entry.getValue(); simpleTypeMap.put(qName, schemaType); } } return simpleTypeMap; } public SchemaTypeSystem compileSchemaTypeSystem(Definition definition) throws DeploymentException { List schemaList = new ArrayList(); addImportsFromDefinition(definition, schemaList); // System.out.println("Schemas: " + schemaList); Collection errors = new ArrayList(); XmlOptions xmlOptions = new XmlOptions(); xmlOptions.setErrorListener(errors); xmlOptions.setEntityResolver(new JarEntityResolver()); XmlObject[] schemas = (XmlObject[]) schemaList.toArray(new XmlObject[schemaList.size()]); try { SchemaTypeSystem schemaTypeSystem = XmlBeans.compileXsd(schemas, basicTypeSystem, xmlOptions); if (errors.size() > 0) { boolean wasError = false; for (Iterator iterator = errors.iterator(); iterator.hasNext();) { XmlError xmlError = (XmlError) iterator.next(); if(xmlError.getSeverity() == XmlError.SEVERITY_ERROR) { log.error(xmlError); wasError = true; } else if(xmlError.getSeverity() == XmlError.SEVERITY_WARNING) { log.warn(xmlError); } else if(xmlError.getSeverity() == XmlError.SEVERITY_INFO) { log.debug(xmlError); } } if (wasError) { throw new DeploymentException("Could not compile schema type system, see log for errors"); } } return schemaTypeSystem; } catch (XmlException e) { throw new DeploymentException("Could not compile schema type system: " + schemaList, e); } } private void addImportsFromDefinition(Definition definition, List schemaList) throws DeploymentException { Map namespaceMap = definition.getNamespaces(); Types types = definition.getTypes(); 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(); addSchemaElement(element, namespaceMap, schemaList); } } else if (o instanceof UnknownExtensibilityElement) { //This is allegedly obsolete as of axis-wsdl4j-1.2-RC3.jar which includes the Schema extension above. //The change notes imply that imported schemas should end up in Schema elements. They don't, so this is still needed. UnknownExtensibilityElement unknownExtensibilityElement = (UnknownExtensibilityElement) o; Element element = unknownExtensibilityElement.getElement(); String elementNamespace = element.getNamespaceURI(); String elementLocalName = element.getNodeName(); if ("http://www.w3.org/2001/XMLSchema".equals(elementNamespace) && "schema".equals(elementLocalName)) { addSchemaElement(element, namespaceMap, schemaList); } } } } Map imports = definition.getImports(); if (imports != null) { for (Iterator iterator = imports.entrySet().iterator(); iterator.hasNext();) { Map.Entry entry = (Map.Entry) iterator.next(); String namespaceURI = (String) entry.getKey(); List importList = (List) entry.getValue(); for (Iterator iterator1 = importList.iterator(); iterator1.hasNext();) { Import anImport = (Import) iterator1.next(); //according to the 1.1 jwsdl mr shcema imports are supposed to show up here, //but according to the 1.0 spec there is supposed to be no Definition. Definition definition1 = anImport.getDefinition(); if (definition1 != null) { try { URI uri = new URI(definition1.getDocumentBaseURI()); uris.push(uri); } catch (URISyntaxException e) { throw new DeploymentException("Could not locate definition", e); } try { addImportsFromDefinition(definition1, schemaList); } finally { uris.pop(); } } else { log.warn("Missing definition in import for namespace " + namespaceURI); } } } } } private void addSchemaElement(Element element, Map namespaceMap, List schemaList) throws DeploymentException { try { XmlObject xmlObject = parseWithNamespaces(element, namespaceMap); schemaList.add(xmlObject); } catch (XmlException e) { throw new DeploymentException("Could not parse schema element", e); } } static XmlObject parseWithNamespaces(Element element, Map namespaceMap) throws XmlException { ArrayList errors = new ArrayList(); XmlOptions xmlOptions = XmlBeansUtil.createXmlOptions(errors); SchemaDocument parsed = SchemaDocument.Factory.parse(element, xmlOptions); if (errors.size() != 0) { throw new XmlException(errors.toArray().toString()); } XmlCursor cursor = parsed.newCursor(); try { cursor.toFirstContentToken(); for (Iterator namespaces = namespaceMap.entrySet().iterator(); namespaces.hasNext();) { Map.Entry entry = (Map.Entry) namespaces.next(); cursor.insertNamespace((String) entry.getKey(), (String) entry.getValue()); } } finally { cursor.dispose(); } return parsed; } /** * builds a map of SchemaTypeKey containing jaxrpc-style fake QName and context info to xmlbeans SchemaType object. * * @param schemaTypeSystem * @return */ private 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 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(); //"" namespace means local element with elementFormDefault="unqualified" 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, elementName); } 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, elementName); } SchemaType schemaType = element.getType(); qnameMap.put(elementKey, schemaType); // new Exception("Adding: " + elementKey.getqName().getLocalPart()).printStackTrace(); //check if it's an array. maxOccurs is null if unbounded //element should always be a SchemaParticle... this is a workaround for XMLBEANS-137 if (element instanceof SchemaParticle) { addArrayForms((SchemaParticle) element, elementKey.getqName(), qnameMap, schemaType); } else { log.warn("element is not a schemaParticle! " + element); } //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 void addSchemaType(QName typeQName, SchemaType schemaType, boolean anonymous, Map qnameMap) { SchemaTypeKey typeKey = new SchemaTypeKey(typeQName, false, schemaType.isSimpleType(), anonymous, null); qnameMap.put(typeKey, schemaType); // new Exception("Adding: " + typeKey.getqName().getLocalPart()).printStackTrace(); //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 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 { QName keyQName = key.getqName(); //TODO I can't distinguish between 3.a and 3.b, so generate names both ways. //3.b String localPart = schemaParticle.getName().getLocalPart(); QName elementName = new QName(keyQName.getNamespaceURI(), localPart); addArrayForms(schemaParticle, elementName, qnameMap, elementType); //3.a localPart = keyQName.getLocalPart() + ">" + schemaParticle.getName().getLocalPart(); elementName = new QName(keyQName.getNamespaceURI(), localPart); addArrayForms(schemaParticle, elementName, qnameMap, elementType); } } else { try { SchemaParticle[] children = schemaParticle.getParticleChildren(); for (int i = 0; i < children.length; i++) { SchemaParticle child = children[i]; addSchemaParticle(child, key, qnameMap); } } catch (NullPointerException e) { //ignore xmlbeans bug } } } private void addArrayForms(SchemaParticle schemaParticle, QName keyName, Map qnameMap, SchemaType elementType) { //it may be a ref or a built in type. If it's an array (maxOccurs >1) form a type for it. if (schemaParticle.getIntMaxOccurs() > 1) { String maxOccurs = schemaParticle.getMaxOccurs() == null ? "unbounded" : "" + schemaParticle.getIntMaxOccurs(); int minOccurs = schemaParticle.getIntMinOccurs(); QName elementName = schemaParticle.getName(); String arrayQNameLocalName = keyName.getLocalPart() + "[" + minOccurs + "," + maxOccurs + "]"; String elementNamespace = elementName.getNamespaceURI(); if (elementNamespace == null || elementNamespace.equals("")) { elementNamespace = keyName.getNamespaceURI(); } QName arrayName = new QName(elementNamespace, arrayQNameLocalName); SchemaTypeKey arrayKey = new SchemaTypeKey(arrayName, false, false, true, elementName); //TODO not clear we want the schemaType as the value qnameMap.put(arrayKey, elementType); // new Exception("Adding: " + arrayKey.getqName().getLocalPart()).printStackTrace(); if (minOccurs == 1) { arrayQNameLocalName = keyName.getLocalPart() + "[," + maxOccurs + "]"; arrayName = new QName(elementNamespace, arrayQNameLocalName); arrayKey = new SchemaTypeKey(arrayName, false, false, true, elementName); //TODO not clear we want the schemaType as the value qnameMap.put(arrayKey, elementType); } } } public Definition readWsdl(JarFile moduleFile, URI wsdlURI) throws DeploymentException { Definition definition; WSDLFactory wsdlFactory = null; try { wsdlFactory = WSDLFactory.newInstance(); } catch (WSDLException e) { throw new DeploymentException("Could not create WSDLFactory", e); } WSDLReader wsdlReaderNoImport = wsdlFactory.newWSDLReader(); wsdlReaderNoImport.setFeature("javax.wsdl.importDocuments", false); ExtensionRegistry extensionRegistry = new PopulatedExtensionRegistry(); extensionRegistry.mapExtensionTypes(Types.class, SchemaConstants.Q_ELEM_XSD_1999, UnknownExtensibilityElement.class); extensionRegistry.registerDeserializer(Types.class, SchemaConstants.Q_ELEM_XSD_1999, extensionRegistry.getDefaultDeserializer()); extensionRegistry.registerSerializer(Types.class, SchemaConstants.Q_ELEM_XSD_1999, extensionRegistry.getDefaultSerializer()); extensionRegistry.mapExtensionTypes(Types.class, SchemaConstants.Q_ELEM_XSD_2000, UnknownExtensibilityElement.class); extensionRegistry.registerDeserializer(Types.class, SchemaConstants.Q_ELEM_XSD_2000, extensionRegistry.getDefaultDeserializer()); extensionRegistry.registerSerializer(Types.class, SchemaConstants.Q_ELEM_XSD_2000, extensionRegistry.getDefaultSerializer()); extensionRegistry.mapExtensionTypes(Types.class, SchemaConstants.Q_ELEM_XSD_2001, UnknownExtensibilityElement.class); extensionRegistry.registerDeserializer(Types.class, SchemaConstants.Q_ELEM_XSD_2001, extensionRegistry.getDefaultDeserializer()); extensionRegistry.registerSerializer(Types.class, SchemaConstants.Q_ELEM_XSD_2001, extensionRegistry.getDefaultSerializer()); wsdlReaderNoImport.setExtensionRegistry(extensionRegistry); JarWSDLLocator wsdlLocator = new JarWSDLLocator(wsdlURI); WSDLReader wsdlReader = wsdlFactory.newWSDLReader(); Thread thread = Thread.currentThread(); ClassLoader oldCl = thread.getContextClassLoader(); thread.setContextClassLoader(this.getClass().getClassLoader()); try { try { definition = wsdlReader.readWSDL(wsdlLocator); } catch (WSDLException e) { throw new DeploymentException("Failed to read wsdl document", e); } } finally { thread.setContextClassLoader(oldCl); } return definition; } public static ExtensibilityElement getExtensibilityElement(Class clazz, List extensibilityElements) throws DeploymentException { for (Iterator iterator = extensibilityElements.iterator(); iterator.hasNext();) { ExtensibilityElement extensibilityElement = (ExtensibilityElement) iterator.next(); if (clazz.isAssignableFrom(extensibilityElement.getClass())) { return extensibilityElement; } } throw new DeploymentException("No element of class " + clazz.getName() + " found"); } public String movePortLocation(String portComponentName, String servletLocation) throws DeploymentException { DefinitionsDocument doc = (DefinitionsDocument) wsdlMap.get(uris.get(0)); TDefinitions definitions = doc.getDefinitions(); TService[] services = definitions.getServiceArray(); for (int i = 0; i < services.length; i++) { TService service = services[i]; TPort[] ports = service.getPortArray(); for (int j = 0; j < ports.length; j++) { TPort port = ports[j]; if (port.getName().trim().equals(portComponentName)) { XmlCursor portCursor = port.newCursor(); try { if (portCursor.toChild(ADDRESS_QNAME)) { if (servletLocation == null) { String original = portCursor.getAttributeText(LOCATION_QNAME); URI originalURI = new URI(original); servletLocation = originalURI.getPath(); } portCursor.setAttributeText(LOCATION_QNAME, AxisWebServiceContainer.LOCATION_REPLACEMENT_TOKEN + servletLocation); return servletLocation; } } catch (URISyntaxException e) { throw new DeploymentException("Could not construct URI for ejb location in wsdl", e); } finally { portCursor.dispose(); } } } } throw new DeploymentException("No port found with name " + portComponentName + " expected at " + servletLocation); } private class JarEntityResolver implements EntityResolver { private final static String PROJECT_URL_PREFIX = "project://local/"; public InputSource resolveEntity(String publicId, String systemId) throws SAXException, IOException { //seems like this must be a bug in xmlbeans... if (systemId.indexOf(PROJECT_URL_PREFIX) > -1) { systemId = systemId.substring(PROJECT_URL_PREFIX.length()); } URI location = ((URI) uris.peek()).resolve(systemId); InputStream wsdlInputStream = null; try { ZipEntry entry = moduleFile.getEntry(location.toString()); wsdlInputStream = moduleFile.getInputStream(entry); XmlObject xmlObject = SchemaDocument.Factory.parse(wsdlInputStream); wsdlMap.put(location, xmlObject); wsdlInputStream.close(); wsdlInputStream = moduleFile.getInputStream(entry); } catch (XmlException e) { throw (IOException) new IOException("Could not parse schema document").initCause(e); } return new InputSource(wsdlInputStream); } } class JarWSDLLocator implements WSDLLocator { private final URI wsdlURI; private URI latestImportURI; public JarWSDLLocator(URI wsdlURI) { this.wsdlURI = wsdlURI; } public InputSource getBaseInputSource() { InputStream wsdlInputStream = null; try { ZipEntry entry = moduleFile.getEntry(wsdlURI.toString()); wsdlInputStream = moduleFile.getInputStream(entry); DefinitionsDocument definition = DefinitionsDocument.Factory.parse(wsdlInputStream); wsdlMap.put(wsdlURI, definition); wsdlInputStream.close(); wsdlInputStream = moduleFile.getInputStream(entry); } catch (Exception e) { throw new RuntimeException("Could not open stream to wsdl file", e); } return new InputSource(wsdlInputStream); } public String getBaseURI() { return wsdlURI.toString(); } public InputSource getImportInputSource(String parentLocation, String relativeLocation) { URI parentURI = URI.create(parentLocation); latestImportURI = parentURI.resolve(relativeLocation); InputStream importInputStream = null; try { ZipEntry entry = moduleFile.getEntry(latestImportURI.toString()); importInputStream = moduleFile.getInputStream(entry); try { DefinitionsDocument definition = DefinitionsDocument.Factory.parse(importInputStream); importInputStream.close(); wsdlMap.put(latestImportURI, definition); importInputStream.close(); } catch (XmlException e) { //probably was a schema rather than wsdl. If there are real problems they will show up later. } importInputStream = moduleFile.getInputStream(entry); } catch (Exception e) { throw new RuntimeException("Could not open stream to import file", e); } InputSource inputSource = new InputSource(importInputStream); inputSource.setSystemId(getLatestImportURI()); return inputSource; } public String getLatestImportURI() { return latestImportURI.toString(); } } }