/*
* Copyright 2000-2013 Enonic AS
* http://www.enonic.com/license
*/
package com.enonic.cms.server.service.admin.mvc.controller;
import java.io.PrintWriter;
import java.io.Writer;
import java.util.Map;
public final class TranslationWriter
extends PrintWriter
{
/**
* The language map.
*/
private Map translationMap;
/**
* State: Listen. The translation writer listens for the variable start character (%).
*/
private static int LISTEN = 0;
/**
* State: Inside variable. The translation writer are inside a variable.
*/
private static int INSIDE_VARIABLE = 1;
/**
* State: Variable finished. The translation writer just read the variable end character (%).
*/
//private static int VARIABLE_FINISHED = 2;
/**
* The translation writer state. Initial state: Listen.
*/
private int state = LISTEN;
/**
* The current variable. Empty when in listen state.
*/
protected StringBuffer variable = new StringBuffer();
/**
* Creates a new translation writer.
*
* @param translationMap
* @param out a writer to print out to
*/
public TranslationWriter( Map translationMap, Writer out )
{
super( out );
this.translationMap = translationMap;
}
/**
* Writes a single character and handles translation of variables.
*
* @param c
*/
public void write( int c )
{
// if we are listening for a tag start..
if ( state == LISTEN )
{
if ( c == '%' )
{
state = INSIDE_VARIABLE;
variable.append( '%' );
}
else
{
super.write( c );
}
}
// if we are inside a tag..
else if ( state == INSIDE_VARIABLE )
{
// if the tag is closed..
if ( c == '%' )
{
variable.append( '%' );
translate();
state = LISTEN;
variable.setLength( 0 );
return;
}
// A variable may contain only letters a-z/A-Z and numbers 0-9
boolean letter = ( ( c >= 'a' && c <= 'z' ) || ( c >= 'A' && c <= 'Z' ) );
boolean number = ( c >= '0' && c <= '9' );
// If it is not a letter or number, or it does not start with a letter
if ( !( letter || number ) || ( variable.length() == 1 && !letter ) )
{
variable.append( (char) c );
super.write( variable.toString() );
variable.setLength( 0 );
state = LISTEN;
}
else
{
variable.append( (char) c );
}
}
}
/**
* Translate the variable.
*/
private void translate()
{
String key = variable.toString();
if ( translationMap.containsKey( key ) )
{
String translated = (String) translationMap.get( key );
write( translated );
}
else
{
write( key );
}
}
/**
* @see java.io.Writer#close()
*/
public void close()
{
if ( variable.length() > 0 )
{
write( variable.toString() );
super.flush();
}
super.close();
}
/**
* @see java.io.Writer#flush()
*/
public void flush()
{
super.flush();
}
/**
* @see java.io.Writer#write(char[],int,int)
*/
public void write( char[] cbuf, int off, int len )
{
for ( int i = off; i < off + len; i++ )
{
write( cbuf[i] );
}
}
}