View Javadoc
1   /*
2    * This file is part of dependency-check-core.
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) 2016 Stefan Neuhaus. All Rights Reserved.
17   */
18  package org.owasp.dependencycheck;
19  
20  import org.owasp.dependencycheck.analyzer.Analyzer;
21  import org.owasp.dependencycheck.analyzer.FileTypeAnalyzer;
22  import org.owasp.dependencycheck.analyzer.exception.AnalysisException;
23  import org.owasp.dependencycheck.dependency.Dependency;
24  import org.owasp.dependencycheck.utils.Settings;
25  import org.slf4j.Logger;
26  import org.slf4j.LoggerFactory;
27  
28  import java.util.List;
29  import java.util.concurrent.Callable;
30  
31  /**
32   * Task to support parallelism of dependency-check analysis. Analyses a single
33   * {@link Dependency} by a specific {@link Analyzer}.
34   *
35   * @author Stefan Neuhaus
36   */
37  class AnalysisTask implements Callable<Void> {
38  
39      /**
40       * Instance of the logger.
41       */
42      private static final Logger LOGGER = LoggerFactory.getLogger(AnalysisTask.class);
43  
44      /**
45       * A reference to the analyzer.
46       */
47      private final Analyzer analyzer;
48      /**
49       * The dependency to analyze.
50       */
51      private final Dependency dependency;
52      /**
53       * A reference to the dependency-check engine.
54       */
55      private final Engine engine;
56      /**
57       * The list of exceptions that may occur during analysis.
58       */
59      private final List<Throwable> exceptions;
60      /**
61       * A reference to the global settings object.
62       */
63      private final Settings settings;
64  
65      /**
66       * Creates a new analysis task.
67       *
68       * @param analyzer a reference of the analyzer to execute
69       * @param dependency the dependency to analyze
70       * @param engine the dependency-check engine
71       * @param exceptions exceptions that occur during analysis will be added to
72       * this collection of exceptions
73       * @param settings a reference to the global settings object; this is
74       * necessary so that when the thread is started the dependencies have a
75       * correct reference to the global settings.
76       */
77      AnalysisTask(Analyzer analyzer, Dependency dependency, Engine engine, List<Throwable> exceptions, Settings settings) {
78          this.analyzer = analyzer;
79          this.dependency = dependency;
80          this.engine = engine;
81          this.exceptions = exceptions;
82          this.settings = settings;
83      }
84  
85      /**
86       * Executes the analysis task.
87       *
88       * @return null
89       * @throws Exception thrown if unable to execute the analysis task
90       */
91      @Override
92      public Void call() {
93          try {
94              Settings.setInstance(settings);
95  
96              if (shouldAnalyze()) {
97                  LOGGER.debug("Begin Analysis of '{}' ({})", dependency.getActualFilePath(), analyzer.getName());
98                  try {
99                      analyzer.analyze(dependency, engine);
100                 } catch (AnalysisException ex) {
101                     LOGGER.warn("An error occurred while analyzing '{}' ({}).", dependency.getActualFilePath(), analyzer.getName());
102                     LOGGER.debug("", ex);
103                     exceptions.add(ex);
104                 } catch (Throwable ex) {
105                     LOGGER.warn("An unexpected error occurred during analysis of '{}' ({}): {}",
106                             dependency.getActualFilePath(), analyzer.getName(), ex.getMessage());
107                     LOGGER.debug("", ex);
108                     exceptions.add(ex);
109                 }
110             }
111         } finally {
112             Settings.cleanup(false);
113         }
114         return null;
115     }
116 
117     /**
118      * Determines if the analyzer can analyze the given dependency.
119      *
120      * @return whether or not the analyzer can analyze the dependency
121      */
122     boolean shouldAnalyze() {
123         if (analyzer instanceof FileTypeAnalyzer) {
124             final FileTypeAnalyzer fileTypeAnalyzer = (FileTypeAnalyzer) analyzer;
125             return fileTypeAnalyzer.accept(dependency.getActualFile());
126         }
127 
128         return true;
129     }
130 }