View Javadoc
1   /*
2    * This file is part of dependency-check-maven.
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    *     http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   *
16   * Copyright (c) 2014 Jeremy Long. All Rights Reserved.
17   */
18  package org.owasp.dependencycheck.maven;
19  
20  import java.util.logging.Logger;
21  import org.apache.maven.project.MavenProject;
22  import org.owasp.dependencycheck.analyzer.Analyzer;
23  import org.owasp.dependencycheck.analyzer.CPEAnalyzer;
24  import org.owasp.dependencycheck.data.nvdcve.DatabaseException;
25  import org.owasp.dependencycheck.utils.Settings;
26  
27  /**
28   * A modified version of the core engine specifically designed to persist some data between multiple executions of a
29   * multi-module Maven project.
30   *
31   * @author Jeremy Long <jeremy.long@owasp.org>
32   */
33  public class Engine extends org.owasp.dependencycheck.Engine {
34  
35      /**
36       * The logger.
37       */
38      private static final transient Logger LOGGER = Logger.getLogger(Engine.class.getName());
39      /**
40       * A key used to persist an object in the MavenProject.
41       */
42      private static final String CPE_ANALYZER_KEY = "dependency-check-CPEAnalyzer";
43      /**
44       * The current MavenProject.
45       */
46      private MavenProject currentProject;
47  
48      /**
49       * Creates a new Engine to perform anyalsis on dependencies.
50       *
51       * @param project the current Maven project
52       * @throws DatabaseException thrown if there is an issue connecting to the database
53       */
54      public Engine(MavenProject project) throws DatabaseException {
55          this.currentProject = project;
56          final MavenProject parent = getRootParent();
57          if (parent != null && parent.getContextValue("dependency-check-data-was-updated") != null) {
58              System.setProperty(Settings.KEYS.AUTO_UPDATE, Boolean.FALSE.toString());
59          }
60          initializeEngine();
61          if (parent != null) {
62              parent.setContextValue("dependency-check-data-was-updated", Boolean.valueOf(true));
63          }
64      }
65  
66      /**
67       * This constructor should not be called. Use Engine(MavenProject) instead.
68       *
69       * @throws DatabaseException thrown if there is an issue connecting to the database
70       */
71      private Engine() throws DatabaseException {
72      }
73  
74      /**
75       * Initializes the given analyzer. This skips the initialization of the CPEAnalyzer if it has been initialized by a
76       * previous execution.
77       *
78       * @param analyzer the analyzer to initialize
79       * @return the initialized analyzer
80       */
81      @Override
82      protected Analyzer initializeAnalyzer(Analyzer analyzer) {
83          if ((analyzer instanceof CPEAnalyzer)) {
84              CPEAnalyzer cpe = getPreviouslyLoadedAnalyzer();
85              if (cpe != null) {
86                  return cpe;
87              }
88              cpe = (CPEAnalyzer) super.initializeAnalyzer(analyzer);
89              storeCPEAnalyzer(cpe);
90          }
91          return super.initializeAnalyzer(analyzer);
92      }
93  
94      /**
95       * Closes the given analyzer. This skips closing the CPEAnalyzer.
96       *
97       * @param analyzer the analyzer to close
98       */
99      @Override
100     protected void closeAnalyzer(Analyzer analyzer) {
101         if ((analyzer instanceof CPEAnalyzer)) {
102             if (getPreviouslyLoadedAnalyzer() == null) {
103                 super.closeAnalyzer(analyzer);
104             }
105         } else {
106             super.closeAnalyzer(analyzer);
107         }
108     }
109 
110     /**
111      * Closes the CPEAnalyzer if it has been created and persisted in the root parent MavenProject context.
112      */
113     public void cleanupFinal() {
114         final CPEAnalyzer cpe = getPreviouslyLoadedAnalyzer();
115         if (cpe != null) {
116             cpe.close();
117         }
118     }
119 
120     /**
121      * Gets the CPEAnalyzer from the root Maven Project.
122      *
123      * @return an initialized CPEAnalyzer
124      */
125     private CPEAnalyzer getPreviouslyLoadedAnalyzer() {
126         CPEAnalyzer cpe = null;
127         final MavenProject project = getRootParent();
128         if (project != null) {
129             cpe = (CPEAnalyzer) project.getContextValue(CPE_ANALYZER_KEY);
130         }
131         return cpe;
132     }
133 
134     /**
135      * Stores a CPEAnalyzer in the root Maven Project.
136      *
137      * @param cpe the CPEAnalyzer to store
138      */
139     private void storeCPEAnalyzer(CPEAnalyzer cpe) {
140         final MavenProject p = getRootParent();
141         if (p != null) {
142             p.setContextValue(CPE_ANALYZER_KEY, cpe);
143         }
144     }
145 
146     /**
147      * Returns the root Maven Project.
148      *
149      * @return the root Maven Project
150      */
151     private MavenProject getRootParent() {
152         if (this.currentProject == null) {
153             return null;
154         }
155         MavenProject p = this.currentProject;
156         while (p.getParent() != null) {
157             p = p.getParent();
158         }
159         return p;
160     }
161 }