package org.fastcatsearch.http.action.management.analysis; import java.io.CharArrayReader; import java.io.Writer; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Map.Entry; import org.apache.lucene.analysis.Analyzer; import org.apache.lucene.analysis.TokenStream; import org.apache.lucene.analysis.core.AnalyzerOption; import org.apache.lucene.analysis.tokenattributes.AdditionalTermAttribute; import org.apache.lucene.analysis.tokenattributes.CharTermAttribute; import org.apache.lucene.analysis.tokenattributes.CharsRefTermAttribute; import org.apache.lucene.analysis.tokenattributes.StopwordAttribute; import org.apache.lucene.analysis.tokenattributes.SynonymAttribute; import org.fastcatsearch.http.ActionAuthority; import org.fastcatsearch.http.ActionAuthorityLevel; import org.fastcatsearch.http.ActionMapping; import org.fastcatsearch.http.action.ActionRequest; import org.fastcatsearch.http.action.ActionResponse; import org.fastcatsearch.http.action.AuthAction; import org.fastcatsearch.ir.analysis.AnalyzerPool; import org.fastcatsearch.ir.io.CharVector; import org.fastcatsearch.plugin.Plugin; import org.fastcatsearch.plugin.PluginService; import org.fastcatsearch.plugin.analysis.AnalysisPlugin; import org.fastcatsearch.service.ServiceManager; import org.fastcatsearch.util.ResponseWriter; import org.fastcatsearch.util.ResultWriterException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @ActionMapping(value = "/management/analysis/analyze", authority = ActionAuthority.Analysis, authorityLevel = ActionAuthorityLevel.READABLE) public class GetAnalizedResultAction extends AuthAction { private static final Logger logger = LoggerFactory.getLogger(GetAnalizedResultAction.class); @Override public void doAuthAction(ActionRequest request, ActionResponse response) throws Exception { PluginService pluginService = ServiceManager.getInstance().getService(PluginService.class); String pluginId = request.getParameter("pluginId"); String analyzerId = request.getParameter("analyzerId"); String optionValues = request.getParameter("optionValues"); String[] optionValueArray; if(optionValues==null) { optionValues=""; } optionValueArray = optionValues.split(","); Map<String, String> parameterMap = request.getParameterMap(); String errorMessage = null; Writer writer = response.getWriter(); ResponseWriter responseWriter = getDefaultResponseWriter(writer); responseWriter.object(); try { Plugin plugin = pluginService.getPlugin(pluginId); if (plugin == null) { throw new Exception("Cannot find plugin >> " + (pluginId + "." + analyzerId)); } @SuppressWarnings("rawtypes") AnalysisPlugin analysisPlugin = (AnalysisPlugin) plugin; AnalyzerPool analyzerPool = analysisPlugin.getAnalyzerPool(analyzerId); if (analyzerPool == null) { throw new Exception("Cannot find analyzer >> " + (pluginId + "." + analyzerId)); } Analyzer analyzer = null; try{ analyzer = analyzerPool.getFromPool(); responseWriter.key("result").object(); for(Entry<String, String> entry : parameterMap.entrySet()) { String key = entry.getKey(); if(key.equals("pluginId") || key.equals("analyzerId") || key.equals("optionValues")){ continue; } responseWriter.key(key).array("e"); char[] fieldValue = entry.getValue().toCharArray(); AnalyzerOption options = new AnalyzerOption(); if(optionValueArray.length > 0) { options.useStopword("y".equalsIgnoreCase(optionValueArray[0])); } if(optionValueArray.length > 1) { options.useSynonym("y".equalsIgnoreCase(optionValueArray[1])); } TokenStream tokenStream = analyzer.tokenStream("", new CharArrayReader(fieldValue), options); tokenStream.reset(); CharsRefTermAttribute termAttribute = null; if (tokenStream.hasAttribute(CharsRefTermAttribute.class)) { termAttribute = tokenStream.getAttribute(CharsRefTermAttribute.class); } SynonymAttribute synonymAttribute = null; if(tokenStream.hasAttribute(SynonymAttribute.class)) { synonymAttribute = tokenStream.getAttribute(SynonymAttribute.class); } AdditionalTermAttribute additionalTermAttribute = null; if(tokenStream.hasAttribute(AdditionalTermAttribute.class)) { additionalTermAttribute = tokenStream.getAttribute(AdditionalTermAttribute.class); } StopwordAttribute stopwordAttribute = null; if(tokenStream.hasAttribute(StopwordAttribute.class)) { stopwordAttribute = tokenStream.getAttribute(StopwordAttribute.class); } CharTermAttribute charTermAttribute = tokenStream.getAttribute(CharTermAttribute.class); while (tokenStream.incrementToken()) { String word = ""; if (termAttribute != null) { word = termAttribute.toString(); } else { word = charTermAttribute.toString(); } //remove stopword if(stopwordAttribute.isStopword()) { continue; } responseWriter.value(word); appendSynonyms(responseWriter, synonymAttribute); //if found additiona term. print it. if(additionalTermAttribute !=null && additionalTermAttribute.size() > 0) { Iterator<String> termIter = additionalTermAttribute.iterateAdditionalTerms(); while(termIter.hasNext()) { String token = termIter.next(); responseWriter.value(token); appendSynonyms(responseWriter, synonymAttribute); } } } responseWriter.endArray(); } }finally{ responseWriter.endObject(); analyzerPool.releaseToPool(analyzer); } } catch (Throwable t) { errorMessage = t.toString(); logger.error("", t); } finally { if(errorMessage != null){ responseWriter.key("success").value(false); responseWriter.key("errorMessage").value(errorMessage); }else{ responseWriter.key("success").value(true); } responseWriter.endObject().done(); if (writer != null) { writer.close(); } } } private void appendSynonyms(ResponseWriter responseWriter, SynonymAttribute synonymAttribute) throws ResultWriterException { //synonym extraction if (synonymAttribute!=null) { @SuppressWarnings("rawtypes") List synonyms = synonymAttribute.getSynonyms(); if(synonyms != null) { for(Object synonymObj : synonyms) { if(synonymObj instanceof CharVector) { CharVector synonym = (CharVector)synonymObj; responseWriter.value(synonym.toString()); } else if(synonymObj instanceof List) { @SuppressWarnings("rawtypes") List synonymList = (List)synonymObj; for(Object synonym : synonymList) { responseWriter.value(synonym.toString()); } } } } } } }