/*
 * Copyright (c) 2011, 2021 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);
        }
    }

    @Override
    @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());
        }
     }
}
