001/*
002 * Copyright 2004-2006 Geert Bevin <gbevin[remove] at uwyn dot com>
003 * Distributed under the terms of either:
004 * - the common development and distribution license (CDDL), v1.0; or
005 * - the GNU Lesser General Public License, v2.1 or later
006 * $Id: JHighlight.java 3106 2006-03-13 17:53:50Z gbevin $
007 */
008package com.uwyn.jhighlight;
009
010import com.uwyn.jhighlight.renderer.XhtmlRendererFactory;
011import com.uwyn.jhighlight.tools.FileUtils;
012import java.io.File;
013import java.io.FileOutputStream;
014import java.io.IOException;
015import java.util.ArrayList;
016import java.util.Iterator;
017import java.util.Set;
018import java.util.regex.Pattern;
019
020/**
021 * Provides console access to the source code syntax highlighting for Java,
022 * HTML, XHTML, XML and LZX files. The rendering will be done in HTML.
023 * <p>The following file extensions will be processed: <code>.java</code>,
024 * <code>.html</code>, <code>.htm</code>, <code>.xhtml</code>,
025 * <code>.xml</code> and <code>.lzx</code>.
026 * <p>Execute the highlighting with the following syntax:
027 * <pre>java com.uwyn.jhighlight.JHighlight [--verbose] [--fragment] [-d destdir] [-e encoding] file|dir ...</pre>
028 * <table border="0">
029 * <tr>
030 * <td><code>--verbose</code></td>
031 * <td>Output messages about what the parser is doing.</td>
032 * </tr>
033 * <tr>
034 * <td><code>--fragment</code></td>
035 * <td>Output fragments instead of complete documents.</td>
036 * </tr>
037 * <tr>
038 * <td><code>-d</code></td>
039 * <td>Specify the destination directory</td>
040 * </tr>
041 * <tr>
042 * <td><code>-e</code></td>
043 * <td>Specify the encoding of the files</td>
044 * </tr>
045 * </table>
046 * <p><a href="https://rife.dev.java.net">RIFE</a> template tags are also
047 * supported and will be clearly highlighted.
048 *
049 * @author Geert Bevin (gbevin[remove] at uwyn dot com)
050 * @version $Revision: 3106 $
051 * @since 1.0
052 */
053public class JHighlight
054{
055        public static void main(String[] arguments) throws Throwable
056        {
057                String      destdir_name = null;
058                boolean     verbose = false;
059                String          encoding = null;
060                boolean     fragment = false;
061                ArrayList   names = new ArrayList();
062                
063                boolean valid_arguments = true;
064                if (arguments.length < 1)
065                {
066                        valid_arguments = false;
067                }
068                else
069                {
070                        boolean next_is_destdir = false;
071                        boolean next_is_encoding = false;
072                        String argument;
073                        for (int i = 0; i < arguments.length; i++)
074                        {
075                                argument = arguments[i];
076                                if (next_is_destdir)
077                                {
078                                        destdir_name = argument;
079                                        next_is_destdir = false;
080                                        continue;
081                                }
082                                
083                                if (next_is_encoding)
084                                {
085                                        encoding = argument;
086                                        next_is_encoding = false;
087                                        continue;
088                                }
089                                
090                                if (argument.equals("-d"))
091                                {
092                                        next_is_destdir = true;
093                                        continue;
094                                }
095                                
096                                if (argument.equals("-e"))
097                                {
098                                        next_is_encoding = true;
099                                        continue;
100                                }
101                                
102                                if (argument.equals("--verbose"))
103                                {
104                                        verbose = true;
105                                        continue;
106                                }
107                                
108                                if (argument.equals("--fragment"))
109                                {
110                                        fragment = true;
111                                        continue;
112                                }
113                                
114                                names.add(argument);
115                        }
116                }
117                
118                if (0 == names.size())
119                {
120                        valid_arguments = false;
121                }
122                
123                if (!valid_arguments)
124                {
125                        System.err.println("Usage : java " + JHighlight.class.getName() + " [--verbose] [--fragment] [-d destdir] [-e encoding] file|dir ...");
126                        System.err.println("Generates highlighted XHTML files from all Java and XML source files");
127                        System.err.println("in the specified directories.");
128                        System.err.println("  --verbose  Output messages about what the parser is doing");
129                        System.err.println("  --fragment Output fragments instead of complete documents");
130                        System.err.println("  -d         Specify the destination directory");
131                        System.err.println("  -e         Specify the encoding of the files");
132                        System.exit(1);
133                }
134                
135                File    destdir = null;
136                if (destdir_name != null)
137                {
138                        destdir = new File(destdir_name);
139                        if (!destdir.exists())
140                        {
141                                throw new IOException("The destination directory '" + destdir_name + "' doesn't exist.");
142                        }
143                        if (!destdir.canWrite())
144                        {
145                                throw new IOException("The destination directory '" + destdir_name + "' is not writable.");
146                        }
147                        if (!destdir.isDirectory())
148                        {
149                                throw new IOException("The destination directory '" + destdir_name + "' is not a directory.");
150                        }
151                }
152                
153                Iterator    names_it = names.iterator();
154                String      name;
155                while (names_it.hasNext())
156                {
157                        name = (String)names_it.next();
158                        
159                        File    location = new File(name);
160                        if (!location.exists())
161                        {
162                                throw new IOException("The source location '" + name + "' doesn't exist.");
163                        }
164                        if (!location.canRead())
165                        {
166                                throw new IOException("The source location '" + name + "' is not readable.");
167                        }
168                        
169                        if (!location.isDirectory())
170                        {
171                                File out = null;
172                                if (null == destdir)
173                                {
174                                        out = new File(location.getAbsolutePath() + ".html");
175                                }
176                                else
177                                {
178                                        out = new File(destdir, location.getName() + ".html");
179                                }
180                                
181                                highlightFile(location.getName(), location, out, encoding, fragment, verbose);
182                        }
183                        else
184                        {
185                                Set                     supported_types = XhtmlRendererFactory.getSupportedTypes();
186                                Pattern[]       included = new Pattern[supported_types.size()];
187                                Pattern[]       excluded = new Pattern[supported_types.size()+5];
188                                excluded[0] = Pattern.compile(".*SCCS.*");
189                                excluded[0] = Pattern.compile(".*svn.*");
190                                excluded[0] = Pattern.compile(".*CVS.*");
191                                excluded[0] = Pattern.compile(".*jetty.*");
192                                excluded[0] = Pattern.compile(".*tomcat.*");
193                                
194                                Iterator        types_it = supported_types.iterator();
195                                String          type;
196                                int                     counter = 0;
197                                while (types_it.hasNext())
198                                {
199                                        type = (String)types_it.next();
200                                        included[counter] = Pattern.compile(".*\\."+type+"$");
201                                        excluded[counter+5] = Pattern.compile(".*\\."+type+"\\.html\\.*");
202
203                                        counter++;
204                                }
205
206                                ArrayList file_names = FileUtils.getFileList(location, included, excluded);
207                                
208                                Iterator    file_names_it = file_names.iterator();
209                                String      file_name;
210                                while (file_names_it.hasNext())
211                                {
212                                        file_name = (String)file_names_it.next();
213                                        
214                                        File in = new File(location.getAbsolutePath() + File.separator + file_name);
215                                        File out = null;
216                                        if (null == destdir)
217                                        {
218                                                out = new File(location.getAbsolutePath() + File.separator + file_name + ".html");
219                                        }
220                                        else
221                                        {
222                                                out = new File(destdir, location.getName() + File.separator + file_name + ".html");
223                                        }
224                                        
225                                        highlightFile(location.getName() + File.separator + file_name, in, out, encoding, fragment, verbose);
226                                }
227                        }
228                }
229        }
230        
231        private static void highlightFile(String name, File in, File out, String encoding, boolean fragment, boolean verbose)
232        throws IOException
233        {
234                out.getParentFile().mkdirs();
235                
236                if (verbose)
237                {
238                        System.out.print(name + " ... ");
239                }
240                
241                XhtmlRendererFactory.getRenderer(FileUtils.getExtension(name))
242                        .highlight(name,
243                                           in.toURL().openStream(),
244                                           new FileOutputStream(out),
245                                           encoding,
246                                           fragment);
247                
248                if (verbose)
249                {
250                        System.out.println("done.");
251                }
252        }
253}