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