20 package org.sleuthkit.autopsy.keywordsearch;
 
   22 import java.util.ArrayList;
 
   23 import java.util.Collection;
 
   24 import java.util.HashSet;
 
   25 import java.util.List;
 
   27 import java.util.logging.Level;
 
   29 import java.util.regex.Pattern;
 
   30 import java.util.regex.PatternSyntaxException;
 
   31 import org.apache.solr.client.solrj.SolrQuery;
 
   32 import org.apache.solr.client.solrj.response.TermsResponse;
 
   33 import org.apache.solr.client.solrj.response.TermsResponse.Term;
 
   45 class TermComponentQuery 
implements KeywordSearchQuery {
 
   47     private static final int TERMS_UNLIMITED = -1;
 
   49     private static final String TERMS_SEARCH_FIELD = Server.Schema.CONTENT_WS.toString();
 
   50     private static final String TERMS_HANDLER = 
"/terms"; 
 
   51     private static final int TERMS_TIMEOUT = 90 * 1000; 
 
   52     private static final Logger logger = Logger.getLogger(TermComponentQuery.class.getName());
 
   53     private String queryEscaped;
 
   54     private final KeywordList keywordList;
 
   55     private final Keyword keyword;
 
   56     private boolean isEscaped;
 
   57     private List<Term> terms;
 
   58     private final List<KeywordQueryFilter> filters = 
new ArrayList<>();
 
   60     private static final int MAX_TERMS_RESULTS = 20000;
 
   62     private static final boolean DEBUG = (Version.getBuildType() == Version.Type.DEVELOPMENT);
 
   64     public TermComponentQuery(KeywordList keywordList, Keyword keyword) {
 
   66         this.keyword = keyword;
 
   67         this.keywordList = keywordList;
 
   68         this.queryEscaped = keyword.getQuery();
 
   74     public void addFilter(KeywordQueryFilter filter) {
 
   75         this.filters.add(filter);
 
   79     public void setField(String field) {
 
   84     public void setSubstringQuery() {
 
   85         queryEscaped = 
".*" + queryEscaped + 
".*";
 
   89     public void escape() {
 
   90         queryEscaped = Pattern.quote(keyword.getQuery());
 
   95     public boolean validate() {
 
   96         if (queryEscaped.equals(
"")) {
 
  100         boolean valid = 
true;
 
  102             Pattern.compile(queryEscaped);
 
  103         } 
catch (PatternSyntaxException ex1) {
 
  105         } 
catch (IllegalArgumentException ex2) {
 
  112     public boolean isEscaped() {
 
  117     public boolean isLiteral() {
 
  124     protected SolrQuery createQuery() {
 
  125         final SolrQuery q = 
new SolrQuery();
 
  126         q.setRequestHandler(TERMS_HANDLER);
 
  128         q.setTermsLimit(TERMS_UNLIMITED);
 
  129         q.setTermsRegexFlag(
"case_insensitive"); 
 
  133         q.setTermsRegex(queryEscaped);
 
  134         q.addTermsField(TERMS_SEARCH_FIELD);
 
  135         q.setTimeAllowed(TERMS_TIMEOUT);
 
  144     protected List<Term> executeQuery(SolrQuery q) 
throws NoOpenCoreException {
 
  146             Server solrServer = KeywordSearch.getServer();
 
  147             TermsResponse tr = solrServer.queryTerms(q);
 
  148             List<Term> termsCol = tr.getTerms(TERMS_SEARCH_FIELD);
 
  150         } 
catch (KeywordSearchModuleException ex) {
 
  151             logger.log(Level.WARNING, 
"Error executing the regex terms query: " + keyword.getQuery(), ex); 
 
  157     public String getEscapedQueryString() {
 
  158         return this.queryEscaped;
 
  162     public String getQueryString() {
 
  163         return keyword.getQuery();
 
  169     public KeywordCachedArtifact writeSingleFileHitsToBlackBoard(String termHit, KeywordHit hit, String snippet, String listName) {
 
  170         final String MODULE_NAME = KeywordSearchModuleFactory.getModuleName();
 
  173         BlackboardArtifact bba;
 
  174         KeywordCachedArtifact writeResult;
 
  175         Collection<BlackboardAttribute> attributes = 
new ArrayList<>();
 
  177             bba = hit.getContent().newArtifact(ARTIFACT_TYPE.TSK_KEYWORD_HIT);
 
  178             writeResult = 
new KeywordCachedArtifact(bba);
 
  179         } 
catch (Exception e) {
 
  180             logger.log(Level.WARNING, 
"Error adding bb artifact for keyword hit", e); 
 
  185         attributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_KEYWORD.getTypeID(), MODULE_NAME, termHit));
 
  187         if ((listName != null) && (listName.equals(
"") == 
false)) {
 
  188             attributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_SET_NAME.getTypeID(), MODULE_NAME, listName));
 
  192         if (snippet != null) {
 
  193             attributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_KEYWORD_PREVIEW.getTypeID(), MODULE_NAME, snippet));
 
  196         attributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_KEYWORD_REGEXP.getTypeID(), MODULE_NAME, keyword.getQuery()));
 
  198         if (hit.isArtifactHit()) {
 
  199             attributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_ASSOCIATED_ARTIFACT.getTypeID(), MODULE_NAME, hit.getArtifact().getArtifactID()));
 
  203             bba.addAttributes(attributes);
 
  204             writeResult.add(attributes);
 
  206         } 
catch (TskException e) {
 
  207             logger.log(Level.WARNING, 
"Error adding bb attributes for terms search artifact", e); 
 
  214     public QueryResults performQuery() throws NoOpenCoreException {
 
  216         final SolrQuery q = createQuery();
 
  217         q.setShowDebugInfo(DEBUG);
 
  218         q.setTermsLimit(MAX_TERMS_RESULTS); 
 
  219         logger.log(Level.INFO, 
"Query: {0}", q.toString()); 
 
  220         terms = executeQuery(q);
 
  222         QueryResults results = 
new QueryResults(
this, keywordList);
 
  225         for (Term term : terms) {
 
  226             final String termStr = KeywordSearchUtil.escapeLuceneQuery(term.getTerm());
 
  228             LuceneQuery filesQuery = 
new LuceneQuery(keywordList, 
new Keyword(termStr, 
true));
 
  231             for (KeywordQueryFilter filter : filters) {
 
  235                 filesQuery.addFilter(filter);
 
  238                 QueryResults subResults = filesQuery.performQuery();
 
  239                 Set<KeywordHit> filesResults = 
new HashSet<>();
 
  240                 for (Keyword key : subResults.getKeywords()) {
 
  241                     List<KeywordHit> keyRes = subResults.getResults(key);
 
  242                     resultSize += keyRes.size();
 
  243                     filesResults.addAll(keyRes);
 
  245                 results.addResult(
new Keyword(term.getTerm(), 
false), 
new ArrayList<>(filesResults));
 
  246             } 
catch (NoOpenCoreException e) {
 
  247                 logger.log(Level.WARNING, 
"Error executing Solr query,", e); 
 
  249             } 
catch (RuntimeException e) {
 
  250                 logger.log(Level.WARNING, 
"Error executing Solr query,", e); 
 
  256         logger.log(Level.INFO, 
"Regex # results: {0}", resultSize); 
 
  262     public KeywordList getKeywordList() {