View Javadoc

1   package org.apache.velocity.convert;
2   
3   /*
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   *   http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing,
15   * software distributed under the License is distributed on an
16   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17   * KIND, either express or implied.  See the License for the
18   * specific language governing permissions and limitations
19   * under the License.    
20   */
21  
22  import java.io.File;
23  import java.io.FileWriter;
24  import java.io.IOException;
25  
26  import org.apache.oro.text.perl.Perl5Util;
27  import org.apache.velocity.util.StringUtils;
28  import org.apache.tools.ant.DirectoryScanner;
29  
30  /**
31   * This is deprecated without replacement.
32   *
33   * @author <a href="mailto:jvanzyl@apache.org">Jason van Zyl</a>
34   * @author <a href="mailto:dlr@finemaltcoding.com">Daniel Rall</a>
35   * @version $Id: WebMacro.java 898028 2010-01-11 19:36:31Z nbubna $
36   * @deprecated Obsolete and outdated.
37   */
38  public class WebMacro
39  {
40      /**
41       *
42       */
43      protected static final String VM_EXT = ".vm";
44  
45      /**
46       *
47       */
48      protected static final String WM_EXT = ".wm";
49  
50      /**
51       * The regexes to use for line by line substition. The regexes
52       * come in pairs. The first is the string to match, the second is
53       * the substitution to make.
54       */
55      protected static String[] perLineREs =
56      {
57          // Make #if directive match the Velocity directive style.
58          "#if\\s*[(]\\s*(.*\\S)\\s*[)]\\s*(#begin|{)[ \\t]?",
59          "#if( $1 )",
60  
61          // Remove the WM #end #else #begin usage.
62          "[ \\t]?(#end|})[ \\t]*\n(\\s*)#else\\s*(#begin|{)[ \\t]?(\\w)",
63          "$2#else#**#$4", // avoid touching followup word with embedded comment
64          "[ \\t]?(#end|})[ \\t]*\n(\\s*)#else\\s*(#begin|{)[ \\t]?",
65          "$2#else",
66          "(#end|})(\\s*#else)\\s*(#begin|{)[ \\t]?",
67          "$1\n$2",
68  
69          // Convert WM style #foreach to Velocity directive style.
70          "#foreach\\s+(\\$\\w+)\\s+in\\s+(\\$[^\\s#]+)\\s*(#begin|{)[ \\t]?",
71          "#foreach( $1 in $2 )",
72  
73          // Convert WM style #set to Velocity directive style.
74          "#set\\s+(\\$[^\\s=]+)\\s*=\\s*([\\S \\t]+)",
75          "#set( $1 = $2 )",
76          "(##[# \\t\\w]*)\\)", // fix comments included at end of line
77          ")$1",
78  
79          // Convert WM style #parse to Velocity directive style.
80          "#parse\\s+([^\\s#]+)[ \\t]?",
81          "#parse( $1 )",
82  
83          // Convert WM style #include to Velocity directive style.
84          "#include\\s+([^\\s#]+)[ \\t]?",
85          "#include( $1 )",
86  
87          // Convert WM formal reference to VTL syntax.
88          "\\$\\(([^\\)]+)\\)",
89          "${$1}",
90          "\\${([^}\\(]+)\\(([^}]+)}\\)", // fix encapsulated brakets: {(})
91          "${$1($2)}",
92  
93          // Velocity currently does not permit leading underscore.
94          "\\$_",
95          "$l_",
96          "\\${(_[^}]+)}", // within a formal reference
97          "${l$1}",
98  
99          // Eat semi-colons in (converted) VTL #set directives.
100         "(#set\\s*\\([^;]+);(\\s*\\))",
101         "$1$2",
102 
103         // Convert explicitly terminated WM statements to VTL syntax.
104         "(^|[^\\\\])\\$(\\w[^=\n;'\"]*);",
105         "$1${$2}",
106 
107         // Change extensions when seen.
108         "\\.wm",
109         ".vm"
110     };
111 
112     /**
113      * Iterate through the set of find/replace regexes
114      * that will convert a given WM template to a VM template
115      * @param target
116      */
117     public void convert(String target)
118     {
119         File file = new File(target);
120 
121         if (!file.exists())
122         {
123             throw new RuntimeException("The specified template or directory does not exist");
124         }
125 
126         if (file.isDirectory())
127         {
128             String basedir = file.getAbsolutePath();
129             String newBasedir = basedir + VM_EXT;
130 
131             DirectoryScanner ds = new DirectoryScanner();
132             ds.setBasedir(basedir);
133             ds.addDefaultExcludes();
134             ds.scan();
135             String[] files = ds.getIncludedFiles();
136 
137             for (int i = 0; i < files.length; i++)
138             {
139                 writeTemplate(files[i], basedir, newBasedir);
140             }
141         }
142         else
143         {
144             writeTemplate(file.getAbsolutePath(), "", "");
145         }
146     }
147 
148     /**
149      * Write out the converted template to the given named file
150      * and base directory.
151      */
152     private boolean writeTemplate(String file, String basedir,
153                                   String newBasedir)
154     {
155         if (file.indexOf(WM_EXT) < 0)
156         {
157             return false;
158         }
159 
160         System.out.println("Converting " + file + "...");
161 
162         String template = file;
163         String newTemplate = convertName(file);
164 
165         if (basedir.length() > 0)
166         {
167             String templateDir = newBasedir + extractPath(file);
168             File outputDirectory = new File(templateDir);
169 
170             template = basedir + File.separator + file;
171 
172 
173             if (! outputDirectory.exists())
174             {
175                 outputDirectory.mkdirs();
176             }
177 
178             newTemplate = newBasedir + File.separator + convertName(file);
179         }
180 
181         String convertedTemplate = convertTemplate(template);
182 
183         FileWriter fw = null;
184         try
185         {
186             fw = new FileWriter(newTemplate);
187             fw.write(convertedTemplate);
188         }
189         catch (Exception e)
190         {
191             e.printStackTrace();
192         }
193         finally
194         {
195             if (fw != null)
196             {
197                 try
198                 {
199                     fw.close();
200                 }
201                 catch (IOException io)
202                 {
203                     // Do nothing
204                 }
205             }
206         }
207 
208         return true;
209     }
210 
211     /**
212      * Gets the path segment of the full path to a file (i.e. one
213      * which originally included the file name).
214      */
215     private final String extractPath(String file)
216     {
217         int lastSepPos = file.lastIndexOf(File.separator);
218         return (lastSepPos == -1 ? "" :
219                 File.separator + file.substring(0, lastSepPos));
220     }
221 
222     /**
223      * Simple extension conversion of .wm to .vm
224      */
225     private String convertName(String name)
226     {
227         return (name.indexOf(WM_EXT) < 0)
228                 ? name
229                 : name.substring(0, name.indexOf(WM_EXT)) + VM_EXT;
230     }
231 
232     /**
233      * How to use this little puppy :-)
234      */
235     private static final void usage()
236     {
237         System.err.println("Usage: convert-wm <template.wm | directory>");
238     }
239 
240     /**
241      * Apply find/replace regexes to our WM template
242      * @param template
243      * @return Returns the template with all regexprs applied.
244      */
245     public String convertTemplate(String template)
246     {
247         String contents = StringUtils.fileContentsToString(template);
248 
249         // Overcome Velocity 0.71 limitation.
250         // HELP: Is this still necessary?
251         if (!contents.endsWith("\n"))
252         {
253             contents += "\n";
254         }
255 
256         // Convert most markup.
257         Perl5Util perl = new Perl5Util();
258         for (int i = 0; i < perLineREs.length; i += 2)
259         {
260             contents = perl.substitute(makeSubstRE(i), contents);
261         }
262 
263         // Convert closing curlies.
264         if (perl.match("m/javascript/i", contents))
265         {
266             // ASSUMPTION: JavaScript is indented, WM is not.
267             contents = perl.substitute("s/\n}/\n#end/g", contents);
268         }
269         else
270         {
271             contents = perl.substitute("s/(\n\\s*)}/$1#end/g", contents);
272             contents = perl.substitute("s/#end\\s*\n\\s*#else/#else/g",
273                                        contents);
274         }
275 
276         return contents;
277     }
278 
279     /**
280      * Makes a Perl 5 regular expression for use by ORO.
281      */
282     private final String makeSubstRE(int i)
283     {
284         return ("s/" + perLineREs[i] + '/' + perLineREs[i + 1] + "/g");
285     }
286 
287     /**
288      * Main hook for the conversion process.
289      * @param args
290      */
291     public static void main(String[] args)
292     {
293         if (args.length > 0)
294         {
295             for (int x=0; x < args.length; x++)
296             {
297                 WebMacro converter = new WebMacro();
298                 converter.convert(args[x]);
299             }
300         }
301         else
302         {
303             usage();
304         }
305     }
306 }