blob: 72eb6b1df99dbd062a913d68860cb828455165d1 [file] [log] [blame]
package org.apache.flex.forks.velocity.convert;
/*
* Copyright 2001,2004 The Apache Software Foundation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import java.io.File;
import java.io.FileWriter;
import org.apache.oro.text.perl.Perl5Util;
import org.apache.flex.forks.velocity.util.StringUtils;
import org.apache.tools.ant.DirectoryScanner;
/**
* This class will convert a WebMacro template to
* a Velocity template. Uses the ORO Regexp package to do the
* rewrites. Note, it isn't 100% perfect, but will definitely get
* you about 99.99% of the way to a converted system. Please
* see the website documentation for more information on how to use
* this class.
*
* @author <a href="mailto:jvanzyl@apache.org">Jason van Zyl</a>
* @author <a href="mailto:dlr@finemaltcoding.com">Daniel Rall</a>
* @version $Id: WebMacro.java,v 1.20.8.1 2004/03/03 23:22:54 geirm Exp $
*/
public class WebMacro
{
protected static final String VM_EXT = ".vm";
protected static final String WM_EXT = ".wm";
/**
* The regexes to use for line by line substition. The regexes
* come in pairs. The first is the string to match, the second is
* the substitution to make.
*/
protected static String[] perLineREs =
{
// Make #if directive match the Velocity directive style.
"#if\\s*[(]\\s*(.*\\S)\\s*[)]\\s*(#begin|{)[ \\t]?",
"#if( $1 )",
// Remove the WM #end #else #begin usage.
"[ \\t]?(#end|})[ \\t]*\n(\\s*)#else\\s*(#begin|{)[ \\t]?(\\w)",
"$2#else#**#$4", // avoid touching followup word with embedded comment
"[ \\t]?(#end|})[ \\t]*\n(\\s*)#else\\s*(#begin|{)[ \\t]?",
"$2#else",
"(#end|})(\\s*#else)\\s*(#begin|{)[ \\t]?",
"$1\n$2",
// Convert WM style #foreach to Velocity directive style.
"#foreach\\s+(\\$\\w+)\\s+in\\s+(\\$[^\\s#]+)\\s*(#begin|{)[ \\t]?",
"#foreach( $1 in $2 )",
// Convert WM style #set to Velocity directive style.
"#set\\s+(\\$[^\\s=]+)\\s*=\\s*([\\S \\t]+)",
"#set( $1 = $2 )",
"(##[# \\t\\w]*)\\)", // fix comments included at end of line
")$1",
// Convert WM style #parse to Velocity directive style.
"#parse\\s+([^\\s#]+)[ \\t]?",
"#parse( $1 )",
// Convert WM style #include to Velocity directive style.
"#include\\s+([^\\s#]+)[ \\t]?",
"#include( $1 )",
// Convert WM formal reference to VTL syntax.
"\\$\\(([^\\)]+)\\)",
"${$1}",
"\\${([^}\\(]+)\\(([^}]+)}\\)", // fix encapsulated brakets: {(})
"${$1($2)}",
// Velocity currently does not permit leading underscore.
"\\$_",
"$l_",
"\\${(_[^}]+)}", // within a formal reference
"${l$1}",
// Eat semi-colons in (converted) VTL #set directives.
"(#set\\s*\\([^;]+);(\\s*\\))",
"$1$2",
// Convert explicitly terminated WM statements to VTL syntax.
"(^|[^\\\\])\\$(\\w[^=\n;'\"]*);",
"$1${$2}",
// Change extensions when seen.
"\\.wm",
".vm"
};
/**
* Iterate through the set of find/replace regexes
* that will convert a given WM template to a VM template
*/
public void convert(String target)
{
File file = new File(target);
if (!file.exists())
{
System.err.println
("The specified template or directory does not exist");
System.exit(1);
}
if (file.isDirectory())
{
String basedir = file.getAbsolutePath();
String newBasedir = basedir + VM_EXT;
DirectoryScanner ds = new DirectoryScanner();
ds.setBasedir(basedir);
ds.addDefaultExcludes();
ds.scan();
String[] files = ds.getIncludedFiles();
for (int i = 0; i < files.length; i++)
{
writeTemplate(files[i], basedir, newBasedir);
}
}
else
{
writeTemplate(file.getAbsolutePath(), "", "");
}
}
/**
* Write out the converted template to the given named file
* and base directory.
*/
private boolean writeTemplate(String file, String basedir,
String newBasedir)
{
if (file.indexOf(WM_EXT) < 0)
{
return false;
}
System.out.println("Converting " + file + "...");
String template;
String templateDir;
String newTemplate;
File outputDirectory;
if (basedir.length() == 0)
{
template = file;
templateDir = "";
newTemplate = convertName(file);
}
else
{
template = basedir + File.separator + file;
templateDir = newBasedir + extractPath(file);
outputDirectory = new File(templateDir);
if (! outputDirectory.exists())
{
outputDirectory.mkdirs();
}
newTemplate = newBasedir + File.separator + convertName(file);
}
String convertedTemplate = convertTemplate(template);
try
{
FileWriter fw = new FileWriter(newTemplate);
fw.write(convertedTemplate);
fw.close();
}
catch (Exception e)
{
e.printStackTrace();
}
return true;
}
/**
* Gets the path segment of the full path to a file (i.e. one
* which originally included the file name).
*/
private final String extractPath(String file)
{
int lastSepPos = file.lastIndexOf(File.separator);
return (lastSepPos == -1 ? "" :
File.separator + file.substring(0, lastSepPos));
}
/**
* Simple extension conversion of .wm to .vm
*/
private String convertName(String name)
{
if (name.indexOf(WM_EXT) > 0)
{
return name.substring(0, name.indexOf(WM_EXT)) + VM_EXT;
}
else
{
return name;
}
}
/**
* How to use this little puppy :-)
*/
private static final void usage()
{
System.err.println("Usage: convert-wm <template.wm | directory>");
System.exit(1);
}
/**
* Apply find/replace regexes to our WM template
*/
public String convertTemplate(String template)
{
String contents = StringUtils.fileContentsToString(template);
// Overcome Velocity 0.71 limitation.
// HELP: Is this still necessary?
if (!contents.endsWith("\n"))
{
contents += "\n";
}
// Convert most markup.
Perl5Util perl = new Perl5Util();
for (int i = 0; i < perLineREs.length; i += 2)
{
contents = perl.substitute(makeSubstRE(i), contents);
}
// Convert closing curlies.
if (perl.match("m/javascript/i", contents))
{
// ASSUMPTION: JavaScript is indented, WM is not.
contents = perl.substitute("s/\n}/\n#end/g", contents);
}
else
{
contents = perl.substitute("s/(\n\\s*)}/$1#end/g", contents);
contents = perl.substitute("s/#end\\s*\n\\s*#else/#else/g",
contents);
}
return contents;
}
/**
* Makes a Perl 5 regular expression for use by ORO.
*/
private final String makeSubstRE(int i)
{
return ("s/" + perLineREs[i] + '/' + perLineREs[i + 1] + "/g");
}
/**
* Main hook for the conversion process.
*/
public static void main(String[] args)
{
if (args.length > 0)
{
for (int x=0; x < args.length; x++)
{
WebMacro converter = new WebMacro();
converter.convert(args[x]);
}
}
else
{
usage();
}
}
}