package org.apache.torque.ant.task;
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.
*/
import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.Project;
import org.apache.tools.ant.Task;
import org.apache.torque.generator.configuration.ConfigurationException;
import org.apache.torque.generator.configuration.UnitDescriptor;
import org.apache.torque.generator.configuration.UnitDescriptor.Packaging;
import org.apache.torque.generator.configuration.controller.Loglevel;
import org.apache.torque.generator.configuration.option.MapOptionsConfiguration;
import org.apache.torque.generator.configuration.option.OptionsConfiguration;
import org.apache.torque.generator.configuration.paths.CustomProjectPaths;
import org.apache.torque.generator.configuration.paths.DefaultTorqueGeneratorPaths;
import org.apache.torque.generator.configuration.paths.Maven2DirectoryProjectPaths;
import org.apache.torque.generator.configuration.paths.Maven2JarProjectPaths;
import org.apache.torque.generator.configuration.paths.ProjectPaths;
import org.apache.torque.generator.control.Controller;
import org.apache.torque.generator.file.Fileset;
import org.apache.torque.generator.source.stream.FileSourceProvider;
/**
* Executes a unit of generation within the torque generator.
*
* $Id: TorqueGeneratorTask.java 1401885 2012-10-24 21:13:09Z tfischer $
*
* @goal generate
*/
public class TorqueGeneratorTask extends Task
{
/**
* The packaging type of the generation unit, either "directory" , "jar"
* or "classpath". Default is "directory".
*/
private String packaging = "directory";
/**
* The root directory of the project.
* Has no effect if packaging is "classpath".
* Default is ".".
*/
private File projectRootDir = new File(".");
/**
* The configuration directory of the generation unit.
* Has no effect if packaging is "classpath".
*/
private File configDir;
/**
* The configuration package of the generation unit.
* Has only effect if packaging is "classpath".
*/
private String configPackage;
/**
* The directory where the source files reside.
*/
private File sourceDir;
/**
* Include patterns for the source files.
* If set, the include and exclude patterns from the templates
* are overridden.
* If not set, then the include patterns from the templates are used.
* The patterns are case sensitive, wildcards are * and ?.
*/
private Set<String> sourceIncludes;
/**
* Exclude patterns for the source files.
* If set, the include and exclude patterns from the templates
* are overridden.
* If not set, then the include patterns from the templates are used.
* The patterns are case sensitive, wildcards are * and ?.
*/
private Set<String> sourceExcludes;
/**
* The target directory for files which are generated each time anew.
* Default is "target/generated-sources"
*/
private File defaultOutputDir = new File("target/generated-sources");
/**
* The target directories for files which are not generated each time anew.
* Default is modifiable -> "./src/main/generated-java"
*/
private Map<String, File> outputDirMap = new HashMap<String, File>();
/**
* The filename of the jar file of the generation unit.
* Has only effect if packaging is "jar".
*/
private String jarFile;
/**
* The config directory of the project overriding the settings.
* If set, the settings of this directory are used as "child"
* and the "normal" settings are used as "parent".
*/
private File overrideConfigDir;
/**
* The Loglevel to use in the generation process. Must be one of
* trace, debug, info, warn or error.
* If not set, the log level defined in the generation unit is used.
*/
private String loglevel;
/**
* Whether to add debug information to the output.
*/
private boolean addDebuggingInfoToOutput = false;
/**
* The encoding which should be used for the files which do not have an
* output encoding set in the templates.
*/
private String defaultOutputEncoding;
/**
* Whether all source files should be combined into one source tree.
* If false, each source file will be read in its own source tree
* and start a new generation run.
* If true, a single source tree with the following structure will be
* built from all source files:
* <source>
* <file path="path/to/file1">
* <rootOfFile1>
* ...
* </rootOfFile1>
* </file>
* <file path="path/to/file2">
* <rootOfFile2>
* ...
* </rootOfFile2>
* </file>
* ...
* </source>
* If not set, the settings from the templates will be used.
*/
private Boolean combineFiles;
/** The list of options for the generation task. */
private final List<Option> options = new ArrayList<Option>();
/**
* Creates a new option and adds it to the list of options.
*
* @return the newly created option.
*/
public Option createOption()
{
Option option = new Option();
options.add(option);
return option;
}
/**
* Runs the generation.
*/
@Override
public void execute() throws BuildException
{
Controller controller = new Controller();
List<UnitDescriptor> unitDescriptors = new ArrayList<UnitDescriptor>();
UnitDescriptor.Packaging packaging;
if ("jar".equals(this.packaging))
{
packaging = UnitDescriptor.Packaging.JAR;
}
else if ("directory".equals(this.packaging))
{
packaging = UnitDescriptor.Packaging.DIRECTORY;
}
else if ("classpath".equals(this.packaging))
{
packaging = UnitDescriptor.Packaging.CLASSPATH;
}
else
{
throw new IllegalArgumentException(
"Unknown packaging " + this.packaging
+ ", must be jar, directory or classpath");
}
log("Packaging is " + packaging, Project.MSG_DEBUG);
ProjectPaths defaultProjectPaths;
if (UnitDescriptor.Packaging.JAR == packaging)
{
defaultProjectPaths
= new Maven2JarProjectPaths(projectRootDir, jarFile);
}
else if (UnitDescriptor.Packaging.DIRECTORY == packaging)
{
defaultProjectPaths
= new Maven2DirectoryProjectPaths(projectRootDir);
}
else if (UnitDescriptor.Packaging.CLASSPATH == packaging)
{
defaultProjectPaths
= new Maven2DirectoryProjectPaths(projectRootDir);
}
else
{
throw new IllegalStateException("Unknown packaging" + packaging);
}
CustomProjectPaths projectPaths
= new CustomProjectPaths(defaultProjectPaths);
if (UnitDescriptor.Packaging.CLASSPATH == packaging)
{
if (configPackage == null)
{
throw new BuildException(
"configPackage must be set for packaging =\"classpath\"");
}
projectPaths.setConfigurationPackage(configPackage);
projectPaths.setConfigurationDir(null);
}
else
{
if (configDir != null)
{
projectPaths.setConfigurationDir(configDir);
log("Setting config dir to " + configDir.toString(),
Project.MSG_DEBUG);
}
}
if (sourceDir != null)
{
projectPaths.setSourceDir(sourceDir);
log("Setting source dir to " + sourceDir.toString(),
Project.MSG_DEBUG);
}
FileSourceProvider fileSourceProvider = null;
if (sourceIncludes != null || sourceExcludes != null)
{
Fileset sourceFileset
= new Fileset(
projectPaths.getDefaultSourcePath(),
sourceIncludes,
sourceExcludes);
log("Setting source includes to " + sourceIncludes,
Project.MSG_DEBUG);
log("Setting source excludes to " + sourceExcludes,
Project.MSG_DEBUG);
try
{
fileSourceProvider = new FileSourceProvider(
null,
sourceFileset,
combineFiles);
}
catch (ConfigurationException e)
{
throw new BuildException(
"The source provider cannot be instantiated", e);
}
}
if (defaultOutputDir != null)
{
projectPaths.setOutputDirectory(null, defaultOutputDir);
log("Setting defaultOutputDir to "
+ defaultOutputDir.getAbsolutePath(),
Project.MSG_DEBUG);
}
if (outputDirMap != null)
{
for (Map.Entry<String, File> dirEntry : outputDirMap.entrySet())
{
projectPaths.setOutputDirectory(
dirEntry.getKey(),
dirEntry.getValue());
log("Setting output directory with key " + dirEntry.getKey()
+ " to "
+ dirEntry.getValue(),
Project.MSG_DEBUG);
}
}
log("ProjectPaths = " + projectPaths, Project.MSG_DEBUG);
OptionsConfiguration optionConfiguration = null;
if (!options.isEmpty())
{
Map<String, String> optionsMap = new HashMap<String, String>();
for (Option option : options)
{
optionsMap.put(option.getKey(), option.getValue());
}
optionConfiguration = new MapOptionsConfiguration(optionsMap);
}
Loglevel convertedLoglevel = null;
if (this.loglevel != null)
{
convertedLoglevel = Loglevel.getByKey(loglevel);
}
UnitDescriptor unitDescriptor = new UnitDescriptor(
packaging,
projectPaths,
new DefaultTorqueGeneratorPaths());
unitDescriptor.setOverrideSourceProvider(fileSourceProvider);
unitDescriptor.setOverrideOptions(optionConfiguration);
unitDescriptor.setLoglevel(convertedLoglevel);
unitDescriptor.setAddDebuggingInfoToOutput(addDebuggingInfoToOutput);
unitDescriptor.setDefaultOutputEncoding(defaultOutputEncoding);
log("unit descriptor created", Project.MSG_DEBUG);
if (overrideConfigDir != null)
{
CustomProjectPaths childProjectPaths
= new CustomProjectPaths(projectPaths);
childProjectPaths.setConfigurationDir(overrideConfigDir);
UnitDescriptor parentUnitDescriptor = new UnitDescriptor(
Packaging.DIRECTORY,
childProjectPaths,
new DefaultTorqueGeneratorPaths());
parentUnitDescriptor.setInheritsFrom(unitDescriptor);
parentUnitDescriptor.setOverrideSourceProvider(fileSourceProvider);
parentUnitDescriptor.setOverrideOptions(optionConfiguration);
parentUnitDescriptor.setLoglevel(convertedLoglevel);
parentUnitDescriptor.setDefaultOutputEncoding(
defaultOutputEncoding);
log("child unit descriptor created",Project.MSG_DEBUG);
unitDescriptor = parentUnitDescriptor;
}
unitDescriptors.add(unitDescriptor);
try
{
log("Generation started", Project.MSG_DEBUG);
controller.run(unitDescriptors);
log("Generation successful", Project.MSG_INFO);
}
catch (Exception e)
{
log("Error during generation", e, Project.MSG_ERR);
throw new BuildException(e.getMessage());
}
}
/**
* Sets the packaging.
*
* @param packaging the packaging, either "jar" or "directory"
*/
public void setPackaging(String packaging)
{
this.packaging = packaging;
}
/**
* Sets the root directory of the project.
*
* @param projectRootDir the project root Directory.
*/
public void setProjectRootDir(File projectRootDir)
{
this.projectRootDir = projectRootDir;
}
public void setConfigDir(File configDir)
{
this.configDir = configDir;
}
public void setConfigPackage(String configPackage)
{
this.configPackage = configPackage;
}
/**
* Sets the default output base directory for generated files.
*
* @param targetDir the default output directory,
* or null to use the default.
*/
public void setDefaultOutputDir(File defaultOutputDir)
{
this.defaultOutputDir = defaultOutputDir;
}
/**
* Sets the mapping from outputDirKey to output directories.
* The outputDirKeys are defined in the templates you use.
*
* @param outputDirMap the new outputDirMap.
*/
public void setOutputDirMap(Map<String, File> outputDirMap)
{
this.outputDirMap = outputDirMap;
}
/**
* The path to the jar file to use.
*
* @param jarFile the jar file, or null.
*/
public void setJarFile(String jarFile)
{
this.jarFile = jarFile;
}
/**
* Sets the directory in which the source files are located.
*
* @param sourceDir the directory in which the source files are located.
*/
public void setSourceDir(File sourceDir)
{
this.sourceDir = sourceDir;
}
/**
* Sets the pattern which files are included in the generation process.
*
* @param sourceIncludes a list containing the include patterns, or null
* if no include pattern should be used.
*/
public void setSourceIncludes(Set<String> sourceIncludes)
{
this.sourceIncludes = sourceIncludes;
}
/**
* Sets the pattern which files are excluded in the generation process.
*
* @param sourceExcludes a list containing the exclude patterns, or null
* if no exclude pattern should be used.
*/
public void setSourceExcludes(Set<String> sourceExcludes)
{
this.sourceExcludes = sourceExcludes;
}
/**
* Sets the config directory overriding the template settings.
* If set, the settings of this directory are used as "child"
* and the "normal" settings are used as "parent".
*
* @parameter the config directory overriding the template settings,
* or null if the template settings will not be overridden.
*/
public void setOverrideConfigDir(File overrideConfigDir)
{
this.overrideConfigDir = overrideConfigDir;
}
/**
* Sets the Loglevel to use in the generation process.
*
* @param loglevel the loglevel, must be one of trace, debug, info, warn
* or error, or null if the loglevel defined in the templates
* should be used.
*/
public void setLoglevel(String loglevel)
{
this.loglevel = loglevel;
}
/**
* Sets whether debugging information should be added to the output.
*
* @param addDebuggingInfoToOutput true if debugging information
* should be added to the output, false otherwise.
*/
public void setAddDebuggingInfoToOutput(boolean addDebuggingInfoToOutput)
{
this.addDebuggingInfoToOutput = addDebuggingInfoToOutput;
}
/**
* Sets the encoding which should be used for the files which do not have
* an output encoding set in the templates.
*
* @param defaultOutputEncoding the default output encoding,
* or null to use the generator default
* (the platform default encoding).
*/
public void setDefaultOutputEncoding(String defaultOutputEncoding)
{
this.defaultOutputEncoding = defaultOutputEncoding;
}
/**
* Sets whether all source files should be combined into one source tree.
* If false, each source file will be read in its own source tree
* and start a new generation run.
* If true, a single source tree with the following structure will be
* built from all source files:
* <source>
* <file path="path/to/file1">
* <rootOfFile1>
* ...
* </rootOfFile1>
* </file>
* <file path="path/to/file2">
* <rootOfFile2>
* ...
* </rootOfFile2>
* </file>
* ...
* </source>
* If not set, the settings from the templates will be used.
*
* @param combineFiles whether all sources should be combined.
*/
public void setCombineFiles(Boolean combineFiles)
{
this.combineFiles = combineFiles;
}
}