package lia.analysis.synonym;
import org.apache.lucene.analysis.TokenStream;
import org.apache.lucene.analysis.TokenFilter;
import org.apache.lucene.analysis.Token;
import java.io.IOException;
import java.util.Stack;
public class SynonymFilter extends TokenFilter {
public static final String TOKEN_TYPE_SYNONYM = "SYNONYM";
private Stack synonymStack;
private SynonymEngine engine;
public SynonymFilter(TokenStream in, SynonymEngine engine) {
super(in);
synonymStack = new Stack();
this.engine = engine;
}
public Token next() throws IOException {
if (synonymStack.size() > 0) { // 유의어 스택에 토큰이 있다면 리턴
return (Token) synonymStack.pop();
}
Token token = input.next(); // 토큰 스트림에서 다음 토큰 가져오기..
if (token == null) {
return null;
}
addAliasesToStack(token); //유의어를 찾아서 스택에 쌓는다.
return token; // 원래 토큰을 우선 리턴
}
private void addAliasesToStack(Token token) throws IOException {
String[] synonyms = engine.getSynonyms(token.termText());
if (synonyms == null) return;
for (int i = 0; i < synonyms.length; i++) {
Token synToken = new Token(synonyms[i],
token.startOffset(),
token.endOffset(),
TOKEN_TYPE_SYNONYM);
synToken.setPositionIncrement(0);
synonymStack.push(synToken);
}
}
}
방식이 우선 원래 토큰을 리턴해주고
원래 토큰에 대한 유의어를 스택에 쌓아둔 다음에
next호출때 그 유의어들을 차례대로 리턴해준다.
유의어를 리턴해줄때는 원래 단어와 같은 위치에 존재함을 알려주기 위해
위치 증가값을 0으로 지정한다.
(원래 토큰의 위치가 1이면, 이 유의어들도 1..)