001: /*
002: * Enhydra Java Application Server Project
003: *
004: * The contents of this file are subject to the Enhydra Public License
005: * Version 1.1 (the "License"); you may not use this file except in
006: * compliance with the License. You may obtain a copy of the License on
007: * the Enhydra web site ( http://www.enhydra.org/ ).
008: *
009: * Software distributed under the License is distributed on an "AS IS"
010: * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
011: * the License for the specific terms governing rights and limitations
012: * under the License.
013: *
014: * The Initial Developer of the Enhydra Application Server is Lutris
015: * Technologies, Inc. The Enhydra Application Server and portions created
016: * by Lutris Technologies, Inc. are Copyright Lutris Technologies, Inc.
017: * All Rights Reserved.
018: *
019: * Contributor(s):
020: * Paul Mahar
021: *
022: */
023: package org.enhydra.kelp.common.xmlc;
024:
025: // Kelp imports
026: import org.enhydra.kelp.common.bridge.Generator;
027: import org.enhydra.kelp.common.bridge.Parser;
028: import org.enhydra.kelp.common.bridge.PrintInfo;
029: import org.enhydra.kelp.common.bridge.XMLCConnectionFactory;
030: import org.enhydra.kelp.common.node.OtterXMLCNode;
031:
032: // Enhydra imports
033: import org.enhydra.xml.xmlc.commands.xmlc.*;
034: import org.enhydra.xml.xmlc.commands.options.*;
035: import org.enhydra.xml.xmlc.compiler.EditDOM;
036: import org.enhydra.xml.xmlc.dom.XMLCDocument;
037: import org.enhydra.xml.xmlc.parsers.*;
038: import org.enhydra.xml.xmlc.XMLCUtil;
039: import org.enhydra.xml.xmlc.XMLCVersion;
040: import org.enhydra.xml.xmlc.XMLCException;
041: import org.w3c.dom.*;
042: import org.xml.sax.SAXException;
043:
044: // Standard imports
045: import java.io.*;
046: import java.lang.reflect.Constructor;
047: import java.lang.reflect.Method;
048: import java.util.Enumeration;
049: import java.util.Hashtable;
050: import java.util.Vector;
051: import java.util.ResourceBundle;
052:
053: /**
054: * Class derived from the XMLC compiler program for use in this wizard.
055: * TODO: Mark may change some things that will require changes to this class.
056: */
057: public class XMLCRunner {
058:
059: // string not to be resourced
060: static ResourceBundle res = ResourceBundle
061: .getBundle("org.enhydra.kelp.common.Res"); // nores
062: private final String JAVA_LANG = "java.lang."; // nores
063:
064: /*
065: * Object containing the parsed standard options.
066: */
067: private OtterXMLCNode node;
068:
069: /*
070: * Document being compiled.
071: */
072: private Document document;
073:
074: /*
075: * Trace and verbose output.
076: */
077: private PrintWriter traceWriter = new PrintWriter(System.err, true);
078:
079: /*
080: * XML DOM management object.
081: */
082: private XMLCDocument xmlcDoc;
083:
084: /**
085: * Constructor declaration
086: *
087: *
088: * @see
089: */
090: public XMLCRunner() {
091: }
092:
093: /**
094: * Method declaration
095: *
096: *
097: * @param tw
098: *
099: * @see
100: */
101: public void setTraceWriter(PrintWriter tw) {
102: traceWriter = tw;
103: }
104:
105: /**
106: * Method declaration
107: *
108: *
109: * @return
110: *
111: * @see
112: */
113: public PrintWriter getTraceWriter() {
114: return traceWriter;
115: }
116:
117: /*
118: * Print out a stack trace. This works around bugs in SAXException that
119: * cause printing a stack trace to generate a null pointer exception. We
120: * can't just fix this in the OpenXML source (we did), because other
121: * parsers include that same broken class.
122: */
123:
124: /**
125: * Method declaration
126: *
127: *
128: * @param except
129: *
130: * @see
131: */
132: private void printStackTrace(Throwable except) {
133:
134: // FIXME: needed???
135: if (except instanceof SAXException) {
136: Exception except2 = ((SAXException) except).getException();
137:
138: if (except2 != null) {
139: except2.printStackTrace();
140: return;
141: }
142: }
143: except.printStackTrace();
144: }
145:
146: /*
147: * Handle an exception, printing the approriate error
148: * message.
149: */
150:
151: /**
152: * Method declaration
153: *
154: *
155: * @param except
156: *
157: * @see
158: */
159: public void printException(Throwable except) {
160: except.printStackTrace();
161:
162: // Must check that options have been parsed before using them.
163: if (except instanceof XMLCException) {
164: System.err.println(res.getString("Error_")
165: + except.getMessage());
166: if ((node.getMetaDataHandler() != null)
167: && (node.getMetaDataHandler().getVerbose())) {
168: printStackTrace(except);
169: }
170:
171: // If this is result of a java.lang exception, print stack.
172: Throwable cause = ((XMLCException) except).getCause();
173:
174: if ((cause != null)
175: && cause.getClass().getName().startsWith(JAVA_LANG)) {
176: printStackTrace(cause);
177: }
178: } else if ((except instanceof FileNotFoundException)
179: || (except instanceof IOException)) {
180: System.err.println(res.getString("Error_")
181: + except.getClass().getName()
182: + res.getString("LineEnd") + except.getMessage());
183: if ((node.getMetaDataHandler() != null)
184: && (node.getMetaDataHandler().getVerbose())) {
185: printStackTrace(except);
186: }
187: } else {
188: System.err.println(res.getString("Error_")
189: + except.getClass().getName()
190: + res.getString("LineEnd") + except.getMessage());
191: printStackTrace(except);
192: }
193: System.exit(1);
194: }
195:
196: /*
197: * Parse the page into the DOM and perform various checks and edits.
198: */
199:
200: /**
201: * Method declaration
202: *
203: *
204: * @throws FileNotFoundException
205: * @throws IOException
206: * @throws SAXException
207: * @throws XMLCException
208: *
209: * @see
210: */
211:
212: /*
213: * Parse the page into the DOM and perform various checks and edits.
214: */
215: private void parsePage() throws Throwable {
216: if (node.getMetaDataHandler().getVerbose()) {
217: traceWriter.println(res.getString("_parsing")
218: + node.getMetaDataHandler().getInputDocument());
219: }
220: Parser parser = null;
221:
222: parser = XMLCConnectionFactory.createParser(traceWriter, node
223: .getMetaDataHandler());
224: xmlcDoc = (XMLCDocument) parser.parse();
225: document = xmlcDoc.getDocument();
226: if (node.getMetaDataHandler().getPrintDocumentInfo()) {
227: if (node.getMetaDataHandler().getVerbose()) {
228: traceWriter
229: .println(res.getString("_printing_document"));
230: }
231: PrintInfo info = XMLCConnectionFactory.createPrintInfo(
232: document, xmlcDoc);
233:
234: info.printInfo(traceWriter);
235: }
236: EditDOM editDOM = null;
237:
238: editDOM = XMLCConnectionFactory.createEditDOM(node
239: .getMetaDataHandler());
240: editDOM.edit(xmlcDoc);
241: if (node.getMetaDataHandler().getPrintDOM()) {
242: if (node.getMetaDataHandler().getVerbose()) {
243: traceWriter.println(res.getString("_dumping_document"));
244: }
245: XMLCUtil.printNode(res.getString("DOM_hierarchy"),
246: document, XMLCUtil.PRINT_ALL, traceWriter);
247: }
248: }
249:
250: /*
251: * Generate the Java source files.
252: */
253:
254: /**
255: * Method declaration
256: *
257: *
258: * @exception IOException
259: * @exception XMLCException
260: *
261: * @see
262: */
263: private void generateJavaSource() throws XMLCException, IOException {
264: PrintWriter accessorWriter = null;
265: PrintWriter verboseWriter = null;
266: Generator codeGen = null;
267:
268: if (node.getMetaDataHandler().getPrintAccessorInfo()) {
269: accessorWriter = traceWriter;
270: }
271: if (node.getMetaDataHandler().getVerbose()) {
272: traceWriter.println(res.getString("_generating_code"));
273: verboseWriter = traceWriter;
274: }
275: codeGen = XMLCConnectionFactory.createGenerator(node
276: .getMetaDataHandler(), xmlcDoc, accessorWriter);
277: codeGen.generateJavaSource(verboseWriter);
278: }
279:
280: /*
281: * Generate method information without generating code.
282: */
283:
284: /**
285: * Method declaration
286: *
287: *
288: * @exception IOException
289: * @exception XMLCException
290: *
291: * @see
292: */
293: private void generateJavaSourceInfo() throws XMLCException,
294: IOException {
295: if (node.getMetaDataHandler().getVerbose()) {
296: traceWriter.println(res.getString("_generating_code_info"));
297: }
298: Generator codeGen = XMLCConnectionFactory
299: .createGenerator(node.getMetaDataHandler(), xmlcDoc,
300: (node.getMetaDataHandler()
301: .getPrintAccessorInfo() ? traceWriter
302: : null));
303:
304: codeGen.generateJavaSource(node.getMetaDataHandler()
305: .getVerbose() ? traceWriter : null);
306: }
307:
308: /**
309: * Write the DOM to a file.
310: */
311: private void writeDOM() throws IOException {
312: File outputFile = new File(node.getMetaDataHandler()
313: .getDocumentOutput());
314: String dir = outputFile.getParent();
315:
316: if (dir != null) {
317: new File(dir).mkdirs();
318: }
319: PrintWriter domOut = new PrintWriter(new BufferedOutputStream(
320: new FileOutputStream(node.getMetaDataHandler()
321: .getDocumentOutput())));
322:
323: try {
324: domOut.println(xmlcDoc.toDocument());
325: } finally {
326: domOut.close();
327: }
328: }
329:
330: /*
331: * Generate the Jave source and Compile the page.
332: */
333:
334: /**
335: * Method declaration
336: *
337: *
338: * @exception FileNotFoundException
339: * @exception IOException
340: * @exception XMLCException
341: *
342: * @see
343: */
344: private void compilePage() throws XMLCException,
345: FileNotFoundException, IOException {
346: generateJavaSource();
347:
348: // do not compile Java and always check for recomp.
349: if (node.getMetaDataHandler().getRecompilation()) {
350: File op = node.getOptionFileForRecomp();
351:
352: if (!op.getParentFile().exists()) {
353: op.getParentFile().mkdirs();
354: }
355: node.getMetaDataHandler().save(
356: node.getOptionFileForRecomp());
357:
358: // node.getMetaDataHandler().getMetaData().getMetaDataDocument().serialize();
359: }
360:
361: // do not compile Java
362: // never delete source.
363: }
364:
365: /**
366: * Print the XMLC version number.
367: */
368: private void printVersion() {
369: System.out.println(res.getString("Enhydra_XMLC_version")
370: + XMLCVersion.VERSION);
371: System.out.println(res.getString("See_http_www_enhydra"));
372: }
373:
374: /*
375: * Parse arguments and compile the page.
376: */
377:
378: /**
379: * Method declaration
380: *
381: *
382: * @throws FileNotFoundException
383: * @throws IOException
384: * @throws SAXException
385: * @throws XMLCException
386: *
387: * @see
388: */
389: public void compile() throws Throwable {
390:
391: // Setup and document parsing.
392: node.initProjectOptions();
393: if (node.getMetaDataHandler().getPrintVersion()) {
394: printVersion();
395: if (node.getMetaDataHandler().getInputDocument() == null) {
396: return;
397: }
398: }
399: parsePage();
400: if (node.getMetaDataHandler().getDocumentOutput() == null) {
401: compilePage();
402: } else {
403: if (node.getMetaDataHandler().getPrintAccessorInfo()) {
404: generateJavaSourceInfo();
405: }
406: writeDOM();
407: }
408: if (node.getMetaDataHandler().getVerbose()) {
409: traceWriter.println(res.getString("_completed"));
410: }
411: }
412:
413: /**
414: * Method declaration
415: *
416: *
417: * @param cn
418: *
419: * @see
420: */
421: public void setNode(OtterXMLCNode n) {
422: node = n;
423: }
424:
425: }
|