/* * Copyright 2007 Werner Guttmann * * 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. */ package org.castor.anttask; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStream; import java.util.Vector; import org.apache.tools.ant.BuildException; import org.apache.tools.ant.DirectoryScanner; import org.apache.tools.ant.taskdefs.MatchingTask; import org.apache.tools.ant.types.FileSet; import org.castor.ddlgen.Generator; import org.castor.ddlgen.GeneratorException; import org.castor.ddlgen.GeneratorFactory; import org.castor.mapping.MappingUnmarshaller; import org.exolab.castor.mapping.Mapping; import org.exolab.castor.mapping.MappingException; /** * An <a href="http://ant.apache.org/">Ant</a> task to call the Castor * DDL Generator. It can be passed a file, a directory, a Fileset or all * three. * * @author <a href="mailto:werner DOT guttmann AT gmx DOT net">Werner Guttmann</a> * @version $Revision: 6543 $ $Date: 2005-03-05 06:42:06 -0700 (Sat, 05 Mar 2005) $ */ public final class CastorDDLGenTask extends MatchingTask { //-------------------------------------------------------------------------- /** Error message -- no mapping to run ddl generator on. */ private static final String NO_MAPPING_MSG = "A mapping file must be provided for DDL generation."; //-------------------------------------------------------------------------- /** If processing one schema file, this lists the file. */ private File _mappingFile = null; /** If processing all mapping files in a directory, this lists the directory. */ private File _mappingDir = null; /** If processing a fileset, this lists the fileset. */ private Vector _mappingFilesets = new Vector(); // Begin DDL Generator parameters /** The package that generated code will belong to. */ private String _ddlFileName; /** Name of database engine to generate DDL for. */ private String _databaseEngine; /** Global properties file to be used during DDL generation. */ private String _globalProperties; /** Database specific properties file to be used during DDL generatrion. */ private String _databaseEngineProperties; /** OutputStream used for writing the generated DDL statements. */ private OutputStream _outputStream; //-------------------------------------------------------------------------- /** * Sets the individual schema that will have code generated for it. * * @param file One schema file. */ public void setFile(final File file) { _mappingFile = file; } /** * Sets the directory such that all schemas in this directory will have code * generated for them. * * @param dir The directory containing schemas to process. */ public void setDir(final File dir) { _mappingDir = dir; } /** * Adds a fileset to process that contains schemas to process. * * @param set An individual file set containing schemas. */ public void addFileset(final FileSet set) { _mappingFilesets.addElement(set); } /** * Specifies the name of database engine to generate DDL for. * @param databaseEngine Name of the database engine */ public void setDatabaseEngine(final String databaseEngine) { _databaseEngine = databaseEngine; } /** * Specifies the name of a database specific properties file to be used * during DDL generation. * @param databaseEngineProperties Database specific properties */ public void setDatabaseEngineProperties(final String databaseEngineProperties) { _databaseEngineProperties = databaseEngineProperties; } /** * Specifies the name of the DDL file to be generated. * @param ddlFileName Name of the DDL file to be generated */ public void setDdlFileName(final String ddlFileName) { _ddlFileName = ddlFileName; } /** * Specifies the name of a global properties file to be used during * DDL generation. * @param globalProperties Custom global properties for DDL generation. */ public void setGlobalProperties(final String globalProperties) { _globalProperties = globalProperties; } //-------------------------------------------------------------------------- /** * Configured the code generator. If anything goes wrong during configuration of the * Ant task a BuildException will be thrown. */ private void config() { if (_databaseEngine == null) { throw new BuildException("No database engine specified."); } try { _outputStream = new FileOutputStream(_ddlFileName); } catch (IOException e) { throw new BuildException("Problem finding the Castor JDO mapping file " + _mappingFile.getAbsolutePath(), e); } } /** * Runs source generation. If anything goes wrong during source generation a * BuildException will be thrown. * * @param filePath an individual Schema to generate code for. */ private void processFile(final String filePath) { log("Processing " + filePath); try { Generator ddlgen = GeneratorFactory.createDDLGenerator( _databaseEngine, _globalProperties, _databaseEngineProperties); Mapping mapping = new Mapping(); mapping.loadMapping(filePath); new MappingUnmarshaller().loadMappingOnly(mapping); // TODO: Joachim 2007-09-07 the InternalContext should be set into the unmarshaller! ddlgen.setMapping(mapping); ddlgen.generateDDL(_outputStream); } catch (IOException e) { throw new BuildException ("Problem finding the Castor JDO mapping file " + _mappingFile.getAbsolutePath(), e); } catch (MappingException e) { throw new BuildException ("Problem loading the Castor JDO mapping file " + _mappingFile.getAbsolutePath(), e); } catch (GeneratorException e) { throw new BuildException ("Problem generating DDL script for " + _mappingFile.getAbsolutePath(), e); } } /** * Public execute method -- entry point for the Ant task. Loops over all * schema that need code generated and creates needed code generators, then * executes them. If anything goes wrong during execution of the Ant task a * BuildException will be thrown. * * @see org.apache.tools.ant.Task#execute() */ public void execute() { // Must have something to run the source generator on if (_mappingFile == null && _mappingDir == null && _mappingFilesets.size() == 0) { throw new BuildException(NO_MAPPING_MSG); } config(); // Run DDL generator on file if (_mappingFile != null) { processFile(_mappingFile.getAbsolutePath()); } // Run source generator on all files in directory if (_mappingDir != null && _mappingDir.exists() && _mappingDir.isDirectory()) { DirectoryScanner ds = this.getDirectoryScanner(_mappingDir); String[] files = ds.getIncludedFiles(); for (int i = 0; i < files.length; i++) { String filePath = _mappingDir.getAbsolutePath() + File.separator + files[i]; processFile(filePath); } } // Run source generator on all files in FileSet for (int i = 0; i < _mappingFilesets.size(); i++) { FileSet fs = (FileSet) _mappingFilesets.elementAt(i); DirectoryScanner ds = fs.getDirectoryScanner(getProject()); File subdir = fs.getDir(getProject()); String[] files = ds.getIncludedFiles(); for (int j = 0; j < files.length; j++) { String filePath = subdir.getAbsolutePath() + File.separator + files[j]; processFile(filePath); } } } }