DO NOT REPLY TO THIS EMAIL, BUT PLEASE POST YOUR BUG 
RELATED COMMENTS THROUGH THE WEB INTERFACE AVAILABLE AT
<http://nagoya.apache.org/bugzilla/show_bug.cgi?id=13214>.
ANY REPLY MADE TO THIS MESSAGE WILL NOT BE COLLECTED AND 
INSERTED IN THE BUG DATABASE.

http://nagoya.apache.org/bugzilla/show_bug.cgi?id=13214

Nexted xs:import statements do not work correctly.

           Summary: Nexted xs:import statements do not work correctly.
           Product: Axis
           Version: 1.0-rc2
          Platform: All
        OS/Version: Other
            Status: NEW
          Severity: Blocker
          Priority: Other
         Component: WSDL processing
        AssignedTo: [EMAIL PROTECTED]
        ReportedBy: [EMAIL PROTECTED]


Axis RC2 has a bug that causes nested xs:import statements to work 
incorrectly.  To see this bug create the following files:

Wsdl1.xsd:

<definitions xmlns="http://schemas.xmlsoap.org/wsdl/"; 
xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"; 
xmlns:http="http://schemas.xmlsoap.org/wsdl/http/"; 
xmlns:xs="http://www.w3.org/2001/XMLSchema"; 
xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/"; 
xmlns:mime="http://schemas.xmlsoap.org/wsdl/mime/"; 
xmlns:test="http://www.test.com"; xmlns:y="http://new.webservice.namespace"; 
targetNamespace="http://new.webservice.namespace";>
        <import namespace="http://www.test.com"; location="./schema1.xsd"/>
        <message name="testMessage">
                <part name="parameters" element="test:test"/>
        </message>
        <portType name="testPortType">
                <operation name="testOperation">
                        <input message="y:testMessage"/>
                </operation>
        </portType>
        <binding name="testBinding" type="y:testPortType">
                <soap:binding style="document" 
transport="http://schemas.xmlsoap.org/soap/http"/>
                <operation name="testOperation">
                        <soap:operation 
soapAction="http://www.opengis.net/ows/testOperation"; style="document"/>
                        <input>
                                <soap:body use="literal"/>
                        </input>
                </operation>
        </binding>
        <service name="testService">
                <port name="testPort" binding="y:testBinding">
                        <soap:address location="http://localhost/test"/>
                </port>
        </service>
</definitions>


Schema1.xsd:

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema targetNamespace="http://www.test.com"; 
xmlns:test="http://www.test.com"; xmlns:xs="http://www.w3.org/2001/XMLSchema"; 
elementFormDefault="qualified" attributeFormDefault="unqualified">
        <xs:import namespace="http://www.test.com"; 
schemaLocation="../directory2/schema2.xsd"/>
        <xs:element name="test" type="test:testType"/>
</xs:schema>

Schema2.xsd:

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema targetNamespace="http://www.test.com"; 
xmlns:xs="http://www.w3.org/2001/XMLSchema"; xmlns:test="http://www.test.com"; 
elementFormDefault="qualified" attributeFormDefault="unqualified">
        <xs:import namespace="http://www.test.com"; 
schemaLocation="schema3.xsd"/>
</xs:schema>


Schema3.xsd:

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema targetNamespace="http://www.test.com"; 
xmlns:xs="http://www.w3.org/2001/XMLSchema"; xmlns:test="http://www.test.com"; 
elementFormDefault="qualified" attributeFormDefault="unqualified">
        <xs:complexType name="testType"/>
</xs:schema>



Now place the schemas in the following directory structure:

- some_directory
    - schema_test
        - directory1
                wsdl1.xsd
                schema1.xsd
        - directory2
                schema2.xsd
                schema3.xsd

When you run the Axis WSDL2Java tool (org.apache.axis.wsdl.WSDL2Java), you’ll 
get the following error:

Parsing XML file:  http://localhost/schemas/schema_test/directory1/wsdl1.wsdl

- Exception:

org.xml.sax.SAXException: Fatal Error: URI=null Line=0: 
File "http://localhost/schemas/schema_test/directory1/schema3.xsd"; not found.
        at org.apache.axis.utils.XMLUtils$ParserErrorHandler.fatalError
(XMLUtils.java:556)
        at org.apache.xerces.framework.XMLParser.reportError
(XMLParser.java:1225)
        at 
org.apache.xerces.readers.DefaultEntityHandler.startReadingFromDocument
(DefaultEntityHandler.java:512)
        at org.apache.xerces.framework.XMLParser.parseSomeSetup
(XMLParser.java:312)
        at org.apache.xerces.framework.XMLParser.parse(XMLParser.java:1080)
        at org.apache.xerces.jaxp.DocumentBuilderImpl.parse
(DocumentBuilderImpl.java:195)
        at org.apache.axis.utils.XMLUtils.newDocument(XMLUtils.java:304)
        at org.apache.axis.utils.XMLUtils.newDocument(XMLUtils.java:329)

        at org.apache.axis.utils.XMLUtils.newDocument(XMLUtils.java:319)
        at org.apache.axis.wsdl.symbolTable.SymbolTable.lookForImports
(SymbolTable.java:616)
        at org.apache.axis.wsdl.symbolTable.SymbolTable.lookForImports
(SymbolTable.java:623)
        at org.apache.axis.wsdl.symbolTable.SymbolTable.populate
(SymbolTable.java:513)
        at org.apache.axis.wsdl.symbolTable.SymbolTable.lookForImports
(SymbolTable.java:616)
        at org.apache.axis.wsdl.symbolTable.SymbolTable.lookForImports
(SymbolTable.java:623)
        at org.apache.axis.wsdl.symbolTable.SymbolTable.populate
(SymbolTable.java:513)
        at org.apache.axis.wsdl.symbolTable.SymbolTable.populate
(SymbolTable.java:529)
        at org.apache.axis.wsdl.symbolTable.SymbolTable.add
(SymbolTable.java:384)
        at org.apache.axis.wsdl.symbolTable.SymbolTable.populate
(SymbolTable.java:372)
        at org.apache.axis.wsdl.symbolTable.SymbolTable.populate
(SymbolTable.java:359)
        at org.apache.axis.wsdl.gen.Parser$WSDLRunnable.run(Parser.java:247)
        at java.lang.Thread.run(Thread.java:484)

java.io.IOException: Type {http://www.test.com}testType is referenced but not 
defined.
        at org.apache.axis.wsdl.symbolTable.SymbolTable.checkForUndefined
(SymbolTable.java:485)
        at org.apache.axis.wsdl.symbolTable.SymbolTable.add
(SymbolTable.java:385)
        at org.apache.axis.wsdl.symbolTable.SymbolTable.populate
(SymbolTable.java:372)
        at org.apache.axis.wsdl.symbolTable.SymbolTable.populate
(SymbolTable.java:359)
        at org.apache.axis.wsdl.gen.Parser$WSDLRunnable.run(Parser.java:247)
        at java.lang.Thread.run(Thread.java:484)


The problem is caused by Axis assuming that all relative paths referenced in 
xs:import commands (under the schemaLocation attribute) are relative to 
schema1.xsd.  Thus the following statement in schema2.xsd causes Axis to look 
for schema3 in directory1, not directory 2:

        <xs:import namespace="http://www.test.com"; 
schemaLocation="schema3.xsd"/>

Fixing this bug is easy – it requires updating the SymbolTable.LookForImports 
method in Axis and then rebuilding Axis.  The fix is:

    private void lookForImports(URL context, Node node) throws IOException {
        NodeList children = node.getChildNodes();
        for (int i = 0; i < children.getLength(); i++) {
            Node child = children.item(i);
            if ("import".equals(child.getLocalName())) {
                NamedNodeMap attributes = child.getAttributes();
                Node namespace = attributes.getNamedItem("namespace");
                // skip XSD import of soap encoding
                if (namespace != null &&
                        Constants.isSOAP_ENC(namespace.getNodeValue())) {
                    continue;
                }
                Node importFile = attributes.getNamedItem("schemaLocation");
                if (importFile != null) {
                    URL url = getURL(context,
                            importFile.getNodeValue());
                    if (!importedFiles.contains(url)) {
                        importedFiles.add(url);
                        String filename = url.toString();
                           // This is NOT correct.  The correct path is         
                   // given by URL, not the original context
                     //  populate(context, null,
                     //          XMLUtils.newDocument(filename), 
                           //          filename);

                           // This is the correct call.
                               populate(url, null,
                               XMLUtils.newDocument(filename), 
                                         filename);
                    }
                }
            }
            lookForImports(context, child);
        }
    } // lookForImports

Reply via email to