| Classes in this File | Line Coverage | Branch Coverage | Complexity | ||||
| WebMacroConverter |
|
| 3.5;3.5 |
| 1 | /* | |
| 2 | * $Source: /usr/cvsroot/melati/melati/src/main/java/org/melati/template/velocity/WebMacroConverter.java,v $ | |
| 3 | * $Revision: 1.9 $ | |
| 4 | * | |
| 5 | * Copyright (C) 2006 Tim Pizey | |
| 6 | * | |
| 7 | * Part of Melati (http://melati.org), a framework for the rapid | |
| 8 | * development of clean, maintainable web applications. | |
| 9 | * | |
| 10 | * Melati is free software; Permission is granted to copy, distribute | |
| 11 | * and/or modify this software under the terms either: | |
| 12 | * | |
| 13 | * a) the GNU General Public License as published by the Free Software | |
| 14 | * Foundation; either version 2 of the License, or (at your option) | |
| 15 | * any later version, | |
| 16 | * | |
| 17 | * or | |
| 18 | * | |
| 19 | * b) any version of the Melati Software License, as published | |
| 20 | * at http://melati.org | |
| 21 | * | |
| 22 | * You should have received a copy of the GNU General Public License and | |
| 23 | * the Melati Software License along with this program; | |
| 24 | * if not, write to the Free Software Foundation, Inc., | |
| 25 | * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA to obtain the | |
| 26 | * GNU General Public License and visit http://melati.org to obtain the | |
| 27 | * Melati Software License. | |
| 28 | * | |
| 29 | * Feel free to contact the Developers of Melati (http://melati.org), | |
| 30 | * if you would like to work out a different arrangement than the options | |
| 31 | * outlined here. It is our intention to allow Melati to be used by as | |
| 32 | * wide an audience as possible. | |
| 33 | * | |
| 34 | * This program is distributed in the hope that it will be useful, | |
| 35 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
| 36 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
| 37 | * GNU General Public License for more details. | |
| 38 | * | |
| 39 | * Contact details for copyright holder: | |
| 40 | * | |
| 41 | * Tim Pizey <timp At paneris.org> | |
| 42 | */ | |
| 43 | package org.melati.template.velocity; | |
| 44 | ||
| 45 | import java.io.ByteArrayInputStream; | |
| 46 | import java.io.IOException; | |
| 47 | import java.io.InputStream; | |
| 48 | ||
| 49 | import org.apache.oro.text.perl.Perl5Util; | |
| 50 | import org.melati.util.MelatiBugMelatiException; | |
| 51 | ||
| 52 | /** | |
| 53 | * Converter from WebMacro templates to Velocity templates. | |
| 54 | * | |
| 55 | * Note that this does not succeed for modern WebMacro syntax | |
| 56 | * which uses optionional #begin in #foreach. | |
| 57 | * | |
| 58 | * @author Tim Pizey based on work by Jason van Zyl and Tim Joyce. | |
| 59 | * | |
| 60 | */ | |
| 61 | public final class WebMacroConverter { | |
| 62 | ||
| 63 | 0 | private WebMacroConverter() {} |
| 64 | /** | |
| 65 | * The regexes to use for substition. The regexes come | |
| 66 | * in pairs. The first is the string to match, the | |
| 67 | * second is the substitution to make. | |
| 68 | */ | |
| 69 | 0 | public static final String[] regExps = { |
| 70 | // Make #if directive match the Velocity directive style. | |
| 71 | "#if\\s*[(]\\s*(.*\\S)\\s*[)]\\s*(#begin|{)[ \\t]?", | |
| 72 | "#if( $1 )", | |
| 73 | ||
| 74 | // Remove the WM #end #else #begin usage. | |
| 75 | "[ \\t]?(#end|})\\s*#else\\s*(#begin|{)[ \\t]?(\\w)", | |
| 76 | "#else#**#$3", // avoid touching a followup word with embedded comment | |
| 77 | "[ \\t]?(#end|})\\s*#else\\s*(#begin|{)[ \\t]?", | |
| 78 | "#else", | |
| 79 | ||
| 80 | // Convert nulls. | |
| 81 | // This converts | |
| 82 | // $var != null | |
| 83 | // to | |
| 84 | // $var | |
| 85 | "\\s*(\\$[^\\s\\!]+)\\s*!=\\s*null\\s*", | |
| 86 | " $1 ", | |
| 87 | // This converts | |
| 88 | // $var == null | |
| 89 | // to | |
| 90 | // !$var | |
| 91 | "\\s*(\\$[^\\s\\!]+)\\s*==\\s*null\\s*", | |
| 92 | " !$1 ", | |
| 93 | ||
| 94 | // Convert WM style #foreach to Velocity directive style. | |
| 95 | "#foreach\\s+(\\$\\w+)\\s+in\\s+(\\$[^\\s#]+)\\s*(#begin|{)[ \\t]?", | |
| 96 | "#foreach( $1 in $2 )", | |
| 97 | ||
| 98 | // Change the "}" to #end. Have to get more | |
| 99 | // sophisticated here. Will assume either {} | |
| 100 | // and no javascript, or #begin/#end with the | |
| 101 | // possibility of javascript. | |
| 102 | "\n}", // assumes that javascript is indented, WMs not!!! | |
| 103 | "\n#end", | |
| 104 | ||
| 105 | // Convert WM style #set to Velocity directive style. | |
| 106 | //"#set\\s+(\\$[^\\s=]+)\\s*=\\s*(.*\\S)[ \\t]*", | |
| 107 | "#set\\s+(\\$[^\\s=]+)\\s*=\\s*([\\S \\t]+)", | |
| 108 | "#set( $1 = $2 )", | |
| 109 | "(##[# \\t\\w]*)\\)", // fix comments included at end of line | |
| 110 | ")$1", | |
| 111 | ||
| 112 | // Convert WM style #parse to Velocity directive style. | |
| 113 | "#parse\\s+([^\\s#]+)[ \\t]?", | |
| 114 | "#parse( $1 )", | |
| 115 | ||
| 116 | // parse is now depricated for web macro | |
| 117 | // include as template is recommended. | |
| 118 | // Velocity supports only parse | |
| 119 | // added for melati conversion | |
| 120 | "#include\\s+as\\s+template\\s+([^\\s#]+)[ \\t]?", | |
| 121 | "#parse( $1 )", | |
| 122 | ||
| 123 | // Convert WM style #include to Velocity directive style. | |
| 124 | "#include\\s+([^\\s#]+)[ \\t]?", | |
| 125 | "#include( $1 )", | |
| 126 | ||
| 127 | // Convert WM formal reference to VL syntax. | |
| 128 | "\\$\\(([^\\)]+)\\)", | |
| 129 | "${$1}", | |
| 130 | "\\${([^}\\(]+)\\(([^}]+)}\\)", // fix encapsulated brakets: {(}) | |
| 131 | "${$1($2)}", | |
| 132 | ||
| 133 | // Velocity currently does not permit leading underscore. | |
| 134 | "\\$_", | |
| 135 | "$l_", | |
| 136 | "\\${(_[^}]+)}", // within a formal reference | |
| 137 | "${l$1}", | |
| 138 | ||
| 139 | }; | |
| 140 | ||
| 141 | /** | |
| 142 | * Do the conversion. | |
| 143 | * | |
| 144 | * @param in | |
| 145 | * @return the InputStream with substitutions applied | |
| 146 | */ | |
| 147 | public static InputStream convert(InputStream in) { | |
| 148 | byte[] ca; | |
| 149 | try { | |
| 150 | 0 | ca = new byte[in.available()]; |
| 151 | 0 | in.read(ca); |
| 152 | 0 | String contents = new String(ca); |
| 153 | /* Regular expression tool */ | |
| 154 | 0 | final Perl5Util perl = new Perl5Util(); |
| 155 | 0 | for (int i = 0; i < regExps.length; i += 2) { |
| 156 | 0 | while (perl.match("/" + regExps[i] + "/", contents)) { |
| 157 | 0 | contents = perl.substitute( |
| 158 | "s/" + regExps[i] + "/" + regExps[i+1] + "/", contents); | |
| 159 | } | |
| 160 | } | |
| 161 | // System.err.println(contents); | |
| 162 | 0 | return new ByteArrayInputStream(contents.getBytes()); |
| 163 | 0 | } catch (IOException e) { |
| 164 | 0 | throw new MelatiBugMelatiException( |
| 165 | "Problem loading WebMacro template as a VelocityTemplate", e); | |
| 166 | } | |
| 167 | } | |
| 168 | } |