package bsh.servlet;
/**
This file is derived from Pat Niemeyer's free utilities package.
Now part of BeanShell.
@see http://www.pat.net/javautil/
@version 1.0
@author Pat Niemeyer ([email protected])
*/
import java.io.*;
import java.util.*;
import java.net.URL;
/**
This is a simple template engine. An instance of SimpleTemplate wraps
a StringBuffer and performs replace operations on one or more parameters
embedded as HMTL style comments. The value can then be retrieved as a
String or written to a stream.
Template values in the text are of the form:
<!-- TEMPLATE-NAME -->
Substitutions then take the form of:
template.replace( "NAME", value );
Two static util methods are provided to help read the text of a template
from a stream (perhaps a URL or resource). e.g.
@author Pat Niemeyer
*/
public class SimpleTemplate
{
StringBuffer buff;
static String NO_TEMPLATE = "NO_TEMPLATE"; // Flag for non-existent
static Map templateData = new HashMap();
static boolean cacheTemplates = true;
/**
Get a template by name, with caching.
Note: this should be updated to search the resource path first, etc.
Create a new instance of a template from the specified file.
The file text is cached so lookup is fast. Failure to find the
file is also cached so the read will not happen twice.
*/
public static SimpleTemplate getTemplate( String file )
{
String templateText = (String)templateData.get( file );
if ( templateText == null || !cacheTemplates ) {
try {
FileReader fr = new FileReader( file );
templateText = SimpleTemplate.getStringFromStream( fr );
templateData.put( file, templateText );
} catch ( IOException e ) {
// Not found
templateData.put( file, NO_TEMPLATE );
}
} else
// Quick check prevents trying each time
if ( templateText.equals( NO_TEMPLATE ) )
return null;
if ( templateText == null )
return null;
else
return new SimpleTemplate( templateText );
}
public static String getStringFromStream( InputStream ins )
throws IOException
{
return getStringFromStream( new InputStreamReader( ins ) );
}
public static String getStringFromStream( Reader reader ) throws IOException {
StringBuffer sb = new StringBuffer();
BufferedReader br = new BufferedReader( reader );
String line;
while ( ( line = br.readLine() ) != null )
sb.append( line +"\n");
return sb.toString();
}
public SimpleTemplate( String template ) {
init(template);
}
public SimpleTemplate( Reader reader ) throws IOException {
String template = getStringFromStream( reader );
init(template);
}
public SimpleTemplate( URL url ) throws IOException
{
String template = getStringFromStream( url.openStream() );
init(template);
}
private void init( String s ) {
buff = new StringBuffer( s );
}
/**
Substitute the specified text for the parameter
*/
public void replace( String param, String value ) {
int [] range;
while ( (range = findTemplate( param )) != null )
buff.replace( range[0], range[1], value );
}
/**
Find the starting (inclusive) and ending (exclusive) index of the
named template and return them as a two element int [].
Or return null if the param is not found.
*/
int [] findTemplate( String name ) {
String text = buff.toString();
int len = text.length();
int start = 0;
while ( start < len ) {
// Find begin and end comment
int cstart = text.indexOf( "<!--", start );
if ( cstart == -1 )
return null; // no more comments
int cend = text.indexOf( "-->", cstart );
if ( cend == -1 )
return null; // no more complete comments
cend += "-->".length();
// Find template tag
int tstart = text.indexOf( "TEMPLATE-", cstart );
if ( tstart == -1 ) {
start = cend; // try the next comment
continue;
}
// Is the tag inside the comment we found?
if ( tstart > cend ) {
start = cend; // try the next comment
continue;
}
// find begin and end of param name
int pstart = tstart + "TEMPLATE-".length();
int pend = len;
for ( pend = pstart; pend < len; pend++) {
char c = text.charAt( pend );
if ( c == ' ' || c == '\t' || c == '-' )
break;
}
if ( pend >= len )
return null;
String param = text.substring( pstart, pend );
// If it's the correct one, return the comment extent
if ( param.equals( name ) )
return new int [] { cstart, cend };
//System.out.println( "Found param: {"+param+"} in comment: "+ text.substring(cstart, cend) +"}");
// Else try the next one
start = cend;
}
// Not found
return null;
}
public String toString() {
return buff.toString();
}
public void write( PrintWriter out ) {
out.println( toString() );
}
public void write( PrintStream out ) {
out.println( toString() );
}
/**
usage: filename param value
*/
public static void main( String [] args ) throws IOException
{
String filename = args[0];
String param = args[1];
String value = args[2];
FileReader fr = new FileReader( filename );
String templateText = SimpleTemplate.getStringFromStream( fr );
SimpleTemplate template = new SimpleTemplate( templateText );
template.replace( param, value );
template.write( System.out );
}
public static void setCacheTemplates( boolean b ) {
cacheTemplates = b;
}
}
|