/*
* 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.FileWriter;
import java.io.IOException;
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.exolab.castor.xml.schema.Schema;
import org.exolab.castor.xml.schema.util.XMLInstance2Schema;
import org.xml.sax.SAXException;
/**
* An <a href="http://ant.apache.org/">Ant</a> task to call the Castor {@link XMLInstance2Schema}
* tool. 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 XMLInstance2SchemaTask extends MatchingTask {
//--------------------------------------------------------------------------
/**
* Error message -- no input provided.
*/
private static final String NO_XML_DOCUMENT_MSG =
"At least one XML document instance must be provided.";
//--------------------------------------------------------------------------
/**
* Enlists the XML file to process.
*/
private File _xmlInstanceFile;
/**
* Enlists a directory, for which the user wants to process all XML instance files.
**/
private File _xmlInstanceDir;
/**
* Enlists the fileset the user wants to process.
*/
private Vector _xmlInstanceFileSets = new Vector();
// Begin application-specific parameters
/**
* Name of the XML schema file to which the output should be written.
*/
private String _xmlSchemaFileName;
/**
* Default grouping to be <xsd:ALL/>.
*/
private boolean _defaultGroupingAsAll;
//--------------------------------------------------------------------------
/**
* Sets the individual schema that will have code generated for it.
*
* @param file One schema file.
*/
public void setFile(final File file) {
_xmlInstanceFile = 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) {
_xmlInstanceDir = 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) {
_xmlInstanceFileSets.addElement(set);
}
/**
* Specifies the name of the DDL file to be generated.
* @param ddlFileName Name of the DDL file to be generated
*/
public void setXmlSchemaFileName(final String ddlFileName) {
_xmlSchemaFileName = ddlFileName;
}
/**
* Specifies the default grouping to be <xsd:all/>.
* @param defaultGroupingAsAll Default grouping to be used
*/
public void setDefaultGrouping(final String defaultGroupingAsAll) {
_defaultGroupingAsAll = true;
}
//--------------------------------------------------------------------------
/**
* Configured the code generator. If anything goes wrong during configuration of the
* Ant task a BuildException will be thrown.
*/
private void config() {
}
/**
* Runs source generation. If anything goes wrong during source generation a
* BuildException will be thrown.
*
* @param filePath an individual Schema to generate code for.
* @param outputFilePath Name of the output file to create.
*/
private void processFile(final String filePath, final String outputFilePath) {
log("Processing " + filePath);
try {
XMLInstance2Schema schemaGenerator = new XMLInstance2Schema();
if (_defaultGroupingAsAll) {
schemaGenerator.setDefaultGroupingAsAll();
}
Schema schema = schemaGenerator.createSchema(filePath);
String outputFileName = outputFilePath;
if (outputFileName == null) {
outputFileName = deriveOutputFilePath(filePath);
}
FileWriter dstWriter = new FileWriter(outputFileName);
schemaGenerator.serializeSchema(dstWriter, schema);
} catch (IOException e) {
throw new BuildException ("Problem writing to the given putput sink "
+ _xmlInstanceFile.getAbsolutePath(), e);
} catch (SAXException e) {
throw new BuildException ("Problem streaming the generated XML schema instance "
+ "to the given file.", e);
}
}
/**
* Derives the XML schema file name from the XML instance document name.
* @param outputFileName Name of the XML instance document.
* @return The name of the XML schema instance.
*/
private String deriveOutputFilePath(final String outputFileName) {
return outputFileName + ".xsd";
}
/**
* 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 (_xmlInstanceFile == null && _xmlInstanceDir == null
&& _xmlInstanceFileSets.size() == 0) {
throw new BuildException(NO_XML_DOCUMENT_MSG);
}
config();
// process just the file specified
if (_xmlInstanceFile != null) {
processFile(_xmlInstanceFile.getAbsolutePath(), _xmlSchemaFileName);
}
// process all files in the given directory
if (_xmlInstanceDir != null && _xmlInstanceDir.exists() && _xmlInstanceDir.isDirectory()) {
log("Given XML schema file name will be ignored.");
DirectoryScanner ds = this.getDirectoryScanner(_xmlInstanceDir);
String[] files = ds.getIncludedFiles();
for (int i = 0; i < files.length; i++) {
String filePath = _xmlInstanceDir.getAbsolutePath() + File.separator + files[i];
processFile(filePath, null);
}
}
// process all files of the given FileSet
for (int i = 0; i < _xmlInstanceFileSets.size(); i++) {
log("Given XML schema file name will be ignored.");
FileSet fs = (FileSet) _xmlInstanceFileSets.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, null);
}
}
}
}