Coverage Report - org.owasp.dependencycheck.data.lucene.AbstractIndex
 
Classes in this File Line Coverage Branch Coverage Complexity
AbstractIndex
54%
46/85
57%
15/26
1.947
 
 1  
 /*
 2  
  * This file is part of dependency-check-core.
 3  
  *
 4  
  * Dependency-check-core is free software: you can redistribute it and/or modify it
 5  
  * under the terms of the GNU General Public License as published by the Free
 6  
  * Software Foundation, either version 3 of the License, or (at your option) any
 7  
  * later version.
 8  
  *
 9  
  * Dependency-check-core is distributed in the hope that it will be useful, but
 10  
  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 11  
  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
 12  
  * details.
 13  
  *
 14  
  * You should have received a copy of the GNU General Public License along with
 15  
  * dependency-check-core. If not, see http://www.gnu.org/licenses/.
 16  
  *
 17  
  * Copyright (c) 2012 Jeremy Long. All Rights Reserved.
 18  
  */
 19  
 package org.owasp.dependencycheck.data.lucene;
 20  
 
 21  
 import java.io.IOException;
 22  
 import java.util.logging.Level;
 23  
 import java.util.logging.Logger;
 24  
 import org.apache.lucene.analysis.Analyzer;
 25  
 import org.apache.lucene.document.Document;
 26  
 import org.apache.lucene.index.CorruptIndexException;
 27  
 import org.apache.lucene.index.DirectoryReader;
 28  
 import org.apache.lucene.index.IndexReader;
 29  
 import org.apache.lucene.index.IndexWriter;
 30  
 import org.apache.lucene.index.IndexWriterConfig;
 31  
 import org.apache.lucene.queryparser.classic.ParseException;
 32  
 import org.apache.lucene.queryparser.classic.QueryParser;
 33  
 import org.apache.lucene.search.IndexSearcher;
 34  
 import org.apache.lucene.search.Query;
 35  
 import org.apache.lucene.search.TopDocs;
 36  
 import org.apache.lucene.store.Directory;
 37  
 import org.apache.lucene.store.LockObtainFailedException;
 38  
 import org.apache.lucene.util.Version;
 39  
 
 40  
 /**
 41  
  * The base Index for other index objects. Implements the open and close
 42  
  * methods.
 43  
  *
 44  
  * @author Jeremy Long (jeremy.long@owasp.org)
 45  
  */
 46  30
 public abstract class AbstractIndex {
 47  
 
 48  
     /**
 49  
      * The Lucene directory containing the index.
 50  
      */
 51  
     private Directory directory;
 52  
     /**
 53  
      * The IndexWriter for the Lucene index.
 54  
      */
 55  
     private IndexWriter indexWriter;
 56  
     /**
 57  
      * The Lucene IndexReader.
 58  
      */
 59  
     private IndexReader indexReader;
 60  
     /**
 61  
      * The Lucene IndexSearcher.
 62  
      */
 63  
     private IndexSearcher indexSearcher;
 64  
     /**
 65  
      * The Lucene Analyzer used for Indexing.
 66  
      */
 67  
     private Analyzer indexingAnalyzer;
 68  
     /**
 69  
      * The Lucene Analyzer used for Searching.
 70  
      */
 71  
     private Analyzer searchingAnalyzer;
 72  
     /**
 73  
      * The Lucene QueryParser used for Searching.
 74  
      */
 75  
     private QueryParser queryParser;
 76  
     /**
 77  
      * Indicates whether or not the Lucene Index is open.
 78  
      */
 79  30
     private boolean indexOpen = false;
 80  
 
 81  
     /**
 82  
      * Opens the CPE Index.
 83  
      *
 84  
      * @throws IOException is thrown if an IOException occurs opening the index.
 85  
      */
 86  
     public void open() throws IOException {
 87  27
         directory = this.getDirectory();
 88  27
         indexingAnalyzer = this.getIndexingAnalyzer();
 89  27
         searchingAnalyzer = this.getSearchingAnalyzer();
 90  27
         indexOpen = true;
 91  27
     }
 92  
 
 93  
     /**
 94  
      * Commits any pending changes.
 95  
      */
 96  
     public void commit() {
 97  0
         if (indexWriter != null) {
 98  
             try {
 99  0
                 indexWriter.commit();
 100  0
             } catch (CorruptIndexException ex) {
 101  0
                 final String msg = "Unable to update database, there is a corrupt index.";
 102  0
                 Logger.getLogger(AbstractIndex.class.getName()).log(Level.SEVERE, msg);
 103  0
                 Logger.getLogger(AbstractIndex.class.getName()).log(Level.FINE, null, ex);
 104  0
             } catch (IOException ex) {
 105  0
                 final String msg = "Unable to update database due to an IO error.";
 106  0
                 Logger.getLogger(AbstractIndex.class.getName()).log(Level.SEVERE, msg);
 107  0
                 Logger.getLogger(AbstractIndex.class.getName()).log(Level.FINE, null, ex);
 108  0
             }
 109  
         }
 110  0
     }
 111  
 
 112  
     /**
 113  
      * Closes the CPE Index.
 114  
      */
 115  
     public void close() {
 116  27
         if (indexWriter != null) {
 117  0
             commit();
 118  
             try {
 119  0
                 indexWriter.close(true);
 120  0
             } catch (CorruptIndexException ex) {
 121  0
                 final String msg = "Unable to update database, there is a corrupt index.";
 122  0
                 Logger.getLogger(AbstractIndex.class.getName()).log(Level.SEVERE, msg);
 123  0
                 Logger.getLogger(AbstractIndex.class.getName()).log(Level.FINE, null, ex);
 124  0
             } catch (IOException ex) {
 125  0
                 final String msg = "Unable to update database due to an IO error.";
 126  0
                 Logger.getLogger(AbstractIndex.class.getName()).log(Level.SEVERE, msg);
 127  0
                 Logger.getLogger(AbstractIndex.class.getName()).log(Level.FINE, null, ex);
 128  
             } finally {
 129  0
                 indexWriter = null;
 130  0
             }
 131  
         }
 132  27
         if (indexSearcher != null) {
 133  21
             indexSearcher = null;
 134  
         }
 135  
 
 136  27
         if (indexingAnalyzer != null) {
 137  27
             indexingAnalyzer.close();
 138  27
             indexingAnalyzer = null;
 139  
         }
 140  
 
 141  27
         if (searchingAnalyzer != null) {
 142  27
             searchingAnalyzer.close();
 143  27
             searchingAnalyzer = null;
 144  
         }
 145  
 
 146  
         try {
 147  27
             directory.close();
 148  0
         } catch (IOException ex) {
 149  0
             final String msg = "Unable to update database due to an IO error.";
 150  0
             Logger.getLogger(AbstractIndex.class.getName()).log(Level.SEVERE, msg);
 151  0
             Logger.getLogger(AbstractIndex.class.getName()).log(Level.FINE, null, ex);
 152  
         } finally {
 153  27
             directory = null;
 154  27
         }
 155  27
         indexOpen = false;
 156  27
     }
 157  
 
 158  
     /**
 159  
      * Returns the status of the data source - is the index open.
 160  
      *
 161  
      * @return true or false.
 162  
      */
 163  
     public boolean isOpen() {
 164  37
         return indexOpen;
 165  
     }
 166  
 
 167  
     /**
 168  
      * Opens the Lucene Index Writer.
 169  
      *
 170  
      * @throws CorruptIndexException is thrown if the Lucene index is corrupt.
 171  
      * @throws IOException is thrown if an IOException occurs opening the index.
 172  
      */
 173  
     public void openIndexWriter() throws CorruptIndexException, IOException {
 174  0
         if (!isOpen()) {
 175  0
             open();
 176  
         }
 177  0
         final IndexWriterConfig conf = new IndexWriterConfig(Version.LUCENE_43, indexingAnalyzer);
 178  0
         indexWriter = new IndexWriter(directory, conf);
 179  0
     }
 180  
 
 181  
     /**
 182  
      * Retrieves the IndexWriter for the Lucene Index.
 183  
      *
 184  
      * @return an IndexWriter.
 185  
      * @throws CorruptIndexException is thrown if the Lucene Index is corrupt.
 186  
      * @throws LockObtainFailedException is thrown if there is an exception
 187  
      * obtaining a lock on the Lucene index.
 188  
      * @throws IOException is thrown if an IOException occurs opening the index.
 189  
      */
 190  
     public IndexWriter getIndexWriter() throws CorruptIndexException, LockObtainFailedException, IOException {
 191  0
         if (indexWriter == null) {
 192  0
             openIndexWriter();
 193  
         }
 194  0
         return indexWriter;
 195  
     }
 196  
 
 197  
     /**
 198  
      * Opens the Lucene Index for reading.
 199  
      *
 200  
      * @throws CorruptIndexException is thrown if the index is corrupt.
 201  
      * @throws IOException is thrown if there is an exception reading the index.
 202  
      */
 203  
     public void openIndexReader() throws CorruptIndexException, IOException {
 204  21
         if (!isOpen()) {
 205  0
             open();
 206  
         }
 207  
         //indexReader = IndexReader.open(directory, true);
 208  21
         indexReader = DirectoryReader.open(directory);
 209  21
     }
 210  
 
 211  
     /**
 212  
      * Returns an IndexSearcher for the Lucene Index.
 213  
      *
 214  
      * @return an IndexSearcher.
 215  
      * @throws CorruptIndexException is thrown if the index is corrupt.
 216  
      * @throws IOException is thrown if there is an exception reading the index.
 217  
      */
 218  
     protected IndexSearcher getIndexSearcher() throws CorruptIndexException, IOException {
 219  2820
         if (indexReader == null) {
 220  21
             openIndexReader();
 221  
         }
 222  2820
         if (indexSearcher == null) {
 223  21
             indexSearcher = new IndexSearcher(indexReader);
 224  
         }
 225  2820
         return indexSearcher;
 226  
     }
 227  
 
 228  
     /**
 229  
      * Returns an Analyzer to be used when indexing.
 230  
      *
 231  
      * @return an Analyzer.
 232  
      */
 233  
     public Analyzer getIndexingAnalyzer() {
 234  27
         if (indexingAnalyzer == null) {
 235  27
             indexingAnalyzer = createIndexingAnalyzer();
 236  
         }
 237  27
         return indexingAnalyzer;
 238  
     }
 239  
 
 240  
     /**
 241  
      * Returns an analyzer used for searching the index
 242  
      *
 243  
      * @return a lucene analyzer
 244  
      */
 245  
     protected Analyzer getSearchingAnalyzer() {
 246  48
         if (searchingAnalyzer == null) {
 247  27
             searchingAnalyzer = createSearchingAnalyzer();
 248  
         }
 249  48
         return searchingAnalyzer;
 250  
     }
 251  
 
 252  
     /**
 253  
      * Gets a query parser
 254  
      *
 255  
      * @return a query parser
 256  
      */
 257  
     protected QueryParser getQueryParser() {
 258  111
         if (queryParser == null) {
 259  21
             queryParser = createQueryParser();
 260  
         }
 261  111
         return queryParser;
 262  
     }
 263  
 
 264  
     /**
 265  
      * Searches the index using the given search string.
 266  
      *
 267  
      * @param searchString the query text
 268  
      * @param maxQueryResults the maximum number of documents to return
 269  
      * @return the TopDocs found by the search
 270  
      * @throws ParseException thrown when the searchString is invalid
 271  
      * @throws IOException is thrown if there is an issue with the underlying
 272  
      * Index
 273  
      */
 274  
     public TopDocs search(String searchString, int maxQueryResults) throws ParseException, IOException {
 275  111
         final QueryParser parser = getQueryParser();
 276  111
         final Query query = parser.parse(searchString);
 277  111
         resetSearchingAnalyzer();
 278  111
         final IndexSearcher is = getIndexSearcher();
 279  111
         return is.search(query, maxQueryResults);
 280  
     }
 281  
 
 282  
     /**
 283  
      * Searches the index using the given query.
 284  
      *
 285  
      * @param query the query used to search the index
 286  
      * @param maxQueryResults the max number of results to return
 287  
      * @return the TopDocs found be the query
 288  
      * @throws CorruptIndexException thrown if the Index is corrupt
 289  
      * @throws IOException thrown if there is an IOException
 290  
      */
 291  
     public TopDocs search(Query query, int maxQueryResults) throws CorruptIndexException, IOException {
 292  0
         final IndexSearcher is = getIndexSearcher();
 293  0
         return is.search(query, maxQueryResults);
 294  
     }
 295  
 
 296  
     /**
 297  
      * Retrieves a document from the Index.
 298  
      *
 299  
      * @param documentId the id of the document to retrieve
 300  
      * @return the Document
 301  
      * @throws IOException thrown if there is an IOException
 302  
      */
 303  
     public Document getDocument(int documentId) throws IOException {
 304  2709
         final IndexSearcher is = getIndexSearcher();
 305  2709
         return is.doc(documentId);
 306  
     }
 307  
 
 308  
     /**
 309  
      * Gets the directory that contains the Lucene Index.
 310  
      *
 311  
      * @return a Lucene Directory
 312  
      * @throws IOException is thrown when an IOException occurs
 313  
      */
 314  
     public abstract Directory getDirectory() throws IOException;
 315  
 
 316  
     /**
 317  
      * Creates the Lucene Analyzer used when indexing.
 318  
      *
 319  
      * @return a Lucene Analyzer
 320  
      */
 321  
     public abstract Analyzer createIndexingAnalyzer();
 322  
 
 323  
     /**
 324  
      * Creates the Lucene Analyzer used when querying the index.
 325  
      *
 326  
      * @return a Lucene Analyzer
 327  
      */
 328  
     public abstract Analyzer createSearchingAnalyzer();
 329  
 
 330  
     /**
 331  
      * Creates the Lucene QueryParser used when querying the index.
 332  
      *
 333  
      * @return a QueryParser
 334  
      */
 335  
     public abstract QueryParser createQueryParser();
 336  
 
 337  
     /**
 338  
      * Resets the searching analyzers
 339  
      */
 340  
     protected abstract void resetSearchingAnalyzer();
 341  
 }