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    }