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) 2012 Jeremy Long. All Rights Reserved.
17 */
18 package org.owasp.dependencycheck.analyzer;
19
20 import java.util.ArrayList;
21
22 import org.slf4j.LoggerFactory;
23
24 import static java.util.Arrays.asList;
25
26 import java.util.Iterator;
27 import java.util.List;
28 import java.util.ServiceLoader;
29 import javax.annotation.concurrent.ThreadSafe;
30
31 import org.owasp.dependencycheck.utils.Settings;
32
33 /**
34 * The Analyzer Service Loader. This class loads all services that implement
35 * {@link org.owasp.dependencycheck.analyzer.Analyzer}.
36 *
37 * @author Jeremy Long
38 */
39 @ThreadSafe
40 public class AnalyzerService {
41
42 /**
43 * The Logger for use throughout the class.
44 */
45 private static final org.slf4j.Logger LOGGER = LoggerFactory.getLogger(AnalyzerService.class);
46
47 /**
48 * The service loader for analyzers.
49 */
50 private final ServiceLoader<Analyzer> service;
51 /**
52 * The configured settings.
53 */
54 private final Settings settings;
55
56 /**
57 * Creates a new instance of AnalyzerService.
58 *
59 * @param classLoader the ClassLoader to use when dynamically loading
60 * Analyzer and Update services
61 * @param settings the configured settings
62 */
63 public AnalyzerService(ClassLoader classLoader, Settings settings) {
64 service = ServiceLoader.load(Analyzer.class, classLoader);
65 this.settings = settings;
66 }
67
68 /**
69 * Returns a list of all instances of the Analyzer interface.
70 *
71 * @return a list of Analyzers.
72 */
73 public List<Analyzer> getAnalyzers() {
74 return getAnalyzers(AnalysisPhase.values());
75 }
76
77 /**
78 * Returns a list of all instances of the Analyzer interface that are bound
79 * to one of the given phases.
80 *
81 * @param phases the phases to obtain analyzers for
82 * @return a list of Analyzers.
83 */
84 public List<Analyzer> getAnalyzers(AnalysisPhase... phases) {
85 return getAnalyzers(asList(phases));
86 }
87
88 /**
89 * Returns a list of all instances of the Analyzer interface that are bound
90 * to one of the given phases.
91 *
92 * @param phases the phases to obtain analyzers for
93 * @return a list of Analyzers
94 */
95 public List<Analyzer> getAnalyzers(List<AnalysisPhase> phases) {
96 final List<Analyzer> analyzers = new ArrayList<>();
97 final Iterator<Analyzer> iterator = service.iterator();
98 final boolean experimentalEnabled;
99 final boolean retiredEnabled;
100 experimentalEnabled = settings.getBoolean(Settings.KEYS.ANALYZER_EXPERIMENTAL_ENABLED, false);
101 retiredEnabled = settings.getBoolean(Settings.KEYS.ANALYZER_RETIRED_ENABLED, false);
102 while (iterator.hasNext()) {
103 final Analyzer a = iterator.next();
104 if (!phases.contains(a.getAnalysisPhase())) {
105 continue;
106 }
107 if (!experimentalEnabled && a.getClass().isAnnotationPresent(Experimental.class)) {
108 continue;
109 }
110 if (!retiredEnabled && a.getClass().isAnnotationPresent(Retired.class)) {
111 continue;
112 }
113 LOGGER.debug("Loaded Analyzer {}", a.getName());
114 analyzers.add(a);
115 }
116 return analyzers;
117 }
118 }