/*
 * Copyright (c) 1998, 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 - May 01 2008, creating DBWS tools package

package org.eclipse.persistence.tools.dbws;

import static java.util.logging.Level.SEVERE;
import static javax.xml.XMLConstants.W3C_XML_SCHEMA_INSTANCE_NS_URI;
import static javax.xml.XMLConstants.W3C_XML_SCHEMA_NS_URI;
// EclipseLink imports
import static org.eclipse.persistence.internal.xr.Util.DBWS_OR_XML;
import static org.eclipse.persistence.internal.xr.Util.DBWS_OX_XML;
import static org.eclipse.persistence.internal.xr.Util.DBWS_SCHEMA_XML;
import static org.eclipse.persistence.internal.xr.Util.DBWS_SERVICE_XML;
import static org.eclipse.persistence.internal.xr.Util.DBWS_SESSIONS_XML;
import static org.eclipse.persistence.internal.xr.Util.DBWS_WSDL;
import static org.eclipse.persistence.tools.dbws.DBWSPackager.ArchiveUse.archive;
import static org.eclipse.persistence.tools.dbws.DBWSPackager.ArchiveUse.ignore;
import static org.eclipse.persistence.tools.dbws.DBWSPackager.ArchiveUse.noArchive;
import static org.eclipse.persistence.tools.dbws.Util.DBWS_PROVIDER_CLASS_FILE;
import static org.eclipse.persistence.tools.dbws.Util.DBWS_PROVIDER_SOURCE_FILE;
import static org.eclipse.persistence.tools.dbws.Util.DEFAULT_PLATFORM_CLASSNAME;
import static org.eclipse.persistence.tools.dbws.Util.DEFAULT_WSDL_LOCATION_URI;
import static org.eclipse.persistence.tools.dbws.Util.PROVIDER_LISTENER_CLASS_FILE;
import static org.eclipse.persistence.tools.dbws.Util.PROVIDER_LISTENER_SOURCE_FILE;
import static org.eclipse.persistence.tools.dbws.Util.SWAREF_FILENAME;
import static org.eclipse.persistence.tools.dbws.Util.WEB_XML_FILENAME;
import static org.eclipse.persistence.tools.dbws.XRPackager.__nullStream;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.security.AccessController;
import java.sql.Connection;
import java.sql.DriverManager;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.ServiceLoader;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;

import javax.wsdl.WSDLException;

import org.eclipse.persistence.dbws.DBWSModel;
import org.eclipse.persistence.descriptors.ClassDescriptor;
import org.eclipse.persistence.internal.databaseaccess.DatabasePlatform;
import org.eclipse.persistence.internal.helper.Helper;
import org.eclipse.persistence.internal.oxm.schema.model.Schema;
import org.eclipse.persistence.internal.security.PrivilegedAccessHelper;
import org.eclipse.persistence.internal.security.PrivilegedClassForName;
import org.eclipse.persistence.internal.sessions.factories.model.project.ProjectClassConfig;
import org.eclipse.persistence.internal.sessions.factories.model.project.ProjectConfig;
import org.eclipse.persistence.internal.sessions.factories.model.project.ProjectXMLConfig;
import org.eclipse.persistence.internal.xr.Operation;
import org.eclipse.persistence.internal.xr.QueryOperation;
import org.eclipse.persistence.internal.xr.XRServiceModel;
import org.eclipse.persistence.internal.xr.sxf.SimpleXMLFormatProject;
import org.eclipse.persistence.oxm.NamespaceResolver;
import org.eclipse.persistence.oxm.XMLContext;
import org.eclipse.persistence.oxm.XMLUnmarshaller;
import org.eclipse.persistence.platform.database.MySQLPlatform;
import org.eclipse.persistence.sessions.Project;
import org.eclipse.persistence.tools.dbws.DBWSPackager.ArchiveUse;
import org.eclipse.persistence.tools.dbws.jdbc.JDBCHelper;
import org.eclipse.persistence.tools.dbws.oracle.OracleHelper;

public class DBWSBuilder extends DBWSBuilderModel {
    public static final String BUILDER_FILE_PATH = "-builderFile";
    public static final String BUILDER_PACKAGING = "-packageAs";
    public static final String STAGE_DIR = "-stageDir";
    public static final String DRIVER_KEY = "driver";
    public static final String USERNAME_KEY= "username";
    public static final String PASSWORD_KEY = "password";
    public static final String URL_KEY = "url";
    public static final String PROJNAME_KEY = "projectName";
    public static final String DEFAULT_PROJECT_NAME = "myProject";
    public static final String CONTEXT_ROOT_KEY = "contextRoot";
    public static final String DATASOURCE_KEY = "dataSource";
    public static final String SESSIONS_FILENAME_KEY = "sessionsFileName";
    public static final String NO_SESSIONS_FILENAME = "no-sessions-fileName";
    public static final String PLATFORM_CLASSNAME_KEY = "platformClassname";
    public static final String ORSESSION_CUSTOMIZER_KEY = "orSessionCustomizerClassName";
    public static final String OXSESSION_CUSTOMIZER_KEY = "oxSessionCustomizerClassName";
    public static final String WSDL_URI_KEY = "wsdlLocationURI";
    public static final String LOG_LEVEL_KEY = "logLevel";
    public static final String TARGET_NAMESPACE_KEY = "targetNamespace";
    public static final String USE_SOAP12_KEY = "useSOAP12";

    public static final Map<String,DBWSPackager> PACKAGERS;
    static {
        Map<String,DBWSPackager> packagersMap = new HashMap<String,DBWSPackager>();
        ServiceLoader<DBWSPackager> packagers = ServiceLoader.load(DBWSPackager.class);
        for (DBWSPackager packager : packagers) {
            packagersMap.put(packager.getPackagerLabel(), packager);
        }
        PACKAGERS = Collections.unmodifiableMap(packagersMap);
    }
    protected DBWSPackager packager;
    protected Logger logger;
    public boolean quiet = false;
    protected String destDir;
    protected DatabasePlatform databasePlatform;
    protected Connection conn;
    protected Project orProject;
    protected Project oxProject;
    protected WSDLGenerator wsdlGenerator = null;
    protected Schema schema = new Schema();
    protected NamespaceResolver ns = schema.getNamespaceResolver();
    protected XRServiceModel xrServiceModel = new DBWSModel();
    protected DBWSBuilderHelper builderHelper = null;
    protected NamingConventionTransformer topTransformer;
    protected Set<String> typeDDL = new HashSet<String>();
    protected Set<String> typeDropDDL = new HashSet<String>();
    public List<String> requireCRUDOperations = new ArrayList<String>();

    public DBWSBuilder() {
        super();
        ns.put("xsi", W3C_XML_SCHEMA_INSTANCE_NS_URI);
        ns.put("xsd", W3C_XML_SCHEMA_NS_URI);
    }

    /**
     * This method creates a new DBWSBuilder instance, and calls the start method
     * with the given arguments.
     */
    public static void main(String[] args) throws WSDLException {
        DBWSBuilder builder = new DBWSBuilder();
        builder.start(args);
    }

    /**
     * This method processes the given arguments, sets properties and operations,
     * initializes the target packager, then calls the start method.
     *
     * This method expects 6 or 7 arguments (7 if the archive file name is provided), as follows:
     *   [0] -builderFile
     *   [1] &lt;builder filename&gt;
     *   [2] -stageDir
     *   [3] &lt;stage dir&gt;
     *   [4] -packagAs
     *   [5] &lt;package type&gt; (wls, jdev, etc.)
     *   [6] &lt;archive filename&gt; (optional)
     */
    public void start(String[] args) throws WSDLException {
        if (args.length > 5 && BUILDER_FILE_PATH.equals(args[0]) && STAGE_DIR.equals(args[2]) && args[4].startsWith(BUILDER_PACKAGING)) {
            String builderFilename = args[1];
            String stageDirname = args[3];
            String packagerTag = args[5];
            String archiverTag = null;
            ArchiveUse archiveUse = ignore;
            int cIdx = args[4].indexOf(':');
            if (cIdx == 10) {
                archiverTag = args[4].substring(cIdx+1);
                if (archive.name().equals(archiverTag)) {
                    archiveUse = archive;
                } else if (noArchive.name().equals(archiverTag)) {
                    archiveUse = noArchive;
                }
            }
            String[] additionalArgs = null;
            if (args.length > 6) {
                additionalArgs = new String[args.length - 6];
                System.arraycopy(args, 6, additionalArgs, 0, args.length - 6);
            }
            File builderFile = new File(builderFilename);
            if (builderFile.exists() && builderFile.isFile()) {
                File stageDir = new File(stageDirname);
                if (stageDir.exists() && stageDir.isDirectory()) {
                    XMLContext context = new XMLContext(new DBWSBuilderModelProject());
                    XMLUnmarshaller unmarshaller = context.createUnmarshaller();
                    DBWSBuilderModel model = (DBWSBuilderModel)unmarshaller.unmarshal(builderFile);
                    properties = model.properties;
                    operations = model.operations;
                    if (operations.size() == 0) {
                        logMessage(SEVERE, "No operations specified");
                        return;
                    }
                    packager = PACKAGERS.get(packagerTag);
                    if (packager != null) {
                        packager.setDBWSBuilder(this);
                        packager.setArchiveUse(archiveUse);
                        packager.setAdditionalArgs(additionalArgs);
                        packager.setStageDir(stageDir);
                        packager.setSessionsFileName(getSessionsFileName());
                        start();
                        return;
                    }
                } else {
                    logMessage(SEVERE, "DBWSBuilder unable to locate stage directory " + stageDirname);
                    return;
                }
            } else {
                logMessage(SEVERE, "DBWSBuilder unable to locate dbws-builder.xml file " + builderFilename);
                return;
            }
        }

        // ------
        // prompt> java -cp eclipselink.jar:eclipselink-dbwsutils.jar:your_favourite_jdbc_driver.jar org.eclipse.persistence.tools.dbws.DBWSBuilder -builderFile {path_to_dbws_builder.xml_file} -stageDir {path_to_staging_directory} -packageAs {how_to_package_output} [additionalArgs]
        // ------

        StringBuilder sb = new StringBuilder(30);
        sb.append("DBWSBuilder usage ([] indicates optional argument):\nprompt> java -cp eclipselink.jar:eclipselink-dbwsutils.jar:your_favourite_jdbc_driver.jar \\\n\t");
        sb.append(this.getClass().getName());
        sb.append(" ");
        sb.append(BUILDER_FILE_PATH);
        sb.append(" {path_to_dbwsbuilder.xml} \\\n\t");
        sb.append(STAGE_DIR);
        sb.append(" ");
        sb.append(" {path_to_stageDir}");
        sb.append(" ");
        sb.append(BUILDER_PACKAGING);
        sb.append("[:archive_flag - archive, noArchive, ignore] {packager} [additional arguments]\nAvailable packagers:\n\t");
        for (Iterator<Map.Entry<String, DBWSPackager>> i = PACKAGERS.entrySet().iterator(); i.hasNext();) {
            Map.Entry<String, DBWSPackager> me = i.next();
            sb.append(me.getValue().getUsage());
            if (i.hasNext()) {
                sb.append("\n\t");
            }
        }
        logMessage(SEVERE, sb.toString());
        return;
    }

    /**
     * Initialize the required OutputStreams and call the build method.
     */
    public void start() throws WSDLException {
        packager.setHasAttachments(hasAttachments());
        OutputStream dbwsSchemaStream = null;
        try {
            dbwsSchemaStream = packager.getSchemaStream();
        } catch (FileNotFoundException fnfe) {
            logMessage(SEVERE, "DBWSBuilder unable to create " + DBWS_SCHEMA_XML, fnfe);
            return;
        }
        OutputStream dbwsSessionsStream = null;
        try {
            dbwsSessionsStream = packager.getSessionsStream(getSessionsFileName());
        } catch (FileNotFoundException fnfe) {
            logMessage(SEVERE, "DBWSBuilder unable to create " + DBWS_SESSIONS_XML, fnfe);
            return;
        };
        OutputStream dbwsServiceStream = null;
        try {
            dbwsServiceStream = packager.getServiceStream();
        } catch (FileNotFoundException fnfe) {
            logMessage(SEVERE, "DBWSBuilder unable to create " + DBWS_SERVICE_XML, fnfe);
            return;
        };
        OutputStream dbwsOrStream = null;
        try {
            dbwsOrStream = packager.getOrStream();
        } catch (FileNotFoundException fnfe) {
            logMessage(SEVERE, "DBWSBuilder unable to create " + DBWS_OR_XML, fnfe);
            return;
        };
        OutputStream dbwsOxStream = null;
        try {
            dbwsOxStream = packager.getOxStream();
        } catch (FileNotFoundException fnfe) {
            logMessage(SEVERE, "DBWSBuilder unable to create " + DBWS_OX_XML, fnfe);
            return;
        };
        OutputStream wsdlStream = null;
        try {
            wsdlStream = packager.getWSDLStream();
        } catch (FileNotFoundException fnfe) {
            logMessage(SEVERE, "DBWSBuilder unable to create " + DBWS_WSDL, fnfe);
            return;
        };
        OutputStream swarefStream = null;
        try {
            swarefStream = packager.getSWARefStream();
        } catch (FileNotFoundException fnfe) {
            logMessage(SEVERE, "DBWSBuilder unable to create " + SWAREF_FILENAME, fnfe);
            return;
        };
        OutputStream webXmlStream = null;
        try {
            webXmlStream = packager.getWebXmlStream();
        } catch (FileNotFoundException fnfe) {
            logMessage(SEVERE, "DBWSBuilder unable to create " + WEB_XML_FILENAME, fnfe);
            return;
        };
        OutputStream classProviderStream = null;
        try {
            classProviderStream = packager.getProviderClassStream();
        } catch (FileNotFoundException fnfe) {
            logMessage(SEVERE,
                "DBWSBuilder unable to create " + DBWS_PROVIDER_CLASS_FILE, fnfe);
            return;
        };
        OutputStream sourceProviderStream = null;
        try {
            sourceProviderStream = packager.getProviderSourceStream();
        } catch (FileNotFoundException fnfe) {
            logMessage(SEVERE,
                "DBWSBuilder unable to create " + DBWS_PROVIDER_SOURCE_FILE, fnfe);
            return;
        };
        OutputStream classProviderListenerStream = null;
        try {
            classProviderListenerStream = packager.getProviderListenerClassStream();
        } catch (FileNotFoundException fnfe) {
            logMessage(SEVERE,
                "DBWSBuilder unable to create " + PROVIDER_LISTENER_CLASS_FILE, fnfe);
            return;
        };
        OutputStream sourceProviderListenerStream = null;
        try {
            sourceProviderListenerStream = packager.getProviderListenerSourceStream();
        } catch (FileNotFoundException fnfe) {
            logMessage(SEVERE,
                "DBWSBuilder unable to create " + PROVIDER_LISTENER_SOURCE_FILE, fnfe);
            return;
        };
        // Deployment descriptor is optional
        OutputStream deploymentDescriptorStream = null;
        if (packager.getDeploymentDescriptorFileName() != null) {
            try {
                deploymentDescriptorStream = packager.getDeploymentDescriptorStream();
            } catch (FileNotFoundException fnfe) {
                logMessage(SEVERE, "DBWSBuilder unable to create " + packager.getDeploymentDescriptorFileName(), fnfe);
                return;
            }
        }
        build(dbwsSchemaStream, dbwsSessionsStream, dbwsServiceStream, dbwsOrStream,
            dbwsOxStream, swarefStream, webXmlStream, wsdlStream, classProviderStream,
            sourceProviderStream, classProviderListenerStream, sourceProviderListenerStream,
            deploymentDescriptorStream, logger);
    }

    /**
     * Continue to support calling the build method without providing an OutputStream
     * for the optional deployment descriptor.
     */
    public void build(OutputStream dbwsSchemaStream, OutputStream dbwsSessionsStream,
            OutputStream dbwsServiceStream, OutputStream dbwsOrStream, OutputStream dbwsOxStream,
            OutputStream swarefStream, OutputStream webXmlStream, OutputStream wsdlStream,
            OutputStream classProviderStream, OutputStream sourceProviderStream,
            OutputStream classProviderListenerStream, OutputStream sourceProviderListenerStream,
            Logger logger)
            throws WSDLException {
        build(dbwsSchemaStream, dbwsSessionsStream, dbwsServiceStream, dbwsOrStream,
                dbwsOxStream, swarefStream, webXmlStream, wsdlStream, classProviderStream,
                sourceProviderStream, classProviderListenerStream, sourceProviderListenerStream,
                null, logger);
    }

    /**
     * Generate the required artifacts for the target packaging/archiving, and write each
     * to the given OutputStreams as appropriate.
     */
    public void build(OutputStream dbwsSchemaStream, OutputStream dbwsSessionsStream,
        OutputStream dbwsServiceStream, OutputStream dbwsOrStream, OutputStream dbwsOxStream,
        OutputStream swarefStream, OutputStream webXmlStream, OutputStream wsdlStream,
        OutputStream classProviderStream, OutputStream sourceProviderStream,
        OutputStream classProviderListenerStream, OutputStream sourceProviderListenerStream,
        OutputStream deploymentDescriptorStream, Logger logger)
        throws WSDLException {

        this.logger = logger; // in case some other tool wishes to use a java.util.logger
        // misc setup
        xrServiceModel.setName(getProjectName());
        String sessionsFileName = getSessionsFileName();
        if (sessionsFileName != null && sessionsFileName.length() > 0) {
            xrServiceModel.setSessionsFile(sessionsFileName);
        }
        //has someone manually set a custom NamingConventionTransformer?
        if (topTransformer == null) {
            // setup the NamingConventionTransformers
            ServiceLoader<NamingConventionTransformer> transformers = ServiceLoader.load(NamingConventionTransformer.class);
            Iterator<NamingConventionTransformer> transformerIter = transformers.iterator();
            topTransformer = transformerIter.next();
            LinkedList<NamingConventionTransformer> transformerList = new LinkedList<NamingConventionTransformer>();
            // check for user-provided transformer in front of default transformers
            if (!((DefaultNamingConventionTransformer)topTransformer).isDefaultTransformer()) {
                // ditch all default transformers, except for the last one - SQLX2003Transformer
                for (; transformerIter.hasNext(); ) {
                    NamingConventionTransformer nextTransformer = transformerIter.next();
                    if (!((DefaultNamingConventionTransformer)nextTransformer).isDefaultTransformer()) {
                        transformerList.addLast(nextTransformer);
                    } else if (nextTransformer instanceof SQLX2003Transformer) {
                        transformerList.addLast(nextTransformer);
                    }
                }
            } else {
                // assume usual configuration: ToLowerTransformer -> TypeSuffixTransformer -> SQLX2003Transformer
                for (; transformerIter.hasNext(); ) {
                    transformerList.addLast(transformerIter.next());
                }
            }
            // hook up the chain-of-responsibility
            NamingConventionTransformer nextTransformer = topTransformer;
            for (Iterator<NamingConventionTransformer> i = transformerList.iterator(); i.hasNext();) {
                NamingConventionTransformer nct = i.next();
                ((DefaultNamingConventionTransformer)nextTransformer).setNextTransformer(nct);
                nextTransformer = nct;
            }
        }
        packager.start();
        DBWSBuilderHelper helper = getBuilderHelper();
        helper.buildDbArtifacts();
        // don't write out projects yet; buildDBWSModel may add additional mappings
        helper.buildOROXProjects(topTransformer, helper.buildTypesList(operations));
        // don't write out schema yet; buildDBWSModel/buildWSDL may add additional schema elements
        helper.buildSchema(topTransformer);
        helper.buildSessionsXML(dbwsSessionsStream);
        packager.setHasAttachments(hasAttachments());
        helper.buildDBWSModel(topTransformer, dbwsServiceStream);
        helper.writeAttachmentSchema(swarefStream);
        helper.buildWSDL(wsdlStream, topTransformer);
        helper.writeWebXML(webXmlStream);
        helper.generateDBWSProvider(sourceProviderStream, classProviderStream, sourceProviderListenerStream,
            classProviderListenerStream);
        helper.writeSchema(dbwsSchemaStream); // now write out schema
        helper.writeOROXProjects(dbwsOrStream, dbwsOxStream);
        helper.writeDeploymentDescriptor(deploymentDescriptorStream);  // write out the (optional) deployment descriptor
        packager.end();
    }

    public OutputStream getShadowDDLStream() {
        return __nullStream;
    }

    /**
     * @deprecated As of release 2.4, use addOperation(OperationModel operation) instead.
     * @see org.eclipse.persistence.tools.dbws.DBWSBuilder#addOperation(OperationModel operation)
     */
    @Deprecated
    public void addSqlOperation(SQLOperationModel sqlOperation) {
        operations.add(sqlOperation);
    }

    /**
     * Add an OperationModel instance to the List of OperationModels
     * to be processed.
     */
    public void addOperation(OperationModel operation) {
        operations.add(operation);
    }

    protected ProjectConfig buildORProjectConfig() {
        ProjectConfig orProjectConfig = null;
        boolean useProjectXML = false;
        if (builderHelper.hasTables() || hasBuildSqlOperations()) {
            useProjectXML = true;
        }
        if (!useProjectXML) {
            // check for any named queries - SimpleXMLFormatProject's sometimes need them
            if (orProject.getQueries().size() > 0) {
                useProjectXML = true;
            }
            // check for ObjectRelationalDataTypeDescriptor's - Advanced JDBC object/varray types
            else if (orProject.getDescriptors().size() > 0) {
                Collection<ClassDescriptor> descriptors = orProject.getDescriptors().values();
                for (ClassDescriptor desc : descriptors) {
                    if (desc.isObjectRelationalDataTypeDescriptor()) {
                        useProjectXML = true;
                        break;
                    }
                }
            }
        }
        if (useProjectXML) {
            orProjectConfig = new ProjectXMLConfig();
            String pathPrefix = packager.getOrProjectPathPrefix();
            orProjectConfig.setProjectString(
                pathPrefix == null ? DBWS_OR_XML : pathPrefix + DBWS_OR_XML);
        }
        else {
            orProjectConfig = new ProjectClassConfig();
            orProjectConfig.setProjectString(Project.class.getName());
        }
        return orProjectConfig;
    }

    protected ProjectConfig buildOXProjectConfig() {
        ProjectConfig oxProjectConfig = null;
        boolean useProjectXML = false;
        if (builderHelper.hasTables() || hasBuildSqlOperations()) {
            useProjectXML = true;
        }
        if (!useProjectXML) {
            // check for any named queries - SimpleXMLFormatProject's sometimes need them
            if (orProject.getQueries().size() > 0) {
                useProjectXML = true;
            }
            // check for ObjectRelationalDataTypeDescriptor's - Advanced JDBC object/varray types
            else if (orProject.getDescriptors().size() > 0) {
                Collection<ClassDescriptor> descriptors = orProject.getDescriptors().values();
                for (ClassDescriptor desc : descriptors) {
                    if (desc.isObjectRelationalDataTypeDescriptor()) {
                        useProjectXML = true;
                        break;
                    }
                }
            }
        }
        if (useProjectXML) {
            oxProjectConfig = new ProjectXMLConfig();
            String pathPrefix = packager.getOxProjectPathPrefix();
            oxProjectConfig.setProjectString(
                pathPrefix == null ? DBWS_OX_XML : pathPrefix + DBWS_OX_XML);
        }
        else {
            oxProjectConfig = new ProjectClassConfig();
            oxProjectConfig.setProjectString(SimpleXMLFormatProject.class.getName());
        }
        return oxProjectConfig;
    }

    protected boolean hasAttachments() {
        for (Operation op : xrServiceModel.getOperationsList()) {
            if (op instanceof QueryOperation) {
                if (((QueryOperation)op).isAttachment()) {
                    return true;
                }
            }
        }
        //check if any operation is marked with binaryAttachment="true"
        for (OperationModel op : operations) {
            if (op.getBinaryAttachment()) {
                return true;
            }
            // check nested operations
            if (op.isTableOperation()) {
                TableOperationModel top = (TableOperationModel)op;
                if (top.additionalOperations != null && top.additionalOperations.size() > 0) {
                    for (OperationModel addOp : top.additionalOperations) {
                        if (addOp.binaryAttachment) {
                            return true;
                        }
                    }
                }
            }
        }
        return false;
    }

    public DBWSPackager getPackager() {
        return packager;
    }
    public void setPackager(DBWSPackager packager) {
        this.packager = packager;
    }

    public String getDriver() {
        return properties.get(DRIVER_KEY);
    }
    public void setDriver(String driver) {
        properties.put(DRIVER_KEY, driver);
    }

    public String getUsername() {
        return properties.get(USERNAME_KEY);
    }
    public void setUsername(String username) {
        properties.put(USERNAME_KEY, username);
    }

    public String getPassword() {
        return properties.get(PASSWORD_KEY);
    }

    public void setPassword(String password) {
        properties.put(PASSWORD_KEY, password);
    }

    public String getUrl() {
        return properties.get(URL_KEY);
    }

    public void setUrl(String url) {
        properties.put(URL_KEY, url);
    }

    public Connection getConnection() {
        if (conn == null ) {
            String driverClassName = getDriver();
            try {
                @SuppressWarnings("unused")
                Class<?> driverClass = null;
                if (PrivilegedAccessHelper.shouldUsePrivilegedAccess()){
                    driverClass = AccessController.doPrivileged(
                        new PrivilegedClassForName(driverClassName));
                }
                else {
                    driverClass = PrivilegedAccessHelper.getClassForName(driverClassName);
                }
                Properties props = new Properties();
                props.put("user", getUsername());
                props.put("password", getPassword());
                if (getPlatformClassname().contains("MySQL")) {
                    props.put("useInformationSchema", "true");
                }
                conn = DriverManager.getConnection(getUrl(), props);
            }
            catch (Exception e) {
                logMessage(SEVERE, "JDBC driver error: " + driverClassName, e);
            }
        }
        return conn;
    }
    public void setConnection(Connection conn) {
        this.conn = conn;
    }

    /**
     * Return the projectName property or the default (myProject) if not set.
     */
    public String getProjectName() {
        String prjName = properties.get(PROJNAME_KEY);
        return (prjName != null && prjName.length() > 0) ? prjName : DEFAULT_PROJECT_NAME;
    }
    /**
     * Sets the projectName property.
     */
    public void setProjectName(String projectName) {
        properties.put(PROJNAME_KEY, projectName);
    }

    public String getContextRoot() {
        String contextRoot = properties.get(CONTEXT_ROOT_KEY);
        if (contextRoot == null) {
            contextRoot = "/" + getProjectName();
            setContextRoot(contextRoot);
        }
        return contextRoot;
    }
    public void setContextRoot(String contextRoot) {
        properties.put(CONTEXT_ROOT_KEY, contextRoot);
    }

    public String getDataSource() {
        return properties.get(DATASOURCE_KEY);
    }
    public void setDataSource(String dataSource) {
        properties.put(DATASOURCE_KEY, dataSource);
    }

    public String getSessionsFileName() {
        String sessionsFileName = properties.get(SESSIONS_FILENAME_KEY);
        if (NO_SESSIONS_FILENAME.equals(sessionsFileName)) {
            return null;
        }
        if (sessionsFileName == null || sessionsFileName.length() == 0) {
            sessionsFileName = DBWS_SESSIONS_XML;
            setSessionsFileName(sessionsFileName);
        }
        return sessionsFileName;
    }
    public void setSessionsFileName(String sessionsFileName) {
        properties.put(SESSIONS_FILENAME_KEY, sessionsFileName);
    }

    public String getPlatformClassname() {
        String platformClassname = properties.get(PLATFORM_CLASSNAME_KEY);
        if (platformClassname == null || platformClassname.length() == 0) {
            platformClassname = DEFAULT_PLATFORM_CLASSNAME;
            setPlatformClassname(platformClassname);
        }
        return platformClassname;

    }
    public void setPlatformClassname(String platformClassname) {
        properties.put(PLATFORM_CLASSNAME_KEY, platformClassname);

    }
    public DatabasePlatform getDatabasePlatform() {
        if (databasePlatform == null) {
            String platformClassname = getPlatformClassname();
            try {
                Class<?> platformClass = null;
                if (PrivilegedAccessHelper.shouldUsePrivilegedAccess()){
                    platformClass = AccessController.doPrivileged(
                        new PrivilegedClassForName(platformClassname));
                }
                else {
                    platformClass =
                        PrivilegedAccessHelper.getClassForName(platformClassname);
                }
                databasePlatform = (DatabasePlatform)Helper.getInstanceFromClass(platformClass);
            }
            catch (Exception e) {
                databasePlatform = new MySQLPlatform();
            }
        }
        return databasePlatform;
    }
    public void setDatabasePlatform(DatabasePlatform databasePlatform) {
        this.databasePlatform = databasePlatform;
    }

    public Project getOrProject() {
        return orProject;
    }
    public void setOrProject(Project orProject) {
        this.orProject = orProject;
    }

    public Project getOxProject() {
        return oxProject;
    }
    public void setOxProject(Project oxProject) {
        this.oxProject = oxProject;
    }

    public Schema getSchema() {
        return schema;
    }
    public void setSchema(Schema schema) {
        this.schema = schema;
    }

    public XRServiceModel getXrServiceModel() {
        return xrServiceModel;
    }

    public String getOrSessionCustomizerClassName() {
        return properties.get(ORSESSION_CUSTOMIZER_KEY);
    }

    public void setOrSessionCustomizerClassName(String sessionCustomizerClassName) {
        properties.put(ORSESSION_CUSTOMIZER_KEY, sessionCustomizerClassName);
    }

    public String getOxSessionCustomizerClassName() {
        return properties.get(OXSESSION_CUSTOMIZER_KEY);
    }

    public void setOXSessionCustomizerClassName(String sessionCustomizerClassName) {
        properties.put(OXSESSION_CUSTOMIZER_KEY, sessionCustomizerClassName);
    }

    public WSDLGenerator getWSDLGenerator() {
        return wsdlGenerator;
    }

    public String getWsdlLocationURI() {
        String wsdlLocationURI = properties.get(WSDL_URI_KEY);
        if (wsdlLocationURI == null || wsdlLocationURI.length() == 0) {
            wsdlLocationURI = DEFAULT_WSDL_LOCATION_URI;
        }
        return wsdlLocationURI;
    }

    public void setWsdlLocationURI(String wsdlLocationURI) {
        properties.put(WSDL_URI_KEY, wsdlLocationURI);
    }

    public String getLogLevel() {
        return properties.get(LOG_LEVEL_KEY);
    }

    public void setLogLevel(String logLevel) {
        properties.put(LOG_LEVEL_KEY, logLevel);
    }

    public String getTargetNamespace() {
        String targetNamespace = properties.get(TARGET_NAMESPACE_KEY);
        if (targetNamespace == null) {
            targetNamespace = "urn:" + getProjectName();
            setTargetNamespace(targetNamespace);
        }
        return targetNamespace;
    }

    public Set<String> getTypeDDL() {
        return typeDDL;
    }

    public Set<String> getTypeDropDDL() {
        return typeDropDDL;
    }

    public DBWSBuilderHelper getBuilderHelper() {
        if (builderHelper == null) {
            boolean isOracle = getDatabasePlatform().getClass().getName().contains("Oracle")
                ? true : false;
            if (isOracle) {
                builderHelper = new OracleHelper(this);
            }
            else {
                builderHelper = new JDBCHelper(this);
            }
        }
        return builderHelper;
    }
    public void setBuilderHelper(DBWSBuilderHelper builderHelper) {
        this.builderHelper = builderHelper;
    }

    public void useSOAP12() {
        properties.put(USE_SOAP12_KEY, "true");

    }
    public boolean usesSOAP12() {
        boolean useSOAP12 = false;
        String s = properties.get(USE_SOAP12_KEY);
        if (s != null) {
            useSOAP12 = s.toLowerCase().equals("true");
        }
        return useSOAP12;
    }

    public boolean mtomEnabled() {
        boolean mtomEnabled = false;

        for (OperationModel opModel : getOperations()) {
            String attachmentType = opModel.getAttachmentType();
            if ("MTOM".equalsIgnoreCase(attachmentType) || "SWAREF".equalsIgnoreCase(attachmentType)) {
                mtomEnabled = true;
                break;
            }
        }
        return mtomEnabled;
    }

    public void setTargetNamespace(String targetNamespace) {
        properties.put(TARGET_NAMESPACE_KEY, targetNamespace);
    }

    public void logMessage(Level level, String message) {
        if (logger != null) {
            logger.log(level, message);
        }
        else if (!quiet) {
            System.out.println(message);
        }
    }

    protected void logMessage(Level severe, String message, Exception e) {
        if (logger != null) {
            logger.log(severe, message, e);
        }
        else {
            PrintWriter pw = new PrintWriter(System.out);
            e.printStackTrace(pw);
            System.out.println(message);
        }
    }

    public NamingConventionTransformer getTopNamingConventionTransformer() {
        return topTransformer;
    }
    public void setTopNamingConventionTransformer(NamingConventionTransformer topTransformer) {
        this.topTransformer = topTransformer;
    }

    public boolean hasBuildSqlOperations() {
        boolean flag = false;
        for (OperationModel om : operations) {
            if (om.isSQLOperation()) {
                SQLOperationModel sqlOm = (SQLOperationModel)om;
                String buildSql = sqlOm.getBuildSql();
                if (buildSql != null && buildSql.length() > 0) {
                    flag = true;
                    break;
                }
            }
        }
        return flag;
    }
}
