Package org.jpox

Source Code of org.jpox.SchemaTool

/**********************************************************************
Copyright (c) 2003 Andy Jefferson and others. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
Contributors:
2004 Joerg Van Frantzius - changes to support a form of DDL output
2004 Erik Bengtson - dbinfo() mode
2004 Andy Jefferson - added "mapping" property to allow ORM files
    ...
**********************************************************************/
package org.jpox;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
import java.util.StringTokenizer;

import javax.jdo.JDOHelper;
import javax.jdo.PersistenceManagerFactory;

import org.jpox.exceptions.JPOXException;
import org.jpox.exceptions.JPOXUserException;
import org.jpox.jdo.AbstractPersistenceManager;
import org.jpox.jdo.JDOPersistenceManagerFactory;
import org.jpox.metadata.FileMetaData;
import org.jpox.metadata.MetaDataManager;
import org.jpox.store.StoreManager;
import org.jpox.util.ClassUtils;
import org.jpox.util.CommandLine;
import org.jpox.util.JPOXLogger;
import org.jpox.util.Localiser;
import org.jpox.util.StringUtils;

/**
* JPOX SchemaTool providing an interface for the maintenance of schemas.
* These utilities include:-
* <ul>
* <li>creation of tables representing classes specified in input data</li>
* <li>deletion of tables representing classes specified in input data</li>
* <li>validation of tables representing classes specified in input data</li>
* <li>details about the datastore</li>
* </ul>
*
* @version $Revision: 1.95 $
*/
public class SchemaTool extends PersistenceConfiguration
{
    /** Localiser for messages. */
    private static final Localiser LOCALISER = Localiser.getInstance("org.jpox.Localisation",
        ObjectManagerFactoryImpl.class.getClassLoader());

    /** ObjectManagerFactory Context **/
    private OMFContext omfContext;

    /** Command Line **/
    private CommandLine cmd;

    /** default command line arguments **/
    private String[] defaultArgs;

    /** Name of a file containing properties. */
    private String propsFileName = null;

    /** create mode **/
    public static final int SCHEMATOOL_CREATE_MODE = 1;

    /** delete mode **/
    public static final int SCHEMATOOL_DELETE_MODE = 2;

    /** validate mode **/
    public static final int SCHEMATOOL_VALIDATE_MODE = 3;

    /** database info mode **/
    public static final int SCHEMATOOL_DATABASE_INFO_MODE = 4;

    /** schema info mode **/
    public static final int SCHEMATOOL_SCHEMA_INFO_MODE = 5;

    /** schema tool mode **/
    public static final String SCHEMATOOL_OPTION_MODE = "org.jpox.schemaTool.mode";

    /** schema tool in verbose **/
    public static final String SCHEMATOOL_OPTION_VERBOSE = "org.jpox.schemaTool.verbose";

    /** properties file for schema tool **/
    public static final String SCHEMATOOL_OPTION_PROPERTIES_FILE = "org.jpox.schemaTool.propertiesFile";

    /** Property specifying the name of a DDL file**/
    public static final String SCHEMATOOL_OPTION_DDLFILE = "org.jpox.schemaTool.ddlFile";

    /** Property specifying the name of a DDL file (deprecated). **/
    public static final String SCHEMATOOL_OPTION_DUMPDDL = "org.jpox.schemaTool.dumpDdl";

    /** create complete DDL, not only for missing elements **/
    public static final String SCHEMATOOL_OPTION_COMPLETEDDL = "org.jpox.schemaTool.completeDdl";

    /** output help for schema tool **/
    public static final String SCHEMATOOL_OPTION_HELP = "org.jpox.schemaTool.help";

    /**
     * Entry method when invoked from the command line.
     * @param args List of options for processing by the available methods in this class.
     * @throws Exception
     */
    public static void main(String[] args) throws Exception
    {
        SchemaTool tool = new SchemaTool();
        tool.setCommandLineArgs(args);

        if (tool.isHelp())
        {
            System.out.println(LOCALISER.msg(false, "014023"));
            System.out.println(LOCALISER.msg(false, "014024"));
            System.out.println(LOCALISER.msg(false, "014025"));
            System.out.println(tool.cmd.toString());
            System.out.println(LOCALISER.msg(false, "014034"));
            System.out.println(LOCALISER.msg(false, "014035"));
            System.exit(0);
        }

        // Mode of operation
        int mode = SCHEMATOOL_CREATE_MODE;
        String msg = null;
        if (tool.getModeName() != null)
        {
            if (tool.getModeName().equals("create"))
            {
                mode = SCHEMATOOL_CREATE_MODE;
                msg = LOCALISER.msg(false, "014000", ObjectManagerFactoryImpl.getVersionNumber());
            }
            else if (tool.getModeName().equals("delete"))
            {
                mode = SCHEMATOOL_DELETE_MODE;
                msg = LOCALISER.msg(false, "014001", ObjectManagerFactoryImpl.getVersionNumber());
            }
            else if (tool.getModeName().equals("validate"))
            {
                mode = SCHEMATOOL_VALIDATE_MODE;
                msg = LOCALISER.msg(false, "014002", ObjectManagerFactoryImpl.getVersionNumber());
            }
            else if (tool.getModeName().equals("dbinfo"))
            {
                mode = SCHEMATOOL_DATABASE_INFO_MODE;
                msg = LOCALISER.msg(false, "014003", ObjectManagerFactoryImpl.getVersionNumber());
            }
            else if (tool.getModeName().equals("schemainfo"))
            {
                mode = SCHEMATOOL_SCHEMA_INFO_MODE;
                msg = LOCALISER.msg(false, "014004", ObjectManagerFactoryImpl.getVersionNumber());
            }
        }
        else
        {
            msg = LOCALISER.msg(false, "014000", ObjectManagerFactoryImpl.getVersionNumber());
        }
        JPOXLogger.SCHEMATOOL.info(msg);
        System.out.println(msg);

        // Classpath
        msg = LOCALISER.msg(false, "014005");
        JPOXLogger.SCHEMATOOL.info(msg);
        if (tool.isVerbose())
        {
            System.out.println(msg);
        }
        StringTokenizer tokeniser = new StringTokenizer(System.getProperty("java.class.path"), File.pathSeparator);
        while (tokeniser.hasMoreTokens())
        {
            msg = LOCALISER.msg(false, "014006", tokeniser.nextToken());
            JPOXLogger.SCHEMATOOL.info(msg);
            if (tool.isVerbose())
            {
                System.out.println(msg);
            }
        }
        if (tool.isVerbose())
        {
            System.out.println();
        }

        // DDL file
        String ddlFilename = tool.getDdlFile();
        if (ddlFilename != null)
        {
            msg = LOCALISER.msg(false, tool.getCompleteDdl() ? "014018" : "014019", ddlFilename);
            JPOXLogger.SCHEMATOOL.info(msg);
            if (tool.isVerbose())
            {
                System.out.println(msg);
                System.out.println();
            }
        }

        // Create a PMF for use with this mode
        PersistenceManagerFactory pmf = null;
        try
        {
            if (tool.getPropsFileName() != null)
            {
                pmf = getPMFForMode(mode, tool.getApi(), tool.getOptions(), tool.getStringProperty("org.jpox.PersistenceUnitName"),
                    ddlFilename, tool.isVerbose());
            }
            else
            {
                pmf = getPMFForMode(mode, tool.getApi(), null, tool.getStringProperty("org.jpox.PersistenceUnitName"), ddlFilename,
                    tool.isVerbose());
            }
        }
        catch (Exception e)
        {
            // Unable to create a PMF so likely input errors
            JPOXLogger.SCHEMATOOL.error("Error creating PMF", e);
            System.out.println(LOCALISER.msg(false, "014008", e.getMessage()));
            System.exit(1);
            return;
        }

        List classNames = null;
        if (mode != SCHEMATOOL_SCHEMA_INFO_MODE && mode != SCHEMATOOL_DATABASE_INFO_MODE)
        {
            // Find the names of the classes to be processed
            // This will load up all MetaData for the specified input and throw exceptions where errors are found
            try
            {
                MetaDataManager metaDataMgr = ((ObjectManagerFactoryImpl)pmf).getOMFContext().getMetaDataManager();
                ClassLoaderResolver clr = ((ObjectManagerFactoryImpl)pmf).getOMFContext().getClassLoaderResolver(null);

                FileMetaData[] filemds = getFileMetaDataForInput(metaDataMgr, clr, tool.isVerbose(),
                    tool.getStringProperty("org.jpox.PersistenceUnitName"), tool.getDefaultArgs());
                classNames = new ArrayList();
                if (filemds == null)
                {
                    msg = LOCALISER.msg(false, "014021");
                    JPOXLogger.SCHEMATOOL.error(msg);
                    System.out.println(msg);
                    System.exit(2);
                    return;
                }
                for (int i=0;i<filemds.length;i++)
                {
                    for (int j=0;j<filemds[i].getNoOfPackages();j++)
                    {
                        for (int k=0;k<filemds[i].getPackage(j).getNoOfClasses();k++)
                        {
                            classNames.add(filemds[i].getPackage(j).getClass(k).getFullClassName());
                        }
                    }
                }
            }
            catch (Exception e)
            {
                // Exception will have been logged and sent to System.out in "getFileMetaDataForInput()"
                System.exit(2);
                return;
            }
        }

        // Run SchemaTool
        try
        {
            if (mode == SCHEMATOOL_CREATE_MODE)
            {
                createSchema(pmf, classNames, ddlFilename, tool.getCompleteDdl());
            }
            else if (mode == SCHEMATOOL_DELETE_MODE)
            {
                deleteSchema(pmf, classNames);
            }
            else if (mode == SCHEMATOOL_VALIDATE_MODE)
            {
                validateSchema(pmf, classNames);
            }
            else if (mode == SCHEMATOOL_DATABASE_INFO_MODE)
            {
                StoreManager srm = ((AbstractPersistenceManager) pmf.getPersistenceManager()).getObjectManager().getStoreManager();
                srm.outputDatastoreInformation(System.out);
            }
            else if (mode == SCHEMATOOL_SCHEMA_INFO_MODE)
            {
                StoreManager srm = ((AbstractPersistenceManager) pmf.getPersistenceManager()).getObjectManager().getStoreManager();
                srm.outputSchemaInformation(System.out);
            }

            msg = LOCALISER.msg(false, "014043");
            JPOXLogger.SCHEMATOOL.info(msg);
            System.out.println(msg);
        }
        catch (Exception e)
        {
            msg = LOCALISER.msg(false, "014037", e.getMessage());
            System.out.println(msg);
            JPOXLogger.SCHEMATOOL.error(msg, e);
            System.exit(2);
            return;
        }
    }

    /**
     * Constructor
     */
    public SchemaTool()
    {
        omfContext = new OMFContext(this);
        cmd = new CommandLine();
        cmd.addOption("create", "create", null, LOCALISER.msg(false, "014026"));
        cmd.addOption("delete", "delete", null, LOCALISER.msg(false, "014027"));
        cmd.addOption("validate", "validate", null, LOCALISER.msg(false, "014028"));
        cmd.addOption("dbinfo", "dbinfo", null, LOCALISER.msg(false, "014029"));
        cmd.addOption("schemainfo", "schemainfo", null, LOCALISER.msg(false, "014030"));
        cmd.addOption("ddlFile", "ddlFile", "ddlFile", LOCALISER.msg(false, "014031"));
        cmd.addOption("dumpDdl", "dumpDdl", "dumpDdl", LOCALISER.msg(false, "014031"));
        cmd.addOption("completeDdl", "completeDdl", null, LOCALISER.msg(false, "014032"));
        cmd.addOption("api", "api", "<adapter-name>", "API Adapter (JDO, JPA, etc)");
        cmd.addOption("help", "help", null, LOCALISER.msg(false, "014033"));
        cmd.addOption("v", "verbose", null, "verbose output");
        cmd.addOption("persistenceUnit", "persistenceUnit", "<persistence-unit>",
            "name of the persistence unit to handle the schema for");
        cmd.addOption("props", "jpoxproperties", "props", "path to a properties file");
    }

    /**
     * Method to create a PersistenceManagerFactory for the specified mode of SchemaTool
     * @param mode Mode of operation of schematool
     * @param api Persistence API
     * @param userProps Map containing user provided properties (usually input via a file)
     * @param persistenceUnitName Name of the persistence-unit (if any)
     * @param ddlFile Name of a file to output DDL to
     * @param verbose Verbose mode
     * @return The PersistenceManagerFactory to use
     * @throws JPOXException Thrown if an error occurs in creating the required PMF
     */
    protected static PersistenceManagerFactory getPMFForMode(int mode, String api, Map userProps,
            String persistenceUnitName, String ddlFile, boolean verbose)
    {
        Map props = new HashMap();
        if (persistenceUnitName != null)
        {
            // persistence-unit specified so take the PMF properties from that
            // Note that this will create the PMF with the properties for the <persistence-unit>
            props.put(JDOPersistenceManagerFactory.JDO_PERSISTENCE_UNIT_NAME_PROPERTY, persistenceUnitName);
        }

        if (userProps != null)
        {
            // Properties specified by the user in a file
            props.putAll(userProps);
        }
        else
        {
            // Properties specified via System properties (only support particular ones)
            if (persistenceUnitName == null &&
                (System.getProperty(JDOPersistenceManagerFactory.JDO_DATASTORE_DRIVERNAME_PROPERTY) == null ||
                 System.getProperty(JDOPersistenceManagerFactory.JDO_DATASTORE_URL_PROPERTY) == null))
            {
                //try to load a default PMF properties file
                File file = new File(System.getProperty("user.home") + "/.jdo/PMFProperties.properties");
                if (file.exists())
                {
                    try
                    {
                        InputStream is = new FileInputStream(file);
                        Properties fileProps = new Properties();
                        fileProps.load(is);
                        props.putAll(fileProps);
                        is.close();
                    }
                    catch (IOException ioe)
                    {
                        // Ignore this
                    }
                }
                else
                {
                    throw new JPOXException(LOCALISER.msg("014041"));
                }
            }

            if (System.getProperty(JDOPersistenceManagerFactory.JDO_DATASTORE_DRIVERNAME_PROPERTY) != null)
            {
                props.put(JDOPersistenceManagerFactory.JDO_DATASTORE_DRIVERNAME_PROPERTY,
                    System.getProperty(JDOPersistenceManagerFactory.JDO_DATASTORE_DRIVERNAME_PROPERTY));
            }
            if (System.getProperty(JDOPersistenceManagerFactory.JDO_DATASTORE_URL_PROPERTY) != null)
            {
                props.put(JDOPersistenceManagerFactory.JDO_DATASTORE_URL_PROPERTY,
                    System.getProperty(JDOPersistenceManagerFactory.JDO_DATASTORE_URL_PROPERTY));
            }
            if (System.getProperty(JDOPersistenceManagerFactory.JDO_DATASTORE_USERNAME_PROPERTY) != null)
            {
                props.put(JDOPersistenceManagerFactory.JDO_DATASTORE_USERNAME_PROPERTY,
                    System.getProperty(JDOPersistenceManagerFactory.JDO_DATASTORE_USERNAME_PROPERTY));
            }
            if (System.getProperty(JDOPersistenceManagerFactory.JDO_DATASTORE_PASSWORD_PROPERTY) != null)
            {
                props.put(JDOPersistenceManagerFactory.JDO_DATASTORE_PASSWORD_PROPERTY,
                    System.getProperty(JDOPersistenceManagerFactory.JDO_DATASTORE_PASSWORD_PROPERTY));
            }
            if (System.getProperty(JDOPersistenceManagerFactory.JDO_MAPPING_PROPERTY) != null)
            {
                props.put(JDOPersistenceManagerFactory.JDO_MAPPING_PROPERTY,
                    System.getProperty(JDOPersistenceManagerFactory.JDO_MAPPING_PROPERTY));
            }
        }

        // Use JPOX PMF
        props.put("javax.jdo.PersistenceManagerFactoryClass", JDOPersistenceManagerFactory.class.getName());

        // Set the API
        props.put("org.jpox.persistenceApiName", api);

        // Tag on the mandatory props that we must have for each mode
        props.put("org.jpox.autoStartMechanism", "None"); // Dont want autostart interference
        if (mode == SCHEMATOOL_CREATE_MODE)
        {
            if (ddlFile != null)
            {
                // the tables must not be created in the DB, so do not validate (DDL is being output to a file)
                props.put("org.jpox.validateConstraints", "false");
                props.put("org.jpox.validateColumns", "false");
                props.put("org.jpox.validateTables", "false");
            }
            props.put("org.jpox.autoCreateSchema", "true");
            props.put("org.jpox.autoCreateTables", "true");
            props.put("org.jpox.autoCreateConstraints", "true");
            props.put("org.jpox.fixedDatastore", "false");
            props.put("org.jpox.readOnlyDatastore", "false");
            props.put("org.jpox.rdbms.CheckExistTablesOrViews", "true");
        }
        else if (mode == SCHEMATOOL_DELETE_MODE)
        {
            props.put("org.jpox.fixedDatastore", "false");
            props.put("org.jpox.readOnlyDatastore", "false");
        }
        else if (mode == SCHEMATOOL_VALIDATE_MODE)
        {
            props.put("org.jpox.autoCreateSchema", "false");
            props.put("org.jpox.autoCreateTables", "false");
            props.put("org.jpox.autoCreateConstraints", "false");
            props.put("org.jpox.autoCreateColumns", "false");
            props.put("org.jpox.validateTables", "true");
            props.put("org.jpox.validateColumns", "true");
            props.put("org.jpox.validateConstraints", "true");
        }

        if (verbose)
        {
            String msg = LOCALISER.msg(false, "014020");
            JPOXLogger.SCHEMATOOL.info(msg);
            System.out.println(msg);

            Set keys = props.keySet();
            List keyNames = new ArrayList(keys);
            Collections.sort(keyNames);
            Iterator keyNamesIter = keyNames.iterator();
            while (keyNamesIter.hasNext())
            {
                String key = (String)keyNamesIter.next();
                if (key.startsWith("org.jpox") && !key.equals("org.jpox.ConnectionPassword"))
                    // Dont output passwords
                {
                    msg = LOCALISER.msg(false, "014022", key, props.get(key));
                    JPOXLogger.SCHEMATOOL.info(msg);
                    System.out.println(msg);
                }
            }
            System.out.println();
        }

        // Create the PMF that we will use to communicate with the datastore
        return JDOHelper.getPersistenceManagerFactory(props);
    }

    /**
     * Method to take the input for SchemaTool and returns the FileMetaData that it implies.
     * The input should either be a persistence-unit name, or a set of input files.
     * @param metaDataMgr Manager for MetaData
     * @param clr ClassLoader resolver
     * @param verbose Whether to put message verbosely
     * @param persistenceUnitName Name of the "persistence-unit"
     * @param inputFiles Input metadata/class files
     * @return The FileMetaData for the input
     * @throws JPOXException Thrown if error(s) occur in processing the input
     */
    protected static FileMetaData[] getFileMetaDataForInput(MetaDataManager metaDataMgr, ClassLoaderResolver clr,
            boolean verbose, String persistenceUnitName, String[] inputFiles)
    {
        FileMetaData[] filemds = null;

        String msg = null;
        if (inputFiles == null && persistenceUnitName == null)
        {
            msg = LOCALISER.msg(false, "014007");
            JPOXLogger.SCHEMATOOL.error(msg);
            System.out.println(msg);
            throw new JPOXUserException(msg);
        }

        if (persistenceUnitName != null)
        {
            // Schema management via "persistence-unit"
            msg = LOCALISER.msg(false, "014015", persistenceUnitName);
            JPOXLogger.SCHEMATOOL.info(msg);
            if (verbose)
            {
                System.out.println(msg);
                System.out.println();
            }

            // The PMF will have initialised the MetaDataManager with the persistence-unit
            filemds = metaDataMgr.getFileMetaData();
        }
        else
        {
            // Schema management via "Input Files" (metadata/class)
            msg = LOCALISER.msg(false, "014009");
            JPOXLogger.SCHEMATOOL.info(msg);
            if (verbose)
            {
                System.out.println(msg);
            }
            for (int i = 0; i < inputFiles.length; i++)
            {
                String entry = LOCALISER.msg(false, "014010", inputFiles[i]);
                JPOXLogger.SCHEMATOOL.info(entry);
                if (verbose)
                {
                    System.out.println(entry);
                }
            }
            if (verbose)
            {
                System.out.println();
            }

            // Read in the specified MetaData files - errors in MetaData will return exceptions and so we stop
            try
            {
                // Split the input files into MetaData files and classes
                JPOXLogger.SCHEMATOOL.debug(LOCALISER.msg(false, "014011", "" + inputFiles.length));
                HashSet metadataFiles = new HashSet();
                HashSet classNames = new HashSet();
                for (int i=0;i<inputFiles.length;i++)
                {
                    if (inputFiles[i].endsWith(".class"))
                    {
                        // Class file
                        URL classFileURL = null;
                        try
                        {
                            classFileURL = new URL("file:" + inputFiles[i]);
                        }
                        catch (Exception e)
                        {
                            msg = LOCALISER.msg(false, "014013", inputFiles[i]);
                            JPOXLogger.SCHEMATOOL.error(msg);
                            throw new JPOXUserException(msg);
                        }

                        String className = ClassUtils.getClassNameForFileURL(classFileURL);
                        classNames.add(className);
                    }
                    else
                    {
                        // MetaData file
                        metadataFiles.add(inputFiles[i]);
                    }
                }

                // Initialise the MetaDataManager using the mapping files and class names
                filemds = metaDataMgr.initialise((String[])metadataFiles.toArray(new String[metadataFiles.size()]),
                    (String[])classNames.toArray(new String[classNames.size()]), clr);
                JPOXLogger.SCHEMATOOL.debug(LOCALISER.msg(false, "014012", "" + inputFiles.length));
            }
            catch (Exception e)
            {
                // Error reading input files
                msg = LOCALISER.msg(false, "014014", e.getMessage());
                JPOXLogger.SCHEMATOOL.error(msg, e);
                System.out.println(msg);
                if (e instanceof JPOXException)
                {
                    throw (JPOXException)e;
                }
                throw new JPOXUserException(msg, e);
            }
        }

        return filemds;
    }

    /**
     * Method to handle the creation of the schema for a set of classes
     * @param pmf PersistenceManagerFactory to use when generating the schema
     * @param classNames names of all classes whose schema is to be created
     * @param ddlFilename Name of the DDL file (optional)
     * @throws Exception Thrown when either an error occurs parsing the MetaData, or the DB definition is not defined.
     */
    public static void createSchema(PersistenceManagerFactory pmf, List classNames, String ddlFilename,
            boolean completeDdl)
    throws Exception
    {
        if (classNames != null && classNames.size() > 0)
        {
            // Create a PersistenceManager for this store and create the tables
            ObjectManager om = ((AbstractPersistenceManager) pmf.getPersistenceManager()).getObjectManager();
            StoreManager storeMgr = om.getStoreManager();

            FileWriter ddlFileWriter = null;
            if (ddlFilename != null)
            {
                // Open the DDL file for writing
                File ddlFile = StringUtils.getFileForFilename(ddlFilename);
                if (ddlFile.exists())
                {
                    // Delete existing file
                    ddlFile.delete();
                }
                if (ddlFile.getParentFile() != null && !ddlFile.getParentFile().exists())
                {
                    // Make sure the directory exists
                    ddlFile.getParentFile().mkdirs();
                }
                ddlFile.createNewFile();
                ddlFileWriter = new FileWriter(ddlFile);

                SimpleDateFormat fmt = new SimpleDateFormat("dd/MM/yyyy HH:mm:ss");
                ddlFileWriter.write("------------------------------------------------------------------\n");
                ddlFileWriter.write("-- JPOX SchemaTool " +
                    "(version " + ObjectManagerFactoryImpl.getVersionNumber() + ")" +
                    " ran at " + fmt.format(new java.util.Date()) +
                    "\n");
                ddlFileWriter.write("------------------------------------------------------------------\n");
                if (completeDdl)
                {
                    ddlFileWriter.write("-- Complete schema required for the following classes:-\n");
                }
                else 
                {
                    ddlFileWriter.write("-- Schema diff for " + pmf.getConnectionURL()+ " and the following classes:-\n");
                }
                Iterator classNameIter = classNames.iterator();
                while (classNameIter.hasNext())
                {
                    ddlFileWriter.write("--     " + classNameIter.next() + "\n");
                }
                ddlFileWriter.write("--\n");
            }

            try
            {
                String[] classNameArray = (String[])classNames.toArray(new String[classNames.size()]);
                storeMgr.addClasses(classNameArray, om.getClassLoaderResolver(), ddlFileWriter, completeDdl);
            }
            finally
            {
                if (ddlFileWriter != null)
                {
                    ddlFileWriter.close();
                }
            }
        }
        else
        {
            String msg = LOCALISER.msg(false, "014039");
            JPOXLogger.SCHEMATOOL.error(msg);
            System.out.println(msg);

            throw new Exception(msg);
        }
    }

    /**
     * Method to handle the deletion of a schema's tables.
     * @param pmf PersistenceManagerFactory to use when generating the schema
     * @param classNames names of all classes whose schema is to be created
     * @throws Exception Thrown when either an error occurs parsing the MetaData, or the DB definition is not defined.
     */
    public static void deleteSchema(PersistenceManagerFactory pmf, List classNames)
    throws Exception
    {
        if (classNames != null && classNames.size() > 0)
        {
            // Create a PersistenceManager for this store and delete the tables
            ObjectManager om = ((AbstractPersistenceManager) pmf.getPersistenceManager()).getObjectManager();
            StoreManager storeMgr = om.getStoreManager();

            String[] classNameArray = (String[])classNames.toArray(new String[classNames.size()]);
            storeMgr.addClasses(classNameArray, om.getClassLoaderResolver()); // Add them to mgr first
            storeMgr.removeAllClasses(om.getClassLoaderResolver());
        }
        else
        {
            String msg = LOCALISER.msg(false, "014039");
            JPOXLogger.SCHEMATOOL.info(msg);
            System.out.println(msg);

            throw new Exception(msg);
        }
    }

    /**
     * Method to handle the validation of a schema's tables.
     * @param pmf PersistenceManagerFactory to use when generating the schema
     * @param classNames names of all classes whose schema is to be created
     * @throws Exception Thrown when either an error occurs parsing the MetaData, or the DB definition is not defined.
     */
    public static void validateSchema(PersistenceManagerFactory pmf, List classNames)
    throws Exception
    {
        if (classNames != null && classNames.size() > 0)
        {
            // Create a PersistenceManager for this store and validate
            ObjectManager om = ((AbstractPersistenceManager) pmf.getPersistenceManager()).getObjectManager();
            StoreManager storeMgr = om.getStoreManager();

            String[] classNameArray = (String[])classNames.toArray(new String[classNames.size()]);
            storeMgr.addClasses(classNameArray, om.getClassLoaderResolver()); // Validates since we have the flags set
        }
        else
        {
            String msg = LOCALISER.msg(false, "014039");
            JPOXLogger.SCHEMATOOL.error(msg);
            System.out.println(msg);

            throw new Exception(msg);
        }
    }

    /**
     * Initialize the command line arguments
     * @param args Command line args
     */
    public void setCommandLineArgs(String[] args)
    {
        cmd.parse(args);

        defaultArgs = cmd.getDefaultArgs();

        // populate options
        if (cmd.hasOption("api"))
        {
            omfContext.setApi(cmd.getOptionArg("api"));
            setApi(cmd.getOptionArg("api"));
        }

        setOptions(omfContext.getApiAdapter().getDefaultFactoryProperties());

        if (cmd.hasOption("create"))
        {
            setProperty(SCHEMATOOL_OPTION_MODE, "create");
        }
        else if (cmd.hasOption("delete"))
        {
            setProperty(SCHEMATOOL_OPTION_MODE, "delete");
        }
        else if (cmd.hasOption("validate"))
        {
            setProperty(SCHEMATOOL_OPTION_MODE, "validate");
        }
        else if (cmd.hasOption("dbinfo"))
        {
            setProperty(SCHEMATOOL_OPTION_MODE, "dbinfo");
        }
        else if (cmd.hasOption("schemainfo"))
        {
            setProperty(SCHEMATOOL_OPTION_MODE, "schemainfo");
        }
        if (cmd.hasOption("help"))
        {
            setProperty(SCHEMATOOL_OPTION_HELP, "true");
        }
        if (cmd.hasOption("ddlFile"))
        {
            setProperty(SCHEMATOOL_OPTION_DDLFILE, cmd.getOptionArg("ddlFile"));
        }
        if (cmd.hasOption("dumpDdl"))
        {
            // Deprecated. Present for backwards compatibility only (use "ddlFile" instead)
            setProperty(SCHEMATOOL_OPTION_DDLFILE, cmd.getOptionArg("dumpDdl"));
        }
        if (cmd.hasOption("completeDdl"))
        {
            setProperty(SCHEMATOOL_OPTION_COMPLETEDDL, "true");
        }
        if (cmd.hasOption("persistenceUnit"))
        {
            setProperty("org.jpox.PersistenceUnitName", cmd.getOptionArg("persistenceUnit"));
        }
        if (cmd.hasOption("props"))
        {
            propsFileName = cmd.getOptionArg("props");
            setProperty("org.jpox.propertiesFile", propsFileName);
        }
        if (cmd.hasOption("v"))
        {
            setProperty(SCHEMATOOL_OPTION_VERBOSE, "true");
        }
    }

    /**
     * @return the help
     */
    public boolean isHelp()
    {
        return getBooleanProperty(SCHEMATOOL_OPTION_HELP);
    }

    /**
     * @param help the help to set
     */
    public void setHelp(boolean help)
    {
        setProperty(SCHEMATOOL_OPTION_HELP, new Boolean(help));
    }

    /**
     * Mutator for the flag to output complete DDL (when using DDL file)
     * @param completeDdl Whether to return complete DDL
     */
    public void setCompleteDdl(boolean completeDdl)
    {
        setProperty(SCHEMATOOL_OPTION_COMPLETEDDL, new Boolean(completeDdl));
    }

    /**
     * @return whether to use complete DDL
     */
    public boolean getCompleteDdl()
    {
        return getBooleanProperty(SCHEMATOOL_OPTION_COMPLETEDDL);
    }

    /**
     * @return the mode
     */
    public String getModeName()
    {
        return getStringProperty(SCHEMATOOL_OPTION_MODE);
    }

    /**
     * @param mode the mode to set
     */
    public void setModeName(String mode)
    {
        setProperty(SCHEMATOOL_OPTION_MODE, mode);
    }

    /**
     * Acessor for the API (JDO, JPA)
     * @return the API
     */
    public String getApi()
    {
        return getStringProperty("org.jpox.persistenceApiName");
    }

    /**
     * Mutator for the API (JDO, JPA)
     * @param api the API
     */
    public void setApi(String api)
    {
        setProperty("org.jpox.persistenceApiName", api);
    }

    /**
     * @return the verbose
     */
    public boolean isVerbose()
    {
        return getBooleanProperty(SCHEMATOOL_OPTION_VERBOSE);
    }

    /**
     * @param verbose the verbose to set
     */
    public void setVerbose(boolean verbose)
    {
        setProperty(SCHEMATOOL_OPTION_VERBOSE, new Boolean(verbose));
    }

    /**
     * @return the defaultArgs
     */
    public String[] getDefaultArgs()
    {
        return defaultArgs;
    }

    /**
     * Accessor for the DDL filename
     * @return the file to use when outputing the DDL
     */
    public String getDdlFile()
    {
        return getStringProperty(SCHEMATOOL_OPTION_DDLFILE);
    }

    /**
     * Mutator for the DDL file
     * @param file the file to use when outputting the DDL
     */
    public void setDdlFile(String file)
    {
        setProperty(SCHEMATOOL_OPTION_DDLFILE, file);
    }

    /**
     * Acessor for the properties file name (optional).
     * @return the props file name
     */
    public String getPropsFileName()
    {
        return propsFileName;
    }
}
TOP

Related Classes of org.jpox.SchemaTool

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.