001: package net.sf.saxon;
002:
003: import net.sf.saxon.instruct.TerminationException;
004: import net.sf.saxon.trans.XPathException;
005: import org.xml.sax.InputSource;
006:
007: import javax.xml.transform.Source;
008: import javax.xml.transform.Templates;
009: import javax.xml.transform.TransformerFactoryConfigurationError;
010: import javax.xml.transform.sax.SAXSource;
011: import java.io.*;
012: import java.util.Date;
013:
014: /**
015: * This <B>Compile</B> class provides a command-line interface allowing a
016: * stylesheet to be compiled.<p>
017: *
018: * @author M.H.Kay
019: */
020:
021: public class Compile {
022:
023: private TransformerFactoryImpl factory = new TransformerFactoryImpl();
024:
025: private boolean showTime = false;
026: private boolean debug = false;
027:
028: /**
029: * Main program, can be used directly from the command line.
030: * <p>The format is:</P>
031: * <p>java net.sf.saxon.Compile [options] <I>style-file</I> <I>output-file</I></P>
032: * <p>This program compiles the XSL style sheet in style-file to the output-file.</p>
033: *
034: * @param args Arguments supplied on the command line
035: * @exception java.lang.Exception Any compilation error occurs
036: */
037:
038: public static void main(String args[]) throws java.lang.Exception {
039: // the real work is delegated to another routine so that it can be used in a subclass
040: (new Compile()).doMain(args);
041: }
042:
043: /**
044: * Support method for main program. This support method can also be invoked from subclasses
045: * that support the same command line interface
046: *
047: * @param args the command-line arguments
048: */
049:
050: protected void doMain(String args[]) {
051:
052: String styleFileName;
053: boolean useURLs = false;
054: String outputFileName;
055:
056: // Check the command-line arguments.
057:
058: try {
059: int i = 0;
060: while (true) {
061: if (i >= args.length)
062: badUsage("No stylesheet file name");
063:
064: if (args[i].charAt(0) == '-') {
065:
066: if (args[i].equals("-u")) {
067: useURLs = true;
068: i++;
069: }
070:
071: else if (args[i].equals("-t")) {
072: System.err.println(factory.getConfiguration()
073: .getProductTitle());
074: System.err.println("Java version "
075: + System.getProperty("java.version"));
076: factory.setAttribute(FeatureKeys.TIMING,
077: Boolean.TRUE);
078:
079: //Loader.setTracing(true);
080: showTime = true;
081: i++;
082: }
083:
084: else if (args[i].equals("-y")) {
085: i++;
086: if (args.length < i + 2)
087: badUsage("No style parser class");
088: String styleParserName = args[i++];
089: factory.setAttribute(
090: FeatureKeys.STYLE_PARSER_CLASS,
091: styleParserName);
092: }
093:
094: else if (args[i].equals("-r")) {
095: i++;
096: if (args.length < i + 2)
097: badUsage("No URIResolver class");
098: String r = args[i++];
099: factory.setURIResolver(factory
100: .getConfiguration().makeURIResolver(r));
101: }
102:
103: else if (args[i].equals("-debug")) {
104: i++;
105: debug = true;
106: }
107:
108: else if (args[i].equals("-1.1")) { // XML 1.1
109: i++;
110: factory.setAttribute(FeatureKeys.XML_VERSION,
111: "1.1");
112: }
113:
114: else
115: badUsage("Unknown option " + args[i]);
116: }
117:
118: else
119: break;
120: }
121:
122: if (args.length < i + 1)
123: badUsage("No stylesheet file name");
124: styleFileName = args[i++];
125:
126: if (args.length < i + 1)
127: badUsage("No output file name");
128: outputFileName = args[i++];
129:
130: long startTime = (new Date()).getTime();
131:
132: Source styleSource;
133: if (useURLs || styleFileName.startsWith("http:")
134: || styleFileName.startsWith("file:")) {
135: styleSource = factory.getURIResolver().resolve(
136: styleFileName, null);
137: if (styleSource == null) {
138: styleSource = factory.getConfiguration()
139: .getSystemURIResolver().resolve(
140: styleFileName, null);
141: }
142:
143: } else {
144: File sheetFile = new File(styleFileName);
145: if (!sheetFile.exists()) {
146: quit("Stylesheet file " + sheetFile
147: + " does not exist", 2);
148: }
149: InputSource eis = new InputSource(sheetFile.toURL()
150: .toString());
151: styleSource = new SAXSource(factory.getConfiguration()
152: .getStyleParser(), eis);
153: }
154:
155: if (styleSource == null) {
156: quit(
157: "URIResolver for stylesheet file must return a Source",
158: 2);
159: }
160:
161: Templates sheet = factory.newTemplates(styleSource);
162:
163: if (showTime) {
164: long endTime = (new Date()).getTime();
165: System.err.println("Stylesheet compilation time: "
166: + (endTime - startTime) + " milliseconds");
167: }
168:
169: try {
170: String msg = ((PreparedStylesheet) sheet)
171: .getExecutable().getReasonUnableToCompile();
172: if (msg != null) {
173: System.err.println(msg);
174: quit("Unable to compile stylesheet", 2);
175: }
176: System.err.println("Serializing compiled stylesheet");
177: ((PreparedStylesheet) sheet)
178: .setTargetNamePool(((PreparedStylesheet) sheet)
179: .getConfiguration().getNamePool());
180: OutputStream fos = new FileOutputStream(outputFileName);
181: if (debug) {
182: fos = new TracingObjectOutputStream(fos);
183: }
184: ObjectOutputStream oos = new ObjectOutputStream(fos);
185: oos.writeObject(sheet);
186: oos.close();
187: System.err.println("Finished serializing stylesheet");
188: } catch (Exception err) {
189: err.printStackTrace();
190: }
191:
192: } catch (TerminationException err) {
193: quit(err.getMessage(), 1);
194: } catch (XPathException err) {
195: quit("Transformation failed: " + err.getMessage(), 2);
196: } catch (TransformerFactoryConfigurationError err) {
197: quit("Transformation failed: " + err.getMessage(), 2);
198: } catch (Exception err2) {
199: err2.printStackTrace();
200: }
201:
202: }
203:
204: /**
205: * Exit with a message
206: *
207: * @param message Message to be output
208: * @param code Result code to be returned to the operating system
209: */
210:
211: protected static void quit(String message, int code) {
212: System.err.println(message);
213: System.exit(code);
214: }
215:
216: /** Output error message when incorrect command line options/arguments are used
217: *
218: * @param message Error message to be displayed
219: */
220: protected void badUsage(String message) {
221: System.err.println(message);
222: System.err
223: .println(factory.getConfiguration().getProductTitle());
224: System.err
225: .println("Usage: java net.sf.saxon.Compile [options] stylesheet-file output-file");
226: System.err.println("Options: ");
227: System.err
228: .println(" -r classname Use specified URIResolver class");
229: System.err
230: .println(" -t Display version and timing information");
231: System.err
232: .println(" -u Names are URLs not filenames");
233: System.err
234: .println(" -y classname Use specified SAX parser for stylesheet");
235: System.err
236: .println(" -debug Produce trace output to diagnose failures");
237: System.err.println(" -1.1 Allow XML 1.1 documents");
238: System.err.println(" -? Display this message ");
239: System.exit(2);
240: }
241:
242: /**
243: * Tracing version of ObjectOutputStream for diagnostics
244: */
245:
246: private static class TracingObjectOutputStream extends
247: FilterOutputStream {
248:
249: OutputStream oos;
250:
251: public TracingObjectOutputStream(OutputStream oos) {
252: super (oos);
253: this .oos = oos;
254: }
255:
256: public void write(byte b[]) throws IOException {
257: char[] chars = new char[b.length];
258: for (int i = 0; i < b.length; i++) {
259: chars[i] = (char) b[i];
260: }
261: String s = new String(chars);
262: if (s.indexOf("saxon") >= 0) {
263: System.err.println("write byte[]: " + s);
264: }
265: super .write(b);
266: }
267:
268: /**
269: * Writes <code>len</code> bytes from the specified
270: * <code>byte</code> array starting at offset <code>off</code> to
271: * this output stream.
272: * <p/>
273: * The <code>write</code> method of <code>FilterOutputStream</code>
274: * calls the <code>write</code> method of one argument on each
275: * <code>byte</code> to output.
276: * <p/>
277: * Note that this method does not call the <code>write</code> method
278: * of its underlying input stream with the same arguments. Subclasses
279: * of <code>FilterOutputStream</code> should provide a more efficient
280: * implementation of this method.
281: *
282: * @param b the data.
283: * @param off the start offset in the data.
284: * @param len the number of bytes to write.
285: * @throws java.io.IOException if an I/O error occurs.
286: * @see java.io.FilterOutputStream#write(int)
287: */
288: public void write(byte b[], int off, int len)
289: throws IOException {
290: char[] chars = new char[len];
291: for (int i = 0; i < len; i++) {
292: chars[i] = (char) b[i + off];
293: }
294: String s = new String(chars);
295: if (s.indexOf("saxon") >= 0) {
296: System.err.println("write byte[]: " + s);
297: }
298: super .write(b, off, len);
299: }
300:
301: /**
302: * Writes the specified <code>byte</code> to this output stream.
303: * <p/>
304: * The <code>write</code> method of <code>FilterOutputStream</code>
305: * calls the <code>write</code> method of its underlying output stream,
306: * that is, it performs <tt>out.write(b)</tt>.
307: * <p/>
308: * Implements the abstract <tt>write</tt> method of <tt>OutputStream</tt>.
309: *
310: * @param b the <code>byte</code>.
311: * @throws java.io.IOException if an I/O error occurs.
312: */
313: // public void write(int b) throws IOException {
314: // char c = (char)b;
315: // System.err.println("write byte: " + c);
316: // super.write(b);
317: // }
318: }
319:
320: }
321:
322: //
323: // The contents of this file are subject to the Mozilla Public License Version 1.0 (the "License");
324: // you may not use this file except in compliance with the License. You may obtain a copy of the
325: // License at http://www.mozilla.org/MPL/
326: //
327: // Software distributed under the License is distributed on an "AS IS" basis,
328: // WITHOUT WARRANTY OF ANY KIND, either express or implied.
329: // See the License for the specific language governing rights and limitations under the License.
330: //
331: // The Original Code is: all this file.
332: //
333: // The Initial Developer of the Original Code is Michael H. Kay.
334: //
335: // Portions created by (your name) are Copyright (C) (your legal entity). All Rights Reserved.
336: //
337: // Contributor(s): none.
338: //
|