package net.sourceforge.gpstools.utils;
/* gpsdings
* Copyright (C) 2006 Moritz Ringler
* $Id: TemplateProcessor.java 441 2010-12-13 20:04:20Z ringler $
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.UnsupportedEncodingException;
import java.nio.CharBuffer;
import java.nio.charset.Charset;
public class TemplateProcessor{
private final Charset enc;
public TemplateProcessor(String encoding) throws UnsupportedEncodingException{
enc = Charset.forName(encoding);
}
public TemplateProcessor(Charset cs){
enc = cs;
}
public void readWriteTemplate(String resourceName,
OutputStream out,
TemplateHandler handler) throws IOException {
InputStream in = getClass().getResourceAsStream(resourceName);
if(in == null){
throw new IllegalArgumentException("Resource " + resourceName + " not found");
}
try{
readWriteTemplate(in, out, handler);
} finally {
in.close();
}
}
public void readWriteTemplate(InputStream in,
OutputStream out,
TemplateHandler handler) throws IOException {
InputStreamReader iw = new InputStreamReader(in, enc);
OutputStreamWriter ow = new OutputStreamWriter(out, enc);
readWriteTemplate(this, iw, ow, handler);
ow.flush();
}
private static int read(Readable source, CharBuffer buff) throws IOException{
buff.clear();
int len = source.read(buff);
buff.flip();
return len;
}
public static void readWriteTemplate(Object eventSource, Readable source, Appendable dest, TemplateHandler handler) throws IOException{
final int buffsize = 4096;
char[] buffc = new char[buffsize];
CharBuffer buff = CharBuffer.wrap(buffc);
buff.clear();
// READSOURCE:
for (int len = read(source, buff);
len != -1;
len = read(source, buff))
{
int start = 0;
/* look for a $ that introduces a variable */
// FINDDOLLAR:
for(int i=0; i < len; i++){
if( buff.charAt(i) == '$' ){
/* write leading non-variable part to dest */
if(start != i){
dest.append(buff, start, i);
}
/* read the variable name */
StringBuilder sb = new StringBuilder(80);
i++; //skip $
// BUILDVARNAME:
do{
/* check if we have reached the end of the buffer */
if(i == len){
/* re-fill the buffer from the source */
len = read(source, buff);
i = 0;
}
for(char c; i < len; i++){
c = buff.charAt(i);
if(Character.isLetter(c)){
sb.append(c);
} else {
break;
}
}
} while (i == len);
/* reset start to the first char after the variable name
* and decrement i to allow for two immediately consecutive
* variables. */
start = i--;
/* handle the variable */
handler.handleTemplateEvent(new TemplateEvent(eventSource, sb.toString(), dest));
}
}
/* write terminal non-variable part to dest */
if(start != len){
dest.append(buff, start, len);
}
/* If we've already hit the end of the source
we break the READSOURCE loop here */
if (len == -1){
break;
}
}
}
}