001: package de.java2html.anttasks;
002:
003: import java.io.File;
004: import java.io.FileWriter;
005: import java.io.IOException;
006: import java.io.Writer;
007:
008: import de.java2html.converter.IJavaSourceConverter;
009: import de.java2html.converter.JavaSourceConverterProvider;
010: import de.java2html.javasource.JavaSource;
011: import de.java2html.javasource.JavaSourceParser;
012: import de.java2html.options.ConversionOptionsUtilities;
013: import de.java2html.options.HorizontalAlignment;
014: import de.java2html.options.JavaSourceConversionOptions;
015: import de.java2html.options.JavaSourceStyleTable;
016: import de.java2html.util.IoUtilities;
017:
018: import org.apache.tools.ant.BuildException;
019: import org.apache.tools.ant.DirectoryScanner;
020: import org.apache.tools.ant.Project;
021: import org.apache.tools.ant.taskdefs.MatchingTask;
022: import org.apache.tools.ant.util.FileNameMapper;
023: import org.apache.tools.ant.util.GlobPatternMapper;
024: import org.apache.tools.ant.util.SourceFileScanner;
025:
026: /**
027: * Runs the java2html converter as a task inside the well known build tool
028: * "ant" (see ant.apache.org).
029: *
030: * Thanks to <a href="mailto:markus@jave.de">Markus Gebhard</a>, the author
031: * of java2html itself. I contribute this code to the project under the same
032: * license as java2html.
033: *
034: * For an example for a <code>build.xml</code> containing this task have a
035: * look at the docs/anttask/ folder.
036: *
037: * @author <a href="mailto:mbohlen@mbohlen.de">Matthias Bohlen</a>
038: * @author <a href="mailto:markus@jave.de">Markus Gebhard</a>
039: */
040: public class Java2HtmlTask extends MatchingTask {
041: private String style = JavaSourceConversionOptions.getDefault()
042: .getStyleTable().getName();
043: private File srcDir;
044: private File destDir;
045: private boolean overwrite = false;
046: private String outputFormat = JavaSourceConverterProvider
047: .getDefaultConverterName();
048: private int tabs = JavaSourceConversionOptions.getDefault()
049: .getTabSize();
050: private boolean showLineNumbers = JavaSourceConversionOptions
051: .getDefault().isShowLineNumbers();
052: private boolean showDefaultTitle = false;
053: private boolean addLineAnchors = false;
054: private String lineAnchorPrefix = "";
055: private boolean showTableBorder = false;
056: private boolean showFileName = false;
057: private boolean includeDocumentHeader = true;
058: private boolean includeDocumentFooter = true;
059: private boolean useShortFileName = false;
060: private String horizontalAlignment = JavaSourceConversionOptions
061: .getDefault().getHorizontalAlignment().getName();
062:
063: /**
064: * Sets the directory where the Java sources are stored.
065: *
066: * @param srcDir
067: * directory name
068: */
069: public void setSrcDir(File srcDir) {
070: this .srcDir = srcDir;
071: }
072:
073: /**
074: * Sets the directory where the output is written.
075: *
076: * @param destDir
077: * directory name
078: */
079: public void setDestDir(File destDir) {
080: this .destDir = destDir;
081: }
082:
083: /**
084: * Sets the output format.
085: *
086: * @param outputFormat
087: * the output format identifier ("html", "xhtml", "latex")
088: */
089: public void setOutputFormat(String outputFormat) {
090: this .outputFormat = outputFormat;
091: }
092:
093: /**
094: * @see org.apache.tools.ant.Task#execute()
095: */
096: public void execute() throws BuildException {
097: if (srcDir == null) {
098: // We directly change the user variable, because it
099: // shouldn't lead to problems
100: srcDir = project.resolveFile(".");
101: }
102:
103: // find the files/directories
104: DirectoryScanner dirScanner = getDirectoryScanner(srcDir);
105:
106: // get a list of files to work on
107: String[] allSourceFiles = dirScanner.getIncludedFiles();
108:
109: IJavaSourceConverter converter = getConverter();
110: JavaSourceConversionOptions options = getConversionOptions();
111: SourceFileScanner sourceScanner = new SourceFileScanner(this );
112:
113: String[] sourceFilesToProcess;
114: if (isOverwrite()) {
115: sourceFilesToProcess = allSourceFiles;
116: } else {
117: FileNameMapper sourceToOutMapper = new GlobPatternMapper();
118: sourceToOutMapper.setFrom("*");
119: sourceToOutMapper
120: .setTo("*."
121: + converter.getMetaData()
122: .getDefaultFileExtension());
123: sourceFilesToProcess = sourceScanner.restrict(
124: allSourceFiles, srcDir, destDir, sourceToOutMapper);
125: }
126:
127: if (sourceFilesToProcess.length > 0) {
128: String files = (sourceFilesToProcess.length == 1 ? " file"
129: : " files");
130: log("Converting " + sourceFilesToProcess.length + files,
131: Project.MSG_INFO);
132: }
133:
134: for (int i = 0; i < sourceFilesToProcess.length; ++i) {
135: process(sourceFilesToProcess[i], options, converter);
136: }
137: }
138:
139: /**
140: * Returns a new conversions options object filled in from the Ant task.
141: *
142: * @return a new conversions options object
143: */
144: private JavaSourceConversionOptions getConversionOptions() {
145: JavaSourceConversionOptions options = JavaSourceConversionOptions
146: .getDefault();
147: options.setTabSize(tabs);
148: options.setShowFileName(isShowFileName());
149: options.setShowTableBorder(isShowTableBorder());
150: options.setShowLineNumbers(isShowLineNumbers());
151: options.setAddLineAnchors(isAddLineAnchors());
152: options.setLineAnchorPrefix(lineAnchorPrefix);
153:
154: JavaSourceStyleTable table = JavaSourceStyleTable
155: .getPredefinedTable(style);
156: if (table == null) {
157: throw new BuildException("Specified style table '"
158: + style
159: + "' does not exist "
160: + " - valid values are: "
161: + ConversionOptionsUtilities
162: .getPredefinedStyleTableNameString());
163: }
164: options.setStyleTable(table);
165:
166: HorizontalAlignment alignment = HorizontalAlignment
167: .getByName(horizontalAlignment);
168: if (alignment == null) {
169: throw new BuildException("Specified alignment '" //$NON-NLS-1$
170: + horizontalAlignment
171: + "'does not exist - valid values are: " //$NON-NLS-1$
172: + ConversionOptionsUtilities
173: .getAvailableHorizontalAlignmentNames());
174: }
175: options.setHorizontalAlignment(alignment);
176:
177: return options;
178: }
179:
180: private IJavaSourceConverter getConverter() throws BuildException {
181: IJavaSourceConverter converter = JavaSourceConverterProvider
182: .getJavaSourceConverterByName(outputFormat);
183: if (converter == null) {
184: throw new BuildException(
185: "unknown output file format: " + outputFormat); //$NON-NLS-1$
186: }
187: return converter;
188: }
189:
190: /**
191: * Convert a Java source to HTML, XHTML or LaTex.
192: *
193: * @param sourcefileName
194: * the name of the file to convert
195: * @param options
196: * conversion options
197: * @param converter
198: * the converter to use
199: */
200: private void process(String sourcefileName,
201: JavaSourceConversionOptions options,
202: IJavaSourceConverter converter) throws BuildException {
203: log("Converting '" + sourcefileName + "'", Project.MSG_VERBOSE); //$NON-NLS-1$ //$NON-NLS-2$
204: JavaSourceParser parser = new JavaSourceParser(options);
205: JavaSource source;
206: File inFile = new File(srcDir, sourcefileName);
207: try {
208: source = parser.parse(inFile);
209: } catch (IOException e1) {
210: throw new BuildException(
211: "Unable to parse file " + inFile.getName(), e1); //$NON-NLS-1$
212: }
213:
214: File outFile = createOutputFile(sourcefileName, converter);
215: ensureDirectoryFor(outFile);
216: Writer writer = null;
217: try {
218: writer = new FileWriter(outFile);
219: } catch (Exception e) {
220: throw new BuildException(
221: "Error opening output file " + outFile.getName(), e); //$NON-NLS-1$
222: }
223:
224: String title = ""; //$NON-NLS-1$
225: if (isShowDefaultTitle()) {
226: title = sourcefileName.replace('\\', '/');
227: }
228: try {
229: if (isIncludeDocumentHeader()) {
230: converter.writeDocumentHeader(writer, options, title);
231: }
232: converter.convert(source, options, writer);
233: if (isIncludeDocumentFooter()) {
234: converter.writeDocumentFooter(writer, options);
235: }
236: } catch (Exception e) {
237: throw new BuildException(
238: "Error writing output to " + outFile.getName(), e); //$NON-NLS-1$
239: } finally {
240: IoUtilities.close(writer);
241: }
242:
243: log("Output: " + outFile, Project.MSG_VERBOSE); //$NON-NLS-1$
244: }
245:
246: private File createOutputFile(String sourcefileName,
247: IJavaSourceConverter converter) {
248: String fileNamePrefix = sourcefileName;
249: if (isUseShortFileName()) {
250: int index = sourcefileName.lastIndexOf('.');
251: if (index != -1) {
252: fileNamePrefix = sourcefileName.substring(0, index);
253: }
254: }
255: return new File(destDir, fileNamePrefix + "."
256: + converter.getMetaData().getDefaultFileExtension());
257: }
258:
259: /**
260: * Sets the number of spaces per tab.
261: *
262: * @param tabs
263: */
264: public void setTabs(int tabs) {
265: this .tabs = tabs;
266: }
267:
268: /**
269: * Sets the table name for the output style, e.g. "kawa" or "eclipse".
270: *
271: * @see JavaSourceStyleTable
272: */
273: public void setStyle(String style) {
274: this .style = style;
275: }
276:
277: /**
278: * Creates directories as needed.
279: *
280: * @param targetFile
281: * a <code>File</code> whose parent directories need to exist
282: * @exception BuildException
283: * if the parent directories couldn't be created
284: */
285: private void ensureDirectoryFor(File targetFile)
286: throws BuildException {
287: File directory = new File(targetFile.getParent());
288: if (!directory.exists()) {
289: if (!directory.mkdirs()) {
290: throw new BuildException("Unable to create directory: "
291: + directory.getAbsolutePath());
292: }
293: }
294: }
295:
296: private boolean isShowFileName() {
297: return showFileName;
298: }
299:
300: private boolean isShowLineNumbers() {
301: return showLineNumbers;
302: }
303:
304: private boolean isShowDefaultTitle() {
305: return showDefaultTitle;
306: }
307:
308: private boolean isShowTableBorder() {
309: return showTableBorder;
310: }
311:
312: public void setShowFileName(boolean showFileName) {
313: this .showFileName = showFileName;
314: }
315:
316: public void setShowLineNumbers(boolean showLineNumbers) {
317: this .showLineNumbers = showLineNumbers;
318: }
319:
320: public void setShowDefaultTitle(boolean showDefaultTitle) {
321: this .showDefaultTitle = showDefaultTitle;
322: }
323:
324: public void setShowTableBorder(boolean showTableBorder) {
325: this .showTableBorder = showTableBorder;
326: }
327:
328: private boolean isIncludeDocumentFooter() {
329: return includeDocumentFooter;
330: }
331:
332: private boolean isIncludeDocumentHeader() {
333: return includeDocumentHeader;
334: }
335:
336: public void setIncludeDocumentFooter(boolean includeDocumentFooter) {
337: this .includeDocumentFooter = includeDocumentFooter;
338: }
339:
340: public void setIncludeDocumentHeader(boolean includeDocumentHeader) {
341: this .includeDocumentHeader = includeDocumentHeader;
342: }
343:
344: private boolean isAddLineAnchors() {
345: return addLineAnchors;
346: }
347:
348: public void setAddLineAnchors(boolean addLineAnchors) {
349: this .addLineAnchors = addLineAnchors;
350: }
351:
352: public void setLineAnchorPrefix(String string) {
353: lineAnchorPrefix = string;
354: }
355:
356: public void setHorizontalAlignment(String horizontalAlignment) {
357: this .horizontalAlignment = horizontalAlignment;
358: }
359:
360: private boolean isUseShortFileName() {
361: return useShortFileName;
362: }
363:
364: public void setUseShortFileName(boolean useShortFileName) {
365: this .useShortFileName = useShortFileName;
366: }
367:
368: private boolean isOverwrite() {
369: return overwrite;
370: }
371:
372: public void setOverwrite(boolean overwrite) {
373: this.overwrite = overwrite;
374: }
375: }
|