/*
 * Copyright (c) 1998, 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 - from Proof-of-concept, become production code
package org.eclipse.persistence.tools.dbws;

//javase imports
import static java.util.logging.Level.FINE;
import static java.util.logging.Level.FINEST;
import static java.util.logging.Level.SEVERE;
import static org.eclipse.persistence.internal.helper.ClassConstants.APBYTE;
import static org.eclipse.persistence.internal.oxm.Constants.BASE_64_BINARY_QNAME;
import static org.eclipse.persistence.internal.oxm.Constants.EMPTY_STRING;
import static org.eclipse.persistence.internal.oxm.Constants.XML_MIME_URL;
import static org.eclipse.persistence.internal.oxm.schema.SchemaModelGeneratorProperties.ELEMENT_FORM_QUALIFIED_KEY;
import static org.eclipse.persistence.internal.xr.Util.DBWS_OR_LABEL;
import static org.eclipse.persistence.internal.xr.Util.DBWS_OX_LABEL;
import static org.eclipse.persistence.internal.xr.Util.DBWS_WSDL;
import static org.eclipse.persistence.internal.xr.Util.DEFAULT_ATTACHMENT_MIMETYPE;
import static org.eclipse.persistence.internal.xr.Util.PK_QUERYNAME;
import static org.eclipse.persistence.internal.xr.Util.TARGET_NAMESPACE_PREFIX;
import static org.eclipse.persistence.internal.xr.Util.getClassFromJDBCType;
import static org.eclipse.persistence.internal.xr.XRDynamicClassLoader.COLLECTION_WRAPPER_SUFFIX;
import static org.eclipse.persistence.internal.xr.sxf.SimpleXMLFormat.DEFAULT_SIMPLE_XML_FORMAT_TAG;
import static org.eclipse.persistence.oxm.mappings.nullpolicy.XMLNullRepresentationType.XSI_NIL;
import static org.eclipse.persistence.tools.dbws.NamingConventionTransformer.ElementStyle.ATTRIBUTE;
import static org.eclipse.persistence.tools.dbws.NamingConventionTransformer.ElementStyle.ELEMENT;
import static org.eclipse.persistence.tools.dbws.NamingConventionTransformer.ElementStyle.NONE;
import static org.eclipse.persistence.tools.dbws.Util.AT_SIGN;
import static org.eclipse.persistence.tools.dbws.Util.CHAR_STR;
import static org.eclipse.persistence.tools.dbws.Util.CLOSE_BRACKET;
import static org.eclipse.persistence.tools.dbws.Util.CLOSE_SQUARE_BRACKET;
import static org.eclipse.persistence.tools.dbws.Util.COMMA;
import static org.eclipse.persistence.tools.dbws.Util.CREATE_OPERATION_NAME;
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.DECIMAL_STR;
import static org.eclipse.persistence.tools.dbws.Util.DOT;
import static org.eclipse.persistence.tools.dbws.Util.FINDALL_QUERYNAME;
import static org.eclipse.persistence.tools.dbws.Util.OPEN_BRACKET;
import static org.eclipse.persistence.tools.dbws.Util.OPEN_SQUARE_BRACKET;
import static org.eclipse.persistence.tools.dbws.Util.PERCENT;
import static org.eclipse.persistence.tools.dbws.Util.REMOVE_OPERATION_NAME;
import static org.eclipse.persistence.tools.dbws.Util.ROWTYPE_STR;
import static org.eclipse.persistence.tools.dbws.Util.SINGLE_SPACE;
import static org.eclipse.persistence.tools.dbws.Util.SLASH_TEXT;
import static org.eclipse.persistence.tools.dbws.Util.THE_INSTANCE_NAME;
import static org.eclipse.persistence.tools.dbws.Util.TYPE_STR;
import static org.eclipse.persistence.tools.dbws.Util.UNDERSCORE;
import static org.eclipse.persistence.tools.dbws.Util.UPDATE_OPERATION_NAME;
import static org.eclipse.persistence.tools.dbws.Util.WSI_SWAREF_PREFIX;
import static org.eclipse.persistence.tools.dbws.Util.WSI_SWAREF_URI;
import static org.eclipse.persistence.tools.dbws.Util.WSI_SWAREF_XSD;
import static org.eclipse.persistence.tools.dbws.Util.WSI_SWAREF_XSD_FILE;
import static org.eclipse.persistence.tools.dbws.Util.XML_MIME_PREFIX;
import static org.eclipse.persistence.tools.dbws.Util.addSimpleXMLFormat;
import static org.eclipse.persistence.tools.dbws.Util.buildORDescriptor;
import static org.eclipse.persistence.tools.dbws.Util.buildOXDescriptor;
import static org.eclipse.persistence.tools.dbws.Util.buildTypeForJDBCType;
import static org.eclipse.persistence.tools.dbws.Util.getGeneratedJavaClassName;
import static org.eclipse.persistence.tools.dbws.Util.getGeneratedWrapperClassName;
import static org.eclipse.persistence.tools.dbws.Util.getJDBCTypeFromTypeName;
import static org.eclipse.persistence.tools.dbws.Util.getJDBCTypeNameFromType;
import static org.eclipse.persistence.tools.dbws.Util.getXMLTypeFromJDBCType;
import static org.eclipse.persistence.tools.dbws.Util.hasPLSQLArgs;
import static org.eclipse.persistence.tools.dbws.Util.isNullStream;
import static org.eclipse.persistence.tools.dbws.Util.requiresSimpleXMLFormat;
import static org.eclipse.persistence.tools.dbws.Util.sqlMatch;

import java.io.BufferedOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.StringReader;
import java.io.StringWriter;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;

//java eXtension imports
import javax.wsdl.WSDLException;
import jakarta.xml.bind.JAXBContext;
import jakarta.xml.bind.JAXBException;
import jakarta.xml.bind.Marshaller;
import javax.xml.namespace.QName;

//EclipseLink imports
import org.eclipse.persistence.dbws.DBWSModelProject;
import org.eclipse.persistence.descriptors.ClassDescriptor;
import org.eclipse.persistence.descriptors.RelationalDescriptor;
import org.eclipse.persistence.exceptions.DBWSException;
import org.eclipse.persistence.expressions.Expression;
import org.eclipse.persistence.expressions.ExpressionBuilder;
import org.eclipse.persistence.internal.databaseaccess.DatabasePlatform;
import org.eclipse.persistence.internal.descriptors.DescriptorHelper;
import org.eclipse.persistence.internal.helper.ComplexDatabaseType;
import org.eclipse.persistence.internal.helper.DatabaseField;
import org.eclipse.persistence.internal.jpa.metadata.xml.XMLEntityMappings;
import org.eclipse.persistence.internal.jpa.metadata.xml.XMLEntityMappingsWriter;
import org.eclipse.persistence.internal.oxm.XMLConversionManager;
import org.eclipse.persistence.internal.oxm.mappings.Descriptor;
import org.eclipse.persistence.internal.oxm.schema.SchemaModelGenerator;
import org.eclipse.persistence.internal.oxm.schema.SchemaModelGeneratorProperties;
import org.eclipse.persistence.internal.oxm.schema.SchemaModelProject;
import org.eclipse.persistence.internal.oxm.schema.model.ComplexType;
import org.eclipse.persistence.internal.oxm.schema.model.Schema;
import org.eclipse.persistence.internal.sessions.factories.MissingDescriptorListener;
import org.eclipse.persistence.internal.sessions.factories.ObjectPersistenceWorkbenchXMLProject;
import org.eclipse.persistence.internal.sessions.factories.XMLSessionConfigProject_11_1_1;
import org.eclipse.persistence.internal.sessions.factories.model.SessionConfigs;
import org.eclipse.persistence.internal.xr.CollectionResult;
import org.eclipse.persistence.internal.xr.DeleteOperation;
import org.eclipse.persistence.internal.xr.InsertOperation;
import org.eclipse.persistence.internal.xr.NamedQueryHandler;
import org.eclipse.persistence.internal.xr.Parameter;
import org.eclipse.persistence.internal.xr.ProjectHelper;
import org.eclipse.persistence.internal.xr.QueryOperation;
import org.eclipse.persistence.internal.xr.Result;
import org.eclipse.persistence.internal.xr.UpdateOperation;
import org.eclipse.persistence.internal.xr.Util;
import org.eclipse.persistence.internal.xr.XRDynamicClassLoader;
import org.eclipse.persistence.internal.xr.XmlBindingsModel;
import org.eclipse.persistence.internal.xr.sxf.SimpleXMLFormat;
import org.eclipse.persistence.internal.xr.sxf.SimpleXMLFormatProject;
import org.eclipse.persistence.jaxb.xmlmodel.XmlBindings;
import org.eclipse.persistence.mappings.DirectToFieldMapping;
import org.eclipse.persistence.oxm.NamespaceResolver;
import org.eclipse.persistence.oxm.XMLConstants;
import org.eclipse.persistence.oxm.XMLContext;
import org.eclipse.persistence.oxm.XMLDescriptor;
import org.eclipse.persistence.oxm.XMLField;
import org.eclipse.persistence.oxm.XMLLogin;
import org.eclipse.persistence.oxm.XMLMarshaller;
import org.eclipse.persistence.oxm.mappings.XMLBinaryDataMapping;
import org.eclipse.persistence.oxm.mappings.XMLDirectMapping;
import org.eclipse.persistence.oxm.mappings.nullpolicy.AbstractNullPolicy;
import org.eclipse.persistence.oxm.platform.DOMPlatform;
import org.eclipse.persistence.platform.database.jdbc.JDBCTypes;
import org.eclipse.persistence.platform.database.oracle.jdbc.OracleArrayType;
import org.eclipse.persistence.platform.database.oracle.jdbc.OracleObjectType;
import org.eclipse.persistence.platform.database.oracle.plsql.OraclePLSQLTypes;
import org.eclipse.persistence.platform.database.oracle.plsql.PLSQLCollection;
import org.eclipse.persistence.platform.database.oracle.plsql.PLSQLCursor;
import org.eclipse.persistence.platform.database.oracle.plsql.PLSQLrecord;
import org.eclipse.persistence.queries.ReadAllQuery;
import org.eclipse.persistence.queries.ReadObjectQuery;
import org.eclipse.persistence.sessions.DatabaseLogin;
import org.eclipse.persistence.sessions.Project;
import org.eclipse.persistence.sessions.factories.XMLProjectReader;
import org.eclipse.persistence.sessions.factories.XMLProjectWriter;
import org.eclipse.persistence.tools.dbws.NamingConventionTransformer.ElementStyle;
import org.eclipse.persistence.tools.dbws.jdbc.DbColumn;
import org.eclipse.persistence.tools.dbws.jdbc.DbTable;
//DDL parser imports
import org.eclipse.persistence.tools.oracleddl.metadata.ArgumentType;
import org.eclipse.persistence.tools.oracleddl.metadata.CompositeDatabaseType;
import org.eclipse.persistence.tools.oracleddl.metadata.DatabaseType;
import org.eclipse.persistence.tools.oracleddl.metadata.FieldType;
import org.eclipse.persistence.tools.oracleddl.metadata.FunctionType;
import org.eclipse.persistence.tools.oracleddl.metadata.NumericType;
import org.eclipse.persistence.tools.oracleddl.metadata.ObjectTableType;
import org.eclipse.persistence.tools.oracleddl.metadata.ObjectType;
import org.eclipse.persistence.tools.oracleddl.metadata.PLSQLCollectionType;
import org.eclipse.persistence.tools.oracleddl.metadata.PLSQLCursorType;
import org.eclipse.persistence.tools.oracleddl.metadata.PLSQLPackageType;
import org.eclipse.persistence.tools.oracleddl.metadata.PLSQLRecordType;
import org.eclipse.persistence.tools.oracleddl.metadata.PLSQLType;
import org.eclipse.persistence.tools.oracleddl.metadata.PrecisionType;
import org.eclipse.persistence.tools.oracleddl.metadata.ProcedureType;
import org.eclipse.persistence.tools.oracleddl.metadata.ROWTYPEType;
import org.eclipse.persistence.tools.oracleddl.metadata.ScalarDatabaseType;
import org.eclipse.persistence.tools.oracleddl.metadata.SizedType;
import org.eclipse.persistence.tools.oracleddl.metadata.TYPEType;
import org.eclipse.persistence.tools.oracleddl.metadata.TableType;
import org.eclipse.persistence.tools.oracleddl.metadata.VArrayType;
import org.eclipse.persistence.tools.oracleddl.metadata.visit.EnclosedTypeVisitor;

public abstract class BaseDBWSBuilderHelper {

    public static final String ITEM_MAPPING_NAME = "item";
    public static final String ITEMS_MAPPING_ATTRIBUTE_NAME = "items";
    public static final String ITEMS_MAPPING_FIELD_NAME = "ITEMS";
    public static final String MTOM_STR = "MTOM";
    public static final String SWAREF_STR = "SWAREF";
    public static final String NO_TABLE_MSG = "No tables were found matching the following: ";
    public static final String NO_PROC_MSG = "No procedures were found matching the following: ";
    public static final String OXM_MARSHAL_EX_MSG = "An exception occurred while attempting to marshal the OXM bindings file";
    public static final String ORM_MARSHAL_EX_MSG = "An exception occurred while attempting to marshal the ORM mappings file";

    public static final String SELECT_FROM_STR = "SELECT * FROM ";
    public static final String WHERE_STR = " WHERE ";
    public static final String AND_STR = " AND ";
    public static final String SET_STR = " SET ";
    public static final String VALUES_STR = " VALUES ";
    public static final String UPDATE_STR = "UPDATE ";
    public static final String INSERT_STR = "INSERT INTO ";
    public static final String DELETE_STR = "DELETE FROM ";
    public static final String COMMA_SPACE_STR = COMMA + SINGLE_SPACE;
    public static final String EQUALS_BINDING1_STR = " = ?1";
    public static final String EQUALS_BINDING_STR = " = ?";
    public static final String TIMESTAMP_CLASS = "oracle.sql.TIMESTAMP";
    public static final String USER_STR = "user";
    public static final String PASSWORD_STR = "password";
    public static final String SIMPLEXML_STR = "simple-xml-format";

    protected List<TableType> dbTables = new ArrayList<TableType>();
    protected List<ProcedureType> dbStoredProcedures = new ArrayList<ProcedureType>();
    protected DBWSBuilder dbwsBuilder;
    protected XMLSessionConfigProject_11_1_1 sessionConfigProject = new XMLSessionConfigProject_11_1_1();
    protected NamingConventionTransformer nct;
    protected ObjectPersistenceWorkbenchXMLProject workbenchXMLProject = new ObjectPersistenceWorkbenchXMLProject();

    protected Map<String, ClassDescriptor> createdORDescriptors = new HashMap<String, ClassDescriptor>();
    protected List<String> referencedORDescriptors = new ArrayList<String>();
    protected List<CompositeDatabaseType> complextypes = new ArrayList<CompositeDatabaseType>();

    protected Map<String, Map<String, String>> crudOps = new HashMap<String, Map<String, String>>();

    public BaseDBWSBuilderHelper(DBWSBuilder dbwsBuilder) {
        this.dbwsBuilder = dbwsBuilder;
    }

    public List<TableType> getDbTables() {
        return dbTables;
    }

    public List<ProcedureType> getDbStoredProcedures() {
        return dbStoredProcedures;
    }

    //abstract methods - platform-specific behavior in JDBCHelper, OracleHelper
    public abstract boolean hasTables();

    protected abstract List<TableType> loadTables(List<String> catalogPatterns, List<String> schemaPatterns, List<String> tableNamePatterns);

    protected abstract List<ProcedureType> loadProcedures(List<String> catalogPatterns, List<String> schemaPatterns, List<String> procedureNamePatterns);

    protected abstract void addToOROXProjectsForComplexTypes(List<CompositeDatabaseType> types, Project orProject, Project oxProject);

    protected abstract void buildQueryForProcedureType(ProcedureType procType, Project orProject, Project oxProject, ProcedureOperationModel opModel, boolean hasComplexArgs);

    protected void addToOROXProjectsForBuildSql(ModelWithBuildSql modelWithBuildSql, Project orProject, Project oxProject, NamingConventionTransformer nct) {
        List<DbColumn> columns = buildDbColumns(dbwsBuilder.getConnection(), modelWithBuildSql.getBuildSql());
        String schemaAlias = modelWithBuildSql.getReturnType();
        String tableName = schemaAlias;
        NamingConventionTransformer customNct = setUpCustomTransformer(tableName, nct);
        RelationalDescriptor desc = buildORDescriptor(tableName, dbwsBuilder.getProjectName(), null, customNct);
        createdORDescriptors.put(desc.getJavaClassName(), desc);

        desc.descriptorIsAggregate();
        orProject.addDescriptor(desc);
        XMLDescriptor xdesc = buildOXDescriptor(desc.getAlias(), schemaAlias, desc.getJavaClassName(), dbwsBuilder.getTargetNamespace());
        oxProject.addDescriptor(xdesc);
        List<String> columnsAlreadyProcessed = new ArrayList<String>();
        for (DbColumn dbColumn : columns) {
            String columnName = dbColumn.getFieldName();
            if (!columnsAlreadyProcessed.contains(columnName)) {
                columnsAlreadyProcessed.add(columnName);
                ElementStyle style = nct.styleForElement(columnName);
                if (style == NONE) {
                    continue;
                }
                dbwsBuilder.logMessage(FINE, "Building mappings for " + columnName);
                DirectToFieldMapping orFieldMapping = buildORFieldMappingFromColumn(dbColumn, desc, dbwsBuilder.getDatabasePlatform(), nct);
                desc.addMapping(orFieldMapping);
                XMLDirectMapping oxFieldMapping = buildOXFieldMappingFromColumn(dbColumn, dbwsBuilder.getDatabasePlatform(), nct);
                if (oxFieldMapping instanceof XMLBinaryDataMapping) {
                    xdesc.getNamespaceResolver().put(XML_MIME_PREFIX, XML_MIME_URL);
                }
                xdesc.addMapping(oxFieldMapping);
            } else {
                dbwsBuilder.logMessage(SEVERE, "Duplicate ResultSet columns not supported '" + columnName + "'");
                throw new RuntimeException("Duplicate ResultSet columns not supported");
            }
        }
    }

    /**
     * Uses a custom visitor to traverse each procedure/function argument and build
     * a list of required Types.  Only on instance of a given type will exist in
     * the list.
     *
     */
    public List<CompositeDatabaseType> buildTypesList(List<OperationModel> operations) {
        EnclosedTypeVisitor etVisitor = new EnclosedTypeVisitor();
        for (OperationModel opModel : operations) {
            if (opModel.isProcedureOperation()) {
                ProcedureOperationModel procedureOperation = (ProcedureOperationModel)opModel;
                if (procedureOperation.isPLSQLProcedureOperation() || procedureOperation.isAdvancedJDBCProcedureOperation()) {
                    for (ProcedureType procType : procedureOperation.getDbStoredProcedures()) {
                        // build list of arguments to process (i.e. build descriptors for)
                        List<ArgumentType> args = new ArrayList<ArgumentType>();
                        // return argument
                        if (procType.isFunctionType()) {
                            // assumes that a function MUST have a return type
                            args.add(((FunctionType)procType).getReturnArgument());
                        }
                        args.addAll(procType.getArguments());
                        // now visit each argument
                        for (ArgumentType arg : args) {
                            // handle ROWTYPETypes
                            if (arg.getEnclosedType().isROWTYPEType()) {
                                ROWTYPEType rType = (ROWTYPEType) arg.getEnclosedType();
                                TableType tableType = (TableType) rType.getEnclosedType();
                                PLSQLRecordType plsqlRec = new PLSQLRecordType(rType.getTypeName());
                                plsqlRec.setParentType(new PLSQLPackageType());
                                for (FieldType col : tableType.getColumns()) {
                                    FieldType ft = new FieldType(col.getFieldName());
                                    ft.setEnclosedType(col.getEnclosedType());
                                    plsqlRec.addField(ft);
                                }
                                arg.setEnclosedType(plsqlRec);
                            }
                            // now visit each, adding types (only one instance of each) to the list
                            if (arg.isComposite()) {
                                etVisitor.visit((CompositeDatabaseType) arg);
                            }
                        }
                    }
                }
            }
        }

        // gather Complex types to hand into XMLEntityMappingsGenerator
        List<CompositeDatabaseType> types = etVisitor.getCompositeDatabaseTypes();
        for (CompositeDatabaseType type : types) {
            complextypes.add(type);
        }
        return etVisitor.getCompositeDatabaseTypes();
    }

    /**
     * Builds OR/OX projects, descriptors {@literal &} mappings.  This method can be
     * used when no complex types exist, and only table(s) and secondary
     * SQL will be used when building.
     */
    public void buildOROXProjects(NamingConventionTransformer nct) {
        buildOROXProjects(nct, new ArrayList<CompositeDatabaseType>());
    }

    /**
     * Builds OR/OX projects, descriptors {@literal &} mappings, based on a given list
     * of types, as well as table(s) and secondary SQL.
     */
    public void buildOROXProjects(NamingConventionTransformer nct, List<CompositeDatabaseType> types) {
        this.nct = nct; // save for later
        String projectName = dbwsBuilder.getProjectName();
        Project orProject = new Project();
        orProject.setName(projectName + UNDERSCORE + DBWS_OR_LABEL);
        Project oxProject = null;
        if (dbTables.isEmpty() && !dbwsBuilder.hasBuildSqlOperations()) {
            dbwsBuilder.logMessage(FINEST, "No tables specified");
            oxProject = new SimpleXMLFormatProject();
        } else {
            oxProject = new Project();
        }
        oxProject.setName(projectName + UNDERSCORE + DBWS_OX_LABEL);
        for (TableType dbTable : dbTables) {
            String tableName = dbTable.getTableName();
            RelationalDescriptor desc = buildORDescriptor(tableName, dbwsBuilder.getProjectName(), dbwsBuilder.requireCRUDOperations, nct);
            orProject.addDescriptor(desc);
            XMLDescriptor xdesc = buildOXDescriptor(tableName, dbwsBuilder.getProjectName(), dbwsBuilder.getTargetNamespace(), nct);
            oxProject.addDescriptor(xdesc);
            for (FieldType dbColumn : dbTable.getColumns()) {
                String columnName = dbColumn.getFieldName();
                ElementStyle style = nct.styleForElement(columnName);
                if (style == NONE) {
                    continue;
                }
                dbwsBuilder.logMessage(FINE, "Building mappings for " + tableName + DOT + columnName);
                DirectToFieldMapping orFieldMapping = buildORFieldMappingFromColumn(dbColumn, desc, dbwsBuilder.getDatabasePlatform(), nct);
                desc.addMapping(orFieldMapping);
                XMLDirectMapping oxFieldMapping = buildOXFieldMappingFromColumn(dbColumn, dbwsBuilder.getDatabasePlatform(), nct);
                if (oxFieldMapping instanceof XMLBinaryDataMapping) {
                    xdesc.getNamespaceResolver().put(XML_MIME_PREFIX, XML_MIME_URL);
                }
                xdesc.addMapping(oxFieldMapping);
                // check for switch from Byte[] to byte[]
                if (oxFieldMapping.getAttributeClassificationName() == APBYTE.getName()) {
                    orFieldMapping.setAttributeClassificationName(APBYTE.getName());
                }
          }
          setUpFindQueries(nct, tableName, desc);
        }
        finishUpProjects(orProject, oxProject, types);
    }

    /**
     * Complete project configuration.  Build descriptors for secondary SQL
     * and complex arguments. Set the projects on the DBWSBuilder instance.
     */
    protected void finishUpProjects(Project orProject, Project oxProject, List<CompositeDatabaseType> typeList) {
        // handle build SQL
        for (OperationModel opModel : dbwsBuilder.operations) {
            if (opModel.hasBuildSql()) {
                addToOROXProjectsForBuildSql((ModelWithBuildSql)opModel, orProject, oxProject, nct);
            }
        }
        // create OR/OX projects, descriptors/mappings for the types
        addToOROXProjectsForComplexTypes(typeList, orProject, oxProject);

        // build queries for procedures with complex arguments
        for (OperationModel opModel : dbwsBuilder.operations) {
            if (opModel.isProcedureOperation()) {
                ProcedureOperationModel procedureOperation = (ProcedureOperationModel)opModel;
                    for (ProcedureType procType : procedureOperation.getDbStoredProcedures()) {
                        buildQueryForProcedureType(procType, orProject, oxProject, procedureOperation,
                                hasPLSQLArgs(getArgumentListForProcedureType(procType)));
                    }
            }
        }

        // set aggregate OR descriptors where appropriate
        for (String refClassName : referencedORDescriptors) {
            ClassDescriptor cdesc = createdORDescriptors.get(refClassName);
            // should not be null, but check to avoid an exception
            if (cdesc != null) {
                cdesc.descriptorIsAggregate();
            }
        }

        DatabaseLogin databaseLogin = new DatabaseLogin();
        databaseLogin.removeProperty(USER_STR);
        databaseLogin.removeProperty(PASSWORD_STR);
        databaseLogin.setDriverClassName(null);
        databaseLogin.setConnectionString(null);
        orProject.setLogin(databaseLogin);
        XMLLogin xmlLogin = new XMLLogin();
        xmlLogin.setDatasourcePlatform(new DOMPlatform());
        xmlLogin.getProperties().remove(USER_STR);
        xmlLogin.getProperties().remove(PASSWORD_STR);
        oxProject.setLogin(xmlLogin);
        dbwsBuilder.setOrProject(orProject);
        dbwsBuilder.setOxProject(oxProject);
    }

    protected DirectToFieldMapping buildORFieldMappingFromColumn(FieldType dbColumn,
        RelationalDescriptor desc, DatabasePlatform databasePlatform,
        NamingConventionTransformer nct) {
        String columnName = dbColumn.getFieldName();
        DatabaseType dataType = dbColumn.getEnclosedType();
        String typeName = getTypeNameForDatabaseType(dataType);
        int jdbcType = getJDBCTypeFromTypeName(typeName);
        String dmdTypeName = getJDBCTypeNameFromType(jdbcType);
        Class<?> attributeClass = null;
        if (CHAR_STR.equalsIgnoreCase(dmdTypeName) && dbColumn.getEnclosedType().isSizedType()) {
            SizedType sizedType = (SizedType)dbColumn.getEnclosedType();
            if (sizedType.getSize() == 1) {
                attributeClass = Character.class;
            } else {
                attributeClass = String.class;
            }
        } else {
            attributeClass = getClassFromJDBCType(dmdTypeName.toUpperCase(), databasePlatform);
        }
        //https://bugs.eclipse.org/bugs/show_bug.cgi?id=359130
        //problem with java.sql.Timestamp conversion and Oracle11 platform
        if (attributeClass.getName().contains(TIMESTAMP_CLASS)) {
            attributeClass = java.sql.Timestamp.class;
        }
        DirectToFieldMapping dtfm = setUpDirectToFieldMapping(desc, columnName, nct, attributeClass, jdbcType, dbColumn.pk());
        return dtfm;
    }

    protected XMLDirectMapping buildOXFieldMappingFromColumn(FieldType dbColumn, DatabasePlatform databasePlatform, NamingConventionTransformer nct) {
        String columnName = dbColumn.getFieldName();
        DatabaseType dataType = dbColumn.getEnclosedType();
        String typeName = getTypeNameForDatabaseType(dataType);
        int jdbcType = getJDBCTypeFromTypeName(typeName);
        String dmdTypeName = getJDBCTypeNameFromType(jdbcType);
        QName qName = getXMLTypeFromJDBCType(jdbcType);
        Class<?> attributeClass;
        if (CHAR_STR.equalsIgnoreCase(dmdTypeName) && dbColumn.getEnclosedType().isSizedType()) {
            SizedType sizedType = (SizedType)dbColumn.getEnclosedType();
            if (sizedType.getSize() == 1) {
                attributeClass = Character.class;
            } else {
                attributeClass = String.class;
            }
        } else {
            attributeClass = getClassFromJDBCType(dmdTypeName.toUpperCase(), databasePlatform);
        }
        //https://bugs.eclipse.org/bugs/show_bug.cgi?id=359130
        //problem with conversion and Oracle11 platform
        if (attributeClass.getName().contains(TIMESTAMP_CLASS)) {
            attributeClass = java.sql.Timestamp.class;
        } else if (attributeClass.getName().contains(java.lang.Character[].class.getName())) {
            attributeClass = java.lang.String.class;
        }
        XMLDirectMapping xdm = setUpXMLDirectMapping(columnName, qName, nct, attributeClass, jdbcType, dbColumn.pk());
        return xdm;
    }

    /**
     * Gather table and procedure information based on TableOperation
     * and ProcedureOperation.  End result will be List&lt;TableType&gt;
     * and List&lt;ProcedureType&gt;.
     */
    public void buildDbArtifacts() {
        List<TableOperationModel> tableOperations = new ArrayList<TableOperationModel>();
        List<ProcedureOperationModel> procedureOperations = new ArrayList<ProcedureOperationModel>();
        //its possible a builder might have pre-built tables
        if (dbTables.size() == 0) {
            //do Table operations first
            for (OperationModel operation : dbwsBuilder.operations) {
                if (operation.isTableOperation()) {
                    TableOperationModel tom = (TableOperationModel)operation;
                    tableOperations.add(tom);
                    if (tom.additionalOperations != null && tom.additionalOperations.size() > 0) {
                        for (OperationModel nestedOperation : tom.additionalOperations) {
                            if (nestedOperation.isProcedureOperation()) {
                                procedureOperations.add((ProcedureOperationModel)nestedOperation);
                            }
                        }
                    }
                }
            }
            if (tableOperations.size() > 0) {
                List<String> catalogPatterns = new ArrayList<String>();
                List<String> schemaPatterns = new ArrayList<String>();
                List<String> tableNamePatterns = new ArrayList<String>();
                for (TableOperationModel tableOperation : tableOperations) {
                    catalogPatterns.add(tableOperation.getCatalogPattern());
                    schemaPatterns.add(tableOperation.getSchemaPattern());
                    tableNamePatterns.add(tableOperation.getTablePattern());
                }
                List<TableType> tables = loadTables(catalogPatterns, schemaPatterns, tableNamePatterns);
                // if we didn't find any tables log a WARNING
                if (tables == null || tables.isEmpty()) {
                    logNotFoundWarnings(NO_TABLE_MSG, schemaPatterns, catalogPatterns, tableNamePatterns);
                } else {
                    //now assign tables to operations
                    for (TableType tableType : tables) {
                        for (TableOperationModel tableOperation : tableOperations) {
                            //figure out catalog(optional)/schema/tableName matching
                            boolean tableNameMatch = sqlMatch(tableOperation.getTablePattern(), tableType.getTableName());
                            boolean schemaNameMatch = sqlMatch(tableOperation.getSchemaPattern(), tableType.getSchema());
                            if (tableNameMatch && schemaNameMatch) {
                                String originalCatalogPattern = tableOperation.getCatalogPattern();
                                if (tableType.isDbTableType() && originalCatalogPattern != null) {
                                    boolean catalogNameMatch = sqlMatch(originalCatalogPattern, ((DbTable) tableType).getCatalog());
                                    if (catalogNameMatch) {
                                        tableOperation.getDbTables().add(tableType);
                                    }
                                } else {
                                    tableOperation.getDbTables().add(tableType);
                                }
                            }
                        }
                    }
                    dbTables.addAll(tables);
                }
            }
        }

        // next do StoredProcedure operations
        // it's possible a builder might have pre-built procedures
        if (dbStoredProcedures.size() == 0) {
            for (OperationModel operation : dbwsBuilder.operations) {
                if (operation.isProcedureOperation()) {
                    procedureOperations.add((ProcedureOperationModel)operation);
                }
            }
            if (procedureOperations.size() > 0) {
                List<String> catalogPatterns = new ArrayList<String>();
                List<String> schemaPatterns = new ArrayList<String>();
                List<String> procedureNamePatterns = new ArrayList<String>();
                for (ProcedureOperationModel procedureOperation : procedureOperations) {
                    catalogPatterns.add(procedureOperation.getCatalogPattern());
                    schemaPatterns.add(procedureOperation.getSchemaPattern());
                    procedureNamePatterns.add(procedureOperation.getProcedurePattern());
                }
                List<ProcedureType> procedures = loadProcedures(catalogPatterns, schemaPatterns, procedureNamePatterns);
                // if we didn't find any procs/funcs log a WARNING
                if (procedures == null || procedures.isEmpty()) {
                    logNotFoundWarnings(NO_PROC_MSG, schemaPatterns, catalogPatterns, procedureNamePatterns);
                } else {
                    //now assign procedures to operations
                    for (ProcedureType procedureType : procedures) {
                        for (ProcedureOperationModel procedureOperation : procedureOperations) {
                            boolean procedureNameMatch = sqlMatch(procedureOperation.getProcedurePattern(),
                                procedureType.getProcedureName());
                            boolean schemaNameMatch = true;
                            boolean catalogNameMatch = true;
                            if (procedureNameMatch) {
                                String originalSchemaPattern = procedureOperation.getSchemaPattern();
                                if (originalSchemaPattern != null) {
                                    schemaNameMatch = sqlMatch(originalSchemaPattern, procedureType.getSchema());
                                }
                                String originalCatalogPattern = procedureOperation.getCatalogPattern();
                                if (originalCatalogPattern != null) {
                                    catalogNameMatch = sqlMatch(originalCatalogPattern, procedureType.getCatalogName());
                                }
                            }
                            if (procedureNameMatch && schemaNameMatch && catalogNameMatch) {
                                procedureOperation.getDbStoredProcedures().add(procedureType);
                            }
                        }
                    }
                    dbStoredProcedures.addAll(procedures);
                }
            }
        }
    }

    /**
     * Build the schema
     */
    @SuppressWarnings({"unchecked", "rawtypes"})
    public void buildSchema(NamingConventionTransformer nct) {
        Project oxProject = dbwsBuilder.getOxProject();
        Schema schema = null;
        List<Descriptor> descriptorsToProcess = new ArrayList<Descriptor>();
        for (Descriptor desc : (List<Descriptor>)(List)oxProject.getOrderedDescriptors()) {
            String alias = desc.getAlias();
            if (!DEFAULT_SIMPLE_XML_FORMAT_TAG.equals(alias)) {
                descriptorsToProcess.add(desc);
            }
        }
        if (descriptorsToProcess.size() > 0) {
            // need a deep-copy clone of oxProject; simplest way is to marshall/unmarshall to a stream
            StringWriter sw = new StringWriter();
            XMLProjectWriter.write(oxProject, sw);
            XRDynamicClassLoader specialLoader = new XRDynamicClassLoader(this.getClass().getClassLoader());
            Project oxProjectClone = XMLProjectReader.read(new StringReader(sw.toString()), specialLoader);
            ProjectHelper.fixOROXAccessors(oxProjectClone, null);
            XMLLogin xmlLogin = new XMLLogin();
            DOMPlatform domPlatform = new DOMPlatform();
            domPlatform.getConversionManager().setLoader(specialLoader);
            xmlLogin.setPlatform(domPlatform);
            oxProjectClone.setLogin(xmlLogin);
            oxProjectClone.createDatabaseSession(); // initialize reference descriptors
            SchemaModelGenerator schemaGenerator = new SchemaModelGenerator(XMLConversionManager.getDefaultXMLManager(), true);
            SchemaModelGeneratorProperties sgProperties = new SchemaModelGeneratorProperties();
            // set element form default to qualified for target namespace
            sgProperties.addProperty(dbwsBuilder.getTargetNamespace(), ELEMENT_FORM_QUALIFIED_KEY, true);
            Map<String, Schema> schemaMap = schemaGenerator.generateSchemas(descriptorsToProcess, sgProperties);
            Schema s = schemaMap.get(dbwsBuilder.getTargetNamespace());
            // check existing schema for any top-level ComplexTypes
            if (dbwsBuilder.getSchema() != null && s != null) {
                Map<String, ComplexType> topLevelComplexTypes = dbwsBuilder.getSchema().getTopLevelComplexTypes();
                for (Map.Entry<String, ComplexType> me : topLevelComplexTypes.entrySet()) {
                    s.addTopLevelComplexTypes(me.getValue());
                }
                // add any additional namespaces
                NamespaceResolver snr = s.getNamespaceResolver();
                NamespaceResolver nr = dbwsBuilder.getSchema().getNamespaceResolver();
                // we only want to add prefix/uri pairs for prefixes that don't already exist
                for (String prefix : nr.getPrefixesToNamespaces().keySet()) {
                    if (snr.resolveNamespacePrefix(prefix) == null) {
                        snr.put(prefix, nr.resolveNamespacePrefix(prefix));
                    }
                }
                schema = s; // switch
                schema.setNamespaceResolver(snr);
            }
        } else {
            schema = new Schema();
            addSimpleXMLFormat(schema);
            schema.setTargetNamespace(dbwsBuilder.getTargetNamespace());
        }
        dbwsBuilder.setSchema(schema);
    }

    /**
     * Build the sessions xml file.
     */
    public void buildSessionsXML(OutputStream dbwsSessionsStream) {
        if (!isNullStream(dbwsSessionsStream)) {
            dbwsBuilder.logMessage(FINEST, "Building " + dbwsBuilder.getSessionsFileName());
            SessionConfigs ts = dbwsBuilder.getPackager().buildSessionsXML(dbwsSessionsStream, dbwsBuilder);
            XMLContext context = new XMLContext(sessionConfigProject);
            XMLMarshaller marshaller = context.createMarshaller();
            marshaller.marshal(ts, new OutputStreamWriter(dbwsSessionsStream));
            dbwsBuilder.getPackager().closeSessionsStream(dbwsSessionsStream);
        }
    }

    /**
     * Build the DBWS model, a.k.a. service file.
     */
    @SuppressWarnings({"rawtypes"})
    public void buildDBWSModel(NamingConventionTransformer nct, OutputStream dbwsServiceStream) {
        Project orProject = dbwsBuilder.getOrProject();
        if (!isNullStream(dbwsServiceStream)) {
            for (Iterator i = orProject.getOrderedDescriptors().iterator(); i.hasNext();) {
                ClassDescriptor desc = (ClassDescriptor)i.next();
                String tablenameAlias = desc.getAlias();
                if (dbwsBuilder.requireCRUDOperations.contains(tablenameAlias)) {
                    String aliasType = tablenameAlias + TYPE_STR;
                    String tableName = desc.getTableName();
                    String schemaAlias = nct.generateSchemaAlias(tableName);
                    Map<String, String> ops;
                    if (!crudOps.containsKey(tableName)) {
                        ops = new HashMap<String, String>();
                        crudOps.put(tableName, ops);
                    }
                    ops = crudOps.get(tableName);

                    String pks = null;
                    int pkCount = 0;
                    for (Iterator j = desc.getPrimaryKeyFields().iterator(); j.hasNext();) {
                        DatabaseField field = (DatabaseField)j.next();
                        if (pkCount++ == 0) {
                            pks = OPEN_BRACKET + field.getName() + EQUALS_BINDING1_STR;
                        } else {
                            pks = pks.concat(AND_STR + field.getName() + EQUALS_BINDING_STR + pkCount++);
                        }
                    }
                    if (pks != null) {
                       pks = pks.concat(CLOSE_BRACKET);
                    }

                    // findByPk
                    String crudOpName = Util.PK_QUERYNAME + UNDERSCORE + aliasType;
                    String findByPKName = crudOpName;
                    QueryOperation findByPKQueryOperation = new QueryOperation();
                    findByPKQueryOperation.setName(crudOpName);
                    findByPKQueryOperation.setUserDefined(false);
                    NamedQueryHandler nqh1 = new NamedQueryHandler();
                    nqh1.setName(crudOpName);
                    nqh1.setDescriptor(tablenameAlias);
                    Result result = new Result();
                    QName theInstanceType = new QName(dbwsBuilder.getTargetNamespace(), schemaAlias, TARGET_NAMESPACE_PREFIX);
                    result.setType(theInstanceType);
                    findByPKQueryOperation.setResult(result);
                    findByPKQueryOperation.setQueryHandler(nqh1);
                    for (Iterator j = desc.getPrimaryKeyFields().iterator(); j.hasNext();) {
                        DatabaseField field = (DatabaseField)j.next();
                        Parameter p = new Parameter();
                        p.setName(field.getName().toLowerCase());
                        p.setType(getXMLTypeFromJDBCType(field.getSqlType()));
                        findByPKQueryOperation.getParameters().add(p);
                    }
                    dbwsBuilder.xrServiceModel.getOperations().put(findByPKQueryOperation.getName(), findByPKQueryOperation);

                    // find all
                    crudOpName = FINDALL_QUERYNAME + UNDERSCORE + aliasType;
                    QueryOperation findAllOperation = new QueryOperation();
                    findAllOperation.setName(crudOpName);
                    findAllOperation.setUserDefined(false);
                    NamedQueryHandler nqh2 = new NamedQueryHandler();
                    nqh2.setName(crudOpName);
                    nqh2.setDescriptor(tablenameAlias);
                    Result result2 = new CollectionResult();
                    result2.setType(theInstanceType);
                    findAllOperation.setResult(result2);
                    findAllOperation.setQueryHandler(nqh2);
                    dbwsBuilder.xrServiceModel.getOperations().put(findAllOperation.getName(), findAllOperation);

                    // create
                    crudOpName = CREATE_OPERATION_NAME + UNDERSCORE + aliasType;
                    InsertOperation insertOperation = new InsertOperation();
                    insertOperation.setName(crudOpName);
                    Parameter theInstance = new Parameter();
                    theInstance.setName(THE_INSTANCE_NAME);
                    theInstance.setType(theInstanceType);
                    insertOperation.getParameters().add(theInstance);
                    dbwsBuilder.xrServiceModel.getOperations().put(insertOperation.getName(), insertOperation);

                    StringBuilder sqlStmt = new StringBuilder(128);
                    sqlStmt.append(INSERT_STR).append(tableName).append(SINGLE_SPACE).append(OPEN_BRACKET);
                    DescriptorHelper.buildColsFromMappings(sqlStmt, desc.getMappings(), COMMA_SPACE_STR);
                    sqlStmt.append(CLOSE_BRACKET).append(VALUES_STR).append(OPEN_BRACKET);
                    DescriptorHelper.buildValuesAsQMarksFromMappings(sqlStmt, desc.getMappings(), COMMA_SPACE_STR);
                    sqlStmt.append(CLOSE_BRACKET);
                    ops.put(crudOpName, sqlStmt.toString());

                    // update
                    crudOpName = UPDATE_OPERATION_NAME + UNDERSCORE + aliasType;
                    UpdateOperation updateOperation = new UpdateOperation();
                    updateOperation.setName(crudOpName);
                    updateOperation.getParameters().add(theInstance);
                    dbwsBuilder.xrServiceModel.getOperations().put(updateOperation.getName(), updateOperation);

                    sqlStmt = new StringBuilder(128);
                    sqlStmt.append(UPDATE_STR).append(tableName).append(SET_STR);
                    DescriptorHelper.buildColsAndValuesBindingsFromMappings(sqlStmt, desc.getMappings(),
                            desc.getPrimaryKeyFields(), pkCount, EQUALS_BINDING_STR, COMMA_SPACE_STR);
                    sqlStmt.append(WHERE_STR).append(pks);
                    ops.put(crudOpName, sqlStmt.toString());

                    // delete
                    crudOpName = REMOVE_OPERATION_NAME + UNDERSCORE + aliasType;
                    DeleteOperation deleteOperation = new DeleteOperation();
                    deleteOperation.setName(crudOpName);
                    deleteOperation.setDescriptorName(tablenameAlias);
                    deleteOperation.setFindByPKQuery(findByPKName);
                    for (Iterator j = desc.getPrimaryKeyFields().iterator(); j.hasNext();) {
                        DatabaseField field = (DatabaseField)j.next();
                        Parameter p = new Parameter();
                        p.setName(field.getName().toLowerCase());
                        p.setType(getXMLTypeFromJDBCType(field.getSqlType()));
                        deleteOperation.getParameters().add(p);
                    }
                    dbwsBuilder.xrServiceModel.getOperations().put(deleteOperation.getName(), deleteOperation);

                    sqlStmt = new StringBuilder(128);
                    sqlStmt.append(DELETE_STR).append(tableName).append(WHERE_STR).append(pks);
                    ops.put(crudOpName, sqlStmt.toString());
                }
            }
            // check for additional operations
            for (OperationModel operation : dbwsBuilder.operations) {
                if (operation.isTableOperation()) {
                    TableOperationModel tableModel = (TableOperationModel)operation;
                    if (tableModel.additionalOperations != null && tableModel.additionalOperations.size() > 0) {
                        for (OperationModel additionalOperation : tableModel.additionalOperations) {
                            if (additionalOperation.hasBuildSql()) {
                                addToOROXProjectsForBuildSql((ModelWithBuildSql) additionalOperation, orProject, dbwsBuilder.getOxProject(), nct);
                            } else {
                                additionalOperation.buildOperation(dbwsBuilder);
                            }
                        }
                    }
                } else { // handle non-nested <sql> and <procedure> operations
                    operation.buildOperation(dbwsBuilder);
                }
            }

            DBWSModelProject modelProject = new DBWSModelProject();
            modelProject.ns.put(TARGET_NAMESPACE_PREFIX, dbwsBuilder.getTargetNamespace());
            XMLContext context = new XMLContext(modelProject);
            XMLMarshaller marshaller = context.createMarshaller();
            marshaller.marshal(dbwsBuilder.xrServiceModel, dbwsServiceStream);
            dbwsBuilder.getPackager().closeServiceStream(dbwsServiceStream);
        }
    }

    public void writeAttachmentSchema(OutputStream swarefStream) {
        if (!isNullStream(swarefStream)) {
            dbwsBuilder.logMessage(FINEST, "writing " + WSI_SWAREF_XSD_FILE);
            OutputStreamWriter osw = new OutputStreamWriter(new BufferedOutputStream(swarefStream));
            try {
                osw.write(WSI_SWAREF_XSD);
                osw.flush();
            } catch (IOException e) {/* ignore */
            }
            dbwsBuilder.getPackager().closeSWARefStream(swarefStream);
        }
    }

    public void buildWSDL(OutputStream wsdlStream, NamingConventionTransformer nct) throws WSDLException {
        if (!isNullStream(wsdlStream)) {
            dbwsBuilder.logMessage(FINEST, "building " + DBWS_WSDL);
            dbwsBuilder.wsdlGenerator = new WSDLGenerator(dbwsBuilder.xrServiceModel, nct, dbwsBuilder.getWsdlLocationURI(), dbwsBuilder.getPackager().hasAttachments(), dbwsBuilder.getTargetNamespace(), wsdlStream);
            dbwsBuilder.wsdlGenerator.generateWSDL(dbwsBuilder.usesSOAP12());
            dbwsBuilder.getPackager().closeWSDLStream(wsdlStream);
        }
    }

    public void writeWebXML(OutputStream webXmlStream) {
        if (!isNullStream(webXmlStream)) {
            dbwsBuilder.logMessage(FINEST, "writing web.xml");
            dbwsBuilder.getPackager().writeWebXml(webXmlStream, dbwsBuilder);
            dbwsBuilder.getPackager().closeWebXmlStream(webXmlStream);
        }
    }

    /**
     * Write the (optional) deployment descriptor to the given OutputStream.
     */
    public void writeDeploymentDescriptor(OutputStream deploymentDescriptorStream) {
        if (!isNullStream(deploymentDescriptorStream)) {
            dbwsBuilder.logMessage(FINEST, "writing " + dbwsBuilder.getPackager().getDeploymentDescriptorFileName());
            dbwsBuilder.getPackager().writeDeploymentDescriptor(deploymentDescriptorStream);
            dbwsBuilder.getPackager().closeDeploymentDescriptorStream(deploymentDescriptorStream);
        }
    }

    public void generateDBWSProvider(OutputStream sourceProviderStream, OutputStream classProviderStream, OutputStream sourceProviderListenerStream, OutputStream classProviderListenerStream) {
        if (isNullStream(sourceProviderStream) && isNullStream(classProviderStream) && isNullStream(sourceProviderListenerStream) && isNullStream(classProviderListenerStream)) {
            //no work to do
            return;
        }

        if (!isNullStream(sourceProviderStream)) {
            dbwsBuilder.logMessage(FINEST, "generating " + DBWS_PROVIDER_SOURCE_FILE);
        }
        if (!isNullStream(classProviderStream)) {
            dbwsBuilder.logMessage(FINEST, "generating " + DBWS_PROVIDER_CLASS_FILE);
        }
        dbwsBuilder.getPackager().writeProvider(sourceProviderStream, classProviderStream, sourceProviderListenerStream, classProviderListenerStream, dbwsBuilder);
        dbwsBuilder.getPackager().closeProviderSourceStream(sourceProviderStream);
        dbwsBuilder.getPackager().closeProviderClassStream(classProviderStream);
    }

    public void writeSchema(OutputStream dbwsSchemaStream) {
        if (!isNullStream(dbwsSchemaStream)) {
            SchemaModelProject schemaProject = new SchemaModelProject();
            if (dbwsBuilder.getSchema().getNamespaceResolver().resolveNamespacePrefix(WSI_SWAREF_PREFIX) != null) {
                XMLDescriptor descriptor = (XMLDescriptor)schemaProject.getClassDescriptor(Schema.class);
                descriptor.getNamespaceResolver().put(WSI_SWAREF_PREFIX, WSI_SWAREF_URI);
            }
            if (dbwsBuilder.getSchema().getNamespaceResolver().resolveNamespacePrefix(XML_MIME_PREFIX) != null) {
                XMLDescriptor descriptor = (XMLDescriptor)schemaProject.getClassDescriptor(Schema.class);
                descriptor.getNamespaceResolver().put(XML_MIME_PREFIX, XML_MIME_URL);
            }
            XMLContext context = new XMLContext(schemaProject);
            XMLMarshaller marshaller = context.createMarshaller();
            marshaller.marshal(dbwsBuilder.getSchema(), dbwsSchemaStream);
            dbwsBuilder.getPackager().closeSchemaStream(dbwsSchemaStream);
        }
    }

    public void writeOROXProjects(OutputStream dbwsOrStream, OutputStream dbwsOxStream) {
        Project orProject = dbwsBuilder.getOrProject();
        Project oxProject = dbwsBuilder.getOxProject();
        boolean writeORProject = false;
        if (hasTables() || dbwsBuilder.hasBuildSqlOperations()) {
            writeORProject = true;
        }
        if (!writeORProject) {
            // check for any named queries - SimpleXMLFormatProject sometimes need them
            if (orProject.getQueries().size() > 0) {
                writeORProject = 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()) {
                        writeORProject = true;
                        break;
                    }
                }
            }
        }
        if ((writeORProject || !dbwsBuilder.xrServiceModel.getOperations().isEmpty()) && !isNullStream(dbwsOrStream)) {
            XMLContext context = new XMLContext(workbenchXMLProject);
            context.getSession(orProject).getEventManager().addListener(new MissingDescriptorListener());

            XMLEntityMappings mappings = XmlEntityMappingsGenerator.generateXmlEntityMappings(orProject, complextypes, crudOps);
            if (mappings != null) {
                XMLEntityMappingsWriter writer = new XMLEntityMappingsWriter();
                writer.write(mappings, dbwsOrStream);
            }
        }
        if (!isNullStream(dbwsOxStream)) {
            boolean writeOXProject = false;
            if (hasTables() || dbwsBuilder.hasBuildSqlOperations()) {
                writeOXProject = true;
            }
            if (!writeOXProject) {
                // check for any named queries - SimpleXMLFormatProject's sometimes need them
                if (orProject.getQueries().size() > 0) {
                    writeOXProject = 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()) {
                            writeOXProject = true;
                            break;
                        }
                    }
                }
            }
            if (writeOXProject) {
                List<XmlBindings> xmlBindingsList = XmlBindingsGenerator.generateXmlBindings(oxProject.getOrderedDescriptors());
                if (xmlBindingsList.size() > 0) {
                    XmlBindingsModel model = new XmlBindingsModel();
                    model.setBindingsList(xmlBindingsList);
                    try {
                        JAXBContext jc = JAXBContext.newInstance(XmlBindingsModel.class);
                        Marshaller marshaller = jc.createMarshaller();
                        marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
                        marshaller.marshal(model, dbwsOxStream);
                    } catch (JAXBException jaxbEx) {
                        throw new DBWSException(OXM_MARSHAL_EX_MSG, jaxbEx);
                    }
                }
           }
        }
        dbwsBuilder.getPackager().closeOrStream(dbwsOrStream);
        dbwsBuilder.getPackager().closeOxStream(dbwsOxStream);
    }

    /**
     * Return a ResultSetMetaData instance for a given SQL statement.
     *
     */
    protected static ResultSetMetaData getResultSetMetadataForSecondarySQL(Connection connection, String secondarySql) {
        ResultSet resultSet = null;
        try {
            Statement statement = connection.createStatement();
            resultSet = statement.executeQuery(secondarySql);
        } catch (SQLException sqlException) {
            throw new IllegalStateException("failure executing secondary SQL: " + secondarySql, sqlException);
        }
        try {
            return resultSet.getMetaData();
        } catch (SQLException sqlException) {
            throw new IllegalStateException("failure retrieving resultSet metadata", sqlException);
        }
    }

    protected static DirectToFieldMapping setUpDirectToFieldMapping(RelationalDescriptor desc, String columnName, NamingConventionTransformer nct, Class<?> attributeClass, int jdbcType, boolean isPk) {
        DirectToFieldMapping dtfm = new DirectToFieldMapping();
        dtfm.setAttributeClassificationName(attributeClass.getName());
        String fieldName = nct.generateElementAlias(columnName);
        dtfm.setAttributeName(fieldName);
        DatabaseField databaseField = new DatabaseField(columnName, desc.getTableName());
        databaseField.setSqlType(jdbcType);
        dtfm.setField(databaseField);
        if (nct.getOptimisticLockingField() != null && nct.getOptimisticLockingField().equalsIgnoreCase(columnName)) {
            desc.useVersionLocking(columnName, false);
        }
        if (isPk) {
            desc.addPrimaryKeyField(databaseField);
        }
        return dtfm;
    }

    protected XMLDirectMapping setUpXMLDirectMapping(String columnName, QName qName, NamingConventionTransformer nct, Class<?> attributeClass, int jdbcType, boolean isPk) {
        XMLDirectMapping xdm = null;
        // figure out if binary attachments are required
        boolean binaryAttach = false;
        String attachmentType = null;
        if (BASE_64_BINARY_QNAME.equals(qName)) {
            // use primitive byte[] array, not object Byte[] array
            attributeClass = APBYTE;
            for (OperationModel om : dbwsBuilder.operations) {
                if (om.isTableOperation()) {
                    TableOperationModel tom = (TableOperationModel)om;
                    if (tom.getBinaryAttachment()) {
                        binaryAttach = true;
                        if (MTOM_STR.equalsIgnoreCase(tom.getAttachmentType())) {
                            attachmentType = MTOM_STR;
                        } else {
                            attachmentType = SWAREF_STR;
                        }
                        // only need one operation to require attachments
                        break;
                    }
                    if (tom.additionalOperations != null && tom.additionalOperations.size() > 0) {
                        for (OperationModel om2 : tom.additionalOperations) {
                            if (om2.isProcedureOperation()) {
                                ProcedureOperationModel pom = (ProcedureOperationModel)om2;
                                if (pom.getBinaryAttachment()) {
                                    binaryAttach = true;
                                    if (MTOM_STR.equalsIgnoreCase(tom.getAttachmentType())) {
                                        attachmentType = MTOM_STR;
                                    } else {
                                        attachmentType = SWAREF_STR;
                                    }
                                    break;
                                }
                            }
                        }
                    }
                }
            }
            XMLBinaryDataMapping xbdm = new XMLBinaryDataMapping();
            if (binaryAttach) {
                if (attachmentType.equals(SWAREF_STR)) {
                    xbdm.setSwaRef(true);
                    qName = XMLConstants.SWA_REF_QNAME;
                }
            } else {
                xbdm.setShouldInlineBinaryData(true);
            }
            xbdm.setMimeType(DEFAULT_ATTACHMENT_MIMETYPE);
            xdm = xbdm;
        } else {
            xdm = new XMLDirectMapping();
        }
        String fieldName = nct.generateElementAlias(columnName);
        xdm.setAttributeName(fieldName);
        xdm.setAttributeClassificationName(attributeClass.getName());
        String xPath = EMPTY_STRING;
        ElementStyle style = nct.styleForElement(columnName);
        if (style == ATTRIBUTE) {
            xPath += AT_SIGN + fieldName;
        } else if (style == ELEMENT) {
            xPath += fieldName;
        }
        if (style == ELEMENT && attributeClass != APBYTE) {
            xPath += SLASH_TEXT;
        }
        xdm.setXPath(xPath);
        XMLField xmlField = (XMLField)xdm.getField();
        xmlField.setSchemaType(qName);
        if (isPk) {
            xmlField.setRequired(true);
        } else {
            AbstractNullPolicy nullPolicy = xdm.getNullPolicy();
            nullPolicy.setNullRepresentedByEmptyNode(false);
            nullPolicy.setMarshalNullRepresentation(XSI_NIL);
            nullPolicy.setNullRepresentedByXsiNil(true);
            xdm.setNullPolicy(nullPolicy);
        }
        return xdm;
    }

    protected NamingConventionTransformer setUpCustomTransformer(String tableName, NamingConventionTransformer nct) {
        // need custom NamingConventionTransformer so that returnType/tableName is used verbatim
        NamingConventionTransformer customNct = new DefaultNamingConventionTransformer() {
            @Override
            protected boolean isDefaultTransformer() {
                return false;
            }
            @Override
            public String generateSchemaAlias(String tableName) {
                return tableName;
            }
        };
        ((DefaultNamingConventionTransformer)customNct).setNextTransformer(nct);
        return customNct;
    }

    /**
     * Generates 'findByPrimaryKey' and 'findAll' queries for a given table
     * and descriptor. The queries are set on the given descriptor.
     */
    protected void setUpFindQueries(NamingConventionTransformer nct, String tableName, RelationalDescriptor desc) {
        ReadObjectQuery roq = new ReadObjectQuery();
        String generatedJavaClassName = getGeneratedJavaClassName(tableName, dbwsBuilder.getProjectName());
        roq.setReferenceClassName(generatedJavaClassName);
        Expression expression = null;
        Expression builder = new ExpressionBuilder();
        Expression subExp1;
        Expression subExp2;
        Expression subExpression;
        String pks = null;
        List<DatabaseField> primaryKeyFields = desc.getPrimaryKeyFields();
        for (int index = 0; index < primaryKeyFields.size(); index++) {
            DatabaseField primaryKeyField = primaryKeyFields.get(index);
            subExp1 = builder.getField(primaryKeyField);
            subExp2 = builder.getParameter(primaryKeyField.getName().toLowerCase());
            subExpression = subExp1.equal(subExp2);
            if (expression == null) {
                expression = subExpression;
            } else {
                expression = expression.and(subExpression);
            }
            roq.addArgument(primaryKeyField.getName().toLowerCase());
            if (index == 0) {
                pks = OPEN_BRACKET + primaryKeyField.getName() + EQUALS_BINDING1_STR;
            } else {
                pks = pks.concat(AND_STR + primaryKeyField.getName() + EQUALS_BINDING_STR + index);
            }
        }
        if (pks != null) {
           pks = pks.concat(CLOSE_BRACKET);
        }

        roq.setSelectionCriteria(expression);

        desc.getQueryManager().addQuery(PK_QUERYNAME + UNDERSCORE + desc.getAlias() + TYPE_STR, roq);
        ReadAllQuery raq = new ReadAllQuery();
        raq.setReferenceClassName(generatedJavaClassName);
        desc.getQueryManager().addQuery(FINDALL_QUERYNAME + UNDERSCORE + desc.getAlias() + TYPE_STR, raq);

        // find by pk
        String findByPk = SELECT_FROM_STR + tableName + WHERE_STR + pks;
        roq.setSQLString(findByPk);

        // find all
        String findAll = SELECT_FROM_STR + tableName;
        raq.setSQLString(findAll);
    }

    protected static List<DbColumn> buildDbColumns(Connection connection, String secondarySql) {
        List<DbColumn> columns = null;
        ResultSetMetaData rsMetaData = getResultSetMetadataForSecondarySQL(connection, secondarySql);
        if (rsMetaData != null) {
            int columnCount = 0;
            try {
                columnCount = rsMetaData.getColumnCount();
            } catch (SQLException sqlException) {
                throw new IllegalStateException("failure retrieving columnCount", sqlException);
            }
            if (columnCount > 0) {
                columns = new ArrayList<DbColumn>(columnCount);
                try {
                    for (int i = 1; i <= columnCount; i++) {
                        String dbColumnName = rsMetaData.getColumnLabel(i);
                        DbColumn dbColumn = new DbColumn(dbColumnName);
                        //dbColumn.setOrdinalPosition(i);
                        dbColumn.setJDBCType(rsMetaData.getColumnType(i));
                        dbColumn.setJDBCTypeName(rsMetaData.getColumnTypeName(i));
                        int dbPrecision = rsMetaData.getPrecision(i);
                        int dbScale = rsMetaData.getScale(i);
                        dbColumn.setEnclosedType(buildTypeForJDBCType(dbColumn.getJDBCType(), dbPrecision, dbScale));
                        if (rsMetaData.isNullable(i) == ResultSetMetaData.columnNullable) {
                            dbColumn.unSetNotNull();
                        } else {
                            dbColumn.setNotNull();
                        }
                        columns.add(dbColumn);
                    }
                } catch (SQLException sqlException) {
                    throw new IllegalStateException("failure retrieving column information", sqlException);
                }
            }
        }
        return columns;
    }

    /**
     * Return the type name to be used for a given database type.  The given
     * DatabaseType's typeName attribute is typically returned, however, in
     * some cases special handling may be required.  For example, in the
     * case of a NumericType instance, "DECIMAL" should be used for the
     * type name.
     */
    protected static String getTypeNameForDatabaseType(DatabaseType dataType) {
        String typeName = dataType.getTypeName();
        if (dataType.isNumericType()) {
            NumericType numericDataType = (NumericType)dataType;
            if (numericDataType.getScale() > 0) {
                typeName = DECIMAL_STR;
            }
        }
        return typeName;
    }

    /**
     * Build a org.eclipse.persistence.internal.helper.DatabaseType instance from an
     * org.eclipse.persistence.tools.oracleddl.metadata.DatabaseType instance.
     */
    protected org.eclipse.persistence.internal.helper.DatabaseType buildDatabaseTypeFromMetadataType(DatabaseType dType) {
        return buildDatabaseTypeFromMetadataType(dType, null);
    }
    /**
     * Build a org.eclipse.persistence.internal.helper.DatabaseType  instance  from an
     * org.eclipse.persistence.tools.oracleddl.metadata.DatabaseType instance.  In the
     * the case of PLSQL Packages, the catalog (package) name can be passed in as well.
     */
    @SuppressWarnings("rawtypes")
    protected org.eclipse.persistence.internal.helper.DatabaseType buildDatabaseTypeFromMetadataType(DatabaseType dType, String catalog) {
        // argument could be from a different package
        if (dType.isPLSQLType()) {
            PLSQLType pType = (PLSQLType) dType;
            catalog = pType.getParentType().getPackageName();
        }

        // handle cursors
        if (dType.isPLSQLCursorType()) {
            if (dType.isArgumentType()) {
                dType = ((ArgumentType)dType).getEnclosedType();
            }
            PLSQLCursorType pType = (PLSQLCursorType)dType;
            return new PLSQLCursor(pType.getParentType().getPackageName() + DOT + pType.getCursorName());
        }

        if (dType.isArgumentType()) {
            dType = ((ArgumentType)dType).getEnclosedType();
        } else if (dType.isTYPEType()) {
            dType = ((TYPEType)dType).getEnclosedType();
        }

        // composite types
        if (dType.isComposite()) {
            String typeName = dType.getTypeName();
            // for %ROWTYPE, the compatible JDBC type name cannot contain '%'
            String compatibleType = typeName.contains(PERCENT) ? typeName.replace(PERCENT, UNDERSCORE) : typeName;
            String javaTypeName = compatibleType.toLowerCase();

            // handle PL/SQL types
            if (dType.isPLSQLType()) {
                // for %ROWTYPE we don't want the catalog name prepended even if non-null
                if (catalog != null && !typeName.contains(ROWTYPE_STR)) {
                    typeName = (catalog + DOT).concat(typeName);
                    compatibleType = (catalog + UNDERSCORE).concat(compatibleType);
                    javaTypeName = (catalog.toLowerCase() + DOT).concat(javaTypeName);
                }
                // handle PL/SQL record
                if (dType.isPLSQLRecordType()) {
                    PLSQLrecord plsqlRec = new PLSQLrecord();
                    plsqlRec.setTypeName(typeName);
                    plsqlRec.setCompatibleType(compatibleType);
                    plsqlRec.setJavaTypeName(javaTypeName);
                    // process fields
                    for (FieldType fld : ((PLSQLRecordType)dType).getFields()) {
                        if (fld.getEnclosedType().isPrecisionType()) {
                            PrecisionType precisionType = (PrecisionType)fld.getEnclosedType();
                            plsqlRec.addField(fld.getFieldName(), buildDatabaseTypeFromMetadataType(precisionType), (int) precisionType.getPrecision(), (int) precisionType.getScale());
                        } else if (fld.getEnclosedType().isSizedType()) {
                            SizedType sizedType = (SizedType) fld.getEnclosedType();
                            plsqlRec.addField(fld.getFieldName(), buildDatabaseTypeFromMetadataType(sizedType), (int)sizedType.getSize());
                        } else {
                            plsqlRec.addField(fld.getFieldName(), buildDatabaseTypeFromMetadataType(fld.getEnclosedType(), catalog));
                        }
                    }
                    return plsqlRec;
                }
                // assumes PL/SQL collection
                PLSQLCollection plsqlCollection = new PLSQLCollection();
                plsqlCollection.setTypeName(typeName);
                plsqlCollection.setCompatibleType(compatibleType);
                plsqlCollection.setJavaTypeName(javaTypeName + COLLECTION_WRAPPER_SUFFIX);
                plsqlCollection.setNestedType(buildDatabaseTypeFromMetadataType(((PLSQLCollectionType) dType).getEnclosedType(), catalog));
                return plsqlCollection;
            }
            // handle advanced Oracle types
            if (dType.isVArrayType()) {
                OracleArrayType varray = new OracleArrayType();
                varray.setTypeName(typeName);
                varray.setCompatibleType(compatibleType);
                varray.setJavaTypeName(getGeneratedWrapperClassName(javaTypeName, dbwsBuilder.getProjectName()));
                varray.setNestedType(buildDatabaseTypeFromMetadataType(((VArrayType) dType).getEnclosedType(), null));
                return varray;
            }
            if (dType.isObjectType()) {
                OracleObjectType objType = new OracleObjectType();
                objType.setTypeName(typeName);
                objType.setCompatibleType(compatibleType);
                objType.setJavaTypeName(getGeneratedJavaClassName(javaTypeName, dbwsBuilder.getProjectName()));
                objType.setJavaType(getWrapperClass(objType.getJavaTypeName()));
                Map<String, org.eclipse.persistence.internal.helper.DatabaseType> fields = objType.getFields();
                ObjectType oType = (ObjectType) dType;
                for (FieldType field : oType.getFields()) {
                    fields.put(field.getFieldName(), buildDatabaseTypeFromMetadataType(field.getEnclosedType()));
                }
                return objType;
            }
            if (dType.isObjectTableType()) {
                OracleArrayType tableType = new OracleArrayType();
                tableType.setTypeName(typeName);
                tableType.setCompatibleType(compatibleType);
                tableType.setJavaTypeName(getGeneratedWrapperClassName(javaTypeName, dbwsBuilder.getProjectName()));
                org.eclipse.persistence.internal.helper.DatabaseType nestedType = buildDatabaseTypeFromMetadataType(((ObjectTableType) dType).getEnclosedType(), null);
                // need to set the Java Type on the nested type
                Class wrapper = getWrapperClass(nestedType);
                if (wrapper != null) {
                    ((ComplexDatabaseType) nestedType).setJavaType(wrapper);
                }
                tableType.setNestedType(nestedType);
                return tableType;
            }
            return null;
        } else if (dType.isScalar()) {
            org.eclipse.persistence.internal.helper.DatabaseType theType = OraclePLSQLTypes.getDatabaseTypeForCode(dType.getTypeName());
            if (theType != null) {
                return theType;
            }
        }
        // scalar types
        return JDBCTypes.getDatabaseTypeForCode(org.eclipse.persistence.tools.dbws.Util.getJDBCTypeFromTypeName(dType.getTypeName()));
    }

    /**
     * Apply SimpleXMLFormat if 'isSimpleXMLFormat' is true.  The SimpleXMLFormat is
     * configured based on the given ProcedureOperationModel's simpleXMLFormatTag
     * and xmlTag (if set) and set on the given Result.  A descriptor is also added
     * to the OXProject if none exists.
     */
    protected void handleSimpleXMLFormat(boolean isSimpleXMLFormat, Result result, ProcedureOperationModel procedureOperationModel) {
        if (isSimpleXMLFormat || result.getType() == Util.SXF_QNAME) {
            SimpleXMLFormat sxf = new SimpleXMLFormat();
            String simpleXMLFormatTag = procedureOperationModel.getSimpleXMLFormatTag();
            if (simpleXMLFormatTag != null && simpleXMLFormatTag.length() > 0) {
                sxf.setSimpleXMLFormatTag(simpleXMLFormatTag);
            }
            String xmlTag = procedureOperationModel.getXmlTag();
            if (xmlTag != null && xmlTag.length() > 0) {
                sxf.setXMLTag(xmlTag);
            }

            result.setSimpleXMLFormat(sxf);
            // check to see if the O-X project needs descriptor for SimpleXMLFormat
            if (dbwsBuilder.getOxProject().getDescriptorForAlias(DEFAULT_SIMPLE_XML_FORMAT_TAG) == null) {
                SimpleXMLFormatProject sxfProject = new SimpleXMLFormatProject();
                dbwsBuilder.getOxProject().addDescriptor(sxfProject.buildXRRowSetModelDescriptor());
            }
        }
    }

    /**
     * Perform any additional actions required for operation creation
     * for both PL/SQL and non-PL/SQL operation models.
     */
    protected void finishProcedureOperation() {
        // check to see if the schema requires sxfType to be added
        if (requiresSimpleXMLFormat(dbwsBuilder.getXrServiceModel()) && dbwsBuilder.getSchema().getTopLevelElements().get(SIMPLEXML_STR) == null) {
            addSimpleXMLFormat(dbwsBuilder.getSchema());
        }
    }

    /**
     * Return a list of ArgumentTypes for a given Procedure Type.  This will include
     * a return argument if pType is a FunctionType.
     */
    protected List<ArgumentType> getArgumentListForProcedureType(ProcedureType pType) {
        List<ArgumentType> args = new ArrayList<ArgumentType>();
        // return argument
        if (pType.isFunctionType()) {
            // assumes that a function MUST have a return type
            args.add(((FunctionType)pType).getReturnArgument());
        }
        args.addAll(pType.getArguments());
        return args;
    }

    /**
     * Return the wrapper class for a given DatabaseType.  The class will be loaded by the
     * XRDynamicClassloader, based on the DatabaseType's javaTypeName.  If the class
     * cannot be loaded, or the given DatabaseType is not a ComplexDatabaseType, null
     * will be returned.
     *
     */
    @SuppressWarnings("rawtypes")
    protected Class getWrapperClass(org.eclipse.persistence.internal.helper.DatabaseType databaseType) {
        if (databaseType instanceof ComplexDatabaseType) {
            return getWrapperClass(((ComplexDatabaseType) databaseType).getJavaTypeName());
        }
        return null;
    }

    /**
     * Return the wrapper class for a wrapper class name.  The wrapper class name would
     * typically be an argument type name, descriptor java class name, or a
     * DatabaseType's javaTypeName.
     *
     * The class will be loaded by the XRDynamicClassloader;  if the class cannot be
     * loaded, null will be returned.
     *
     */
    @SuppressWarnings("rawtypes")
    protected Class getWrapperClass(String wrapperClassName) {
        Class wrapperClass = null;
        try {
            // the following call will try and load the collection wrapper class via XRDynamicClassLoader
            wrapperClass = new XRDynamicClassLoader(this.getClass().getClassLoader()).loadClass(wrapperClassName);
        } catch (ClassNotFoundException e) {
            // should never get here, so ignore
        }
        return wrapperClass;
    }

    /**
     * Log a WARNING with the DBWSBuilder when a target (table, package, stored procedure/function, etc)
     * cannot be found using the information given by the user.
     *
     */
    protected void logNotFoundWarnings(String message, List<String> schemaPatterns, List<String> catalogPatterns, List<String> targetPatterns) {
        StringBuffer sb = new StringBuffer();
        sb.append(message);
        for (int i=0; i < targetPatterns.size(); i++) {
            sb.append(SINGLE_SPACE);
            sb.append(OPEN_SQUARE_BRACKET);
            boolean prependDot = false;
            String schemaName = schemaPatterns.get(i);
            if (schemaName != null && schemaName.length() > 0) {
                sb.append(schemaName);
                prependDot = true;
            }
            String pkgName = catalogPatterns.get(i);
            if (pkgName != null && pkgName.length() > 0) {
                if (prependDot) {
                    sb.append(DOT);
                }
                prependDot = true;
                sb.append(pkgName);
            }
            String tgtName = targetPatterns.get(i);
            if (tgtName != null && tgtName.length() > 0) {
                if (prependDot) {
                    sb.append(DOT);
                }
                sb.append(tgtName);
            }
            sb.append(CLOSE_SQUARE_BRACKET);
        }
        dbwsBuilder.logMessage(Level.WARNING, sb.toString());
    }

    /**
     * Log a WARNING with the DBWSBuilder when a package cannot be found
     * using the information given by the user.
     *
     */
    protected void logPackageNotFoundWarnings(String message, List<String> schemaPatterns, List<String> catalogPatterns) {
        StringBuffer sb = new StringBuffer();
        sb.append(message);
        for (int i=0; i < catalogPatterns.size(); i++) {
            sb.append(SINGLE_SPACE);
            sb.append(OPEN_SQUARE_BRACKET);
            boolean prependDot = false;
            String schemaName = schemaPatterns.get(i);
            if (schemaName != null && schemaName.length() > 0) {
                sb.append(schemaName);
                prependDot = true;
            }
            String pkgName = catalogPatterns.get(i);
            if (pkgName != null && pkgName.length() > 0) {
                if (prependDot) {
                    sb.append(DOT);
                }
                prependDot = true;
                sb.append(pkgName);
            }
            sb.append(CLOSE_SQUARE_BRACKET);
        }
        dbwsBuilder.logMessage(Level.WARNING, sb.toString());
    }
}
