owenb 2002/10/18 03:30:58 Modified: java/src/org/apache/wsif/schema Schema.java Parser.java Log: Added support for imported schemas (xsd files) and also nested schemas i.e. xsd files that import/include other xsd files Revision Changes Path 1.2 +17 -1 xml-axis-wsif/java/src/org/apache/wsif/schema/Schema.java Index: Schema.java =================================================================== RCS file: /home/cvs/xml-axis-wsif/java/src/org/apache/wsif/schema/Schema.java,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- Schema.java 15 Oct 2002 15:33:12 -0000 1.1 +++ Schema.java 18 Oct 2002 10:30:57 -0000 1.2 @@ -73,6 +73,7 @@ private String targetNamespace = ""; private ArrayList types = new ArrayList(); + private ArrayList iai = new ArrayList(); /** * Constructor @@ -90,6 +91,13 @@ types.add(new ComplexType(subEl, targetNamespace)); } else if (elType.equals("simpleType")) { types.add(new SimpleType(subEl, targetNamespace)); + } else if (elType.equals("import") || elType.equals("include")) { + // If either an import or an include is defined, we need to get + // the referenced file so store its location (if appropriate) + String loc = subEl.getAttribute("schemaLocation"); + if (loc != null && !loc.equals("")) { + iai.add(loc); + } } else { //ignore all other types } @@ -110,6 +118,14 @@ * @return The "targetNamespace" attribute */ String getTargetNamespace() { - return null; + return targetNamespace; } + + /** + * Get all the locations of imported/included schemas so that they can also be retrieved + * @return An array of all the import/include schemaLocations + */ + String[] getimportsAndIncludes() { + return (String[]) iai.toArray(new String[iai.size()]); + } } 1.2 +143 -8 xml-axis-wsif/java/src/org/apache/wsif/schema/Parser.java Index: Parser.java =================================================================== RCS file: /home/cvs/xml-axis-wsif/java/src/org/apache/wsif/schema/Parser.java,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- Parser.java 15 Oct 2002 15:33:12 -0000 1.1 +++ Parser.java 18 Oct 2002 10:30:58 -0000 1.2 @@ -57,6 +57,7 @@ package org.apache.wsif.schema; +import java.io.Reader; import java.util.ArrayList; import java.util.Hashtable; import java.util.Iterator; @@ -67,11 +68,19 @@ import javax.wsdl.Import; import javax.wsdl.Types; import javax.wsdl.extensions.UnknownExtensibilityElement; +import javax.wsdl.xml.WSDLLocator; import javax.xml.namespace.QName; +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; import org.apache.wsif.WSIFConstants; +import org.apache.wsif.WSIFException; +import org.apache.wsif.logging.Trc; import org.apache.wsif.util.WSIFUtils; +import org.apache.wsif.wsdl.WSIFWSDLLocatorImpl; +import org.w3c.dom.Document; import org.w3c.dom.Element; +import org.xml.sax.InputSource; import com.ibm.wsdl.util.xml.QNameUtils; @@ -95,8 +104,49 @@ * @param def The Definition object representing the wsdl * @param table The Map to proulate with xml type -> Java class name (QName -> String) mappings */ - public static void getTypeMappings(Definition def, Map table) { - getTypeMappings(def, table, true); + public static void getTypeMappings(Definition def, Map table) throws WSIFException { + getTypeMappings(def, table, true, null); + } + + /** + * Given a Definition object, populate a Map with all the types defined in the schemas in the definition and + * their corresponding Java class names. + * @param def The Definition object representing the wsdl + * @param table The Map to proulate with xml type -> Java class name (QName -> String) mappings + * @param loader A ClassLoader to use in resolving xsd locations + */ + public static void getTypeMappings(Definition def, Map table, ClassLoader loader) throws WSIFException { + WSDLLocator locator = new WSIFWSDLLocatorImpl((String) null, (String) null, loader); + getTypeMappings(def, table, true, locator); + } + + /** + * Given a Definition object, populate a Map with all the types defined in the schemas in the definition and + * their corresponding Java class names. + * @param def The Definition object representing the wsdl + * @param table The Map to proulate with xml type -> Java class name (QName -> String) mappings + * @param loader A ClassLoader to use in resolving xsd locations + * @param includeStandardMappings Flag to indicate whether or not standard xsd, soapenc and Apache SOAP mappings + * should be included in the table + */ + public static void getTypeMappings( + Definition def, + Map table, + ClassLoader loader, + boolean includeStandardMappings) throws WSIFException { + WSDLLocator locator = new WSIFWSDLLocatorImpl((String) null, (String) null, loader); + getTypeMappings(def, table, includeStandardMappings, locator); + } + + /** + * Given a Definition object, populate a Map with all the types defined in the schemas in the definition and + * their corresponding Java class names. + * @param def The Definition object representing the wsdl + * @param table The Map to proulate with xml type -> Java class name (QName -> String) mappings + * @param loc WSDLLocator equal or equivalent to that used to locate the original wsdl document + */ + public static void getTypeMappings(Definition def, Map table, WSDLLocator loc) throws WSIFException { + getTypeMappings(def, table, true, loc); } /** @@ -110,10 +160,34 @@ public static void getTypeMappings( Definition def, Map table, - boolean includeStandardMappings) { - ArrayList schemaList = new ArrayList(); - getTypesSchemas(def, schemaList); + boolean includeStandardMappings) throws WSIFException { + + getTypeMappings(def, table, includeStandardMappings, null); + } + /** + * Given a Definition object, populate a Map with all the types defined in the schemas in the definition and + * their corresponding Java class names. + * @param def The Definition object representing the wsdl + * @param table The Map to proulate with xml type -> Java class name (QName -> String) mappings + * @param includeStandardMappings Flag to indicate whether or not standard xsd, soapenc and Apache SOAP mappings + * should be included in the table + * @param loc WSDLLocator equal or equivalent to that used to locate the original wsdl document + */ + public static void getTypeMappings( + Definition def, + Map table, + boolean includeStandardMappings, + WSDLLocator loc) throws WSIFException { + + Trc.entry(null, def, table, new Boolean(includeStandardMappings), loc); + if (loc == null) { + loc = new WSIFWSDLLocatorImpl((String) null, (String) null, null); + } + + ArrayList schemaList = new ArrayList(); + getTypesSchemas(def, schemaList, loc); + Hashtable standards = null; if (includeStandardMappings) { @@ -257,6 +331,7 @@ } } } + Trc.exit(); } /** @@ -333,7 +408,7 @@ /** * Get all the schemas defined in the Definition object */ - private static void getTypesSchemas(Definition def, List schemas) { + private static void getTypesSchemas(Definition def, List schemas, WSDLLocator loc) throws WSIFException { Types types = def.getTypes(); if (types != null) { Iterator extEleIt = types.getExtensibilityElements().iterator(); @@ -346,7 +421,16 @@ if (QNameUtils.matches(schema2001, schemaEl) || QNameUtils.matches(schema2000, schemaEl) || QNameUtils.matches(schema1999, schemaEl)) { - schemas.add(new Schema(schemaEl)); + Schema sc = new Schema(schemaEl); + schemas.add(sc); + String docBase = def.getDocumentBaseURI(); + if (docBase != null && loc != null) { + String[] importsAndIncludes = sc.getimportsAndIncludes(); + for (int i=0; i<importsAndIncludes.length; i++) { + String sl = importsAndIncludes[i]; + getImportedSchemas(docBase, sl, loc, schemas); + } + } } } } @@ -369,12 +453,63 @@ Definition importedDef = tempImport.getDefinition(); if (importedDef != null) { - getTypesSchemas(importedDef, schemas); + getTypesSchemas(importedDef, schemas, loc); + } else { + String baseLoc = def.getDocumentBaseURI(); + String importLoc = tempImport.getLocationURI(); + if (baseLoc != null && importLoc != null && loc != null) { + getImportedSchemas(baseLoc, importLoc, loc, schemas); + } } } } } } + } + } + + /** + * Get all nested schemas + */ + private static void getImportedSchemas(String base, String rel, WSDLLocator loc, List schemaList) throws WSIFException { + try { + Reader reader = loc.getImportReader(base, rel); + if (reader == null) { + throw new WSIFException("Unable to read schema file "+rel+" relative to "+base); + } + InputSource inputSource = new InputSource(reader); + DocumentBuilderFactory factory = + DocumentBuilderFactory.newInstance(); + + factory.setNamespaceAware(true); + factory.setValidating(false); + + DocumentBuilder builder = factory.newDocumentBuilder(); + Document doc = builder.parse(inputSource); + reader.close(); + + Element el = doc.getDocumentElement(); + if (el != null) { + if (QNameUtils.matches(schema2001, el) + || QNameUtils.matches(schema2000, el) + || QNameUtils.matches(schema1999, el)) { + Schema sc = new Schema(el); + schemaList.add(sc); + String[] importsAndIncludes = sc.getimportsAndIncludes(); + String lastURI = loc.getLatestImportURI(); + for (int i=0; i<importsAndIncludes.length; i++) { + String sl = importsAndIncludes[i]; + getImportedSchemas(lastURI, sl, loc, schemaList); + } + } + } + } catch (Exception e) { + Trc.exception(e); + if (e instanceof WSIFException) { + throw (WSIFException) e; + } else { + throw new WSIFException("Error when getting imported schemas", e); + } } }