package jef.database.test;
import java.io.BufferedReader;
import java.io.CharArrayReader;
import java.io.IOException;
import java.io.Reader;
import java.io.Writer;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import jef.common.log.LogUtil;
/**
* 这个类可以监听数据库日志,在单元测试中可以使用正则表达式从日志中提取需要验证的信息。
* @author jiyi
*
*/
public class LogListener extends Writer{
private Pattern pattern;
private final List<String[]> sqls=new ArrayList<String[]>();
/**
* 构造
* @param regexp 要提取的日志信息的正则表达式
*/
public LogListener(String regexp) {
this.pattern=Pattern.compile(regexp);
LogUtil.addOutput(this);
}
/**
*
* @param regexp 要提取的日志信息的正则表达式
* @param flag
*/
public LogListener(String regexp,int flag) {
this.pattern=Pattern.compile(regexp,flag);
LogUtil.addOutput(this);
}
@Override
public void write(char[] cbuf, int off, int len) throws IOException {
BufferedReader sr=new BufferedReader(new CharArrayReader(cbuf,off,len));
String s;
while((s=sr.readLine())!=null){
Matcher m=pattern.matcher(s);
if(m.matches()){
int n=m.groupCount();
if(n==0){
sqls.add(new String[]{m.group()});
}else{
String[] result=new String[n];
for(int i=1;i<=n;i++){
result[i-1]=m.group(i);
}
sqls.add(result);
}
}
}
}
/**
* 返回匹配的日志中的各个匹配项。
*
* 调用此方法后,监听器不再监听。
* @return 匹配的日志必须仅有一条,如果没有发现匹配日志或者有多条将抛出异常。
*/
public String[] getSingleMatch(){
stop();
if(sqls.isEmpty()){
throw new IllegalArgumentException("No Match Log found for "+ pattern);
}else if(sqls.size()>1){
throw new IllegalArgumentException("There are "+sqls.size()+" Matches Log found for "+ pattern);
}
return sqls.remove(sqls.size()-1);
}
/**
* 返回所有的匹配项
*
* 调用此方法后,监听器不再监听。
* @return
*/
public List<String[]> getAllMatches(){
stop();
List<String[]> result=new ArrayList<String[]>(sqls);
sqls.clear();
return result;
}
/**
* 返回最后一个匹配项
*
* 调用此方法后,监听器还将继续监听。
* @return
*/
public String[] getLastMatch(){
if(sqls.isEmpty()){
throw new IllegalArgumentException("No Match Log found for "+ pattern);
}
return sqls.remove(sqls.size()-1);
}
/**
* 返回最后一个匹配项
* 调用此方法后,监听器还将继续监听。
* @return
*/
public String getLastMatchString(){
if(sqls.isEmpty()){
throw new IllegalArgumentException("No Match Log found for "+ pattern);
}
return sqls.remove(sqls.size()-1)[0];
}
public void close(){
stop();
sqls.clear();
pattern=null;
}
private void stop() {
LogUtil.removeOutput(this);
}
@Override
public void flush() throws IOException {
}
}