001: /*
002: * Copyright 2006 Sun Microsystems, Inc. All Rights Reserved.
003: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
004: *
005: * This code is free software; you can redistribute it and/or modify it
006: * under the terms of the GNU General Public License version 2 only, as
007: * published by the Free Software Foundation. Sun designates this
008: * particular file as subject to the "Classpath" exception as provided
009: * by Sun in the LICENSE file that accompanied this code.
010: *
011: * This code is distributed in the hope that it will be useful, but WITHOUT
012: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
013: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
014: * version 2 for more details (a copy is included in the LICENSE file that
015: * accompanied this code).
016: *
017: * You should have received a copy of the GNU General Public License version
018: * 2 along with this work; if not, write to the Free Software Foundation,
019: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
020: *
021: * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
022: * CA 95054 USA or visit www.sun.com if you need additional information or
023: * have any questions.
024: */
025:
026: package com.sun.tools.internal.txw2;
027:
028: import com.sun.codemodel.writer.FileCodeWriter;
029: import com.sun.codemodel.writer.SingleStreamCodeWriter;
030: import com.sun.tools.internal.txw2.model.NodeSet;
031: import org.kohsuke.args4j.CmdLineException;
032: import org.kohsuke.args4j.CmdLineParser;
033: import org.kohsuke.args4j.opts.BooleanOption;
034: import org.kohsuke.args4j.opts.StringOption;
035: import org.kohsuke.rngom.parse.IllegalSchemaException;
036: import org.kohsuke.rngom.parse.Parseable;
037: import org.kohsuke.rngom.parse.compact.CompactParseable;
038: import org.kohsuke.rngom.parse.xml.SAXParseable;
039: import org.xml.sax.ErrorHandler;
040: import org.xml.sax.InputSource;
041: import org.xml.sax.SAXException;
042: import org.xml.sax.SAXParseException;
043:
044: import java.io.File;
045: import java.io.IOException;
046: import java.net.MalformedURLException;
047: import java.util.Properties;
048:
049: /**
050: * Programatic entry point to the TXW compiler.
051: *
052: * @author Kohsuke Kawaguchi (kohsuke.kawaguchi@sun.com)
053: */
054: public class Main {
055: private final TxwOptions opts;
056:
057: public Main(TxwOptions opts) {
058: this .opts = opts;
059: }
060:
061: public static void main(String[] args) {
062: System.exit(run(args));
063: }
064:
065: public static class Options {
066: public StringOption output = new StringOption("-o");
067: public StringOption pkg = new StringOption("-p");
068: public BooleanOption compact = new BooleanOption("-c");
069: public BooleanOption xml = new BooleanOption("-x");
070: public BooleanOption xsd = new BooleanOption("-xsd");
071: public BooleanOption chain = new BooleanOption("-h");
072: }
073:
074: public static int run(String[] args) {
075: Options opts = new Options();
076: CmdLineParser parser = new CmdLineParser();
077: parser.addOptionClass(opts);
078:
079: try {
080: parser.parse(args);
081: } catch (CmdLineException e) {
082: System.out.println(e.getMessage());
083: printUsage();
084: return 1;
085: }
086:
087: TxwOptions topts = new TxwOptions();
088: topts.errorListener = new ConsoleErrorReporter(System.out);
089:
090: if (opts.output.value != null) {
091: try {
092: topts.codeWriter = new FileCodeWriter(new File(
093: opts.output.value));
094: } catch (IOException e) {
095: System.out.println(e.getMessage());
096: printUsage();
097: return 1;
098: }
099: } else {
100: topts.codeWriter = new SingleStreamCodeWriter(System.out);
101: }
102:
103: if (opts.chain.isOn()) {
104: topts.chainMethod = true;
105: }
106:
107: if (opts.pkg.value != null) {
108: topts._package = topts.codeModel._package(opts.pkg.value);
109: } else {
110: topts._package = topts.codeModel.rootPackage();
111: }
112:
113: // make sure that there's only one argument (namely the schema)
114: if (parser.getArguments().size() != 1) {
115: printUsage();
116: return 1;
117: }
118:
119: try {
120: topts.source = makeSourceSchema(parser, opts,
121: topts.errorListener);
122: } catch (MalformedURLException e) {
123: System.out.println(e.getMessage());
124: printUsage();
125: return 1;
126: }
127:
128: return run(topts);
129: }
130:
131: /**
132: * Parses the command line and makes a {@link Parseable} object
133: * out of the specified schema file.
134: */
135: private static SchemaBuilder makeSourceSchema(CmdLineParser parser,
136: Options opts, ErrorHandler eh) throws MalformedURLException {
137: File f = new File((String) parser.getArguments().get(0));
138: final InputSource in = new InputSource(f.toURL()
139: .toExternalForm());
140:
141: if (opts.xsd.isOff() && opts.xml.isOff()
142: && opts.compact.isOff()) {
143: // auto detect
144: if (in.getSystemId().endsWith(".rnc"))
145: opts.compact.value = true;
146: else if (in.getSystemId().endsWith(".rng"))
147: opts.xml.value = true;
148: else
149: opts.xsd.value = true;
150: }
151:
152: if (opts.xsd.isOn())
153: return new XmlSchemaLoader(in);
154:
155: final Parseable parseable = makeRELAXNGSource(opts, in, eh, f);
156:
157: return new RELAXNGLoader(parseable);
158: }
159:
160: private static Parseable makeRELAXNGSource(Options opts,
161: final InputSource in, ErrorHandler eh, File f) {
162: if (opts.compact.isOn())
163: return new CompactParseable(in, eh);
164:
165: if (opts.xml.isOn())
166: return new SAXParseable(in, eh);
167:
168: // otherwise sniff from the file extension
169: if (f.getPath().toLowerCase().endsWith("rnc"))
170: return new CompactParseable(in, eh);
171: else
172: return new SAXParseable(in, eh);
173: }
174:
175: private static void printUsage() {
176: System.out.println("Typed Xml Writer ver." + getVersion());
177: System.out
178: .println("txw <schema file>\n"
179: + " -o <dir> : Specify the directory to place generated source files\n"
180: + " -p <pkg> : Specify the Java package to put the generated classes into\n"
181: + " -c : The input schema is written in the RELAX NG compact syntax\n"
182: + " -x : The input schema is written in the RELAX NG XML syntax\n"
183: + " -xsd : The input schema is written in the XML SChema\n"
184: + " -h : Generate code that allows method invocation chaining\n");
185: }
186:
187: public static int run(TxwOptions opts) {
188: return new Main(opts).run();
189: }
190:
191: private int run() {
192: try {
193: NodeSet ns = opts.source.build(opts);
194: ns.write(opts);
195: opts.codeModel.build(opts.codeWriter);
196: return 0;
197: } catch (IOException e) {
198: opts.errorListener.error(new SAXParseException(e
199: .getMessage(), null, e));
200: return 1;
201: } catch (IllegalSchemaException e) {
202: opts.errorListener.error(new SAXParseException(e
203: .getMessage(), null, e));
204: return 1;
205: } catch (SAXParseException e) {
206: opts.errorListener.error(e);
207: return 1;
208: } catch (SAXException e) {
209: opts.errorListener.error(new SAXParseException(e
210: .getMessage(), null, e));
211: return 1;
212: }
213: }
214:
215: /**
216: * Gets the version number of TXW.
217: */
218: public static String getVersion() {
219: try {
220: Properties p = new Properties();
221: p
222: .load(Main.class
223: .getResourceAsStream("version.properties"));
224: return p.get("version").toString();
225: } catch (Throwable _) {
226: return "unknown";
227: }
228: }
229:
230: }
|