View Javadoc

    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) 2013 Jeremy Long. All Rights Reserved.
    18   */
    19  package org.owasp.dependencycheck.data.cpe;
    20
    21  import java.io.IOException;
    22  import java.util.HashMap;
    23  import java.util.Map;
    24  import java.util.logging.Level;
    25  import java.util.logging.Logger;
    26  import org.apache.lucene.analysis.Analyzer;
    27  import org.apache.lucene.analysis.core.KeywordAnalyzer;
    28  import org.apache.lucene.analysis.miscellaneous.PerFieldAnalyzerWrapper;
    29  import org.apache.lucene.document.Document;
    30  import org.apache.lucene.document.Field;
    31  import org.apache.lucene.document.StringField;
    32  import org.apache.lucene.document.TextField;
    33  import org.apache.lucene.index.CorruptIndexException;
    34  import org.apache.lucene.index.IndexWriter;
    35  import org.apache.lucene.index.IndexWriterConfig;
    36  import org.apache.lucene.index.Term;
    37  import org.apache.lucene.util.Version;
    38  import org.owasp.dependencycheck.data.lucene.FieldAnalyzer;
    39
    40  /**
    41   *
    42   * @author Jeremy Long (jeremy.long@owasp.org)
    43   */
    44  public class CpeIndexWriter extends BaseIndex {
    45
    46      /**
    47       * The IndexWriter for the Lucene index.
    48       */
    49      private IndexWriter indexWriter;
    50      /**
    51       * The Lucene Analyzer used for Indexing.
    52       */
    53      private Analyzer indexingAnalyzer;
    54
    55      /**
    56       * Opens the CPE Index.
    57       *
    58       * @throws IOException is thrown if an IOException occurs opening the index.
    59       */
    60      @Override
    61      public void open() throws IOException {
    62          //TODO add spinlock
    63          super.open();
    64          indexingAnalyzer = createIndexingAnalyzer();
    65          final IndexWriterConfig conf = new IndexWriterConfig(Version.LUCENE_43, indexingAnalyzer);
    66          indexWriter = new IndexWriter(getDirectory(), conf);
    67      }
    68
    69      /**
    70       * Closes the CPE Index.
    71       */
    72      @Override
    73      public void close() {
    74          //TODO remove spinlock
    75          if (indexWriter != null) {
    76              commit();
    77              try {
    78                  indexWriter.close(true);
    79              } catch (CorruptIndexException ex) {
    80                  final String msg = "Unable to update database, there is a corrupt index.";
    81                  Logger.getLogger(CpeIndexWriter.class.getName()).log(Level.SEVERE, msg);
    82                  Logger.getLogger(CpeIndexWriter.class.getName()).log(Level.FINE, null, ex);
    83              } catch (IOException ex) {
    84                  final String msg = "Unable to update database due to an IO error.";
    85                  Logger.getLogger(CpeIndexWriter.class.getName()).log(Level.SEVERE, msg);
    86                  Logger.getLogger(CpeIndexWriter.class.getName()).log(Level.FINE, null, ex);
    87              } finally {
    88                  indexWriter = null;
    89              }
    90          }
    91          if (indexingAnalyzer != null) {
    92              indexingAnalyzer.close();
    93              indexingAnalyzer = null;
    94          }
    95          super.close();
    96      }
    97
    98      /**
    99       * Commits any pending changes.
    100      */
    101     public void commit() {
    102         if (indexWriter != null) {
    103             try {
    104                 indexWriter.forceMerge(1);
    105                 indexWriter.commit();
    106             } catch (CorruptIndexException ex) {
    107                 final String msg = "Unable to update database, there is a corrupt index.";
    108                 Logger.getLogger(CpeIndexWriter.class.getName()).log(Level.SEVERE, msg);
    109                 Logger.getLogger(CpeIndexWriter.class.getName()).log(Level.FINE, null, ex);
    110             } catch (IOException ex) {
    111                 final String msg = "Unable to update database due to an IO error.";
    112                 Logger.getLogger(CpeIndexWriter.class.getName()).log(Level.SEVERE, msg);
    113                 Logger.getLogger(CpeIndexWriter.class.getName()).log(Level.FINE, null, ex);
    114             }
    115         }
    116     }
    117
    118     /**
    119      * Creates the indexing analyzer for the CPE Index.
    120      *
    121      * @return the CPE Analyzer.
    122      */
    123     @SuppressWarnings("unchecked")
    124     private Analyzer createIndexingAnalyzer() {
    125         final Map fieldAnalyzers = new HashMap();
    126         fieldAnalyzers.put(Fields.DOCUMENT_KEY, new KeywordAnalyzer());
    127         return new PerFieldAnalyzerWrapper(new FieldAnalyzer(Version.LUCENE_43), fieldAnalyzers);
    128     }
    129
    130     /**
    131      * Saves a CPE IndexEntry into the Lucene index.
    132      *
    133      * @param entry a CPE entry.
    134      * @throws CorruptIndexException is thrown if the index is corrupt.
    135      * @throws IOException is thrown if an IOException occurs.
    136      */
    137     public void saveEntry(IndexEntry entry) throws CorruptIndexException, IOException {
    138         final Document doc = new Document();
    139         final Field documentKey = new StringField(Fields.DOCUMENT_KEY, entry.getDocumentId(), Field.Store.NO);
    140         final Field vendor = new TextField(Fields.VENDOR, entry.getVendor(), Field.Store.YES);
    141         final Field product = new TextField(Fields.PRODUCT, entry.getProduct(), Field.Store.YES);
    142         doc.add(documentKey);
    143         doc.add(vendor);
    144         doc.add(product);
    145
    146         final Term term = new Term(Fields.DOCUMENT_KEY, entry.getDocumentId());
    147         indexWriter.updateDocument(term, doc);
    148     }
    149 }