001: /*
002: * Project: BeautyJ - Customizable Java Source Code Transformer
003: * Class: de.gulden.application.beautyj.BeautyJ
004: * Version: 1.1
005: *
006: * Date: 2004-09-29
007: *
008: * Note: Contains auto-generated Javadoc comments created by BeautyJ.
009: *
010: * This is licensed under the GNU General Public License (GPL)
011: * and comes with NO WARRANTY. See file license.txt for details.
012: *
013: * Author: Jens Gulden
014: * Email: beautyj@jensgulden.de
015: */
016:
017: package de.gulden.application.beautyj;
018:
019: import de.gulden.framework.amoda.environment.commandline.*;
020: import de.gulden.framework.amoda.generic.core.*;
021: import de.gulden.framework.amoda.generic.option.*;
022: import de.gulden.framework.amoda.generic.data.GenericValue;
023: import de.gulden.framework.amoda.model.core.ApplicationEnvironment;
024: import de.gulden.framework.amoda.model.data.*;
025: import de.gulden.framework.amoda.model.option.*;
026: import de.gulden.util.javasource.LogPerformer;
027: import de.gulden.util.javasource.sourclet.*;
028: import de.gulden.util.javasource.jjt.ParseException;
029: import java.io.*;
030: import java.util.*;
031:
032: /**
033: * The BeautyJ main program.
034: * As this class extends CommandLineApplication, which itself
035: * extends GenericApplication, this program can be used as
036: * ANT-task, too. This feature is provided by the wrapper class
037: * <code>de.gulden.application.beautyj.ant.Task</code>.
038: *
039: * @author Jens Gulden
040: * @version 1.1
041: * @see de.gulden.framework.amoda.environment.commandline.CommandLineApplication
042: * @see de.gulden.framework.amoda.environment.ant.ANTTaskApplicationWrapper
043: * @see de.gulden.framework.amoda.model.core.Application
044: * @see de.gulden.application.beautyj.ant.Task
045: */
046: public class BeautyJ extends CommandLineApplication implements
047: SourcletOptions, LogPerformer {
048:
049: // ------------------------------------------------------------------------
050: // --- final static fields ---
051: // ------------------------------------------------------------------------
052:
053: /**
054: * Constant OPTION_SOURCLET.
055: */
056: public static final String OPTION_SOURCLET = "sourclet";
057:
058: /**
059: * Constant OPTION_INPUT.
060: */
061: public static final String OPTION_INPUT = "input";
062:
063: /**
064: * Constant OPTION_OUTDIR.
065: */
066: public static final String OPTION_OUTDIR = "output-directory";
067:
068: /**
069: * Constant OPTION_XML_INPUT.
070: */
071: public static final String OPTION_XML_INPUT = "xml.in";
072:
073: /**
074: * Constant OPTION_XML_VALIDATE.
075: */
076: public static final String OPTION_XML_VALIDATE = "xml.validate";
077:
078: /**
079: * Constant OPTION_XML_OUTPUT.
080: */
081: public static final String OPTION_XML_OUTPUT = "xml.out";
082:
083: /**
084: * Constant OPTION_XML_DOCTYPE.
085: */
086: public static final String OPTION_XML_DOCTYPE = "xml.doctype";
087:
088: /**
089: * Constant MESSAGE_SUCCESS.
090: */
091: public static final String MESSAGE_SUCCESS = "message.success";
092:
093: /**
094: * Constant MESSAGE_XML_CREATED.
095: */
096: public static final String MESSAGE_XML_CREATED = "message.xmlcreated";
097:
098: // ------------------------------------------------------------------------
099: // --- field ---
100: // ------------------------------------------------------------------------
101:
102: /**
103: * Cache for pre-parsed multi-value entries.
104: *
105: * @see #hasOption(String,String)
106: */
107: protected HashMap multiValueCache;
108:
109: // ------------------------------------------------------------------------
110: // --- methods ---
111: // ------------------------------------------------------------------------
112:
113: public void init(ApplicationEnvironment env) {
114: super .init(env);
115: if (getOptions().getBoolean("gui")) {
116: ((GenericOptionEntry) getOptions().getOptionEntry("input"))
117: .setSystem(false); // enable option "-input" (to be able to set one input file or diectory via options-dialog when running in auto-gui-mode)
118: }
119: }
120:
121: /**
122: * <p>
123: * Run code transformation.
124: * </p>
125: * <p>
126: * Called by the application environment.
127: * </p>
128: */
129: public void perform() {
130: // no batch mode or interaction - just one single action
131: Sourclet sourclet = null;
132: Value[] params = getEnvironment().getInputValues();
133: File input = getOptions().getFile(OPTION_INPUT);
134: File outDir = getOptions().getFile(OPTION_OUTDIR);
135: File xmlIn = getOptions().getFile(OPTION_XML_INPUT);
136: File xmlOut = getOptions().getFile(OPTION_XML_OUTPUT);
137: multiValueCache = new HashMap();
138:
139: if (xmlOut == null) { // skip Sourclet if generating XML
140: if (outDir == null) {
141: error("output directory must be specified"
142: + (getOptions().getBoolean("gui") ? ""
143: : " using option '-d'"), null, true);
144: }
145: if (!outDir.isDirectory()) {
146: error(outDir.getAbsolutePath()
147: + " is not a valid output directory.", null,
148: true);
149: }
150: sourclet = (Sourclet) getOptions().getClassInstance(
151: OPTION_SOURCLET);
152: sourclet.init(this );
153: } else { // XML output
154: if (outDir != null) {
155: error(
156: "output directory cannot be specified when using XML output",
157: null, true);
158: }
159: }
160:
161: try {
162: de.gulden.util.javasource.Package pakkage = null;
163: de.gulden.util.javasource.SourceParser.verbose = this
164: .isVerbose()
165: || this .getOptions().getBoolean("gui");
166: de.gulden.util.javasource.SourceParser.logPerformer = this ;
167: boolean test = this .getOptions().getBoolean("test");
168: File[] inFiles = null;
169: if (xmlIn != null) { // get input from XML
170: if (params.length == 0 && input == null) {
171: InputStream in;
172: if (!xmlIn.equals(new File(""))) {
173: in = new FileInputStream(xmlIn);
174: } else {
175: in = System.in;
176: }
177: de.gulden.util.javasource.SourceParser.validateXML = isOption(OPTION_XML_VALIDATE);
178: pakkage = de.gulden.util.javasource.SourceParser
179: .parseXML(in);
180: if (in instanceof FileInputStream) {
181: in.close();
182: }
183: } else {
184: error(
185: "input files or directories cannot be specified when using XML input",
186: null, true);
187: }
188: } else { // input from .java-files
189: if (input != null) {
190: inFiles = new File[] { input };
191: } else if (params.length > 0) {
192: inFiles = new File[params.length];
193: for (int i = 0; i < inFiles.length; i++) {
194: inFiles[i] = params[i].getFile();
195: }
196: } else {
197: error(
198: "nothing to do - please specify at least one input file or directory",
199: null, true);
200: }
201: if (inFiles != null) {
202: pakkage = de.gulden.util.javasource.SourceParser
203: .parse(inFiles, null);
204: }
205: }
206:
207: if (!test) {
208: if (xmlOut == null) {
209: if (pakkage != null) {
210: de.gulden.util.javasource.SourceParser
211: .buildSource(pakkage, outDir, inFiles,
212: sourclet); // build beautified sources
213: getMessage(MESSAGE_SUCCESS).perform();
214: }
215: } else { // XML output
216: de.gulden.util.javasource.SourceParser.includeXMLDoctype = isOption(OPTION_XML_DOCTYPE);
217: org.w3c.dom.Document doc = de.gulden.util.javasource.SourceParser
218: .buildXML(pakkage);
219: OutputStream out;
220: if (!xmlOut.equals(new File(""))) {
221: out = new FileOutputStream(xmlOut);
222: } else {
223: out = System.out;
224: }
225: if ((out instanceof FileOutputStream)
226: && this .isVerbose()) {
227: System.out.println("writing "
228: + xmlOut.getAbsolutePath());
229: }
230: org.apache.xml.serialize.OutputFormat outputFormat = new org.apache.xml.serialize.OutputFormat();
231: outputFormat.setIndenting(true);
232: outputFormat.setPreserveSpace(true);
233: org.apache.xml.serialize.XMLSerializer serializer = new org.apache.xml.serialize.XMLSerializer(
234: out, outputFormat);
235: org.apache.xml.serialize.DOMSerializer domSerializer = serializer
236: .asDOMSerializer();
237: domSerializer.serialize(doc);
238: if (out instanceof FileOutputStream) {
239: out.close();
240: }
241: getMessage(MESSAGE_XML_CREATED).perform();
242: }
243: }
244: } catch (IOException ioe) {
245: error("an i/o exception occurred", ioe, true);
246: } catch (ParseException pe) {
247: error("Java parser error", pe, true);
248: } catch (org.xml.sax.SAXException se) {
249: error("XML parser error", se, true);
250: }
251: }
252:
253: /**
254: * Tests whether the application is set to quiet-mode.
255: */
256: public boolean isQuiet() {
257: File xmlOut = getOptions().getFile(OPTION_XML_OUTPUT);
258: boolean xml_to_stdout = (xmlOut != null)
259: && (xmlOut.equals(new File("")));
260: // always be quiet if xml output on stdout is generated
261: return super .isQuiet() || xml_to_stdout;
262: }
263:
264: /**
265: * Returns a string option.
266: *
267: * @param name option name
268: */
269: public String getOption(String name) {
270: return getOptions().getString(name);
271: }
272:
273: /**
274: * Returns an integer option.
275: *
276: * @param name option name
277: */
278: public int getIntOption(String name) {
279: return getOptions().getInt(name);
280: }
281:
282: /**
283: * Returns a boolean option.
284: *
285: * @param name option name
286: */
287: public boolean isOption(String name) {
288: return getOptions().getBoolean(name);
289: }
290:
291: /**
292: * Tests if an option has a specified value.
293: *
294: * @param name option name
295: * @param value value to test for
296: */
297: public boolean isOption(String name, String value) {
298: return getOptions().getBoolean(name);
299: }
300:
301: /**
302: * Tests if a multi-value option contains a specified value among its set of values.
303: * This uses a comma-sperated string as multi-value set.
304: *
305: * @param name option name
306: * @param value value to test for
307: */
308: public boolean hasOption(String name, String value) {
309: TreeSet cached = (TreeSet) multiValueCache.get(name);
310: if (cached == null) {
311: cached = new TreeSet();
312: String s = getOption(name);
313: if (s != null) {
314: StringTokenizer st = new StringTokenizer(s, ",", false);
315: while (st.hasMoreTokens()) {
316: cached.add(st.nextToken().trim());
317: }
318: }
319: multiValueCache.put(name, cached);
320: }
321: return cached.contains(value);
322: }
323:
324: } // end BeautyJ
|