/*
 * Copyright (c) 2011, 2020 Oracle and/or its affiliates. All rights reserved.
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v. 2.0 which is available at
 * http://www.eclipse.org/legal/epl-2.0,
 * or the Eclipse Distribution License v. 1.0 which is available at
 * http://www.eclipse.org/org/documents/edl-v10.php.
 *
 * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
 */

// Contributors:
//     Mike Norman - Sept 2010: added new capabilities based on https://bugs.eclipse.org/bugs/show_bug.cgi?id=322949
package dbws.testing.secondarysql;

//javase imports
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.StringReader;
import java.sql.Connection;
import java.sql.SQLException;
import java.sql.Statement;
import java.text.MessageFormat;
import java.util.HashMap;
import java.util.Map;

import org.w3c.dom.Document;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;

//java eXtension imports
import jakarta.annotation.PostConstruct;
import jakarta.annotation.PreDestroy;
import jakarta.servlet.ServletContext;
import javax.wsdl.WSDLException;
import jakarta.xml.bind.JAXBContext;
import jakarta.xml.bind.JAXBElement;
import jakarta.xml.bind.JAXBException;
import jakarta.xml.bind.Unmarshaller;
import javax.xml.namespace.QName;
import jakarta.xml.soap.MessageFactory;
import jakarta.xml.soap.SOAPException;
import jakarta.xml.soap.SOAPMessage;
import jakarta.xml.soap.SOAPPart;
import javax.xml.transform.Source;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMResult;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamSource;
import jakarta.xml.ws.Dispatch;
import jakarta.xml.ws.Endpoint;
import jakarta.xml.ws.Provider;
import jakarta.xml.ws.Service;
import jakarta.xml.ws.ServiceMode;
import jakarta.xml.ws.WebServiceProvider;
import jakarta.xml.ws.soap.SOAPFaultException;
import static jakarta.xml.ws.Service.Mode.MESSAGE;
import static jakarta.xml.ws.soap.SOAPBinding.SOAP11HTTP_BINDING;

//JUnit4 imports
import org.junit.AfterClass;
import org.junit.BeforeClass;
//import org.junit.Ignore;
import org.junit.Test;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;

//EclipseLink imports
import org.eclipse.persistence.internal.databaseaccess.Platform;
import org.eclipse.persistence.internal.dbws.ProviderHelper;
import org.eclipse.persistence.internal.helper.ConversionManager;
import org.eclipse.persistence.internal.jpa.deployment.PersistenceUnitProcessor;
import org.eclipse.persistence.internal.jpa.metadata.MetadataProcessor;
import org.eclipse.persistence.internal.sessions.DatabaseSessionImpl;
import org.eclipse.persistence.internal.xr.ProjectHelper;
import org.eclipse.persistence.internal.xr.XRDynamicClassLoader;
import org.eclipse.persistence.internal.xr.XmlBindingsModel;
import org.eclipse.persistence.jaxb.JAXBContextProperties;
import org.eclipse.persistence.jaxb.xmlmodel.XmlBindings;
import org.eclipse.persistence.logging.AbstractSessionLog;
import org.eclipse.persistence.logging.SessionLog;
import org.eclipse.persistence.oxm.XMLContext;
import org.eclipse.persistence.oxm.XMLLogin;
import org.eclipse.persistence.oxm.XMLUnmarshaller;
import org.eclipse.persistence.platform.xml.XMLComparer;
import org.eclipse.persistence.platform.xml.XMLParser;
import org.eclipse.persistence.platform.xml.XMLPlatform;
import org.eclipse.persistence.platform.xml.XMLPlatformFactory;
import org.eclipse.persistence.sessions.DatabaseLogin;
import org.eclipse.persistence.sessions.DatabaseSession;
import org.eclipse.persistence.sessions.DatasourceLogin;
import org.eclipse.persistence.sessions.Project;
import org.eclipse.persistence.tools.dbws.DBWSBuilder;
import org.eclipse.persistence.tools.dbws.DBWSBuilderModel;
import org.eclipse.persistence.tools.dbws.DBWSBuilderModelProject;
import org.eclipse.persistence.tools.dbws.JSR109WebServicePackager;
import org.eclipse.persistence.tools.dbws.SQLOperationModel;
import static org.eclipse.persistence.tools.dbws.DBWSBuilder.NO_SESSIONS_FILENAME;
import static org.eclipse.persistence.tools.dbws.DBWSBuilder.SESSIONS_FILENAME_KEY;
import static org.eclipse.persistence.tools.dbws.DBWSPackager.ArchiveUse.noArchive;
import static org.eclipse.persistence.tools.dbws.Util.DOM_PLATFORM_CLASSNAME;
import static org.eclipse.persistence.tools.dbws.Util.OR_PRJ_SUFFIX;
import static org.eclipse.persistence.tools.dbws.XRPackager.__nullStream;

//domain-specific (test) imports
import static dbws.testing.DBWSTestSuite.DATABASE_DDL_CREATE_KEY;
import static dbws.testing.DBWSTestSuite.DATABASE_DDL_DEBUG_KEY;
import static dbws.testing.DBWSTestSuite.DATABASE_DDL_DROP_KEY;
import static dbws.testing.DBWSTestSuite.DATABASE_DRIVER;
import static dbws.testing.DBWSTestSuite.DATABASE_PLATFORM;
import static dbws.testing.DBWSTestSuite.DATABASE_USERNAME_KEY;
import static dbws.testing.DBWSTestSuite.DATABASE_PASSWORD_KEY;
import static dbws.testing.DBWSTestSuite.DATABASE_URL_KEY;
import static dbws.testing.DBWSTestSuite.DEFAULT_DATABASE_DDL_CREATE;
import static dbws.testing.DBWSTestSuite.DEFAULT_DATABASE_DDL_DEBUG;
import static dbws.testing.DBWSTestSuite.DEFAULT_DATABASE_DDL_DROP;
import static dbws.testing.DBWSTestSuite.DEFAULT_DATABASE_USERNAME;
import static dbws.testing.DBWSTestSuite.DEFAULT_DATABASE_PASSWORD;
import static dbws.testing.DBWSTestSuite.DEFAULT_DATABASE_URL;
import static dbws.testing.DBWSTestSuite.NONSENCE_WHERE_SQL;
import static dbws.testing.DBWSTestSuite.SECONDARY;
import static dbws.testing.DBWSTestSuite.SECONDARY_ALL_SCHEMA_TYPE;
import static dbws.testing.DBWSTestSuite.SECONDARY_ALL_SQL;
import static dbws.testing.DBWSTestSuite.SECONDARY_COUNT_SCHEMA_TYPE;
import static dbws.testing.DBWSTestSuite.SECONDARY_COUNT_SQL;
import static dbws.testing.DBWSTestSuite.SECONDARY_NAMESPACE;
import static dbws.testing.DBWSTestSuite.SECONDARY_PORT;
import static dbws.testing.DBWSTestSuite.SECONDARY_SERVICE;
import static dbws.testing.DBWSTestSuite.SECONDARY_SERVICE_NAMESPACE;
import static dbws.testing.DBWSTestSuite.SECONDARY_TEST;
import static dbws.testing.DBWSTestSuite.buildConnection;
import static dbws.testing.DBWSTestSuite.runDdl;

@WebServiceProvider(
    targetNamespace = SECONDARY_SERVICE_NAMESPACE,
    serviceName = SECONDARY_SERVICE,
    portName = SECONDARY_PORT
)
@ServiceMode(MESSAGE)

public class SecondarySQLTestSuite extends ProviderHelper implements Provider<SOAPMessage> {

    static final String CREATE_SECONDARY_TABLE =
        "CREATE TABLE IF NOT EXISTS secondary (" +
            "\nEMPNO NUMERIC(4)," +
            "\nENAME VARCHAR(10)," +
            "\nJOB VARCHAR(9)," +
            "\nMGR NUMERIC(4)," +
            "\nHIREDATE DATE," +
            "\nSAL NUMERIC(7,2)," +
            "\nCOMM NUMERIC(7,2)," +
            "\nDEPTNO NUMERIC(2)," +
            "\nPRIMARY KEY (EMPNO)" +
        "\n)";
    static final String[] POPULATE_SECONDARY_TABLE = new String[] {
        "INSERT INTO secondary VALUES (7369,'SMITH','CLERK',7902,'1980-12-17',800,NULL,20)",
        "INSERT INTO secondary VALUES (7499,'ALLEN','SALESMAN',7698,'1981-2-20',1600,300,30)",
        "INSERT INTO secondary VALUES (7521,'WARD','SALESMAN',7698,'1981-2-22',1250,500,30)",
        "INSERT INTO secondary VALUES (7566,'JONES','MANAGER',7839,'1981-4-2',2975,NULL,20)",
        "INSERT INTO secondary VALUES (7654,'MARTIN','SALESMAN',7698,'1981-9-28',1250,1400,30)",
        "INSERT INTO secondary VALUES (7698,'BLAKE','MANAGER',7839,'1981-5-1',2850,NULL,30)",
        "INSERT INTO secondary VALUES (7782,'CLARK','MANAGER',7839,'1981-6-9',2450,NULL,10)",
        "INSERT INTO secondary VALUES (7788,'SCOTT','ANALYST',7566,'1981-06-09',3000,NULL,20)",
        "INSERT INTO secondary VALUES (7839,'KING','PRESIDENT',NULL,'1981-11-17',5000,NULL,10)",
        "INSERT INTO secondary VALUES (7844,'TURNER','SALESMAN',7698,'1981-9-8',1500,0,30)",
        "INSERT INTO secondary VALUES (7876,'ADAMS','CLERK',7788,'1987-05-23',1100,NULL,20)",
        "INSERT INTO secondary VALUES (7900,'JAMES','CLERK',7698,'1981-12-03',950,NULL,30)",
        "INSERT INTO secondary VALUES (7902,'FORD','ANALYST',7566,'1981-12-03',3000,NULL,20)",
        "INSERT INTO secondary VALUES (7934,'MILLER','CLERK',7782,'1982-01-23',1300,NULL,10)"
    };
    static final String DROP_SECONDARY_TABLE =
        "DROP TABLE secondary";

    static final String ENDPOINT_ADDRESS = "http://localhost:9999/" + SECONDARY_TEST;
    static final String DBWS_BUILDER_XML_USERNAME =
        "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" +
        "<dbws-builder xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\">" +
          "<properties>" +
              "<property name=\"projectName\">" + SECONDARY + "</property>" +
              "<property name=\"logLevel\">off</property>" +
              "<property name=\"username\">";
    static final String DBWS_BUILDER_XML_PASSWORD =
              "</property><property name=\"password\">";
    static final String DBWS_BUILDER_XML_URL =
              "</property><property name=\"url\">";
    static final String DBWS_BUILDER_XML_DRIVER =
              "</property><property name=\"driver\">";
    static final String DBWS_BUILDER_XML_PLATFORM =
              "</property><property name=\"platformClassname\">";
    static final String DBWS_BUILDER_XML_MAIN =
              "</property>" +
          "</properties>" +
          "<sql " +
              "name=\"allSecondary\" " +
              "isCollection=\"true\" " +
              "returnType=\"" + SECONDARY_ALL_SCHEMA_TYPE + "\"> " +
              "<statement><![CDATA[" + SECONDARY_ALL_SQL + "]]></statement>" +
              "<build-statement><![CDATA[" + SECONDARY_ALL_SQL +
                  NONSENCE_WHERE_SQL + "]]></build-statement>" +
          "</sql>" +
          "<sql " +
              "name=\"countSecondary\" " +
              "isCollection=\"false\" " +
              "returnType=\"" + SECONDARY_COUNT_SCHEMA_TYPE +"\"> " +
              "<statement><![CDATA[" + SECONDARY_COUNT_SQL + "]]></statement>" +
              "<build-statement><![CDATA[" + SECONDARY_COUNT_SQL +
                NONSENCE_WHERE_SQL + "]]></build-statement>" +
          "</sql>" +
        "</dbws-builder>";

    // JUnit test fixtures
    static Connection conn = null;
    public static ByteArrayOutputStream DBWS_SERVICE_STREAM = new ByteArrayOutputStream();
    public static ByteArrayOutputStream DBWS_SCHEMA_STREAM = new ByteArrayOutputStream();
    public static ByteArrayOutputStream DBWS_OR_STREAM = new ByteArrayOutputStream();
    public static ByteArrayOutputStream DBWS_OX_STREAM = new ByteArrayOutputStream();
    public static ByteArrayOutputStream DBWS_WSDL_STREAM = new ByteArrayOutputStream();
    public static XMLComparer comparer = new XMLComparer();
    public static XMLPlatform xmlPlatform = XMLPlatformFactory.getInstance().getXMLPlatform();
    public static XMLParser xmlParser = xmlPlatform.newXMLParser();
    public static Endpoint endpoint = null;
    public static QName portQName = null;
    public static Service testService = null;
    public static DBWSBuilder builder = new DBWSBuilder();
    static final String username = System.getProperty(DATABASE_USERNAME_KEY, DEFAULT_DATABASE_USERNAME);
    static final String password = System.getProperty(DATABASE_PASSWORD_KEY, DEFAULT_DATABASE_PASSWORD);
    static final String url = System.getProperty(DATABASE_URL_KEY, DEFAULT_DATABASE_URL);

    static boolean ddlCreate = false;
    static boolean ddlDrop = false;
    static boolean ddlDebug = false;

    @BeforeClass
    public static void setUp() throws WSDLException {
        try {
            conn = buildConnection();
        }
        catch (Exception e) {
            e.printStackTrace();
        }
        String ddlCreateProp = System.getProperty(DATABASE_DDL_CREATE_KEY, DEFAULT_DATABASE_DDL_CREATE);
        if ("true".equalsIgnoreCase(ddlCreateProp)) {
            ddlCreate = true;
        }
        String ddlDropProp = System.getProperty(DATABASE_DDL_DROP_KEY, DEFAULT_DATABASE_DDL_DROP);
        if ("true".equalsIgnoreCase(ddlDropProp)) {
            ddlDrop = true;
        }
        String ddlDebugProp = System.getProperty(DATABASE_DDL_DEBUG_KEY, DEFAULT_DATABASE_DDL_DEBUG);
        if ("true".equalsIgnoreCase(ddlDebugProp)) {
            ddlDebug = true;
        }
        if (ddlCreate) {
            runDdl(conn, CREATE_SECONDARY_TABLE, ddlDebug);
            try {
                Statement stmt = conn.createStatement();
                for (int i = 0; i < POPULATE_SECONDARY_TABLE.length; i++) {
                    stmt.addBatch(POPULATE_SECONDARY_TABLE[i]);
                }
                stmt.executeBatch();
            }
            catch (SQLException e) {
                if (ddlDebug) {
                    e.printStackTrace();
                }
            }
        }

        String builderString = DBWS_BUILDER_XML_USERNAME + username + DBWS_BUILDER_XML_PASSWORD +
        password + DBWS_BUILDER_XML_URL + url + DBWS_BUILDER_XML_DRIVER + DATABASE_DRIVER +
        DBWS_BUILDER_XML_PLATFORM + DATABASE_PLATFORM + DBWS_BUILDER_XML_MAIN;
        XMLContext context = new XMLContext(new DBWSBuilderModelProject());
        XMLUnmarshaller unmarshaller = context.createUnmarshaller();
        DBWSBuilderModel builderModel =
            (DBWSBuilderModel)unmarshaller.unmarshal(new StringReader(builderString));

        builder.quiet = true;
        builder.properties = builderModel.properties;
        builder.getProperties().put(SESSIONS_FILENAME_KEY, NO_SESSIONS_FILENAME);
        builder.getTargetNamespace();
        builder.operations = builderModel.operations;
        //builder.setLogLevel(SessionLog.FINE_LABEL);
        builder.setLogLevel(SessionLog.OFF_LABEL);
        builder.setPackager(new JSR109WebServicePackager(null, "WebServiceTestPackager", noArchive) {
            @Override
            public void start() {
            }
        });
        builder.build(DBWS_SCHEMA_STREAM, __nullStream, DBWS_SERVICE_STREAM, DBWS_OR_STREAM,
            DBWS_OX_STREAM, __nullStream, __nullStream, DBWS_WSDL_STREAM, __nullStream,
            __nullStream, __nullStream, __nullStream, null);
        endpoint = Endpoint.create(new SecondarySQLTestSuite());
        endpoint.publish(ENDPOINT_ADDRESS);
        QName serviceQName = new QName(SECONDARY_SERVICE_NAMESPACE, SECONDARY_SERVICE);
        portQName = new QName(SECONDARY_SERVICE_NAMESPACE, SECONDARY_PORT);
        testService = Service.create(serviceQName);
        testService.addPort(portQName, SOAP11HTTP_BINDING, ENDPOINT_ADDRESS);
    }

    @AfterClass
    public static void teardown() {
        if (endpoint != null) {
            endpoint.stop();
        }
        if (ddlDrop) {
            runDdl(conn, DROP_SECONDARY_TABLE, ddlDebug);
        }
    }

    @PreDestroy
    public void destroy() {
        super.destroy();
    }

    @Override
    protected InputStream initXRServiceStream(ClassLoader parentClassLoader, ServletContext sc) {
        return new ByteArrayInputStream(DBWS_SERVICE_STREAM.toByteArray());
    }

    @Override
    protected InputStream initXRSchemaStream(ClassLoader parentClassLoader, ServletContext sc) {
        return new ByteArrayInputStream(DBWS_SCHEMA_STREAM.toByteArray());
    }

    @Override
    protected InputStream initWSDLInputStream(ClassLoader parentClassLoader, ServletContext sc) {
        return new ByteArrayInputStream(DBWS_WSDL_STREAM.toByteArray());
    }

    @PostConstruct
    public void init() {
        super.init(new XRDynamicClassLoader(Thread.currentThread().getContextClassLoader()),
            null, false);
    }

     @Override
     public void logoutSessions() {
         if (xrService.getORSession() != null) {
             ((DatabaseSession)xrService.getORSession()).logout();
         }
         if (xrService.getOXSession() != null) {
             ((DatabaseSession)xrService.getOXSession()).logout();
         }
     }

     @Override
     public void buildSessions() {
         XRDynamicClassLoader xrdecl = new XRDynamicClassLoader(parentClassLoader);
         DatasourceLogin login = new DatabaseLogin();
         login.setUserName(username);
         login.setPassword(password);
         ((DatabaseLogin) login).setConnectionString(url);
         ((DatabaseLogin) login).setDriverClassName(DATABASE_PLATFORM);
         Platform platform = builder.getDatabasePlatform();
         ConversionManager conversionManager = platform.getConversionManager();
         if (conversionManager != null) {
             conversionManager.setLoader(xrdecl);
         }
         login.setDatasourcePlatform(platform);
         ((DatabaseLogin)login).bindAllParameters();
         ((DatabaseLogin)login).setUsesStreamsForBinding(true);

         Project orProject = null;
         if (DBWS_OR_STREAM.size() != 0) {
             MetadataProcessor processor = new MetadataProcessor(new XRPersistenceUnitInfo(xrdecl),
                     new DatabaseSessionImpl(login), xrdecl, false, true, false, false, false, null, null);
             processor.setMetadataSource(new JPAMetadataSource(xrdecl, new StringReader(DBWS_OR_STREAM.toString())));
             PersistenceUnitProcessor.processORMetadata(processor, true, PersistenceUnitProcessor.Mode.ALL);
             processor.addNamedQueries();
             orProject = processor.getProject().getProject();
         } else {
             orProject = new Project();
         }
         orProject.setName(builder.getProjectName().concat(OR_PRJ_SUFFIX));
         orProject.setDatasourceLogin(login);
         DatabaseSession databaseSession = orProject.createDatabaseSession();
         if ("off".equalsIgnoreCase(builder.getLogLevel())) {
             databaseSession.dontLogMessages();
         } else {
             databaseSession.setLogLevel(AbstractSessionLog.translateStringToLoggingLevel(builder.getLogLevel()));
         }
         xrService.setORSession(databaseSession);
         orProject.convertClassNamesToClasses(xrdecl);

         Project oxProject = null;
         Map<String, OXMMetadataSource> metadataMap = new HashMap<String, OXMMetadataSource>();
         StreamSource xml = new StreamSource(new StringReader(DBWS_OX_STREAM.toString()));
         try {
             JAXBContext jc = JAXBContext.newInstance(XmlBindingsModel.class);
             Unmarshaller unmarshaller = jc.createUnmarshaller();

             JAXBElement<XmlBindingsModel> jaxbElt = unmarshaller.unmarshal(xml, XmlBindingsModel.class);
             XmlBindingsModel model = jaxbElt.getValue();
             for (XmlBindings xmlBindings : model.getBindingsList()) {
                 metadataMap.put(xmlBindings.getPackageName(), new OXMMetadataSource(xmlBindings));
             }
         } catch (JAXBException jaxbex) {
             jaxbex.printStackTrace();
         }

         Map<String, Map<String, OXMMetadataSource>> properties = new HashMap<String, Map<String, OXMMetadataSource>>();
         properties.put(JAXBContextProperties.OXM_METADATA_SOURCE, metadataMap);
         try {
             org.eclipse.persistence.jaxb.dynamic.DynamicJAXBContext jCtx =
                     org.eclipse.persistence.jaxb.dynamic.DynamicJAXBContextFactory.createContextFromOXM(parentClassLoader, properties);
             oxProject = jCtx.getXMLContext().getSession(0).getProject();
         } catch (JAXBException e) {
             e.printStackTrace();
         }
         ((XMLLogin)oxProject.getDatasourceLogin()).setPlatformClassName(DOM_PLATFORM_CLASSNAME);
         ((XMLLogin)oxProject.getDatasourceLogin()).setEqualNamespaceResolvers(false);

         prepareDescriptors(oxProject, orProject, xrdecl);
         ProjectHelper.fixOROXAccessors(orProject, oxProject);
         xrService.setORSession(databaseSession);
         xrService.setXMLContext(new XMLContext(oxProject));
         xrService.setOXSession(xrService.getXMLContext().getSession(0));
     }

     @Test
     public void checkSQLOperationModel() {
         SQLOperationModel sqlModel = (SQLOperationModel)builder.operations.get(0);
         assertEquals(SECONDARY_ALL_SQL + NONSENCE_WHERE_SQL , sqlModel.getBuildSql());
         assertFalse(sqlModel.isSimpleXMLFormat());
         assertEquals(SECONDARY_ALL_SCHEMA_TYPE, sqlModel.getReturnType());
     }

     @Test
     public void checkSchema() {
         Document doc = xmlParser.parse(new StringReader(DBWS_SCHEMA_STREAM.toString()));
         Document controlDoc = xmlParser.parse(new StringReader(SCHEMA_CONTROL_DOC));
         assertTrue("control document not same as instance document", comparer.isNodeEqual(
                 controlDoc, doc));
     }

     public static final String SCHEMA_CONTROL_DOC =
         "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +
         "<xsd:schema xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" targetNamespace=\"urn:secondarySQL\" xmlns=\"urn:secondarySQL\" elementFormDefault=\"qualified\">\n" +
          "   <xsd:complexType name=\"secondaryType\">\n" +
         "      <xsd:sequence>\n" +
         "         <xsd:element name=\"empno\" type=\"xsd:decimal\" minOccurs=\"0\" nillable=\"true\"/>\n" +
         "         <xsd:element name=\"ename\" type=\"xsd:string\" minOccurs=\"0\" nillable=\"true\"/>\n" +
         "         <xsd:element name=\"job\" type=\"xsd:string\" minOccurs=\"0\" nillable=\"true\"/>\n" +
         "         <xsd:element name=\"mgr\" type=\"xsd:decimal\" minOccurs=\"0\" nillable=\"true\"/>\n" +
         "         <xsd:element name=\"hiredate\" type=\"xsd:date\" minOccurs=\"0\" nillable=\"true\"/>\n" +
         "         <xsd:element name=\"sal\" type=\"xsd:decimal\" minOccurs=\"0\" nillable=\"true\"/>\n" +
         "         <xsd:element name=\"comm\" type=\"xsd:decimal\" minOccurs=\"0\" nillable=\"true\"/>\n" +
         "         <xsd:element name=\"deptno\" type=\"xsd:decimal\" minOccurs=\"0\" nillable=\"true\"/>\n" +
         "      </xsd:sequence>\n" +
         "   </xsd:complexType>\n" +
         "   <xsd:complexType name=\"secondaryAggregate\">\n" +
         "      <xsd:sequence>\n" +
         "         <xsd:element name=\"count\" type=\"xsd:integer\" minOccurs=\"0\" nillable=\"true\"/>\n" +
         "         <xsd:element name=\"max-salary\" type=\"xsd:decimal\" minOccurs=\"0\" nillable=\"true\"/>\n" +
         "      </xsd:sequence>\n" +
         "   </xsd:complexType>\n" +
         "   <xsd:element name=\"secondaryType\" type=\"secondaryType\"/>\n" +
         "   <xsd:element name=\"secondaryAggregate\" type=\"secondaryAggregate\"/>\n" +
         "</xsd:schema>";

     static final String ALL_CUSTOM_CONTROL_DOC =
         "<?xml version=\"1.0\" encoding=\"UTF-8\"?> " +
         "<all-custom>" +
         "</all-custom>";

     static final String COUNT_REQUEST_MSG =
         "<env:Envelope xmlns:env=\"http://schemas.xmlsoap.org/soap/envelope/\" " +
             "xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">" +
           "<env:Header/>" +
           "<env:Body>" +
             "<countSecondary xmlns=\"" + SECONDARY_SERVICE_NAMESPACE + "\"/>" +
           "</env:Body>" +
         "</env:Envelope>";

     @Test
     public void countSecondary() throws SOAPException, SAXException, IOException, TransformerException {
         MessageFactory factory = MessageFactory.newInstance();
         SOAPMessage request = factory.createMessage();
         SOAPPart part = request.getSOAPPart();
         DOMSource domSource = new DOMSource(getDocumentBuilder().parse(
             new InputSource(new StringReader(COUNT_REQUEST_MSG))));
         part.setContent(domSource);
         Dispatch<SOAPMessage> dispatch = testService.createDispatch(portQName, SOAPMessage.class,
             Service.Mode.MESSAGE);
         SOAPMessage response = null;
         try {
             response = dispatch.invoke(request);
         }
         catch (SOAPFaultException sfe) {
             sfe.printStackTrace();
         }
         if (response != null) {
             Source src = response.getSOAPPart().getContent();
             TransformerFactory tf = TransformerFactory.newInstance();
             Transformer transformer = tf.newTransformer();
             DOMResult result = new DOMResult();
             transformer.transform(src, result);
             Document resultDoc = (Document)result.getNode();
             Document controlDoc = xmlParser.parse(new StringReader(MessageFormat.format(COUNT_RESPONSE_MSG, NS_STRING, "")));
             boolean docsEqual = comparer.isNodeEqual(controlDoc, resultDoc);
             if (!docsEqual) {
                 // different JDKs put xmlns declaration to different element, so retry
                 controlDoc = xmlParser.parse(new StringReader(MessageFormat.format(COUNT_RESPONSE_MSG, "", NS_STRING)));
                 assertTrue("control document not same as instance document",
                         comparer.isNodeEqual(controlDoc, resultDoc));
             }
         }
     }
     private static final String NS_STRING = " xmlns=\"" + SECONDARY_NAMESPACE + "\" xmlns:srvc=\"" + SECONDARY_SERVICE_NAMESPACE + "\"";
     static final String COUNT_RESPONSE_MSG =
         "<SOAP-ENV:Envelope xmlns:SOAP-ENV=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">" +
         "<SOAP-ENV:Header/>" +
         "<SOAP-ENV:Body{0}>" +
           "<srvc:countSecondaryResponse{1}>" +
             "<srvc:result>" +
               "<secondaryAggregate>" +
                 "<count>14</count>" +
                 "<max-salary>5000.00</max-salary>" +
               "</secondaryAggregate>" +
             "</srvc:result>" +
           "</srvc:countSecondaryResponse>" +
         "</SOAP-ENV:Body>" +
         "</SOAP-ENV:Envelope>";

     static final String ALL_REQUEST_MSG =
         "<env:Envelope xmlns:env=\"http://schemas.xmlsoap.org/soap/envelope/\" " +
             "xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\">" +
           "<env:Header/>" +
           "<env:Body>" +
             "<allSecondary xmlns=\"" + SECONDARY_SERVICE_NAMESPACE + "\"/>" +
           "</env:Body>" +
         "</env:Envelope>";
     @Test
     public void allSecondary() throws SOAPException, SAXException, IOException, TransformerException {
         MessageFactory factory = MessageFactory.newInstance();
         SOAPMessage request = factory.createMessage();
         SOAPPart part = request.getSOAPPart();
         DOMSource domSource = new DOMSource(getDocumentBuilder().parse(
             new InputSource(new StringReader(ALL_REQUEST_MSG))));
         part.setContent(domSource);
         Dispatch<SOAPMessage> dispatch = testService.createDispatch(portQName, SOAPMessage.class,
             Service.Mode.MESSAGE);
         SOAPMessage response = null;
         try {
             response = dispatch.invoke(request);
         }
         catch (SOAPFaultException sfe) {
             sfe.printStackTrace();
         }
         if (response != null) {
             Source src = response.getSOAPPart().getContent();
             TransformerFactory tf = TransformerFactory.newInstance();
             Transformer transformer = tf.newTransformer();
             DOMResult result = new DOMResult();
             transformer.transform(src, result);
             Document resultDoc = (Document)result.getNode();
             Document controlDoc = xmlParser.parse(new StringReader(MessageFormat.format(ALL_RESPONSE_MSG, NS_STRING, "")));
             boolean docsEqual = comparer.isNodeEqual(controlDoc, resultDoc);
             if (!docsEqual) {
                 // different JDKs put xmlns declaration to different element, so retry
                 controlDoc = xmlParser.parse(new StringReader(MessageFormat.format(ALL_RESPONSE_MSG, "", NS_STRING)));
                 assertTrue("control document not same as instance document",
                         comparer.isNodeEqual(controlDoc, resultDoc));
             }
         }
     }
     static final String ALL_RESPONSE_MSG =
       "<SOAP-ENV:Envelope xmlns:SOAP-ENV=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">" +
         "<SOAP-ENV:Header/>" +
         "<SOAP-ENV:Body{0}>" +
           "<srvc:allSecondaryResponse{1}>" +
             "<srvc:result>" +
                "<secondaryType>" +
                  "<empno>7369</empno>" +
                  "<ename>SMITH</ename>" +
                  "<job>CLERK</job>" +
                  "<mgr>7902</mgr>" +
                  "<hiredate>1980-12-17</hiredate>" +
                  "<sal>800.00</sal>" +
                  "<comm xsi:nil=\"true\"/>" +
                  "<deptno>20</deptno>" +
                "</secondaryType>" +
                "<secondaryType>" +
                  "<empno>7499</empno>" +
                  "<ename>ALLEN</ename>" +
                  "<job>SALESMAN</job>" +
                  "<mgr>7698</mgr>" +
                  "<hiredate>1981-02-20</hiredate>" +
                  "<sal>1600.00</sal>" +
                  "<comm>300.00</comm>" +
                  "<deptno>30</deptno>" +
               "</secondaryType>" +
               "<secondaryType>" +
                  "<empno>7521</empno>" +
                  "<ename>WARD</ename>" +
                  "<job>SALESMAN</job>" +
                  "<mgr>7698</mgr>" +
                  "<hiredate>1981-02-22</hiredate>" +
                  "<sal>1250.00</sal>" +
                  "<comm>500.00</comm>" +
                  "<deptno>30</deptno>" +
               "</secondaryType>" +
               "<secondaryType>" +
                  "<empno>7566</empno>" +
                  "<ename>JONES</ename>" +
                  "<job>MANAGER</job>" +
                  "<mgr>7839</mgr>" +
                  "<hiredate>1981-04-02</hiredate>" +
                  "<sal>2975.00</sal>" +
                  "<comm xsi:nil=\"true\"/>" +
                  "<deptno>20</deptno>" +
               "</secondaryType>" +
               "<secondaryType>" +
                  "<empno>7654</empno>" +
                  "<ename>MARTIN</ename>" +
                  "<job>SALESMAN</job>" +
                  "<mgr>7698</mgr>" +
                  "<hiredate>1981-09-28</hiredate>" +
                  "<sal>1250.00</sal>" +
                  "<comm>1400.00</comm>" +
                  "<deptno>30</deptno>" +
               "</secondaryType>" +
               "<secondaryType>" +
                  "<empno>7698</empno>" +
                  "<ename>BLAKE</ename>" +
                  "<job>MANAGER</job>" +
                  "<mgr>7839</mgr>" +
                  "<hiredate>1981-05-01</hiredate>" +
                  "<sal>2850.00</sal>" +
                  "<comm xsi:nil=\"true\"/>" +
                  "<deptno>30</deptno>" +
               "</secondaryType>" +
               "<secondaryType>" +
                  "<empno>7782</empno>" +
                  "<ename>CLARK</ename>" +
                  "<job>MANAGER</job>" +
                  "<mgr>7839</mgr>" +
                  "<hiredate>1981-06-09</hiredate>" +
                  "<sal>2450.00</sal>" +
                  "<comm xsi:nil=\"true\"/>" +
                  "<deptno>10</deptno>" +
               "</secondaryType>" +
               "<secondaryType>" +
                  "<empno>7788</empno>" +
                  "<ename>SCOTT</ename>" +
                  "<job>ANALYST</job>" +
                  "<mgr>7566</mgr>" +
                  "<hiredate>1981-06-09</hiredate>" +
                  "<sal>3000.00</sal>" +
                  "<comm xsi:nil=\"true\"/>" +
                  "<deptno>20</deptno>" +
               "</secondaryType>" +
               "<secondaryType>" +
                  "<empno>7839</empno>" +
                  "<ename>KING</ename>" +
                  "<job>PRESIDENT</job>" +
                  "<mgr xsi:nil=\"true\"/>" +
                  "<hiredate>1981-11-17</hiredate>" +
                  "<sal>5000.00</sal>" +
                  "<comm xsi:nil=\"true\"/>" +
                  "<deptno>10</deptno>" +
               "</secondaryType>" +
               "<secondaryType>" +
                  "<empno>7844</empno>" +
                  "<ename>TURNER</ename>" +
                  "<job>SALESMAN</job>" +
                  "<mgr>7698</mgr>" +
                  "<hiredate>1981-09-08</hiredate>" +
                  "<sal>1500.00</sal>" +
                  "<comm>0.00</comm>" +
                  "<deptno>30</deptno>" +
               "</secondaryType>" +
               "<secondaryType>" +
                  "<empno>7876</empno>" +
                  "<ename>ADAMS</ename>" +
                  "<job>CLERK</job>" +
                  "<mgr>7788</mgr>" +
                  "<hiredate>1987-05-23</hiredate>" +
                  "<sal>1100.00</sal>" +
                  "<comm xsi:nil=\"true\"/>" +
                  "<deptno>20</deptno>" +
               "</secondaryType>" +
               "<secondaryType>" +
                  "<empno>7900</empno>" +
                  "<ename>JAMES</ename>" +
                  "<job>CLERK</job>" +
                  "<mgr>7698</mgr>" +
                  "<hiredate>1981-12-03</hiredate>" +
                  "<sal>950.00</sal>" +
                  "<comm xsi:nil=\"true\"/>" +
                  "<deptno>30</deptno>" +
               "</secondaryType>" +
               "<secondaryType>" +
                  "<empno>7902</empno>" +
                  "<ename>FORD</ename>" +
                  "<job>ANALYST</job>" +
                  "<mgr>7566</mgr>" +
                  "<hiredate>1981-12-03</hiredate>" +
                  "<sal>3000.00</sal>" +
                  "<comm xsi:nil=\"true\"/>" +
                  "<deptno>20</deptno>" +
               "</secondaryType>" +
               "<secondaryType>" +
                  "<empno>7934</empno>" +
                  "<ename>MILLER</ename>" +
                  "<job>CLERK</job>" +
                  "<mgr>7782</mgr>" +
                  "<hiredate>1982-01-23</hiredate>" +
                  "<sal>1300.00</sal>" +
                  "<comm xsi:nil=\"true\"/>" +
                  "<deptno>10</deptno>" +
               "</secondaryType>" +
             "</srvc:result>" +
           "</srvc:allSecondaryResponse>" +
         "</SOAP-ENV:Body>" +
       "</SOAP-ENV:Envelope>";

     @Test
     public void testForDuplicateColumns() {
         String username = System.getProperty(DATABASE_USERNAME_KEY, DEFAULT_DATABASE_USERNAME);
         String password = System.getProperty(DATABASE_PASSWORD_KEY, DEFAULT_DATABASE_PASSWORD);
         String url = System.getProperty(DATABASE_URL_KEY, DEFAULT_DATABASE_URL);
         String builderString = DBWS_BUILDER_XML_USERNAME + username + DBWS_BUILDER_XML_PASSWORD +
             password + DBWS_BUILDER_XML_URL + url + DBWS_BUILDER_XML_DRIVER + DATABASE_DRIVER +
               DBWS_BUILDER_XML_PLATFORM + DATABASE_PLATFORM +
                 "</property>" +
              "</properties>" +
            "<sql " +
              "name=\"badColumns\" " +
              "returnType=\"dontCare\"> " +
              "<statement><![CDATA[dontCare]]></statement>" +
              "<build-statement><![CDATA[select ename, ename from secondary where 0=1]]></build-statement>" +
            "</sql>" +
         "</dbws-builder>";
         XMLContext context = new XMLContext(new DBWSBuilderModelProject());
         XMLUnmarshaller unmarshaller = context.createUnmarshaller();
         DBWSBuilderModel builderModel =
             (DBWSBuilderModel)unmarshaller.unmarshal(new StringReader(builderString));
         DBWSBuilder builder2 = new DBWSBuilder();
         builder2.quiet = true;
         builder2.properties = builderModel.properties;
         builder2.getProperties().put(SESSIONS_FILENAME_KEY, NO_SESSIONS_FILENAME);
         builder2.getTargetNamespace();
         builder2.operations = builderModel.operations;
         builder2.setLogLevel(SessionLog.FINE_LABEL);
         builder2.setPackager(new JSR109WebServicePackager(null, "WebServiceTestPackager", noArchive) {
             @Override
             public void start() {
             }
         });
         try {
            builder2.build(DBWS_SCHEMA_STREAM, __nullStream, DBWS_SERVICE_STREAM, DBWS_OR_STREAM,
                 DBWS_OX_STREAM, __nullStream, __nullStream, DBWS_WSDL_STREAM, __nullStream,
                 __nullStream, __nullStream, __nullStream, null);
        }
        catch (Exception e) {
            assertEquals("Duplicate ResultSet columns not supported", e.getMessage());
        }
     }
}
