001 /*
002 $Id: Wiki2Markup.java,v 1.3 2003/12/31 12:39:48 jstrachan Exp $
003
004 Copyright 2003 (C) James Strachan and Bob Mcwhirter. All Rights Reserved.
005
006 Redistribution and use of this software and associated documentation
007 ("Software"), with or without modification, are permitted provided
008 that the following conditions are met:
009
010 1. Redistributions of source code must retain copyright
011 statements and notices. Redistributions must also contain a
012 copy of this document.
013
014 2. Redistributions in binary form must reproduce the
015 above copyright notice, this list of conditions and the
016 following disclaimer in the documentation and/or other
017 materials provided with the distribution.
018
019 3. The name "groovy" must not be used to endorse or promote
020 products derived from this Software without prior written
021 permission of The Codehaus. For written permission,
022 please contact info@codehaus.org.
023
024 4. Products derived from this Software may not be called "groovy"
025 nor may "groovy" appear in their names without prior written
026 permission of The Codehaus. "groovy" is a registered
027 trademark of The Codehaus.
028
029 5. Due credit should be given to The Codehaus -
030 http://groovy.codehaus.org/
031
032 THIS SOFTWARE IS PROVIDED BY THE CODEHAUS AND CONTRIBUTORS
033 ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT
034 NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
035 FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
036 THE CODEHAUS OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
037 INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
038 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
039 SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
040 HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
041 STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
042 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
043 OF THE POSSIBILITY OF SUCH DAMAGE.
044
045 */
046 package org.codehaus.groovy.wiki;
047
048 import java.io.BufferedReader;
049 import java.io.File;
050 import java.io.FileReader;
051 import java.io.FileWriter;
052 import java.io.IOException;
053
054 import org.apache.tools.ant.BuildException;
055 import org.apache.tools.ant.DirectoryScanner;
056 import org.apache.tools.ant.Project;
057 import org.apache.tools.ant.taskdefs.MatchingTask;
058 import org.apache.tools.ant.types.Path;
059 import org.apache.tools.ant.util.GlobPatternMapper;
060 import org.apache.tools.ant.util.SourceFileScanner;
061 import org.radeox.api.engine.RenderEngine;
062 import org.radeox.api.engine.context.RenderContext;
063 import org.radeox.engine.BaseRenderEngine;
064 import org.radeox.engine.context.BaseRenderContext;
065
066 /**
067 * Converts the Wiki markup into XML/HTML so that it can be styled
068 * by the Maven build
069 *
070 * @author <a href="mailto:james@coredevelopers.net">James Strachan</a>
071 * @version $Revision: 1.3 $
072 */
073 public class Wiki2Markup extends MatchingTask {
074
075 private Path src;
076 private File destDir;
077
078 protected boolean failOnError = true;
079 protected boolean listFiles = false;
080 protected File[] compileList = new File[0];
081 private GlobPatternMapper m = new GlobPatternMapper();
082
083 private RenderContext context;
084 private RenderEngine engine;
085
086 public static void main(String[] args) {
087 try {
088 Wiki2Markup engine = new Wiki2Markup();
089 engine.compileFiles(args);
090 }
091 catch (Exception e) {
092 System.out.println("Caught: " + e);
093 e.printStackTrace();
094 }
095 }
096
097 public Wiki2Markup() {
098 context = new BaseRenderContext();
099 engine = createRenderEngine();
100 m.setFrom("*.wiki");
101 m.setTo(getExtension());
102 }
103
104 /**
105 * Adds a path for source compilation.
106 *
107 * @return a nested src element.
108 */
109 public Path createSrc() {
110 if (src == null) {
111 src = new Path(getProject());
112 }
113 return src.createPath();
114 }
115
116 /**
117 * Recreate src.
118 *
119 * @return a nested src element.
120 */
121 protected Path recreateSrc() {
122 src = null;
123 return createSrc();
124 }
125
126 /**
127 * Set the source directories to find the source Java files.
128 * @param srcDir the source directories as a path
129 */
130 public void setSrcdir(Path srcDir) {
131 if (src == null) {
132 src = srcDir;
133 }
134 else {
135 src.append(srcDir);
136 }
137 }
138
139 /**
140 * Gets the source dirs to find the source java files.
141 * @return the source directorys as a path
142 */
143 public Path getSrcdir() {
144 return src;
145 }
146
147 /**
148 * Set the destination directory into which the Java source
149 * files should be compiled.
150 * @param destDir the destination director
151 */
152 public void setDestdir(File destDir) {
153 this.destDir = destDir;
154 }
155
156 /**
157 * Gets the destination directory into which the java source files
158 * should be compiled.
159 * @return the destination directory
160 */
161 public File getDestdir() {
162 return destDir;
163 }
164
165 /**
166 * If true, list the source files being handed off to the compiler.
167 * @param list if true list the source files
168 */
169 public void setListfiles(boolean list) {
170 listFiles = list;
171 }
172
173 /**
174 * Get the listfiles flag.
175 * @return the listfiles flag
176 */
177 public boolean getListfiles() {
178 return listFiles;
179 }
180
181 /**
182 * Indicates whether the build will continue
183 * even if there are compilation errors; defaults to true.
184 * @param fail if true halt the build on failure
185 */
186 public void setFailonerror(boolean fail) {
187 failOnError = fail;
188 }
189
190 /**
191 * @ant.attribute ignore="true"
192 * @param proceed inverse of failoferror
193 */
194 public void setProceed(boolean proceed) {
195 failOnError = !proceed;
196 }
197
198 /**
199 * Gets the failonerror flag.
200 * @return the failonerror flag
201 */
202 public boolean getFailonerror() {
203 return failOnError;
204 }
205
206 /**
207 * Executes the task.
208 * @exception BuildException if an error occurs
209 */
210 public void execute() throws BuildException {
211 checkParameters();
212 resetFileLists();
213
214 // scan source directories and dest directory to build up
215 // compile lists
216 String[] list = src.list();
217 for (int i = 0; i < list.length; i++) {
218 File srcDir = getProject().resolveFile(list[i]);
219 if (!srcDir.exists()) {
220 throw new BuildException("srcdir \"" + srcDir.getPath() + "\" does not exist!", getLocation());
221 }
222
223 DirectoryScanner ds = this.getDirectoryScanner(srcDir);
224 String[] files = ds.getIncludedFiles();
225
226 scanDir(srcDir, destDir != null ? destDir : srcDir, files);
227 }
228
229 compile();
230 }
231
232 /**
233 * Clear the list of files to be compiled and copied..
234 */
235 protected void resetFileLists() {
236 compileList = new File[0];
237 }
238
239 /**
240 * Scans the directory looking for source files to be compiled.
241 * The results are returned in the class variable compileList
242 *
243 * @param srcDir The source directory
244 * @param destDir The destination directory
245 * @param files An array of filenames
246 */
247 protected void scanDir(File srcDir, File destDir, String[] files) {
248 SourceFileScanner sfs = new SourceFileScanner(this);
249 File[] newFiles = sfs.restrictAsFiles(files, srcDir, destDir, m);
250
251 if (newFiles.length > 0) {
252 File[] newCompileList = new File[compileList.length + newFiles.length];
253 System.arraycopy(compileList, 0, newCompileList, 0, compileList.length);
254 System.arraycopy(newFiles, 0, newCompileList, compileList.length, newFiles.length);
255 compileList = newCompileList;
256 }
257 }
258
259 /**
260 * Gets the list of files to be compiled.
261 * @return the list of files as an array
262 */
263 public File[] getFileList() {
264 return compileList;
265 }
266
267 protected void checkParameters() throws BuildException {
268 if (src == null) {
269 throw new BuildException("srcdir attribute must be set!", getLocation());
270 }
271 if (src.size() == 0) {
272 throw new BuildException("srcdir attribute must be set!", getLocation());
273 }
274
275 if (destDir != null && !destDir.isDirectory()) {
276 throw new BuildException(
277 "destination directory \"" + destDir + "\" does not exist " + "or is not a directory",
278 getLocation());
279 }
280 }
281
282 public void compileFiles(String[] args) throws IOException {
283 for (int i = 0; i < args.length; i++) {
284 File file = new File(args[i]);
285 compile(file, args[i]);
286 }
287 }
288
289 protected void compile() {
290 if (compileList.length > 0) {
291 log(
292 "Compiling "
293 + compileList.length
294 + " source file"
295 + (compileList.length == 1 ? "" : "s")
296 + (destDir != null ? " to " + destDir : ""));
297
298 try {
299 for (int i = 0; i < compileList.length; i++) {
300 String filename = compileList[i].getAbsolutePath();
301 if (listFiles) {
302 log(filename);
303 }
304 compile(compileList[i], compileList[i].getName());
305 }
306 }
307 catch (Exception e) {
308 String message = "Compile failed: " + e;
309 if (failOnError) {
310 throw new BuildException(message, e, getLocation());
311 }
312 else {
313 log(message, Project.MSG_ERR);
314 }
315 }
316 }
317 }
318
319 protected void compile(File file, String name) throws IOException {
320 String[] names = m.mapFileName(name);
321 String outputName = names[0];
322
323 context.set("name", name);
324
325 String text = readFile(file);
326 String result = engine.render(text, context);
327
328 File outputFile = new File(getDestdir(), outputName);
329 System.out.println("Creating file: " + outputFile);
330
331 FileWriter writer = new FileWriter(outputFile);
332 result = filter(result);
333 writer.write(result);
334 writer.close();
335 }
336
337 protected String filter(String result) {
338 return "<html><body>\n" + result + "\n<body><html>\n";
339 }
340
341 protected String readFile(File file) throws IOException {
342 StringBuffer buffer = new StringBuffer();
343 BufferedReader reader = new BufferedReader(new FileReader(file));
344 while (true) {
345 String line = reader.readLine();
346 if (line == null) {
347 break;
348 }
349 buffer.append(line);
350 buffer.append("\n");
351 }
352 return buffer.toString();
353 }
354
355 protected RenderEngine createRenderEngine() {
356 return new BaseRenderEngine();
357 }
358
359 protected String getExtension() {
360 return "*.html";
361 }
362 }