昔、Velocity をよく使ったことがある。最近は使うことがなくなってきたものの、
やはりメッセージなどを単純なテンプレートから作成するケースはまだ発生する。
例えば、{0},{1},{2}...という{ }で囲んだ数字部分を、任意の要素配列で順に
置換(マージ)するのに、いちいち Velocity を使うのも、
プロジェクトにライブラリ追加させて貰うのに面倒なことがある。
処理速度が遅いと思いつつも、代用品を書いてみた。
{ }で囲む数字n、{n}のエスケープ、そのまま{n} にするようにする。
エスケープ文字は、'/' で、{ }の前に置く約束にする。
/{0} のように書いたら、{0}と置換されない。
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Collection;
/**
* Belocity メッセージテンプレート置換
*/
public class Belocity{
private String template;
public Belocity(String template){
this.template = template;
}
public Belocity(InputStream stream){
int i;
try{
ByteArrayOutputStream bos = new ByteArrayOutputStream();
while*1 != -1){
bos.write(i);
}
stream.close();
bos.close();
this.template = new String(bos.toByteArray());
}catch(IOException e){
throw new RuntimeException(e.getMessage(),e);
}
}
public Belocity(InputStream stream,String charset){
int i;
try{
ByteArrayOutputStream bos = new ByteArrayOutputStream();
while*2 != -1){
bos.write(i);
}
stream.close();
bos.close();
this.template = new String(bos.toByteArray(),charset);
}catch(IOException e){
throw new RuntimeException(e.getMessage(),e);
}
}
/**
* マージ実行
* @param elements 置換文字列の配列
* @return マージ結果文字列
*/
public String merge(Object...elements){
String s = template;
int n=0;
for(Object e : elements){
String tary = s.split("/\\{"+n+"\\}");
int k=0;
for(String ts : tary){
tary[k] = ts.replaceAll("\\{"+n+"\\}",e.toString());
k++;
}
s = this.belocityjoin(tary,"{"+n+"}");
n++;
}
return s;
}
/**
* マージ実行ストリーム出力
* @param out OutputStream
* @param charset 文字キャラクタ
* @param elements 置換文字列の配列
*/
public void mergeStream(OutputStream out,String charset,Object...elements){
String s = template;
int n=0;
for(Object e : elements){
String tary = s.split("/\\{"+n+"\\}");
int k=0;
for(String ts : tary){
tary[k] = ts.replaceAll("\\{"+n+"\\}",e.toString());
k++;
}
s = this.belocityjoin(tary,"{"+n+"}");
n++;
}
try{
out.write(s.getBytes(charset));
out.close();
}catch(IOException e){
throw new RuntimeException(e.getMessage(),e);
}
}
/**
* マージ実行(リスト)
* @param elements 置換文字列のCollection
* @return マージ結果文字列
*/
public String mergeList(Collection<?> elements){
String s = template;
int n=0;
for(Object e : elements){
String tary = s.split("/\\{"+n+"\\}");
int k=0;
for(String ts : tary){
tary[k] = ts.replaceAll("\\{"+n+"\\}",e.toString());
k++;
}
s = this.belocityjoin(tary,"{"+n+"}");
n++;
}
return s;
}
/**
* マージ実行ストリーム出力(リスト)
* @param out OutputStream
* @param elements 置換文字列のCollection
*/
public void mergeList(OutputStream out,Collection<?> elements){
String s = template;
int n=0;
for(Object e : elements){
String tary = s.split("/\\{"+n+"\\}");
int k=0;
for(String ts : tary){
tary[k] = ts.replaceAll("\\{"+n+"\\}",e.toString());
k++;
}
s = this.belocityjoin(tary,"{"+n+"}");
n++;
}
try{
out.write(s.getBytes());
out.close();
}catch(IOException e){
throw new RuntimeException(e.getMessage(),e);
}
}
/**
* マージ実行ストリーム出力(リスト)
* @param out OutputStream
* @param charset 文字キャラクタ
* @param elements 置換文字列のCollection
*/
public void mergeList(OutputStream out,String charset,Collection<?> elements){
String s = template;
int n=0;
for(Object e : elements){
String tary = s.split("/\\{"+n+"\\}");
int k=0;
for(String ts : tary){
tary[k] = ts.replaceAll("\\{"+n+"\\}",e.toString());
k++;
}
s = this.belocityjoin(tary,"{"+n+"}");
n++;
}
try{
out.write(s.getBytes(charset));
out.close();
}catch(IOException e){
throw new RuntimeException(e.getMessage(),e);
}
}
private String belocityjoin(String ary,String s){
StringBuilder sb = new StringBuilder(ary[0]);
for(int i=1;i < ary.length;i++){
sb.append(s);
sb.append(ary[i]);
}
return sb.toString();
}
}
-------------------------------
テストは、、、、
StringBuilder sb = new StringBuilder();
sb.append("Belocity test \n");
sb.append("test 1 /{0} : {0} \n");
sb.append("test 2 /{1} : {1} and {1} and {1}\n");
sb.append("test 3 /{2} : {2}{2} \n");
Belocity belocity = new Belocity(sb.toString());
String res = belocity.merge("A",245,"テスト");
System.out.println(res);
-------------------------------
結果は、、、
Belocity test
test 1 {0} : A
test 2 {1} : 245 and 245 and 245
test 3 {2} : テストテスト