/*
* Copyright 2003, 2004 The Apache Software Foundation
*
* 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.apache.ws.jaxme.generator;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import org.apache.ws.jaxme.generator.impl.GeneratorImpl;
import org.apache.ws.jaxme.generator.sg.SGFactoryChain;
import org.apache.ws.jaxme.generator.sg.impl.JAXBSchemaReader;
/** <p>A command line interface for the JaxMe source generator.</p>
* <p><em>Implementation note</em>: If you update this class, you
* should consider updating the following files and classes as
* well:
* <ul>
* <li>{@link Generator}</li>
* <li>{@link XJCTask}</li>
* <li>docs/Reference.html</li>
* </ul></p>
*
* @author <a href="mailto:joe@ispsoft.de">Jochen Wiedmann</a>
*/
public class Main {
/** <p>Prints the Usage message and exits with error status.</p>
*/
public static void Usage(String msg) {
if (msg != null) {
System.err.println(msg);
System.err.println();
}
java.io.PrintStream ps = System.err;
ps.println("Usage: " + Main.class.getName() + " <inputfile> [options]");
ps.println();
ps.println("Reads a schema definition from the given <inputfile>");
ps.println("Possible options are:");
ps.println(" --force Force overwriting files");
ps.println(" --schemaReader=<class> Sets the SchemaReader class; defaults to");
ps.println(" " + JAXBSchemaReader.class.getName());
ps.println(" --sgFactoryChain=<class> Adds an instance of <class> to the");
ps.println(" generation process.");
ps.println(" --logFile=<filename> Sets a logfile for debugging purposes.");
ps.println(" By default System.err is used.");
ps.println(" --logLevel=<level> Sets the default logging level.");
ps.println(" Possible levels are fatal, error (default),");
ps.println(" warn, info and debug");
ps.println(" --option=<name=value> Sets the option <name> to the given <value>.");
ps.println(" --package=<name> Sets the package of the generated sources to");
ps.println(" <name>.");
ps.println(" --target=<dir> Sets the directory where to generate");
ps.println(" sources. By default the current directory");
ps.println(" is used.");
ps.println(" --validating Turns the XML parsers validation on.");
System.exit(1);
}
/**
* @param args the command line arguments
*/
public static void main (String args[]) throws Exception {
java.io.File schemaFile = null;
Generator g = new GeneratorImpl();
String schemaReaderClass = JAXBSchemaReader.class.getName();
String target = null;
String logFile = null;
String logLevel = null;
String packageName = null;
List sgFactoryChains = new ArrayList();
for (int i = 0; i < args.length; i++) {
String arg = args[i];
if (arg.equals("--")) {
for (int j = i; j < args.length; j++) {
if (schemaFile != null) {
Usage("Only one input file may be specified.");
}
schemaFile = new java.io.File(args[j]);
}
break;
}
if (arg.startsWith("--")) {
arg = arg.substring(1);
}
if (arg.startsWith("-")) {
arg = arg.substring(1);
int optIndex = arg.indexOf('=');
String opt = null;
if (optIndex > 0) {
opt = arg.substring(optIndex+1);
arg = arg.substring(0, optIndex);
}
if (arg.equalsIgnoreCase("force")) {
g.setForcingOverwrite(true);
} else if (arg.equalsIgnoreCase("schemaReader")) {
if (logLevel != null) {
Usage("The option " + arg + " may be used only once.");
}
if (opt == null) {
if (i == args.length) {
Usage("Missing argument for option " + arg);
}
opt = args[++i];
}
schemaReaderClass = opt;
} else if (arg.equalsIgnoreCase("logFile")) {
if (logFile != null) {
Usage("The option " + arg + " may be used only once.");
}
if (opt == null) {
if (i == args.length) {
Usage("Missing argument for option " + arg);
}
opt = args[++i];
}
logFile = opt;
} else if (arg.equalsIgnoreCase("package")) {
if (packageName != null) {
Usage("The option " + arg + " may be used only once.");
}
if (opt == null) {
if (i == args.length) {
Usage("Missing argument for option " + arg);
}
opt = args[++i];
}
packageName = opt;
g.setProperty("jaxme.package.name", packageName);
} else if (arg.equalsIgnoreCase("logLevel")) {
if (logLevel != null) {
Usage("The option " + arg + " may be used only once.");
}
if (opt == null) {
if (i == args.length) {
Usage("Missing argument for option " + arg);
}
opt = args[++i];
}
logLevel = opt;
} else if (arg.equalsIgnoreCase("target")) {
if (target != null) {
Usage("The option " + arg + " may be used only once.");
}
if (opt == null) {
if (i == args.length) {
Usage("Missing argument for option " + arg);
}
opt = args[++i];
}
target = opt;
} else if (arg.equalsIgnoreCase("option")) {
if (opt == null) {
if (i == args.length) {
Usage("Missing argument for option " + arg);
}
opt = args[++i];
}
int offset = opt.indexOf('=');
if (offset < 1) {
System.err.println("Failed to parse option definition " + opt);
System.err.println("Must be like --option=name=value or");
System.err.println("--option=name=target=value");
System.err.println();
Usage(null);
}
String optName = opt.substring(0, offset);
String optValue = opt.substring(offset+1);
g.setProperty(optName, optValue);
} else if (arg.equalsIgnoreCase("validating")) {
g.setValidating(true);
} else if ("sgFactoryChain".equals(arg)) {
if (opt == null) {
if (i == args.length) {
Usage("Missing argument for option " + arg);
}
opt = args[++i];
}
Class c = null;
try {
c = Class.forName(opt);
} catch (ClassNotFoundException e) {
try {
c = Thread.currentThread().getContextClassLoader().loadClass(opt);
} catch (ClassNotFoundException f) {
System.err.println("Failed to load class " + opt);
System.exit(1);
}
}
if (!SGFactoryChain.class.isAssignableFrom(c)) {
System.err.println("The SGFactoryChain implementation " + c.getName() +
" is not implementing " + SGFactoryChain.class.getName());
}
sgFactoryChains.add(c);
} else if (arg.equalsIgnoreCase("h") || arg.equalsIgnoreCase("help") ||
arg.equalsIgnoreCase("?")) {
Usage(null);
} else {
Usage("Unknown option name: " + arg);
}
} else if (schemaFile != null) {
Usage("Only one input file may be specified.");
} else {
schemaFile = new java.io.File(args[i]);
}
}
if (schemaFile == null) {
Usage("A Schema file must be specified");
}
SchemaReader sr = null;
try {
Class c = Class.forName(schemaReaderClass);
sr = (SchemaReader) c.newInstance();
g.setSchemaReader(sr);
sr.setGenerator(g);
} catch (ClassNotFoundException e) {
System.err.println("Could not find SchemaReader class " + schemaReaderClass);
System.exit(1);
} catch (ClassCastException e) {
System.err.println("Class " + schemaReaderClass +
" is not implementing " + SchemaReader.class.getName());
System.exit(1);
} catch (InstantiationException e) {
System.err.println("Failed to instantiate SchemaReader class " + schemaReaderClass);
System.exit(1);
} catch (IllegalAccessException e) {
System.err.println("Illegal access to SchemaReader class " + schemaReaderClass);
System.exit(1);
}
if (sgFactoryChains.size() > 0) {
if (!(sr instanceof JAXBSchemaReader)) {
System.err.println("Additional instances of " + SGFactoryChain.class.getName()
+ " may be specified only, if the schema reader is an instance of "
+ JAXBSchemaReader.class.getName());
System.exit(1);
}
JAXBSchemaReader jsr = (JAXBSchemaReader) sr;
for (int i = 0; i < sgFactoryChains.size(); i++) {
jsr.addSGFactoryChain((Class) sgFactoryChains.get(i));
}
}
if (target != null) {
g.setTargetDirectory(new File(target));
}
try {
g.generate(schemaFile);
} catch (Exception e) {
e.printStackTrace();
System.exit(1);
}
System.exit(0); // Explicit System.exit, so that hsqldb closes nicely
}
}