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 com.github.packageurl.MalformedPackageURLException;
21  import com.github.packageurl.PackageURL;
22  import com.github.packageurl.PackageURL.StandardTypes;
23  import org.apache.commons.lang3.StringUtils;
24  import org.apache.maven.artifact.Artifact;
25  import org.apache.maven.artifact.DefaultArtifact;
26  import org.apache.maven.artifact.handler.DefaultArtifactHandler;
27  import org.apache.maven.artifact.repository.ArtifactRepository;
28  import org.apache.maven.artifact.resolver.filter.ExcludesArtifactFilter;
29  import org.apache.maven.artifact.versioning.ArtifactVersion;
30  import org.apache.maven.artifact.versioning.InvalidVersionSpecificationException;
31  import org.apache.maven.artifact.versioning.Restriction;
32  import org.apache.maven.artifact.versioning.VersionRange;
33  import org.apache.maven.doxia.sink.Sink;
34  import org.apache.maven.execution.MavenSession;
35  import org.apache.maven.model.License;
36  import org.apache.maven.plugin.AbstractMojo;
37  import org.apache.maven.plugin.MojoExecution;
38  import org.apache.maven.plugin.MojoExecutionException;
39  import org.apache.maven.plugin.MojoFailureException;
40  import org.apache.maven.plugins.annotations.Component;
41  import org.apache.maven.plugins.annotations.Parameter;
42  import org.apache.maven.project.DefaultProjectBuildingRequest;
43  import org.apache.maven.project.MavenProject;
44  import org.apache.maven.project.ProjectBuildingRequest;
45  import org.apache.maven.reporting.MavenReport;
46  import org.apache.maven.reporting.MavenReportException;
47  import org.apache.maven.settings.Proxy;
48  import org.apache.maven.settings.Server;
49  import org.apache.maven.settings.building.SettingsProblem;
50  import org.apache.maven.settings.crypto.DefaultSettingsDecryptionRequest;
51  import org.apache.maven.settings.crypto.SettingsDecrypter;
52  import org.apache.maven.settings.crypto.SettingsDecryptionResult;
53  import org.apache.maven.shared.artifact.filter.PatternExcludesArtifactFilter;
54  import org.apache.maven.shared.dependency.graph.DependencyGraphBuilder;
55  import org.apache.maven.shared.dependency.graph.DependencyGraphBuilderException;
56  import org.apache.maven.shared.dependency.graph.DependencyNode;
57  import org.apache.maven.shared.dependency.graph.filter.ArtifactDependencyNodeFilter;
58  import org.apache.maven.shared.dependency.graph.internal.DefaultDependencyNode;
59  import org.apache.maven.shared.dependency.graph.traversal.DependencyNodeVisitor;
60  import org.apache.maven.shared.dependency.graph.traversal.FilteringDependencyNodeVisitor;
61  import org.apache.maven.shared.model.fileset.FileSet;
62  import org.apache.maven.shared.model.fileset.util.FileSetManager;
63  import org.apache.maven.shared.transfer.artifact.DefaultArtifactCoordinate;
64  import org.apache.maven.shared.transfer.artifact.resolve.ArtifactResolver;
65  import org.apache.maven.shared.transfer.artifact.resolve.ArtifactResolverException;
66  import org.apache.maven.shared.transfer.artifact.resolve.ArtifactResult;
67  import org.apache.maven.shared.transfer.dependencies.DefaultDependableCoordinate;
68  import org.apache.maven.shared.transfer.dependencies.DependableCoordinate;
69  import org.apache.maven.shared.transfer.dependencies.resolve.DependencyResolver;
70  import org.apache.maven.shared.transfer.dependencies.resolve.DependencyResolverException;
71  import org.eclipse.aether.artifact.ArtifactType;
72  import org.owasp.dependencycheck.Engine;
73  import org.owasp.dependencycheck.agent.DependencyCheckScanAgent;
74  import org.owasp.dependencycheck.analyzer.JarAnalyzer;
75  import org.owasp.dependencycheck.analyzer.exception.AnalysisException;
76  import org.owasp.dependencycheck.data.nexus.MavenArtifact;
77  import org.owasp.dependencycheck.data.nvdcve.DatabaseException;
78  import org.owasp.dependencycheck.dependency.Confidence;
79  import org.owasp.dependencycheck.dependency.Dependency;
80  import org.owasp.dependencycheck.dependency.EvidenceType;
81  import org.owasp.dependencycheck.dependency.Vulnerability;
82  import org.owasp.dependencycheck.dependency.naming.GenericIdentifier;
83  import org.owasp.dependencycheck.dependency.naming.Identifier;
84  import org.owasp.dependencycheck.dependency.naming.PurlIdentifier;
85  import org.owasp.dependencycheck.exception.DependencyNotFoundException;
86  import org.owasp.dependencycheck.exception.ExceptionCollection;
87  import org.owasp.dependencycheck.exception.InitializationException;
88  import org.owasp.dependencycheck.exception.ReportException;
89  import org.owasp.dependencycheck.reporting.ReportGenerator;
90  import org.owasp.dependencycheck.utils.Checksum;
91  import org.owasp.dependencycheck.utils.Downloader;
92  import org.owasp.dependencycheck.utils.Filter;
93  import org.owasp.dependencycheck.utils.InvalidSettingException;
94  import org.owasp.dependencycheck.utils.Settings;
95  import org.owasp.dependencycheck.utils.SeverityUtil;
96  import org.owasp.dependencycheck.xml.pom.Model;
97  import org.owasp.dependencycheck.xml.pom.PomUtils;
98  
99  import java.io.File;
100 import java.io.IOException;
101 import java.io.InputStream;
102 import java.util.ArrayList;
103 import java.util.Arrays;
104 import java.util.Collections;
105 import java.util.HashSet;
106 import java.util.List;
107 import java.util.Locale;
108 import java.util.Map;
109 import java.util.Objects;
110 import java.util.Optional;
111 import java.util.Set;
112 import java.util.stream.Collectors;
113 import java.util.stream.Stream;
114 
115 //CSOFF: FileLength
116 
117 /**
118  * @author Jeremy Long
119  */
120 public abstract class BaseDependencyCheckMojo extends AbstractMojo implements MavenReport {
121 
122     //<editor-fold defaultstate="collapsed" desc="Private fields">
123     /**
124      * The properties file location.
125      */
126     private static final String PROPERTIES_FILE = "mojo.properties";
127     /**
128      * System specific new line character.
129      */
130     private static final String NEW_LINE = System.getProperty("line.separator", "\n").intern();
131     /**
132      * Pattern to include all files in a FileSet.
133      */
134     private static final String INCLUDE_ALL = "**/*";
135     /**
136      * Constant for the HTTPS protocol string.
137      */
138     public static final String PROTOCOL_HTTPS = "https";
139     /**
140      * Constant for the HTTP protocol string.
141      */
142     public static final String PROTOCOL_HTTP = "http";
143     /**
144      * A flag indicating whether or not the Maven site is being generated.
145      */
146     private boolean generatingSite = false;
147     /**
148      * The configured settings.
149      */
150     private Settings settings = null;
151     /**
152      * The list of files that have been scanned.
153      */
154     private final List<File> scannedFiles = new ArrayList<>();
155     //</editor-fold>
156     // <editor-fold defaultstate="collapsed" desc="Maven bound parameters and components">
157     /**
158      * Sets whether or not the mojo should fail if an error occurs.
159      */
160     @SuppressWarnings("CanBeFinal")
161     @Parameter(property = "failOnError", defaultValue = "true", required = true)
162     private boolean failOnError;
163 
164     /**
165      * The Maven Project Object.
166      */
167     @SuppressWarnings("CanBeFinal")
168     @Parameter(property = "project", required = true, readonly = true)
169     private MavenProject project;
170     /**
171      * The Maven Mojo Execution Object.
172      */
173     @Parameter(defaultValue = "${mojoExecution}", readonly = true)
174     private MojoExecution mojoExecution;
175     /**
176      * List of Maven project of the current build
177      */
178     @SuppressWarnings("CanBeFinal")
179     @Parameter(readonly = true, required = true, property = "reactorProjects")
180     private List<MavenProject> reactorProjects;
181     /**
182      * The entry point towards a Maven version independent way of resolving
183      * artifacts (handles both Maven 3.0 Sonatype and Maven 3.1+ eclipse Aether
184      * implementations).
185      */
186     @SuppressWarnings("CanBeFinal")
187     @Component
188     private ArtifactResolver artifactResolver;
189     /**
190      * The entry point towards a Maven version independent way of resolving
191      * dependencies (handles both Maven 3.0 Sonatype and Maven 3.1+ eclipse
192      * Aether implementations). Contrary to the ArtifactResolver this resolver
193      * also takes into account the additional repositories defined in the
194      * dependency-path towards transitive dependencies.
195      */
196     @SuppressWarnings("CanBeFinal")
197     @Component
198     private DependencyResolver dependencyResolver;
199 
200     /**
201      * The Maven Session.
202      */
203     @SuppressWarnings("CanBeFinal")
204     @Parameter(defaultValue = "${session}", readonly = true, required = true)
205     private MavenSession session;
206 
207     /**
208      * Component within Maven to build the dependency graph.
209      */
210     @Component
211     private DependencyGraphBuilder dependencyGraphBuilder;
212 
213     /**
214      * The output directory. This generally maps to "target".
215      */
216     @SuppressWarnings("CanBeFinal")
217     @Parameter(defaultValue = "${project.build.directory}", required = true, property = "odc.outputDirectory")
218     private File outputDirectory;
219     /**
220      * This is a reference to the &gt;reporting&lt; sections
221      * <code>outputDirectory</code>. This cannot be configured in the
222      * dependency-check mojo directly. This generally maps to "target/site".
223      */
224     @Parameter(property = "project.reporting.outputDirectory", readonly = true)
225     private File reportOutputDirectory;
226     /**
227      * Specifies if the build should be failed if a CVSS score above a specified
228      * level is identified. The default is 11 which means since the CVSS scores
229      * are 0-10, by default the build will never fail.
230      */
231     @SuppressWarnings("CanBeFinal")
232     @Parameter(property = "failBuildOnCVSS", defaultValue = "11", required = true)
233     private float failBuildOnCVSS = 11f;
234     /**
235      * Specifies the CVSS score that is considered a "test" failure when
236      * generating a jUnit style report. The default value is 0 - all
237      * vulnerabilities are considered a failure.
238      */
239     @SuppressWarnings("CanBeFinal")
240     @Parameter(property = "junitFailOnCVSS", defaultValue = "0", required = true)
241     private float junitFailOnCVSS = 0;
242     /**
243      * Fail the build if any dependency has a vulnerability listed.
244      *
245      * @deprecated use {@link BaseDependencyCheckMojo#failBuildOnCVSS} with a
246      * value of 0 instead
247      */
248     @SuppressWarnings("CanBeFinal")
249     @Parameter(property = "failBuildOnAnyVulnerability", defaultValue = "false", required = true)
250     @Deprecated
251     private boolean failBuildOnAnyVulnerability = false;
252     /**
253      * Sets whether auto-updating of the NVD CVE data is enabled. It is not
254      * recommended that this be turned to false. Default is true.
255      */
256     @SuppressWarnings("CanBeFinal")
257     @Parameter(property = "autoUpdate")
258     private Boolean autoUpdate;
259     /**
260      * Sets whether Experimental analyzers are enabled. Default is false.
261      */
262     @SuppressWarnings("CanBeFinal")
263     @Parameter(property = "enableExperimental")
264     private Boolean enableExperimental;
265     /**
266      * Sets whether retired analyzers are enabled. Default is false.
267      */
268     @SuppressWarnings("CanBeFinal")
269     @Parameter(property = "enableRetired")
270     private Boolean enableRetired;
271     /**
272      * Sets whether the Golang Dependency analyzer is enabled. Default is true.
273      */
274     @SuppressWarnings("CanBeFinal")
275     @Parameter(property = "golangDepEnabled")
276     private Boolean golangDepEnabled;
277     /**
278      * Sets whether Golang Module Analyzer is enabled; this requires `go` to be
279      * installed. Default is true.
280      */
281     @SuppressWarnings("CanBeFinal")
282     @Parameter(property = "golangModEnabled")
283     private Boolean golangModEnabled;
284     /**
285      * Sets the path to `go`.
286      */
287     @SuppressWarnings("CanBeFinal")
288     @Parameter(property = "pathToGo")
289     private String pathToGo;
290 
291     /**
292      * Sets the path to `yarn`.
293      */
294     @SuppressWarnings("CanBeFinal")
295     @Parameter(property = "pathToYarn")
296     private String pathToYarn;
297     /**
298      * Sets the path to `pnpm`.
299      */
300     @SuppressWarnings("CanBeFinal")
301     @Parameter(property = "pathToPnpm")
302     private String pathToPnpm;
303     /**
304      * Use pom dependency information for snapshot dependencies that are part of
305      * the Maven reactor while aggregate scanning a multi-module project.
306      */
307     @Parameter(property = "dependency-check.virtualSnapshotsFromReactor", defaultValue = "true")
308     private Boolean virtualSnapshotsFromReactor;
309     /**
310      * The report format to be generated (HTML, XML, CSV, JSON, JUNIT, SARIF,
311      * JENKINS, GITLAB, ALL). Multiple formats can be selected using a comma
312      * delineated list.
313      */
314     @SuppressWarnings("CanBeFinal")
315     @Parameter(property = "format", defaultValue = "HTML", required = true)
316     private String format = "HTML";
317 
318     /**
319      * Whether or not the XML and JSON report formats should be pretty printed.
320      * The default is false.
321      */
322     @Parameter(property = "prettyPrint")
323     private Boolean prettyPrint;
324     /**
325      * The report format to be generated (HTML, XML, CSV, JSON, JUNIT, SARIF,
326      * JENKINS, GITLAB, ALL). Multiple formats can be selected using a comma
327      * delineated list.
328      */
329     @Parameter(property = "formats", required = true)
330     private String[] formats;
331     /**
332      * The Maven settings.
333      */
334     @SuppressWarnings("CanBeFinal")
335     @Parameter(property = "mavenSettings", defaultValue = "${settings}")
336     private org.apache.maven.settings.Settings mavenSettings;
337 
338     /**
339      * The maven settings proxy id.
340      */
341     @SuppressWarnings("CanBeFinal")
342     @Parameter(property = "mavenSettingsProxyId")
343     private String mavenSettingsProxyId;
344 
345     /**
346      * The Connection Timeout.
347      */
348     @SuppressWarnings("CanBeFinal")
349     @Parameter(property = "connectionTimeout")
350     private String connectionTimeout;
351     /**
352      * The Read Timeout.
353      */
354     @SuppressWarnings("CanBeFinal")
355     @Parameter(property = "readTimeout")
356     private String readTimeout;
357     /**
358      * Sets whether dependency-check should check if there is a new version
359      * available.
360      */
361     @SuppressWarnings("CanBeFinal")
362     @Parameter(property = "versionCheckEnabled", defaultValue = "true")
363     private boolean versionCheckEnabled;
364     /**
365      * The paths to the suppression files. The parameter value can be a local
366      * file path, a URL to a suppression file, or even a reference to a file on
367      * the class path (see
368      * https://github.com/dependency-check/DependencyCheck/issues/1878#issuecomment-487533799)
369      */
370     @SuppressWarnings("CanBeFinal")
371     @Parameter(property = "suppressionFiles")
372     private String[] suppressionFiles;
373     /**
374      * The paths to the suppression file. The parameter value can be a local
375      * file path, a URL to a suppression file, or even a reference to a file on
376      * the class path (see
377      * https://github.com/dependency-check/DependencyCheck/issues/1878#issuecomment-487533799)
378      */
379     @SuppressWarnings("CanBeFinal")
380     @Parameter(property = "suppressionFile")
381     private String suppressionFile;
382     /**
383      * The username used when connecting to the suppressionFiles.
384      */
385     @Parameter(property = "suppressionFileUser")
386     private String suppressionFileUser;
387     /**
388      * The password used for Basic auth to the suppressionFiles. The `suppressionFileServerId` with user/password should
389      * be used instead otherwise maven debug logging could expose the password.
390      */
391     @Parameter(property = "suppressionFilePassword")
392     private String suppressionFilePassword;
393     /**
394      * The token used for Bearer auth to the suppressionFiles. The `suppressionFileServerId` with only password should
395      * be used instead otherwise maven debug logging could expose the token.
396      */
397     @Parameter(property = "suppressionFileBearerToken")
398     private String suppressionFileBearerToken;
399     /**
400      * The server id in the settings.xml; used to retrieve encrypted passwords
401      * from the settings.xml for suppressionFile(s).
402      */
403     @SuppressWarnings("CanBeFinal")
404     @Parameter(property = "suppressionFileServerId")
405     private String suppressionFileServerId;
406     /**
407      * The path to the hints file.
408      */
409     @SuppressWarnings("CanBeFinal")
410     @Parameter(property = "hintsFile")
411     private String hintsFile;
412 
413     /**
414      * Flag indicating whether or not to show a summary in the output.
415      */
416     @SuppressWarnings("CanBeFinal")
417     @Parameter(property = "showSummary", defaultValue = "true")
418     private boolean showSummary = true;
419 
420     /**
421      * Whether or not the Jar Analyzer is enabled.
422      */
423     @SuppressWarnings("CanBeFinal")
424     @Parameter(property = "jarAnalyzerEnabled")
425     private Boolean jarAnalyzerEnabled;
426 
427     /**
428      * Sets whether the Dart analyzer is enabled. Default is true.
429      */
430     @SuppressWarnings("CanBeFinal")
431     @Parameter(property = "dartAnalyzerEnabled")
432     private Boolean dartAnalyzerEnabled;
433 
434     /**
435      * Whether or not the Archive Analyzer is enabled.
436      */
437     @SuppressWarnings("CanBeFinal")
438     @Parameter(property = "archiveAnalyzerEnabled")
439     private Boolean archiveAnalyzerEnabled;
440     /**
441      * Whether or not the Known Exploited Vulnerability Analyzer is enabled.
442      */
443     @SuppressWarnings("CanBeFinal")
444     @Parameter(property = "knownExploitedEnabled")
445     private Boolean knownExploitedEnabled;
446     /**
447      * The URL to the CISA Known Exploited Vulnerabilities JSON datafeed.
448      */
449     @SuppressWarnings("CanBeFinal")
450     @Parameter(property = "knownExploitedUrl")
451     private String knownExploitedUrl;
452     /**
453      * The server id in the settings.xml; used to retrieve encrypted passwords
454      * from the settings.xml for mirror of CISA Known Exploited Vulnerabilities JSON datafeed.
455      * Credentials with only a password will be used for Bearer auth, credentials with both user and password for Basic auth.
456      */
457     @SuppressWarnings("CanBeFinal")
458     @Parameter(property = "knownExploitedServerId")
459     private String knownExploitedServerId;
460     /**
461      * The username for basic auth mirror of CISA Known Exploited Vulnerabilities JSON datafeed. A `knownExploitedServerId`
462      * with user/password set should be used instead otherwise maven debug logging could expose the password.
463      */
464     @SuppressWarnings("CanBeFinal")
465     @Parameter(property = "knownExploitedUser")
466     private String knownExploitedUser;
467     /**
468      * The password for basic auth mirror of CISA Known Exploited Vulnerabilities JSON datafeed. A `knownExploitedServerId`
469      * with user/password set should be used instead otherwise maven debug logging could expose the password.
470      */
471     @SuppressWarnings("CanBeFinal")
472     @Parameter(property = "knownExploitedPassword")
473     private String knownExploitedPassword;
474     /**
475      * The token for bearer auth mirror of CISA Known Exploited Vulnerabilities JSON datafeed. A `knownExploitedServerId`
476      * with only password set should be used instead otherwise maven debug logging could expose the token.
477      */
478     @SuppressWarnings("CanBeFinal")
479     @Parameter(property = "knownExploitedBearerToken")
480     private String knownExploitedBearerToken;
481     /**
482      * Sets whether the Python Distribution Analyzer will be used.
483      */
484     @SuppressWarnings("CanBeFinal")
485     @Parameter(property = "pyDistributionAnalyzerEnabled")
486     private Boolean pyDistributionAnalyzerEnabled;
487     /**
488      * Sets whether the Python Package Analyzer will be used.
489      */
490     @Parameter(property = "pyPackageAnalyzerEnabled")
491     private Boolean pyPackageAnalyzerEnabled;
492     /**
493      * Sets whether the Ruby Gemspec Analyzer will be used.
494      */
495     @SuppressWarnings("CanBeFinal")
496     @Parameter(property = "rubygemsAnalyzerEnabled")
497     private Boolean rubygemsAnalyzerEnabled;
498     /**
499      * Sets whether or not the openssl Analyzer should be used.
500      */
501     @SuppressWarnings("CanBeFinal")
502     @Parameter(property = "opensslAnalyzerEnabled")
503     private Boolean opensslAnalyzerEnabled;
504     /**
505      * Sets whether or not the CMake Analyzer should be used.
506      */
507     @SuppressWarnings("CanBeFinal")
508     @Parameter(property = "cmakeAnalyzerEnabled")
509     private Boolean cmakeAnalyzerEnabled;
510     /**
511      * Sets whether or not the autoconf Analyzer should be used.
512      */
513     @SuppressWarnings("CanBeFinal")
514     @Parameter(property = "autoconfAnalyzerEnabled")
515     private Boolean autoconfAnalyzerEnabled;
516     /**
517      * Sets whether or not the Maven install Analyzer should be used.
518      */
519     @SuppressWarnings("CanBeFinal")
520     @Parameter(property = "mavenInstallAnalyzerEnabled")
521     private Boolean mavenInstallAnalyzerEnabled;
522     /**
523      * Sets whether or not the pip Analyzer should be used.
524      */
525     @SuppressWarnings("CanBeFinal")
526     @Parameter(property = "pipAnalyzerEnabled")
527     private Boolean pipAnalyzerEnabled;
528     /**
529      * Sets whether or not the pipfile Analyzer should be used.
530      */
531     @SuppressWarnings("CanBeFinal")
532     @Parameter(property = "pipfileAnalyzerEnabled")
533     private Boolean pipfileAnalyzerEnabled;
534     /**
535      * Sets whether or not the poetry Analyzer should be used.
536      */
537     @SuppressWarnings("CanBeFinal")
538     @Parameter(property = "poetryAnalyzerEnabled")
539     private Boolean poetryAnalyzerEnabled;
540     /**
541      * Sets whether or not the PHP Composer Lock File Analyzer should be used.
542      */
543     @Parameter(property = "composerAnalyzerEnabled")
544     private Boolean composerAnalyzerEnabled;
545     /**
546      * Sets whether or not the PHP Composer Lock File Analyzer will scan "packages-dev".
547      */
548     @Parameter(property = "composerAnalyzerSkipDev")
549     private boolean composerAnalyzerSkipDev;
550     /**
551      * Whether or not the Perl CPAN File Analyzer is enabled.
552      */
553     @Parameter(property = "cpanfileAnalyzerEnabled")
554     private Boolean cpanfileAnalyzerEnabled;
555     /**
556      * Sets whether or not the Node.js Analyzer should be used.
557      */
558     @SuppressWarnings("CanBeFinal")
559     @Parameter(property = "nodeAnalyzerEnabled")
560     private Boolean nodeAnalyzerEnabled;
561     /**
562      * Sets whether or not the Node Audit Analyzer should be used.
563      */
564     @SuppressWarnings("CanBeFinal")
565     @Parameter(property = "nodeAuditAnalyzerEnabled")
566     private Boolean nodeAuditAnalyzerEnabled;
567 
568     /**
569      * The Node Audit API URL for the Node Audit Analyzer.
570      */
571     @SuppressWarnings("CanBeFinal")
572     @Parameter(property = "nodeAuditAnalyzerUrl")
573     private String nodeAuditAnalyzerUrl;
574 
575     /**
576      * Sets whether or not the Yarn Audit Analyzer should be used.
577      */
578     @SuppressWarnings("CanBeFinal")
579     @Parameter(property = "yarnAuditAnalyzerEnabled")
580     private Boolean yarnAuditAnalyzerEnabled;
581 
582     /**
583      * Sets whether or not the Pnpm Audit Analyzer should be used.
584      */
585     @SuppressWarnings("CanBeFinal")
586     @Parameter(property = "pnpmAuditAnalyzerEnabled")
587     private Boolean pnpmAuditAnalyzerEnabled;
588 
589     /**
590      * Sets whether or not the Node Audit Analyzer should use a local cache.
591      */
592     @SuppressWarnings("CanBeFinal")
593     @Parameter(property = "nodeAuditAnalyzerUseCache")
594     private Boolean nodeAuditAnalyzerUseCache;
595     /**
596      * Sets whether or not the Node Audit Analyzer should skip devDependencies.
597      */
598     @SuppressWarnings("CanBeFinal")
599     @Parameter(property = "nodeAuditSkipDevDependencies")
600     private Boolean nodeAuditSkipDevDependencies;
601     /**
602      * Sets whether or not the Node.js Analyzer should skip devDependencies.
603      */
604     @SuppressWarnings("CanBeFinal")
605     @Parameter(property = "nodePackageSkipDevDependencies")
606     private Boolean nodePackageSkipDevDependencies;
607     /**
608      * Sets whether or not the Retirejs Analyzer should be used.
609      */
610     @SuppressWarnings("CanBeFinal")
611     @Parameter(property = "retireJsAnalyzerEnabled")
612     private Boolean retireJsAnalyzerEnabled;
613     /**
614      * The Retire JS repository URL.
615      */
616     @SuppressWarnings("CanBeFinal")
617     @Parameter(property = "retireJsUrl")
618     private String retireJsUrl;
619     /**
620      * The username for Basic auth to the retireJsUrl.
621      */
622     @Parameter(property = "retireJsUser")
623     private String retireJsUser;
624     /**
625      * The password for Basic auth to the retireJsUrl. The `retireJsUrlServerId` with user/password set should be used instead otherwise maven debug logging could expose the password.
626      */
627     @Parameter(property = "retireJsPassword")
628     private String retireJsPassword;
629     /**
630      * The token for Bearer auth to the retireJsUrl. The `retireJsUrlServerId` with only password set should be used instead
631      * otherwise maven debug logging could expose the token.
632      */
633     @Parameter(property = "retireJsBearerToken")
634     private String retireJsBearerToken;
635     /**
636      * The server id in the settings.xml; used to retrieve encrypted passwords
637      * from the settings.xml for retireJsUrl.
638      */
639     @SuppressWarnings("CanBeFinal")
640     @Parameter(property = "retireJsUrlServerId")
641     private String retireJsUrlServerId;
642     /**
643      * Whether the Retire JS repository will be updated regardless of the
644      * `autoupdate` settings.
645      */
646     @SuppressWarnings("CanBeFinal")
647     @Parameter(property = "retireJsForceUpdate")
648     private Boolean retireJsForceUpdate;
649     /**
650      * Whether or not the .NET Assembly Analyzer is enabled.
651      */
652     @Parameter(property = "assemblyAnalyzerEnabled")
653     private Boolean assemblyAnalyzerEnabled;
654     /**
655      * Whether or not the MS Build Analyzer is enabled.
656      */
657     @Parameter(property = "msbuildAnalyzerEnabled")
658     private Boolean msbuildAnalyzerEnabled;
659     /**
660      * Whether or not the .NET Nuspec Analyzer is enabled.
661      */
662     @SuppressWarnings("CanBeFinal")
663     @Parameter(property = "nuspecAnalyzerEnabled")
664     private Boolean nuspecAnalyzerEnabled;
665 
666     /**
667      * Whether or not the .NET packages.config Analyzer is enabled.
668      */
669     @SuppressWarnings("CanBeFinal")
670     @Parameter(property = "nugetconfAnalyzerEnabled")
671     private Boolean nugetconfAnalyzerEnabled;
672 
673     /**
674      * Whether or not the Libman Analyzer is enabled.
675      */
676     @SuppressWarnings("CanBeFinal")
677     @Parameter(property = "libmanAnalyzerEnabled")
678     private Boolean libmanAnalyzerEnabled;
679 
680     /**
681      * Whether or not the Central Analyzer is enabled.
682      */
683     @SuppressWarnings("CanBeFinal")
684     @Parameter(property = "centralAnalyzerEnabled")
685     private Boolean centralAnalyzerEnabled;
686 
687     /**
688      * Whether or not the Central Analyzer should use a local cache.
689      */
690     @SuppressWarnings("CanBeFinal")
691     @Parameter(property = "centralAnalyzerUseCache")
692     private Boolean centralAnalyzerUseCache;
693 
694     /**
695      * Whether or not the Artifactory Analyzer is enabled.
696      */
697     @SuppressWarnings("CanBeFinal")
698     @Parameter(property = "artifactoryAnalyzerEnabled")
699     private Boolean artifactoryAnalyzerEnabled;
700     /**
701      * The serverId inside the settings.xml containing the username and token to
702      * access artifactory
703      */
704     @SuppressWarnings("CanBeFinal")
705     @Parameter(property = "artifactoryAnalyzerServerId")
706     private String artifactoryAnalyzerServerId;
707     /**
708      * The username (only used with API token) to connect to Artifactory
709      * instance
710      */
711     @SuppressWarnings("CanBeFinal")
712     @Parameter(property = "artifactoryAnalyzerUsername")
713     private String artifactoryAnalyzerUsername;
714     /**
715      * The API token to connect to Artifactory instance
716      */
717     @SuppressWarnings("CanBeFinal")
718     @Parameter(property = "artifactoryAnalyzerApiToken")
719     private String artifactoryAnalyzerApiToken;
720     /**
721      * The bearer token to connect to Artifactory instance
722      */
723     @SuppressWarnings("CanBeFinal")
724     @Parameter(property = "artifactoryAnalyzerBearerToken")
725     private String artifactoryAnalyzerBearerToken;
726     /**
727      * The Artifactory URL for the Artifactory analyzer.
728      */
729     @SuppressWarnings("CanBeFinal")
730     @Parameter(property = "artifactoryAnalyzerUrl")
731     private String artifactoryAnalyzerUrl;
732     /**
733      * Whether Artifactory should be accessed through a proxy or not
734      */
735     @SuppressWarnings("CanBeFinal")
736     @Parameter(property = "artifactoryAnalyzerUseProxy")
737     private Boolean artifactoryAnalyzerUseProxy;
738     /**
739      * Whether the Artifactory analyzer should be run in parallel or not.
740      */
741     @SuppressWarnings("CanBeFinal")
742     @Parameter(property = "artifactoryAnalyzerParallelAnalysis", defaultValue = "true")
743     private Boolean artifactoryAnalyzerParallelAnalysis;
744     /**
745      * Whether the Unused Suppression Rule analyzer should fail if there are unused rules.
746      */
747     @SuppressWarnings("CanBeFinal")
748     @Parameter(property = "failBuildOnUnusedSuppressionRule", defaultValue = "false")
749     private Boolean failBuildOnUnusedSuppressionRule;
750     /**
751      * Whether or not the Nexus Analyzer is enabled.
752      */
753     @SuppressWarnings("CanBeFinal")
754     @Parameter(property = "nexusAnalyzerEnabled")
755     private Boolean nexusAnalyzerEnabled;
756 
757     /**
758      * Whether or not the Sonatype OSS Index analyzer is enabled.
759      */
760     @SuppressWarnings("CanBeFinal")
761     @Parameter(property = "ossIndexAnalyzerEnabled", alias = "ossindexAnalyzerEnabled")
762     private Boolean ossIndexAnalyzerEnabled;
763     /**
764      * Whether or not the Sonatype OSS Index analyzer should cache results.
765      */
766     @SuppressWarnings("CanBeFinal")
767     @Parameter(property = "ossIndexAnalyzerUseCache", alias = "ossindexAnalyzerUseCache")
768     private Boolean ossIndexAnalyzerUseCache;
769     /**
770      * URL of the Sonatype OSS Index service.
771      */
772     @SuppressWarnings("CanBeFinal")
773     @Parameter(property = "ossIndexAnalyzerUrl", alias = "ossindexAnalyzerUrl")
774     private String ossIndexAnalyzerUrl;
775 
776     /**
777      * The id of a server defined in the settings.xml to authenticate Sonatype
778      * OSS Index requests and profit from higher rate limits. Provide the OSS
779      * account email address as username and password or API token as password.
780      */
781     @SuppressWarnings("CanBeFinal")
782     @Parameter(property = "ossIndexServerId")
783     private String ossIndexServerId;
784 
785     /**
786      * OSS account email address as an alternative to the indirection through
787      * the ossIndexServerId (see above). Both ossIndexUsername and
788      * ossIndexPassword must be set to use this approach instead of the server
789      * ID.
790      */
791     @SuppressWarnings("CanBeFinal")
792     @Parameter(property = "ossIndexUsername")
793     private String ossIndexUsername;
794 
795     /**
796      * OSS password or API token as an alternative to the indirection through
797      * the ossIndexServerId (see above). Both ossIndexUsername and
798      * ossIndexPassword must be set to use this approach instead of the server
799      * ID.
800      */
801     @SuppressWarnings("CanBeFinal")
802     @Parameter(property = "ossIndexPassword")
803     private String ossIndexPassword;
804 
805     /**
806      * Whether we should only warn about Sonatype OSS Index remote errors
807      * instead of failing the goal completely.
808      */
809     @SuppressWarnings("CanBeFinal")
810     @Parameter(property = "ossIndexWarnOnlyOnRemoteErrors")
811     private Boolean ossIndexWarnOnlyOnRemoteErrors;
812 
813     /**
814      * Whether or not the Elixir Mix Audit Analyzer is enabled.
815      */
816     @Parameter(property = "mixAuditAnalyzerEnabled")
817     private Boolean mixAuditAnalyzerEnabled;
818 
819     /**
820      * Sets the path for the mix_audit binary.
821      */
822     @SuppressWarnings("CanBeFinal")
823     @Parameter(property = "mixAuditPath")
824     private String mixAuditPath;
825 
826     /**
827      * Whether or not the Ruby Bundle Audit Analyzer is enabled.
828      */
829     @Parameter(property = "bundleAuditAnalyzerEnabled")
830     private Boolean bundleAuditAnalyzerEnabled;
831 
832     /**
833      * Sets the path for the bundle-audit binary.
834      */
835     @SuppressWarnings("CanBeFinal")
836     @Parameter(property = "bundleAuditPath")
837     private String bundleAuditPath;
838 
839     /**
840      * Sets the path for the working directory that the bundle-audit binary
841      * should be executed from.
842      */
843     @SuppressWarnings("CanBeFinal")
844     @Parameter(property = "bundleAuditWorkingDirectory")
845     private String bundleAuditWorkingDirectory;
846 
847     /**
848      * Whether or not the CocoaPods Analyzer is enabled.
849      */
850     @SuppressWarnings("CanBeFinal")
851     @Parameter(property = "cocoapodsAnalyzerEnabled")
852     private Boolean cocoapodsAnalyzerEnabled;
853 
854     /**
855      * Whether or not the Carthage Analyzer is enabled.
856      */
857     @SuppressWarnings("CanBeFinal")
858     @Parameter(property = "carthageAnalyzerEnabled")
859     private Boolean carthageAnalyzerEnabled;
860 
861     /**
862      * Whether or not the Swift package Analyzer is enabled.
863      */
864     @SuppressWarnings("CanBeFinal")
865     @Parameter(property = "swiftPackageManagerAnalyzerEnabled")
866     private Boolean swiftPackageManagerAnalyzerEnabled;
867     /**
868      * Whether or not the Swift package resolved Analyzer is enabled.
869      */
870     @SuppressWarnings("CanBeFinal")
871     @Parameter(property = "swiftPackageResolvedAnalyzerEnabled")
872     private Boolean swiftPackageResolvedAnalyzerEnabled;
873     /**
874      * The URL of a Nexus server's REST API end point
875      * (http://domain/nexus/service/local).
876      */
877     @SuppressWarnings("CanBeFinal")
878     @Parameter(property = "nexusUrl")
879     private String nexusUrl;
880     /**
881      * The id of a server defined in the settings.xml that configures the
882      * credentials (username and password) for a Nexus server's REST API end
883      * point. When not specified the communication with the Nexus server's REST
884      * API will be unauthenticated.
885      */
886     @SuppressWarnings("CanBeFinal")
887     @Parameter(property = "nexusServerId")
888     private String nexusServerId;
889     /**
890      * Whether or not the configured proxy is used to connect to Nexus.
891      */
892     @SuppressWarnings("CanBeFinal")
893     @Parameter(property = "nexusUsesProxy")
894     private Boolean nexusUsesProxy;
895     /**
896      * The database connection string.
897      */
898     @SuppressWarnings("CanBeFinal")
899     @Parameter(property = "connectionString")
900     private String connectionString;
901 
902     /**
903      * The database driver name. An example would be org.h2.Driver.
904      */
905     @SuppressWarnings("CanBeFinal")
906     @Parameter(property = "databaseDriverName")
907     private String databaseDriverName;
908     /**
909      * The path to the database driver if it is not on the class path.
910      */
911     @SuppressWarnings("CanBeFinal")
912     @Parameter(property = "databaseDriverPath")
913     private String databaseDriverPath;
914     /**
915      * A reference to the settings.xml settings.
916      */
917     @SuppressWarnings("CanBeFinal")
918     @Parameter(defaultValue = "${settings}", readonly = true, required = true)
919     private org.apache.maven.settings.Settings settingsXml;
920 
921     /**
922      * The settingsDecryptor from Maven to decrypt passwords from Settings.xml servers section
923      */
924     @Component
925     private SettingsDecrypter settingsDecrypter;
926 
927     /**
928      * The database user name.
929      */
930     @Parameter(property = "databaseUser")
931     private String databaseUser;
932     /**
933      * The password to use when connecting to the database. The `serverId` should be used instead otherwise maven debug logging could expose the password.
934      */
935     @Parameter(property = "databasePassword")
936     private String databasePassword;
937     /**
938      * A comma-separated list of file extensions to add to analysis next to jar,
939      * zip, ....
940      */
941     @SuppressWarnings("CanBeFinal")
942     @Parameter(property = "zipExtensions")
943     private String zipExtensions;
944     /**
945      * Skip Dependency Check altogether.
946      */
947     @SuppressWarnings("CanBeFinal")
948     @Parameter(property = "dependency-check.skip", defaultValue = "false")
949     private boolean skip = false;
950     /**
951      * Skip Analysis for Test Scope Dependencies.
952      */
953     @SuppressWarnings("CanBeFinal")
954     @Parameter(property = "skipTestScope", defaultValue = "true")
955     private boolean skipTestScope = true;
956     /**
957      * Skip Analysis for Runtime Scope Dependencies.
958      */
959     @SuppressWarnings("CanBeFinal")
960     @Parameter(property = "skipRuntimeScope", defaultValue = "false")
961     private boolean skipRuntimeScope = false;
962     /**
963      * Skip Analysis for Provided Scope Dependencies.
964      */
965     @SuppressWarnings("CanBeFinal")
966     @Parameter(property = "skipProvidedScope", defaultValue = "false")
967     private boolean skipProvidedScope = false;
968 
969     /**
970      * Skip Analysis for System Scope Dependencies.
971      */
972     @SuppressWarnings("CanBeFinal")
973     @Parameter(property = "skipSystemScope", defaultValue = "false")
974     private boolean skipSystemScope = false;
975 
976     /**
977      * Skip Analysis for dependencyManagement section.
978      */
979     @SuppressWarnings("CanBeFinal")
980     @Parameter(property = "skipDependencyManagement", defaultValue = "true")
981     private boolean skipDependencyManagement = true;
982 
983     /**
984      * Skip analysis for dependencies which type matches this regular
985      * expression. This filters on the `type` of dependency as defined in the
986      * dependency section: jar, pom, test-jar, etc.
987      */
988     @SuppressWarnings("CanBeFinal")
989     @Parameter(property = "skipArtifactType")
990     private String skipArtifactType;
991 
992     /**
993      * The data directory, hold DC SQL DB.
994      */
995     @SuppressWarnings("CanBeFinal")
996     @Parameter(property = "dataDirectory")
997     private String dataDirectory;
998 
999     /**
1000      * The name of the DC DB.
1001      */
1002     @SuppressWarnings("CanBeFinal")
1003     @Parameter(property = "dbFilename")
1004     private String dbFilename;
1005     /**
1006      * The server id in the settings.xml; used to retrieve encrypted passwords
1007      * from the settings.xml. This is used for the database username and
1008      * password.
1009      */
1010     @SuppressWarnings("CanBeFinal")
1011     @Parameter(property = "serverId")
1012     private String serverId;
1013     /**
1014      * The NVD API Key. The parameters {@link #nvdApiKeyEnvironmentVariable} or {@link #nvdApiServerId} should be used instead otherwise
1015      * Maven debug logging could expose the API Key (see <a href="https://github.com/advisories/GHSA-qqhq-8r2c-c3f5">GHSA-qqhq-8r2c-c3f5</a>).
1016      * This takes precedence over {@link #nvdApiServerId} and {@link #nvdApiKeyEnvironmentVariable}.
1017      */
1018     @SuppressWarnings("CanBeFinal")
1019     @Parameter(property = "nvdApiKey")
1020     private String nvdApiKey;
1021     /**
1022      * The maximum number of retry requests for a single call to the NVD API.
1023      */
1024     @SuppressWarnings("CanBeFinal")
1025     @Parameter(property = "nvdMaxRetryCount")
1026     private Integer nvdMaxRetryCount;
1027     /**
1028      * The server id in the settings.xml; used to retrieve encrypted API Key
1029      * from the settings.xml for the NVD API Key. Note that the password is used
1030      * as the API Key.
1031      * Is potentially overwritten by {@link #nvdApiKeyEnvironmentVariable} or {@link #nvdApiKey}.
1032      */
1033     @SuppressWarnings("CanBeFinal")
1034     @Parameter(property = "nvdApiServerId")
1035     private String nvdApiServerId;
1036     /**
1037      * The environment variable from which to retrieve the API key for the NVD API.
1038      * Takes precedence over {@link #nvdApiServerId} but is potentially overwritten by {@link #nvdApiKey}.
1039      * This is the recommended option to pass the API key in CI builds.
1040      */
1041     @SuppressWarnings("CanBeFinal")
1042     @Parameter(property = "nvdApiKeyEnvironmentVariable")
1043     private String nvdApiKeyEnvironmentVariable;
1044     /**
1045      * The number of hours to wait before checking for new updates from the NVD.
1046      */
1047     @SuppressWarnings("CanBeFinal")
1048     @Parameter(property = "nvdValidForHours")
1049     private Integer nvdValidForHours;
1050     /**
1051      * The NVD API Endpoint; setting this is uncommon.
1052      */
1053     @SuppressWarnings("CanBeFinal")
1054     @Parameter(property = "nvdApiEndpoint")
1055     private String nvdApiEndpoint;
1056     /**
1057      * The NVD API Data Feed URL.
1058      */
1059     @SuppressWarnings("CanBeFinal")
1060     @Parameter(property = "nvdDatafeedUrl")
1061     private String nvdDatafeedUrl;
1062 
1063     /**
1064      * The server id in the settings.xml; used to retrieve encrypted credentials
1065      * from the settings.xml for the NVD Data Feed.<br/>
1066      * Credentials with only a password will be used for Bearer auth, credentials with both user and password for Basic auth.
1067      */
1068     @SuppressWarnings("CanBeFinal")
1069     @Parameter(property = "nvdDatafeedServerId")
1070     private String nvdDatafeedServerId;
1071     /**
1072      * The username for basic auth to the NVD Data Feed. A `nvdDatafeedServerId` with user/password set should be used
1073      * instead otherwise maven debug logging could expose the password.
1074      */
1075     @SuppressWarnings("CanBeFinal")
1076     @Parameter(property = "nvdUser")
1077     private String nvdUser;
1078     /**
1079      * The password for basic auth to the NVD Data Feed. A `nvdDatafeedServerId` with user/password set should be used
1080      * instead otherwise maven debug logging could expose the password.
1081      */
1082     @SuppressWarnings("CanBeFinal")
1083     @Parameter(property = "nvdPassword")
1084     private String nvdPassword;
1085     /**
1086      * The token for bearer auth to the NVD Data Feed. A `nvdDatafeedServerId` with only password set should be used
1087      * instead otherwise maven debug logging could expose the token.
1088      */
1089     @SuppressWarnings("CanBeFinal")
1090     @Parameter(property = "nvdBearerToken")
1091     private String nvdBearerToken;
1092     /**
1093      * The time in milliseconds to wait between downloading NVD API data.
1094      */
1095     @SuppressWarnings("CanBeFinal")
1096     @Parameter(property = "nvdApiDelay")
1097     private Integer nvdApiDelay;
1098 
1099     /**
1100      * The number records for a single page from NVD API (must be <=2000).
1101      */
1102     @SuppressWarnings("CanBeFinal")
1103     @Parameter(property = "nvdApiResultsPerPage")
1104     private Integer nvdApiResultsPerPage;
1105 
1106     /**
1107      * The path to dotnet core.
1108      */
1109     @SuppressWarnings("CanBeFinal")
1110     @Parameter(property = "pathToCore")
1111     private String pathToCore;
1112     /**
1113      * The hosted suppressions file URL.
1114      */
1115     @SuppressWarnings("CanBeFinal")
1116     @Parameter(property = "hostedSuppressionsUrl")
1117     private String hostedSuppressionsUrl;
1118     /**
1119      * The password used for Basic auth to the suppressionFiles.
1120      */
1121     @SuppressWarnings("CanBeFinal")
1122     @Parameter(property = "hostedSuppressionsUser")
1123     private String hostedSuppressionsUser;
1124     /**
1125      * The password used for Basic auth to the suppressionFiles. The `hostedSuppressionsServerId` with user/password should be used instead otherwise maven debug logging could expose the password.
1126      */
1127     @SuppressWarnings("CanBeFinal")
1128     @Parameter(property = "hostedSuppressionsPassword")
1129     private String hostedSuppressionsPassword;
1130     /**
1131      * The token used for Bearer auth to the suppressionFiles. The `hostedSuppressionsServerId` with only password should
1132      * be used instead otherwise maven debug logging could expose the token.
1133      */
1134     @SuppressWarnings("CanBeFinal")
1135     @Parameter(property = "hostedSuppressionsBearerToken")
1136     private String hostedSuppressionsBearerToken;
1137     /**
1138      * The server id in the settings.xml used to retrieve encrypted passwords
1139      * from the settings.xml for a mirror of the HostedSuppressions XML file.
1140      */
1141     @SuppressWarnings("CanBeFinal")
1142     @Parameter(property = "hostedSuppressionsServerId")
1143     private String hostedSuppressionsServerId;
1144     /**
1145      * Whether the hosted suppressions file will be updated regardless of the
1146      * `autoupdate` settings.
1147      */
1148     @SuppressWarnings("CanBeFinal")
1149     @Parameter(property = "hostedSuppressionsForceUpdate")
1150     private Boolean hostedSuppressionsForceUpdate;
1151     /**
1152      * Whether the hosted suppressions file will be used.
1153      */
1154     @SuppressWarnings("CanBeFinal")
1155     @Parameter(property = "hostedSuppressionsEnabled")
1156     private Boolean hostedSuppressionsEnabled;
1157     /**
1158      * Skip excessive hosted suppression file update checks for a designated
1159      * duration in hours (defaults to 2 hours).
1160      */
1161     @SuppressWarnings("CanBeFinal")
1162     @Parameter(property = "hostedSuppressionsValidForHours")
1163     private Integer hostedSuppressionsValidForHours;
1164 
1165     /**
1166      * The RetireJS Analyzer configuration:
1167      * <pre>
1168      *   filters: an array of filter patterns that are used to exclude JS files that contain a match
1169      *   filterNonVulnerable: a boolean that when true will remove non-vulnerable JS from the report
1170      *
1171      * Example:
1172      *   &lt;retirejs&gt;
1173      *     &lt;filters&gt;
1174      *       &lt;filter&gt;copyright 2018\(c\) Jeremy Long&lt;/filter&gt;
1175      *     &lt;/filters&gt;
1176      *     &lt;filterNonVulnerable&gt;true&lt;/filterNonVulnerable&gt;
1177      *   &lt;/retirejs&gt;
1178      * </pre>
1179      */
1180     @SuppressWarnings("CanBeFinal")
1181     @Parameter(property = "retirejs")
1182     private Retirejs retirejs;
1183 
1184     /**
1185      * The list of patterns to exclude from the check. This is matched against the project dependencies (and will implicitly also remove transitive dependencies from matching dependencies).
1186      * Each pattern has the format {@code [groupId]:[artifactId]:[type]:[version]}. You can leave out unspecified parts (which is equal to using {@code *}).
1187      * Examples: {@code org.apache.*} would match all artifacts whose group id starts with {@code org.apache.}, and {@code :::*-SNAPSHOT} would match all snapshot artifacts.
1188      */
1189     @Parameter(property = "odc.excludes")
1190     private List<String> excludes;
1191 
1192     /**
1193      * The artifact scope filter.
1194      */
1195     private Filter<String> artifactScopeExcluded;
1196 
1197     /**
1198      * Filter for artifact type.
1199      */
1200     private Filter<String> artifactTypeExcluded;
1201 
1202     /**
1203      * An collection of <code>fileSet</code>s that specify additional files
1204      * and/or directories (from the basedir) to analyze as part of the scan. If
1205      * not specified, defaults to Maven conventions of: src/main/resources,
1206      * src/main/filters, and src/main/webapp. Note, this cannot be set via the
1207      * command line - use `scanDirectory` instead.
1208      */
1209     @Parameter
1210     private List<FileSet> scanSet;
1211     /**
1212      * A list of directories to scan. Note, this should only be used via the
1213      * command line - if configuring the directories to scan consider using the
1214      * `scanSet` instead.
1215      */
1216     @Parameter(property = "scanDirectory")
1217     private List<String> scanDirectory;
1218 
1219     /**
1220      * Whether the project's plugins should also be scanned.
1221      */
1222     @SuppressWarnings("CanBeFinal")
1223     @Parameter(property = "odc.plugins.scan", defaultValue = "false", required = false)
1224     private boolean scanPlugins = false;
1225     /**
1226      * Whether the project's dependencies should also be scanned.
1227      */
1228     @SuppressWarnings("CanBeFinal")
1229     @Parameter(property = "odc.dependencies.scan", defaultValue = "true", required = false)
1230     private boolean scanDependencies = true;
1231     /**
1232      * The proxy configuration.
1233      */
1234     @Parameter
1235     private ProxyConfig proxy;
1236 
1237     // </editor-fold>
1238     //<editor-fold defaultstate="collapsed" desc="Base Maven implementation">
1239 
1240     /**
1241      * Determines if the groupId, artifactId, and version of the Maven
1242      * dependency and artifact match.
1243      *
1244      * @param d the Maven dependency
1245      * @param a the Maven artifact
1246      * @return true if the groupId, artifactId, and version match
1247      */
1248     private static boolean artifactsMatch(org.apache.maven.model.Dependency d, Artifact a) {
1249         return isEqualOrNull(a.getArtifactId(), d.getArtifactId())
1250                 && isEqualOrNull(a.getGroupId(), d.getGroupId())
1251                 && isEqualOrNull(a.getVersion(), d.getVersion());
1252     }
1253 
1254     /**
1255      * Compares two strings for equality; if both strings are null they are
1256      * considered equal.
1257      *
1258      * @param left the first string to compare
1259      * @param right the second string to compare
1260      * @return true if the strings are equal or if they are both null; otherwise
1261      * false.
1262      */
1263     private static boolean isEqualOrNull(String left, String right) {
1264         return (left != null && left.equals(right)) || (left == null && right == null);
1265     }
1266 
1267     /**
1268      * Executes dependency-check.
1269      *
1270      * @throws MojoExecutionException thrown if there is an exception executing
1271      * the mojo
1272      * @throws MojoFailureException thrown if dependency-check failed the build
1273      */
1274     @Override
1275     public void execute() throws MojoExecutionException, MojoFailureException {
1276         generatingSite = false;
1277         final boolean shouldSkip = Boolean.parseBoolean(System.getProperty("dependency-check.skip", Boolean.toString(skip)));
1278         if (shouldSkip) {
1279             getLog().info("Skipping " + getName(Locale.US));
1280         } else {
1281             project.setContextValue("dependency-check-output-dir", this.outputDirectory);
1282             runCheck();
1283         }
1284     }
1285 
1286     /**
1287      * Returns true if the Maven site is being generated.
1288      *
1289      * @return true if the Maven site is being generated
1290      */
1291     protected boolean isGeneratingSite() {
1292         return generatingSite;
1293     }
1294 
1295     /**
1296      * Returns the connection string.
1297      *
1298      * @return the connection string
1299      */
1300     protected String getConnectionString() {
1301         return connectionString;
1302     }
1303 
1304     /**
1305      * Returns if the mojo should fail the build if an exception occurs.
1306      *
1307      * @return whether or not the mojo should fail the build
1308      */
1309     protected boolean isFailOnError() {
1310         return failOnError;
1311     }
1312 
1313     /**
1314      * Generates the Dependency-Check Site Report.
1315      *
1316      * @param sink the sink to write the report to
1317      * @param locale the locale to use when generating the report
1318      * @throws MavenReportException if a maven report exception occurs
1319      */
1320     public void generate(Sink sink, Locale locale) throws MavenReportException {
1321         final boolean shouldSkip = Boolean.parseBoolean(System.getProperty("dependency-check.skip", Boolean.toString(skip)));
1322         if (shouldSkip) {
1323             getLog().info("Skipping report generation " + getName(Locale.US));
1324             return;
1325         }
1326 
1327         generatingSite = true;
1328         project.setContextValue("dependency-check-output-dir", getReportOutputDirectory());
1329         try {
1330             runCheck();
1331         } catch (MojoExecutionException ex) {
1332             throw new MavenReportException(ex.getMessage(), ex);
1333         } catch (MojoFailureException ex) {
1334             getLog().warn("Vulnerabilities were identifies that exceed the CVSS threshold for failing the build");
1335         }
1336     }
1337 
1338     /**
1339      * Returns the correct output directory depending on if a site is being
1340      * executed or not.
1341      *
1342      * @return the directory to write the report(s)
1343      * @throws MojoExecutionException thrown if there is an error loading the
1344      * file path
1345      */
1346     protected File getCorrectOutputDirectory() throws MojoExecutionException {
1347         return getCorrectOutputDirectory(this.project);
1348     }
1349 
1350     /**
1351      * Returns the correct output directory depending on if a site is being
1352      * executed or not.
1353      *
1354      * @param current the Maven project to get the output directory from
1355      * @return the directory to write the report(s)
1356      */
1357     protected File getCorrectOutputDirectory(MavenProject current) {
1358         final Object obj = current.getContextValue("dependency-check-output-dir");
1359         if (obj != null && obj instanceof File) {
1360             return (File) obj;
1361         }
1362         //else we guess
1363         File target = new File(current.getBuild().getDirectory());
1364         if (target.getParentFile() != null && "target".equals(target.getParentFile().getName())) {
1365             target = target.getParentFile();
1366         }
1367         return target;
1368     }
1369 
1370     /**
1371      * Scans the project's artifacts and adds them to the engine's dependency
1372      * list.
1373      *
1374      * @param project the project to scan the dependencies of
1375      * @param engine the engine to use to scan the dependencies
1376      * @return a collection of exceptions that may have occurred while resolving
1377      * and scanning the dependencies
1378      */
1379     protected ExceptionCollection scanArtifacts(MavenProject project, Engine engine) {
1380         return scanArtifacts(project, engine, false);
1381     }
1382 
1383     /**
1384      * Scans the project's artifacts and adds them to the engine's dependency
1385      * list.
1386      *
1387      * @param project the project to scan the dependencies of
1388      * @param engine the engine to use to scan the dependencies
1389      * @param aggregate whether the scan is part of an aggregate build
1390      * @return a collection of exceptions that may have occurred while resolving
1391      * and scanning the dependencies
1392      */
1393     protected ExceptionCollection scanArtifacts(MavenProject project, Engine engine, boolean aggregate) {
1394         try {
1395             final List<String> filterItems = Collections.singletonList(String.format("%s:%s", project.getGroupId(), project.getArtifactId()));
1396             final ProjectBuildingRequest buildingRequest = newResolveArtifactProjectBuildingRequest(project, project.getRemoteArtifactRepositories());
1397             //For some reason the filter does not filter out the project being analyzed
1398             //if we pass in the filter below instead of null to the dependencyGraphBuilder
1399             final DependencyNode dn = dependencyGraphBuilder.buildDependencyGraph(buildingRequest, null);
1400 
1401             final CollectingRootDependencyGraphVisitor collectorVisitor = new CollectingRootDependencyGraphVisitor();
1402 
1403             // exclude artifact by pattern and its dependencies
1404             final DependencyNodeVisitor transitiveFilterVisitor = new FilteringDependencyTransitiveNodeVisitor(collectorVisitor,
1405                     new ArtifactDependencyNodeFilter(new PatternExcludesArtifactFilter(getExcludes())));
1406             // exclude exact artifact but not its dependencies, this filter must be appied on the root for first otherwise
1407             // in case the exclude has the same groupId of the current bundle its direct dependencies are not visited
1408             final DependencyNodeVisitor artifactFilter = new FilteringDependencyNodeVisitor(transitiveFilterVisitor,
1409                     new ArtifactDependencyNodeFilter(new ExcludesArtifactFilter(filterItems)));
1410             dn.accept(artifactFilter);
1411 
1412             //collect dependencies with the filter - see comment above.
1413             final Map<DependencyNode, List<DependencyNode>> nodes = collectorVisitor.getNodes();
1414 
1415             return collectDependencies(engine, project, nodes, buildingRequest, aggregate);
1416         } catch (DependencyGraphBuilderException ex) {
1417             final String msg = String.format("Unable to build dependency graph on project %s", project.getName());
1418             getLog().debug(msg, ex);
1419             return new ExceptionCollection(ex);
1420         }
1421     }
1422 
1423     /**
1424      * Scans the project's artifacts for plugin-dependencies and adds them to
1425      * the engine's dependency list.
1426      *
1427      * @param project the project to scan the plugin-dependencies of
1428      * @param engine the engine to use to scan the plugin-dependencies
1429      * @param exCollection the collection of exceptions that have previously
1430      * occurred
1431      * @return a collection of exceptions that may have occurred while resolving
1432      * and scanning the plugins and their dependencies
1433      */
1434     protected ExceptionCollection scanPlugins(MavenProject project, Engine engine, ExceptionCollection exCollection) {
1435         ExceptionCollection exCol = exCollection;
1436         final Set<Artifact> plugins = new HashSet<>();
1437         final Set<Artifact> buildPlugins = getProject().getPluginArtifacts();
1438         final Set<Artifact> reportPlugins = getProject().getReportArtifacts();
1439         final Set<Artifact> extensions = getProject().getExtensionArtifacts();
1440 
1441         plugins.addAll(buildPlugins);
1442         plugins.addAll(reportPlugins);
1443         plugins.addAll(extensions);
1444 
1445         final ProjectBuildingRequest buildingRequest = newResolveArtifactProjectBuildingRequest(project, project.getPluginArtifactRepositories());
1446         for (Artifact plugin : plugins) {
1447             try {
1448                 final Artifact resolved = artifactResolver.resolveArtifact(buildingRequest, plugin).getArtifact();
1449 
1450                 exCol = addPluginToDependencies(project, engine, resolved, "pom.xml (plugins)", exCol);
1451 
1452                 final DefaultDependableCoordinate pluginCoordinate = new DefaultDependableCoordinate();
1453                 pluginCoordinate.setGroupId(resolved.getGroupId());
1454                 pluginCoordinate.setArtifactId(resolved.getArtifactId());
1455                 pluginCoordinate.setVersion(resolved.getVersion());
1456 
1457                 final String parent = buildReference(resolved.getGroupId(), resolved.getArtifactId(), resolved.getVersion());
1458                 for (Artifact artifact : resolveArtifactDependencies(pluginCoordinate, project)) {
1459                     exCol = addPluginToDependencies(project, engine, artifact, parent, exCol);
1460                 }
1461             } catch (ArtifactResolverException ex) {
1462                 throw new RuntimeException(ex);
1463             } catch (IllegalArgumentException ex) {
1464                 throw new RuntimeException(ex);
1465             } catch (DependencyResolverException ex) {
1466                 throw new RuntimeException(ex);
1467             }
1468         }
1469 
1470         return null;
1471 
1472     }
1473 
1474     private ExceptionCollection addPluginToDependencies(MavenProject project, Engine engine, Artifact artifact, String parent, ExceptionCollection exCollection) {
1475         ExceptionCollection exCol = exCollection;
1476         final String groupId = artifact.getGroupId();
1477         final String artifactId = artifact.getArtifactId();
1478         final String version = artifact.getVersion();
1479         final File artifactFile = artifact.getFile();
1480         if (artifactFile.isFile()) {
1481             final List<ArtifactVersion> availableVersions = artifact.getAvailableVersions();
1482 
1483             final List<Dependency> deps = engine.scan(artifactFile.getAbsoluteFile(),
1484                     project.getName() + " (plugins)");
1485             if (deps != null) {
1486                 Dependency d = null;
1487                 if (deps.size() == 1) {
1488                     d = deps.get(0);
1489                 } else {
1490                     for (Dependency possible : deps) {
1491                         if (artifactFile.getAbsoluteFile().equals(possible.getActualFile())) {
1492                             d = possible;
1493                             break;
1494                         }
1495                     }
1496                     for (Dependency dep : deps) {
1497                         if (d != null && d != dep) {
1498                             final String includedBy = buildReference(groupId, artifactId, version);
1499                             dep.addIncludedBy(includedBy, "plugins");
1500                         }
1501                     }
1502                 }
1503                 if (d != null) {
1504                     final MavenArtifact ma = new MavenArtifact(groupId, artifactId, version);
1505                     d.addAsEvidence("pom", ma, Confidence.HIGHEST);
1506                     if (parent != null) {
1507                         d.addIncludedBy(parent, "plugins");
1508                     } else {
1509                         final String includedby = buildReference(
1510                                 project.getGroupId(),
1511                                 project.getArtifactId(),
1512                                 project.getVersion());
1513                         d.addIncludedBy(includedby, "plugins");
1514                     }
1515                     if (availableVersions != null) {
1516                         for (ArtifactVersion av : availableVersions) {
1517                             d.addAvailableVersion(av.toString());
1518                         }
1519                     }
1520                 }
1521             }
1522         } else {
1523             if (exCol == null) {
1524                 exCol = new ExceptionCollection();
1525             }
1526             exCol.addException(new DependencyNotFoundException("Unable to resolve plugin: "
1527                     + groupId + ":" + artifactId + ":" + version));
1528         }
1529 
1530         return exCol;
1531     }
1532 
1533     private String buildReference(final String groupId, final String artifactId, final String version) {
1534         String includedBy;
1535         try {
1536             final PackageURL purl = new PackageURL("maven", groupId, artifactId, version, null, null);
1537             includedBy = purl.toString();
1538         } catch (MalformedPackageURLException ex) {
1539             getLog().warn("Unable to generate build reference for " + groupId
1540                     + ":" + artifactId + ":" + version, ex);
1541             includedBy = groupId + ":" + artifactId + ":" + version;
1542         }
1543         return includedBy;
1544     }
1545 
1546     protected Set<Artifact> resolveArtifactDependencies(final DependableCoordinate artifact, MavenProject project)
1547             throws DependencyResolverException {
1548         final ProjectBuildingRequest buildingRequest = newResolveArtifactProjectBuildingRequest(project, project.getRemoteArtifactRepositories());
1549 
1550         final Iterable<ArtifactResult> artifactResults = dependencyResolver.resolveDependencies(buildingRequest, artifact, null);
1551 
1552         final Set<Artifact> artifacts = new HashSet<>();
1553 
1554         for (ArtifactResult artifactResult : artifactResults) {
1555             artifacts.add(artifactResult.getArtifact());
1556         }
1557 
1558         return artifacts;
1559 
1560     }
1561 
1562     /**
1563      * Converts the dependency to a dependency node object.
1564      *
1565      * @param nodes the list of dependency nodes
1566      * @param buildingRequest the Maven project building request
1567      * @param parent the parent node
1568      * @param dependency the dependency to convert
1569      * @return the resulting dependency node
1570      * @throws ArtifactResolverException thrown if the artifact could not be
1571      * retrieved
1572      */
1573     private DependencyNode toDependencyNode(List<DependencyNode> nodes, ProjectBuildingRequest buildingRequest,
1574                                             DependencyNode parent, org.apache.maven.model.Dependency dependency) throws ArtifactResolverException {
1575 
1576         final DefaultArtifactCoordinate coordinate = new DefaultArtifactCoordinate();
1577 
1578         coordinate.setGroupId(dependency.getGroupId());
1579         coordinate.setArtifactId(dependency.getArtifactId());
1580         String version = null;
1581         final VersionRange vr;
1582         try {
1583             vr = VersionRange.createFromVersionSpec(dependency.getVersion());
1584         } catch (InvalidVersionSpecificationException ex) {
1585             throw new ArtifactResolverException("Invalid version specification: "
1586                     + dependency.getGroupId() + ":"
1587                     + dependency.getArtifactId() + ":"
1588                     + dependency.getVersion(), ex);
1589         }
1590         if (vr.hasRestrictions()) {
1591             version = findVersion(nodes, dependency.getGroupId(), dependency.getArtifactId());
1592             if (version == null) {
1593                 //TODO - this still may fail if the restriction is not a valid version number (i.e. only 2.9 instead of 2.9.1)
1594                 //need to get available versions and filter on the restrictions.
1595                 if (vr.getRecommendedVersion() != null) {
1596                     version = vr.getRecommendedVersion().toString();
1597                 } else if (vr.hasRestrictions()) {
1598                     for (Restriction restriction : vr.getRestrictions()) {
1599                         if (restriction.getLowerBound() != null) {
1600                             version = restriction.getLowerBound().toString();
1601                         }
1602                         if (restriction.getUpperBound() != null) {
1603                             version = restriction.getUpperBound().toString();
1604                         }
1605                     }
1606                 } else {
1607                     version = vr.toString();
1608                 }
1609             }
1610         }
1611         if (version == null) {
1612             version = dependency.getVersion();
1613         }
1614         coordinate.setVersion(version);
1615 
1616         final ArtifactType type = session.getRepositorySession().getArtifactTypeRegistry().get(dependency.getType());
1617         coordinate.setExtension(type.getExtension());
1618         coordinate.setClassifier((null == dependency.getClassifier() || dependency.getClassifier().isEmpty())
1619                 ? type.getClassifier() : dependency.getClassifier());
1620         final Artifact artifact = artifactResolver.resolveArtifact(buildingRequest, coordinate).getArtifact();
1621         artifact.setScope(dependency.getScope());
1622         return new DefaultDependencyNode(parent, artifact, dependency.getVersion(), dependency.getScope(), null);
1623     }
1624 
1625     /**
1626      * Returns the version from the list of nodes that match the given groupId
1627      * and artifactID.
1628      *
1629      * @param nodes the nodes to search
1630      * @param groupId the group id to find
1631      * @param artifactId the artifact id to find
1632      * @return the version from the list of nodes that match the given groupId
1633      * and artifactID; otherwise <code>null</code> is returned
1634      */
1635     private String findVersion(List<DependencyNode> nodes, String groupId, String artifactId) {
1636         final Optional<DependencyNode> f = nodes.stream().filter(p
1637                 -> groupId.equals(p.getArtifact().getGroupId())
1638                 && artifactId.equals(p.getArtifact().getArtifactId())).findFirst();
1639         if (f.isPresent()) {
1640             return f.get().getArtifact().getVersion();
1641         }
1642         return null;
1643     }
1644 
1645     /**
1646      * Collect dependencies from the dependency management section.
1647      *
1648      * @param engine reference to the ODC engine
1649      * @param buildingRequest the Maven project building request
1650      * @param project the project being analyzed
1651      * @param nodes the list of dependency nodes
1652      * @param aggregate whether or not this is an aggregate analysis
1653      * @return a collection of exceptions if any occurred; otherwise
1654      * <code>null</code>
1655      */
1656     private ExceptionCollection collectDependencyManagementDependencies(Engine engine, ProjectBuildingRequest buildingRequest,
1657                                                                         MavenProject project, List<DependencyNode> nodes, boolean aggregate) {
1658         if (skipDependencyManagement || project.getDependencyManagement() == null) {
1659             return null;
1660         }
1661 
1662         ExceptionCollection exCol = null;
1663         for (org.apache.maven.model.Dependency dependency : project.getDependencyManagement().getDependencies()) {
1664             try {
1665                 nodes.add(toDependencyNode(nodes, buildingRequest, null, dependency));
1666             } catch (ArtifactResolverException ex) {
1667                 getLog().debug(String.format("Aggregate : %s", aggregate));
1668                 boolean addException = true;
1669                 //CSOFF: EmptyBlock
1670                 if (!aggregate) {
1671                     // do nothing, exception is to be reported
1672                 } else if (addReactorDependency(engine,
1673                         new DefaultArtifact(dependency.getGroupId(), dependency.getArtifactId(),
1674                                 dependency.getVersion(), dependency.getScope(), dependency.getType(), dependency.getClassifier(),
1675                                 new DefaultArtifactHandler()), project)) {
1676                     addException = false;
1677                 }
1678                 //CSON: EmptyBlock
1679                 if (addException) {
1680                     if (exCol == null) {
1681                         exCol = new ExceptionCollection();
1682                     }
1683                     exCol.addException(ex);
1684                 }
1685             }
1686         }
1687         return exCol;
1688     }
1689 
1690     /**
1691      * Resolves the projects artifacts using Aether and scans the resulting
1692      * dependencies.
1693      *
1694      * @param engine the core dependency-check engine
1695      * @param project the project being scanned
1696      * @param nodeMap the map of dependency nodes, generally obtained via the
1697      * DependencyGraphBuilder using the CollectingRootDependencyGraphVisitor
1698      * @param buildingRequest the Maven project building request
1699      * @param aggregate whether the scan is part of an aggregate build
1700      * @return a collection of exceptions that may have occurred while resolving
1701      * and scanning the dependencies
1702      */
1703     //CSOFF: OperatorWrap
1704     private ExceptionCollection collectMavenDependencies(Engine engine, MavenProject project,
1705                                                          Map<DependencyNode, List<DependencyNode>> nodeMap, ProjectBuildingRequest buildingRequest, boolean aggregate) {
1706 
1707         final List<ArtifactResult> allResolvedDeps = new ArrayList<>();
1708 
1709         //dependency management
1710         final List<DependencyNode> dmNodes = new ArrayList<>();
1711         ExceptionCollection exCol = collectDependencyManagementDependencies(engine, buildingRequest, project, dmNodes, aggregate);
1712         for (DependencyNode dependencyNode : dmNodes) {
1713             exCol = scanDependencyNode(dependencyNode, null, engine, project, allResolvedDeps, buildingRequest, aggregate, exCol);
1714         }
1715 
1716         //dependencies
1717         for (Map.Entry<DependencyNode, List<DependencyNode>> entry : nodeMap.entrySet()) {
1718             exCol = scanDependencyNode(entry.getKey(), null, engine, project, allResolvedDeps, buildingRequest, aggregate, exCol);
1719             for (DependencyNode dependencyNode : entry.getValue()) {
1720                 exCol = scanDependencyNode(dependencyNode, entry.getKey(), engine, project, allResolvedDeps, buildingRequest, aggregate, exCol);
1721             }
1722         }
1723         return exCol;
1724     }
1725     //CSON: OperatorWrap
1726 
1727     /**
1728      * Utility method for a work-around to MSHARED-998
1729      *
1730      * @param allDeps The List of ArtifactResults for all dependencies
1731      * @param unresolvedArtifact The ArtifactCoordinate of the artifact we're
1732      * looking for
1733      * @param project The project in whose context resolution was attempted
1734      * @return the resolved artifact matching with {@code unresolvedArtifact}
1735      * @throws DependencyNotFoundException If {@code unresolvedArtifact} could
1736      * not be found within {@code allDeps}
1737      */
1738     private Artifact findInAllDeps(final List<ArtifactResult> allDeps, final Artifact unresolvedArtifact,
1739                                    final MavenProject project)
1740             throws DependencyNotFoundException {
1741         Artifact result = null;
1742         for (final ArtifactResult res : allDeps) {
1743             if (sameArtifact(res, unresolvedArtifact)) {
1744                 result = res.getArtifact();
1745                 break;
1746             }
1747         }
1748         if (result == null) {
1749             throw new DependencyNotFoundException(String.format("Expected dependency not found in resolved artifacts for "
1750                     + "dependency %s of project-artifact %s", unresolvedArtifact, project.getArtifactId()));
1751         }
1752         return result;
1753     }
1754 
1755     /**
1756      * Utility method for a work-around to MSHARED-998
1757      *
1758      * @param res A single ArtifactResult obtained from the DependencyResolver
1759      * @param unresolvedArtifact The unresolved Artifact from the
1760      * dependencyGraph that we try to find
1761      * @return {@code true} when unresolvedArtifact is non-null and matches with
1762      * the artifact of res
1763      */
1764     private boolean sameArtifact(final ArtifactResult res, final Artifact unresolvedArtifact) {
1765         if (res == null || res.getArtifact() == null || unresolvedArtifact == null) {
1766             return false;
1767         }
1768         boolean result = Objects.equals(res.getArtifact().getGroupId(), unresolvedArtifact.getGroupId());
1769         result &= Objects.equals(res.getArtifact().getArtifactId(), unresolvedArtifact.getArtifactId());
1770         // accept any version as matching "LATEST" and any non-snapshot version as matching "RELEASE" meta-version
1771         if ("RELEASE".equals(unresolvedArtifact.getBaseVersion())) {
1772             result &= !res.getArtifact().isSnapshot();
1773         } else if (!"LATEST".equals(unresolvedArtifact.getBaseVersion())) {
1774             result &= Objects.equals(res.getArtifact().getBaseVersion(), unresolvedArtifact.getBaseVersion());
1775         }
1776         result &= Objects.equals(res.getArtifact().getClassifier(), unresolvedArtifact.getClassifier());
1777         result &= Objects.equals(res.getArtifact().getType(), unresolvedArtifact.getType());
1778         return result;
1779     }
1780 
1781     /**
1782      * @param project the {@link MavenProject}
1783      * @param dependencyNode the {@link DependencyNode}
1784      * @return the name to be used when creating a
1785      * {@link Dependency#getProjectReferences() project reference} in a
1786      * {@link Dependency}. The behavior of this method returns {@link MavenProject#getName() project.getName()}<code> + ":" +
1787      * </code>
1788      * {@link DependencyNode#getArtifact() dependencyNode.getArtifact()}{@link Artifact#getScope() .getScope()}.
1789      */
1790     protected String createProjectReferenceName(MavenProject project, DependencyNode dependencyNode) {
1791         return project.getName() + ":" + dependencyNode.getArtifact().getScope();
1792     }
1793 
1794     /**
1795      * Scans the projects dependencies including the default (or defined)
1796      * FileSets.
1797      *
1798      * @param engine the core dependency-check engine
1799      * @param project the project being scanned
1800      * @param nodes the list of dependency nodes, generally obtained via the
1801      * DependencyGraphBuilder
1802      * @param buildingRequest the Maven project building request
1803      * @param aggregate whether the scan is part of an aggregate build
1804      * @return a collection of exceptions that may have occurred while resolving
1805      * and scanning the dependencies
1806      */
1807     private ExceptionCollection collectDependencies(Engine engine, MavenProject project,
1808                                                     Map<DependencyNode, List<DependencyNode>> nodes, ProjectBuildingRequest buildingRequest, boolean aggregate) {
1809 
1810         ExceptionCollection exCol;
1811         exCol = collectMavenDependencies(engine, project, nodes, buildingRequest, aggregate);
1812 
1813         final List<FileSet> projectScan;
1814 
1815         if (scanDirectory != null && !scanDirectory.isEmpty()) {
1816             if (scanSet == null) {
1817                 scanSet = new ArrayList<>();
1818             }
1819             scanDirectory.forEach(d -> {
1820                 final FileSet fs = new FileSet();
1821                 fs.setDirectory(d);
1822                 fs.addInclude(INCLUDE_ALL);
1823                 scanSet.add(fs);
1824             });
1825         }
1826 
1827         if (scanSet == null || scanSet.isEmpty()) {
1828             // Define the default FileSets
1829             final FileSet resourcesSet = new FileSet();
1830             final FileSet filtersSet = new FileSet();
1831             final FileSet webappSet = new FileSet();
1832             final FileSet mixedLangSet = new FileSet();
1833             try {
1834                 resourcesSet.setDirectory(new File(project.getBasedir(), "src/main/resources").getCanonicalPath());
1835                 resourcesSet.addInclude(INCLUDE_ALL);
1836                 filtersSet.setDirectory(new File(project.getBasedir(), "src/main/filters").getCanonicalPath());
1837                 filtersSet.addInclude(INCLUDE_ALL);
1838                 webappSet.setDirectory(new File(project.getBasedir(), "src/main/webapp").getCanonicalPath());
1839                 webappSet.addInclude(INCLUDE_ALL);
1840                 mixedLangSet.setDirectory(project.getBasedir().getCanonicalPath());
1841                 mixedLangSet.addInclude("package.json");
1842                 mixedLangSet.addInclude("package-lock.json");
1843                 mixedLangSet.addInclude("npm-shrinkwrap.json");
1844                 mixedLangSet.addInclude("Gopkg.lock");
1845                 mixedLangSet.addInclude("go.mod");
1846                 mixedLangSet.addInclude("yarn.lock");
1847                 mixedLangSet.addInclude("pnpm-lock.yaml");
1848                 mixedLangSet.addExclude("/node_modules/");
1849             } catch (IOException ex) {
1850                 if (exCol == null) {
1851                     exCol = new ExceptionCollection();
1852                 }
1853                 exCol.addException(ex);
1854             }
1855             projectScan = new ArrayList<>();
1856             projectScan.add(resourcesSet);
1857             projectScan.add(filtersSet);
1858             projectScan.add(webappSet);
1859             projectScan.add(mixedLangSet);
1860 
1861         } else if (aggregate) {
1862             projectScan = new ArrayList<>();
1863             for (FileSet copyFrom : scanSet) {
1864                 //deep copy of the FileSet - modifying the directory if it is not absolute.
1865                 final FileSet fsCopy = new FileSet();
1866                 final File f = new File(copyFrom.getDirectory());
1867                 if (f.isAbsolute()) {
1868                     fsCopy.setDirectory(copyFrom.getDirectory());
1869                 } else {
1870                     try {
1871                         fsCopy.setDirectory(new File(project.getBasedir(), copyFrom.getDirectory()).getCanonicalPath());
1872                     } catch (IOException ex) {
1873                         if (exCol == null) {
1874                             exCol = new ExceptionCollection();
1875                         }
1876                         exCol.addException(ex);
1877                         fsCopy.setDirectory(copyFrom.getDirectory());
1878                     }
1879                 }
1880                 fsCopy.setDirectoryMode(copyFrom.getDirectoryMode());
1881                 fsCopy.setExcludes(copyFrom.getExcludes());
1882                 fsCopy.setFileMode(copyFrom.getFileMode());
1883                 fsCopy.setFollowSymlinks(copyFrom.isFollowSymlinks());
1884                 fsCopy.setIncludes(copyFrom.getIncludes());
1885                 fsCopy.setLineEnding(copyFrom.getLineEnding());
1886                 fsCopy.setMapper(copyFrom.getMapper());
1887                 fsCopy.setModelEncoding(copyFrom.getModelEncoding());
1888                 fsCopy.setOutputDirectory(copyFrom.getOutputDirectory());
1889                 fsCopy.setUseDefaultExcludes(copyFrom.isUseDefaultExcludes());
1890                 projectScan.add(fsCopy);
1891             }
1892         } else {
1893             projectScan = scanSet;
1894         }
1895 
1896         // Iterate through FileSets and scan included files
1897         final FileSetManager fileSetManager = new FileSetManager();
1898         for (FileSet fileSet : projectScan) {
1899             getLog().debug("Scanning fileSet: " + fileSet.getDirectory());
1900             final String[] includedFiles = fileSetManager.getIncludedFiles(fileSet);
1901             for (String include : includedFiles) {
1902                 final File includeFile = new File(fileSet.getDirectory(), include).getAbsoluteFile();
1903                 if (includeFile.exists()) {
1904                     engine.scan(includeFile, project.getName());
1905                 }
1906             }
1907         }
1908         return exCol;
1909     }
1910 
1911     /**
1912      * Checks if the current artifact is actually in the reactor projects that
1913      * have not yet been built. If true a virtual dependency is created based on
1914      * the evidence in the project.
1915      *
1916      * @param engine a reference to the engine being used to scan
1917      * @param artifact the artifact being analyzed in the mojo
1918      * @param depender The project that depends on this virtual dependency
1919      * @return <code>true</code> if the artifact is in the reactor; otherwise
1920      * <code>false</code>
1921      */
1922     private boolean addReactorDependency(Engine engine, Artifact artifact, final MavenProject depender) {
1923         return addVirtualDependencyFromReactor(engine, artifact, depender, "Unable to resolve %s as it has not been built yet "
1924                 + "- creating a virtual dependency instead.");
1925     }
1926 
1927     /**
1928      * Checks if the current artifact is actually in the reactor projects. If
1929      * true a virtual dependency is created based on the evidence in the
1930      * project.
1931      *
1932      * @param engine a reference to the engine being used to scan
1933      * @param artifact the artifact being analyzed in the mojo
1934      * @param depender The project that depends on this virtual dependency
1935      * @param infoLogTemplate the template for the infoLog entry written when a
1936      * virtual dependency is added. Needs a single %s placeholder for the
1937      * location of the displayName in the message
1938      * @return <code>true</code> if the artifact is in the reactor; otherwise
1939      * <code>false</code>
1940      */
1941     private boolean addVirtualDependencyFromReactor(Engine engine, Artifact artifact,
1942                                                     final MavenProject depender, String infoLogTemplate) {
1943 
1944         getLog().debug(String.format("Checking the reactor projects (%d) for %s:%s:%s",
1945                 reactorProjects.size(),
1946                 artifact.getGroupId(), artifact.getArtifactId(), artifact.getVersion()));
1947 
1948         for (MavenProject prj : reactorProjects) {
1949 
1950             getLog().debug(String.format("Comparing %s:%s:%s to %s:%s:%s",
1951                     artifact.getGroupId(), artifact.getArtifactId(), artifact.getBaseVersion(),
1952                     prj.getGroupId(), prj.getArtifactId(), prj.getVersion()));
1953 
1954             if (prj.getArtifactId().equals(artifact.getArtifactId())
1955                     && prj.getGroupId().equals(artifact.getGroupId())
1956                     && prj.getVersion().equals(artifact.getBaseVersion())) {
1957 
1958                 final String displayName = String.format("%s:%s:%s",
1959                         prj.getGroupId(), prj.getArtifactId(), prj.getVersion());
1960                 getLog().info(String.format(infoLogTemplate,
1961                         displayName));
1962                 final Dependency d = newDependency(prj);
1963                 final String key = String.format("%s:%s:%s", prj.getGroupId(), prj.getArtifactId(), prj.getVersion());
1964                 d.setSha1sum(Checksum.getSHA1Checksum(key));
1965                 d.setSha256sum(Checksum.getSHA256Checksum(key));
1966                 d.setMd5sum(Checksum.getMD5Checksum(key));
1967                 d.setEcosystem(JarAnalyzer.DEPENDENCY_ECOSYSTEM);
1968                 d.setDisplayFileName(displayName);
1969                 d.addProjectReference(depender.getName());
1970                 final String includedby = buildReference(
1971                         depender.getGroupId(),
1972                         depender.getArtifactId(),
1973                         depender.getVersion());
1974                 d.addIncludedBy(includedby);
1975                 d.addEvidence(EvidenceType.PRODUCT, "project", "artifactid", prj.getArtifactId(), Confidence.HIGHEST);
1976                 d.addEvidence(EvidenceType.VENDOR, "project", "artifactid", prj.getArtifactId(), Confidence.LOW);
1977 
1978                 d.addEvidence(EvidenceType.VENDOR, "project", "groupid", prj.getGroupId(), Confidence.HIGHEST);
1979                 d.addEvidence(EvidenceType.PRODUCT, "project", "groupid", prj.getGroupId(), Confidence.LOW);
1980                 d.setEcosystem(JarAnalyzer.DEPENDENCY_ECOSYSTEM);
1981                 Identifier id;
1982                 try {
1983                     id = new PurlIdentifier(StandardTypes.MAVEN, artifact.getGroupId(),
1984                             artifact.getArtifactId(), artifact.getVersion(), Confidence.HIGHEST);
1985                 } catch (MalformedPackageURLException ex) {
1986                     getLog().debug("Unable to create PackageURL object:" + key);
1987                     id = new GenericIdentifier("maven:" + key, Confidence.HIGHEST);
1988                 }
1989                 d.addSoftwareIdentifier(id);
1990                 //TODO unify the setName/version and package path - they are equivelent ideas submitted by two seperate committers
1991                 d.setName(String.format("%s:%s", prj.getGroupId(), prj.getArtifactId()));
1992                 d.setVersion(prj.getVersion());
1993                 d.setPackagePath(displayName);
1994                 if (prj.getDescription() != null) {
1995                     JarAnalyzer.addDescription(d, prj.getDescription(), "project", "description");
1996                 }
1997                 for (License l : prj.getLicenses()) {
1998                     final StringBuilder license = new StringBuilder();
1999                     if (l.getName() != null) {
2000                         license.append(l.getName());
2001                     }
2002                     if (l.getUrl() != null) {
2003                         license.append(" ").append(l.getUrl());
2004                     }
2005                     if (d.getLicense() == null) {
2006                         d.setLicense(license.toString());
2007                     } else if (!d.getLicense().contains(license)) {
2008                         d.setLicense(String.format("%s%n%s", d.getLicense(), license));
2009                     }
2010                 }
2011                 engine.addDependency(d);
2012                 return true;
2013             }
2014         }
2015         return false;
2016     }
2017 
2018     Dependency newDependency(MavenProject prj) {
2019         final File pom = new File(prj.getBasedir(), "pom.xml");
2020 
2021         if (pom.isFile()) {
2022             getLog().debug("Adding virtual dependency from pom.xml");
2023             return new Dependency(pom, true);
2024         } else if (prj.getFile().isFile()) {
2025             getLog().debug("Adding virtual dependency from file");
2026             return new Dependency(prj.getFile(), true);
2027         } else {
2028             return new Dependency(true);
2029         }
2030     }
2031 
2032     /**
2033      * Checks if the current artifact is actually in the reactor projects. If
2034      * true a virtual dependency is created based on the evidence in the
2035      * project.
2036      *
2037      * @param engine a reference to the engine being used to scan
2038      * @param artifact the artifact being analyzed in the mojo
2039      * @param depender The project that depends on this virtual dependency
2040      * @return <code>true</code> if the artifact is a snapshot artifact in the
2041      * reactor; otherwise <code>false</code>
2042      */
2043     private boolean addSnapshotReactorDependency(Engine engine, Artifact artifact, final MavenProject depender) {
2044         if (!artifact.isSnapshot()) {
2045             return false;
2046         }
2047         return addVirtualDependencyFromReactor(engine, artifact, depender, "Found snapshot reactor project in aggregate for %s - "
2048                 + "creating a virtual dependency as the snapshot found in the repository may contain outdated dependencies.");
2049     }
2050 
2051     /**
2052      * @param project The target project to create a building request for.
2053      * @param repos the artifact repositories to use.
2054      * @return Returns a new ProjectBuildingRequest populated from the current
2055      * session and the target project remote repositories, used to resolve
2056      * artifacts.
2057      */
2058     public ProjectBuildingRequest newResolveArtifactProjectBuildingRequest(MavenProject project, List<ArtifactRepository> repos) {
2059         final ProjectBuildingRequest buildingRequest = new DefaultProjectBuildingRequest(session.getProjectBuildingRequest());
2060         buildingRequest.setRemoteRepositories(repos);
2061         buildingRequest.setProject(project);
2062         return buildingRequest;
2063     }
2064 
2065     /**
2066      * Executes the dependency-check scan and generates the necessary report.
2067      *
2068      * @throws MojoExecutionException thrown if there is an exception running
2069      * the scan
2070      * @throws MojoFailureException thrown if dependency-check is configured to
2071      * fail the build
2072      */
2073     protected void runCheck() throws MojoExecutionException, MojoFailureException {
2074         muteNoisyLoggers();
2075         try (Engine engine = initializeEngine()) {
2076             ExceptionCollection exCol = null;
2077             if (scanDependencies) {
2078                 exCol = scanDependencies(engine);
2079             }
2080             if (scanPlugins) {
2081                 exCol = scanPlugins(engine, exCol);
2082             }
2083             try {
2084                 engine.analyzeDependencies();
2085             } catch (ExceptionCollection ex) {
2086                 exCol = handleAnalysisExceptions(exCol, ex);
2087             }
2088             if (exCol == null || !exCol.isFatal()) {
2089 
2090                 File outputDir = getCorrectOutputDirectory(this.getProject());
2091                 if (outputDir == null) {
2092                     //in some regards we shouldn't be writing this, but we are anyway.
2093                     //we shouldn't write this because nothing is configured to generate this report.
2094                     outputDir = new File(this.getProject().getBuild().getDirectory());
2095                 }
2096                 try {
2097                     final MavenProject p = this.getProject();
2098                     for (String f : getFormats()) {
2099                         engine.writeReports(p.getName(), p.getGroupId(), p.getArtifactId(), p.getVersion(), outputDir, f, exCol);
2100                     }
2101                 } catch (ReportException ex) {
2102                     if (exCol == null) {
2103                         exCol = new ExceptionCollection(ex);
2104                     } else {
2105                         exCol.addException(ex);
2106                     }
2107                     if (this.isFailOnError()) {
2108                         throw new MojoExecutionException("One or more exceptions occurred during dependency-check analysis", exCol);
2109                     } else {
2110                         getLog().debug("Error writing the report", ex);
2111                     }
2112                 }
2113                 showSummary(this.getProject(), engine.getDependencies());
2114                 checkForFailure(engine.getDependencies());
2115                 if (exCol != null && this.isFailOnError()) {
2116                     throw new MojoExecutionException("One or more exceptions occurred during dependency-check analysis", exCol);
2117                 }
2118             }
2119         } catch (DatabaseException ex) {
2120             if (getLog().isDebugEnabled()) {
2121                 getLog().debug("Database connection error", ex);
2122             }
2123             final String msg = "An exception occurred connecting to the local database. Please see the log file for more details.";
2124             if (this.isFailOnError()) {
2125                 throw new MojoExecutionException(msg, ex);
2126             }
2127             getLog().error(msg, ex);
2128         } finally {
2129             getSettings().cleanup();
2130         }
2131     }
2132 
2133     /**
2134      * Combines the two exception collections and if either are fatal, throw an
2135      * MojoExecutionException
2136      *
2137      * @param currentEx the primary exception collection
2138      * @param newEx the new exception collection to add
2139      * @return the combined exception collection
2140      * @throws MojoExecutionException thrown if dependency-check is configured
2141      * to fail on errors
2142      */
2143     private ExceptionCollection handleAnalysisExceptions(ExceptionCollection currentEx, ExceptionCollection newEx) throws MojoExecutionException {
2144         ExceptionCollection returnEx = currentEx;
2145         if (returnEx == null) {
2146             returnEx = newEx;
2147         } else {
2148             returnEx.getExceptions().addAll(newEx.getExceptions());
2149             if (newEx.isFatal()) {
2150                 returnEx.setFatal(true);
2151             }
2152         }
2153         if (returnEx.isFatal()) {
2154             final String msg = String.format("Fatal exception(s) analyzing %s", getProject().getName());
2155             if (this.isFailOnError()) {
2156                 throw new MojoExecutionException(msg, returnEx);
2157             }
2158             getLog().error(msg);
2159             if (getLog().isDebugEnabled()) {
2160                 getLog().debug(returnEx);
2161             }
2162         } else {
2163             final String msg = String.format("Exception(s) analyzing %s", getProject().getName());
2164             if (getLog().isDebugEnabled()) {
2165                 getLog().debug(msg, returnEx);
2166             }
2167         }
2168         return returnEx;
2169     }
2170 
2171     /**
2172      * Scans the dependencies of the projects.
2173      *
2174      * @param engine the engine used to perform the scanning
2175      * @return a collection of exceptions
2176      * @throws MojoExecutionException thrown if a fatal exception occurs
2177      */
2178     protected abstract ExceptionCollection scanDependencies(Engine engine) throws MojoExecutionException;
2179 
2180     /**
2181      * Scans the plugins of the projects.
2182      *
2183      * @param engine the engine used to perform the scanning
2184      * @param exCol the collection of any exceptions that have previously been
2185      * captured.
2186      * @return a collection of exceptions
2187      * @throws MojoExecutionException thrown if a fatal exception occurs
2188      */
2189     protected abstract ExceptionCollection scanPlugins(Engine engine, ExceptionCollection exCol) throws MojoExecutionException;
2190 
2191     /**
2192      * Returns the report output directory.
2193      *
2194      * @return the report output directory
2195      */
2196     @Override
2197     public File getReportOutputDirectory() {
2198         return reportOutputDirectory;
2199     }
2200 
2201     /**
2202      * Sets the Reporting output directory.
2203      *
2204      * @param directory the output directory
2205      */
2206     @Override
2207     public void setReportOutputDirectory(File directory) {
2208         reportOutputDirectory = directory;
2209     }
2210 
2211     /**
2212      * Returns the output directory.
2213      *
2214      * @return the output directory
2215      */
2216     public File getOutputDirectory() {
2217         return outputDirectory;
2218     }
2219 
2220     /**
2221      * Returns whether this is an external report. This method always returns
2222      * true.
2223      *
2224      * @return <code>true</code>
2225      */
2226     @Override
2227     public final boolean isExternalReport() {
2228         return true;
2229     }
2230 
2231     /**
2232      * Returns the output name.
2233      *
2234      * @return the output name
2235      */
2236     @Override
2237     public String getOutputName() {
2238         final Set<String> selectedFormats = getFormats();
2239         if (selectedFormats.contains("HTML") || selectedFormats.contains("ALL") || selectedFormats.size() > 1) {
2240             return "dependency-check-report";
2241         } else if (selectedFormats.contains("JENKINS")) {
2242             return "dependency-check-jenkins.html";
2243         } else if (selectedFormats.contains("XML")) {
2244             return "dependency-check-report.xml";
2245         } else if (selectedFormats.contains("JUNIT")) {
2246             return "dependency-check-junit.xml";
2247         } else if (selectedFormats.contains("JSON")) {
2248             return "dependency-check-report.json";
2249         } else if (selectedFormats.contains("SARIF")) {
2250             return "dependency-check-report.sarif";
2251         } else if (selectedFormats.contains("CSV")) {
2252             return "dependency-check-report.csv";
2253         } else {
2254             getLog().warn("Unknown report format used during site generation.");
2255             return "dependency-check-report";
2256         }
2257     }
2258 
2259     /**
2260      * Returns the category name.
2261      *
2262      * @return the category name
2263      */
2264     @Override
2265     public String getCategoryName() {
2266         return MavenReport.CATEGORY_PROJECT_REPORTS;
2267     }
2268     //</editor-fold>
2269 
2270     /**
2271      * Initializes a new <code>Engine</code> that can be used for scanning. This
2272      * method should only be called in a try-with-resources to ensure that the
2273      * engine is properly closed.
2274      *
2275      * @return a newly instantiated <code>Engine</code>
2276      * @throws DatabaseException thrown if there is a database exception
2277      * @throws MojoExecutionException on configuration errors when failOnError is true
2278      * @throws MojoFailureException on configuration errors when failOnError is false
2279      */
2280     protected Engine initializeEngine() throws DatabaseException, MojoExecutionException, MojoFailureException {
2281         populateSettings();
2282         try {
2283             Downloader.getInstance().configure(settings);
2284         } catch (InvalidSettingException e) {
2285             if (this.failOnError) {
2286                 throw new MojoFailureException(e.getMessage(), e);
2287             } else {
2288                 throw new MojoExecutionException(e.getMessage(), e);
2289             }
2290         }
2291         return new Engine(settings);
2292     }
2293 
2294     //CSOFF: MethodLength
2295 
2296     /**
2297      * Takes the properties supplied and updates the dependency-check settings.
2298      * Additionally, this sets the system properties required to change the
2299      * proxy URL, port, and connection timeout.
2300      */
2301     protected void populateSettings() throws MojoFailureException, MojoExecutionException {
2302         settings = new Settings();
2303         InputStream mojoProperties = null;
2304         try {
2305             mojoProperties = this.getClass().getClassLoader().getResourceAsStream(PROPERTIES_FILE);
2306             settings.mergeProperties(mojoProperties);
2307         } catch (IOException ex) {
2308             getLog().warn("Unable to load the dependency-check maven mojo.properties file.");
2309             if (getLog().isDebugEnabled()) {
2310                 getLog().debug("", ex);
2311             }
2312         } finally {
2313             if (mojoProperties != null) {
2314                 try {
2315                     mojoProperties.close();
2316                 } catch (IOException ex) {
2317                     if (getLog().isDebugEnabled()) {
2318                         getLog().debug("", ex);
2319                     }
2320                 }
2321             }
2322         }
2323         checkForDeprecatedParameters();
2324 
2325         settings.setStringIfNotEmpty(Settings.KEYS.MAVEN_LOCAL_REPO, mavenSettings.getLocalRepository());
2326         settings.setBooleanIfNotNull(Settings.KEYS.AUTO_UPDATE, autoUpdate);
2327         settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_EXPERIMENTAL_ENABLED, enableExperimental);
2328         settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_RETIRED_ENABLED, enableRetired);
2329         settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_GOLANG_DEP_ENABLED, golangDepEnabled);
2330         settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_GOLANG_MOD_ENABLED, golangModEnabled);
2331         settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_DART_ENABLED, dartAnalyzerEnabled);
2332         settings.setStringIfNotNull(Settings.KEYS.ANALYZER_GOLANG_PATH, pathToGo);
2333         settings.setStringIfNotNull(Settings.KEYS.ANALYZER_YARN_PATH, pathToYarn);
2334         settings.setStringIfNotNull(Settings.KEYS.ANALYZER_PNPM_PATH, pathToPnpm);
2335 
2336         // use global maven proxy if provided and system properties are not set
2337         final Proxy mavenProxyHttp = getMavenProxy(PROTOCOL_HTTP);
2338         final Proxy mavenProxyHttps = getMavenProxy(PROTOCOL_HTTPS);
2339         String httpsNonProxyHosts = null;
2340         String httpNonProxyHosts = null;
2341         boolean proxySetFromMavenSettings = false;
2342         if (mavenProxyHttps != null || mavenProxyHttp != null) {
2343             final String existingHttps = StringUtils.trimToNull(System.getProperty("https.proxyHost"));
2344             if (existingHttps == null) {
2345                 proxySetFromMavenSettings = true;
2346                 if (mavenProxyHttps != null) {
2347                     setProxyServerSysPropsFromMavenProxy(mavenProxyHttps, PROTOCOL_HTTPS);
2348                     if (mavenProxyHttps.getNonProxyHosts() != null && !mavenProxyHttps.getNonProxyHosts().isEmpty()) {
2349                         httpsNonProxyHosts = mavenProxyHttps.getNonProxyHosts();
2350                     }
2351                 } else {
2352                     setProxyServerSysPropsFromMavenProxy(mavenProxyHttp, PROTOCOL_HTTPS);
2353                     httpsNonProxyHosts = mavenProxyHttp.getNonProxyHosts();
2354                 }
2355             }
2356             final String existingHttp = StringUtils.trimToNull(System.getProperty("http.proxyHost"));
2357             if (mavenProxyHttp != null && existingHttp == null) {
2358                 proxySetFromMavenSettings = true;
2359                 setProxyServerSysPropsFromMavenProxy(mavenProxyHttp, PROTOCOL_HTTP);
2360                 httpNonProxyHosts = mavenProxyHttp.getNonProxyHosts();
2361             }
2362             if (proxySetFromMavenSettings) {
2363                 final String existingNonProxyHosts = System.getProperty("http.nonProxyHosts");
2364                 System.setProperty("http.nonProxyHosts", mergeNonProxyHosts(existingNonProxyHosts, httpNonProxyHosts, httpsNonProxyHosts));
2365             }
2366         } else if (this.proxy != null && this.proxy.getHost() != null) {
2367             // or use configured <proxy>
2368             settings.setString(Settings.KEYS.PROXY_SERVER, this.proxy.getHost());
2369             settings.setString(Settings.KEYS.PROXY_PORT, Integer.toString(this.proxy.getPort()));
2370             // user name and password from <server> entry settings.xml
2371             configureServerCredentials(this.proxy.getServerId(), Settings.KEYS.PROXY_USERNAME, Settings.KEYS.PROXY_PASSWORD);
2372         }
2373 
2374         final String[] suppressions = determineSuppressions();
2375         settings.setArrayIfNotEmpty(Settings.KEYS.SUPPRESSION_FILE, suppressions);
2376         settings.setBooleanIfNotNull(Settings.KEYS.UPDATE_VERSION_CHECK_ENABLED, versionCheckEnabled);
2377         settings.setStringIfNotEmpty(Settings.KEYS.CONNECTION_TIMEOUT, connectionTimeout);
2378         settings.setStringIfNotEmpty(Settings.KEYS.CONNECTION_READ_TIMEOUT, readTimeout);
2379         settings.setStringIfNotEmpty(Settings.KEYS.HINTS_FILE, hintsFile);
2380         settings.setFloat(Settings.KEYS.JUNIT_FAIL_ON_CVSS, junitFailOnCVSS);
2381         settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_JAR_ENABLED, jarAnalyzerEnabled);
2382         settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_NUSPEC_ENABLED, nuspecAnalyzerEnabled);
2383         settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_NUGETCONF_ENABLED, nugetconfAnalyzerEnabled);
2384         settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_LIBMAN_ENABLED, libmanAnalyzerEnabled);
2385         settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_CENTRAL_ENABLED, centralAnalyzerEnabled);
2386         settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_CENTRAL_USE_CACHE, centralAnalyzerUseCache);
2387         settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_ARTIFACTORY_ENABLED, artifactoryAnalyzerEnabled);
2388         settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_NEXUS_ENABLED, nexusAnalyzerEnabled);
2389         settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_ASSEMBLY_ENABLED, assemblyAnalyzerEnabled);
2390         settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_MSBUILD_PROJECT_ENABLED, msbuildAnalyzerEnabled);
2391         settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_ARCHIVE_ENABLED, archiveAnalyzerEnabled);
2392         settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_KNOWN_EXPLOITED_ENABLED, knownExploitedEnabled);
2393         settings.setStringIfNotEmpty(Settings.KEYS.KEV_URL, knownExploitedUrl);
2394         try {
2395             configureCredentials(knownExploitedServerId, knownExploitedUser, knownExploitedPassword, knownExploitedBearerToken,
2396                     Settings.KEYS.KEV_USER, Settings.KEYS.KEV_PASSWORD, Settings.KEYS.KEV_BEARER_TOKEN);
2397         } catch (InitializationException ex) {
2398             if (this.failOnError) {
2399                 throw new MojoFailureException("Invalid plugin configuration specified for Known Exploited data feed authentication", ex);
2400             } else {
2401                 throw new MojoExecutionException("Invalid plugin configuration specified for Known Exploited data feed authentication", ex);
2402             }
2403         }
2404         settings.setStringIfNotEmpty(Settings.KEYS.ADDITIONAL_ZIP_EXTENSIONS, zipExtensions);
2405         settings.setStringIfNotEmpty(Settings.KEYS.ANALYZER_ASSEMBLY_DOTNET_PATH, pathToCore);
2406         settings.setStringIfNotEmpty(Settings.KEYS.ANALYZER_NEXUS_URL, nexusUrl);
2407         configureServerCredentials(nexusServerId, Settings.KEYS.ANALYZER_NEXUS_USER, Settings.KEYS.ANALYZER_NEXUS_PASSWORD);
2408         settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_NEXUS_USES_PROXY, nexusUsesProxy);
2409         settings.setStringIfNotNull(Settings.KEYS.ANALYZER_ARTIFACTORY_URL, artifactoryAnalyzerUrl);
2410         settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_ARTIFACTORY_USES_PROXY, artifactoryAnalyzerUseProxy);
2411         settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_ARTIFACTORY_PARALLEL_ANALYSIS, artifactoryAnalyzerParallelAnalysis);
2412         settings.setBooleanIfNotNull(Settings.KEYS.FAIL_ON_UNUSED_SUPPRESSION_RULE, failBuildOnUnusedSuppressionRule);
2413         if (Boolean.TRUE.equals(artifactoryAnalyzerEnabled)) {
2414             if (artifactoryAnalyzerServerId != null) {
2415                 configureServerCredentials(artifactoryAnalyzerServerId, Settings.KEYS.ANALYZER_ARTIFACTORY_API_USERNAME,
2416                         Settings.KEYS.ANALYZER_ARTIFACTORY_API_TOKEN);
2417             } else {
2418                 settings.setStringIfNotNull(Settings.KEYS.ANALYZER_ARTIFACTORY_API_USERNAME, artifactoryAnalyzerUsername);
2419                 settings.setStringIfNotNull(Settings.KEYS.ANALYZER_ARTIFACTORY_API_TOKEN, artifactoryAnalyzerApiToken);
2420             }
2421             settings.setStringIfNotNull(Settings.KEYS.ANALYZER_ARTIFACTORY_BEARER_TOKEN, artifactoryAnalyzerBearerToken);
2422         }
2423         settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_PYTHON_DISTRIBUTION_ENABLED, pyDistributionAnalyzerEnabled);
2424         settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_PYTHON_PACKAGE_ENABLED, pyPackageAnalyzerEnabled);
2425         settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_RUBY_GEMSPEC_ENABLED, rubygemsAnalyzerEnabled);
2426         settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_OPENSSL_ENABLED, opensslAnalyzerEnabled);
2427         settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_CMAKE_ENABLED, cmakeAnalyzerEnabled);
2428         settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_AUTOCONF_ENABLED, autoconfAnalyzerEnabled);
2429         settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_MAVEN_INSTALL_ENABLED, mavenInstallAnalyzerEnabled);
2430         settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_PIP_ENABLED, pipAnalyzerEnabled);
2431         settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_PIPFILE_ENABLED, pipfileAnalyzerEnabled);
2432         settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_POETRY_ENABLED, poetryAnalyzerEnabled);
2433         settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_COMPOSER_LOCK_ENABLED, composerAnalyzerEnabled);
2434         settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_COMPOSER_LOCK_SKIP_DEV, composerAnalyzerSkipDev);
2435         settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_CPANFILE_ENABLED, cpanfileAnalyzerEnabled);
2436         settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_NODE_PACKAGE_ENABLED, nodeAnalyzerEnabled);
2437         settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_NODE_AUDIT_ENABLED, nodeAuditAnalyzerEnabled);
2438         settings.setStringIfNotNull(Settings.KEYS.ANALYZER_NODE_AUDIT_URL, nodeAuditAnalyzerUrl);
2439         settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_NODE_AUDIT_USE_CACHE, nodeAuditAnalyzerUseCache);
2440         settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_NODE_PACKAGE_SKIPDEV, nodePackageSkipDevDependencies);
2441         settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_NODE_AUDIT_SKIPDEV, nodeAuditSkipDevDependencies);
2442         settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_YARN_AUDIT_ENABLED, yarnAuditAnalyzerEnabled);
2443         settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_PNPM_AUDIT_ENABLED, pnpmAuditAnalyzerEnabled);
2444         settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_RETIREJS_ENABLED, retireJsAnalyzerEnabled);
2445         settings.setStringIfNotNull(Settings.KEYS.ANALYZER_RETIREJS_REPO_JS_URL, retireJsUrl);
2446         settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_RETIREJS_FORCEUPDATE, retireJsForceUpdate);
2447 
2448         try {
2449             configureCredentials(retireJsUrlServerId, retireJsUser, retireJsPassword, retireJsBearerToken,
2450                     Settings.KEYS.ANALYZER_RETIREJS_REPO_JS_USER, Settings.KEYS.ANALYZER_RETIREJS_REPO_JS_PASSWORD,
2451                     Settings.KEYS.ANALYZER_RETIREJS_REPO_JS_BEARER_TOKEN);
2452         } catch (InitializationException ex) {
2453             if (this.failOnError) {
2454                 throw new MojoFailureException("Invalid plugin configuration specified for retireJsUrl authentication", ex);
2455             } else {
2456                 throw new MojoExecutionException("Invalid plugin configuration specified for retireJsUrl authentication", ex);
2457             }
2458         }
2459         settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_MIX_AUDIT_ENABLED, mixAuditAnalyzerEnabled);
2460         settings.setStringIfNotNull(Settings.KEYS.ANALYZER_MIX_AUDIT_PATH, mixAuditPath);
2461         settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_BUNDLE_AUDIT_ENABLED, bundleAuditAnalyzerEnabled);
2462         settings.setStringIfNotNull(Settings.KEYS.ANALYZER_BUNDLE_AUDIT_PATH, bundleAuditPath);
2463         settings.setStringIfNotNull(Settings.KEYS.ANALYZER_BUNDLE_AUDIT_WORKING_DIRECTORY, bundleAuditWorkingDirectory);
2464         settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_COCOAPODS_ENABLED, cocoapodsAnalyzerEnabled);
2465         settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_CARTHAGE_ENABLED, carthageAnalyzerEnabled);
2466         settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_SWIFT_PACKAGE_MANAGER_ENABLED, swiftPackageManagerAnalyzerEnabled);
2467         settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_SWIFT_PACKAGE_RESOLVED_ENABLED, swiftPackageResolvedAnalyzerEnabled);
2468         settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_OSSINDEX_ENABLED, ossIndexAnalyzerEnabled);
2469         settings.setStringIfNotEmpty(Settings.KEYS.ANALYZER_OSSINDEX_URL, ossIndexAnalyzerUrl);
2470         if (StringUtils.isEmpty(ossIndexUsername) || StringUtils.isEmpty(ossIndexPassword)) {
2471             configureServerCredentials(ossIndexServerId, Settings.KEYS.ANALYZER_OSSINDEX_USER, Settings.KEYS.ANALYZER_OSSINDEX_PASSWORD);
2472         } else {
2473             settings.setStringIfNotEmpty(Settings.KEYS.ANALYZER_OSSINDEX_USER, ossIndexUsername);
2474             settings.setStringIfNotEmpty(Settings.KEYS.ANALYZER_OSSINDEX_PASSWORD, ossIndexPassword);
2475         }
2476         settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_OSSINDEX_USE_CACHE, ossIndexAnalyzerUseCache);
2477         settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_OSSINDEX_WARN_ONLY_ON_REMOTE_ERRORS, ossIndexWarnOnlyOnRemoteErrors);
2478         if (retirejs != null) {
2479             settings.setBooleanIfNotNull(Settings.KEYS.ANALYZER_RETIREJS_FILTER_NON_VULNERABLE, retirejs.getFilterNonVulnerable());
2480             settings.setArrayIfNotEmpty(Settings.KEYS.ANALYZER_RETIREJS_FILTERS, retirejs.getFilters());
2481         }
2482         //Database configuration
2483         settings.setStringIfNotEmpty(Settings.KEYS.DB_DRIVER_NAME, databaseDriverName);
2484         settings.setStringIfNotEmpty(Settings.KEYS.DB_DRIVER_PATH, databaseDriverPath);
2485         settings.setStringIfNotEmpty(Settings.KEYS.DB_CONNECTION_STRING, connectionString);
2486         if (databaseUser == null && databasePassword == null && serverId != null) {
2487             configureServerCredentials(serverId, Settings.KEYS.DB_USER, Settings.KEYS.DB_PASSWORD);
2488         } else {
2489             settings.setStringIfNotEmpty(Settings.KEYS.DB_USER, databaseUser);
2490             settings.setStringIfNotEmpty(Settings.KEYS.DB_PASSWORD, databasePassword);
2491         }
2492         settings.setStringIfNotEmpty(Settings.KEYS.DATA_DIRECTORY, dataDirectory);
2493         settings.setStringIfNotEmpty(Settings.KEYS.DB_FILE_NAME, dbFilename);
2494         settings.setStringIfNotNull(Settings.KEYS.NVD_API_ENDPOINT, nvdApiEndpoint);
2495         settings.setIntIfNotNull(Settings.KEYS.NVD_API_DELAY, nvdApiDelay);
2496         settings.setIntIfNotNull(Settings.KEYS.NVD_API_RESULTS_PER_PAGE, nvdApiResultsPerPage);
2497         settings.setStringIfNotEmpty(Settings.KEYS.NVD_API_DATAFEED_URL, nvdDatafeedUrl);
2498         settings.setIntIfNotNull(Settings.KEYS.NVD_API_VALID_FOR_HOURS, nvdValidForHours);
2499         settings.setIntIfNotNull(Settings.KEYS.NVD_API_MAX_RETRY_COUNT, nvdMaxRetryCount);
2500         if (nvdApiKey == null) {
2501             if (nvdApiKeyEnvironmentVariable != null) {
2502                 settings.setStringIfNotEmpty(Settings.KEYS.NVD_API_KEY, System.getenv(nvdApiKeyEnvironmentVariable));
2503                 getLog().debug("Using NVD API key from environment variable " + nvdApiKeyEnvironmentVariable);
2504             } else if (nvdApiServerId != null) {
2505                 try {
2506                     configureServerCredentialsApiKey(nvdApiServerId, Settings.KEYS.NVD_API_KEY);
2507                 } catch (InitializationException ex) {
2508                     if (this.failOnError) {
2509                         throw new MojoFailureException("Invalid plugin configuration specified for NVD API authentication", ex);
2510                     } else {
2511                         throw new MojoExecutionException("Invalid plugin configuration specified for NVD API authentication", ex);
2512                     }
2513                 }
2514                 getLog().debug("Using NVD API key from server's password with id " + nvdApiServerId + " in settings.xml");
2515             }
2516         } else {
2517             settings.setStringIfNotEmpty(Settings.KEYS.NVD_API_KEY, nvdApiKey);
2518         }
2519         try {
2520             configureCredentials(nvdDatafeedServerId, nvdUser, nvdPassword, nvdBearerToken,
2521                     Settings.KEYS.NVD_API_DATAFEED_USER, Settings.KEYS.NVD_API_DATAFEED_PASSWORD, Settings.KEYS.NVD_API_DATAFEED_BEARER_TOKEN);
2522         } catch (InitializationException ex) {
2523             if (this.failOnError) {
2524                 throw new MojoFailureException("Invalid plugin configuration specified for NVD Datafeed authentication", ex);
2525             } else {
2526                 throw new MojoExecutionException("Invalid plugin configuration specified for NVD Datafeed authentication", ex);
2527             }
2528         }
2529         settings.setBooleanIfNotNull(Settings.KEYS.PRETTY_PRINT, prettyPrint);
2530         artifactScopeExcluded = new ArtifactScopeExcluded(skipTestScope, skipProvidedScope, skipSystemScope, skipRuntimeScope);
2531         artifactTypeExcluded = new ArtifactTypeExcluded(skipArtifactType);
2532         try {
2533             configureCredentials(suppressionFileServerId, suppressionFileUser, suppressionFilePassword, suppressionFileBearerToken,
2534                     Settings.KEYS.SUPPRESSION_FILE_USER, Settings.KEYS.SUPPRESSION_FILE_PASSWORD, Settings.KEYS.SUPPRESSION_FILE_BEARER_TOKEN);
2535         } catch (InitializationException ex) {
2536             if (this.failOnError) {
2537                 throw new MojoFailureException("Invalid plugin configuration specified for suppression file authentication", ex);
2538             } else {
2539                 throw new MojoExecutionException("Invalid plugin configuration specified for suppression file authentication", ex);
2540             }
2541         }
2542 
2543         settings.setIntIfNotNull(Settings.KEYS.HOSTED_SUPPRESSIONS_VALID_FOR_HOURS, hostedSuppressionsValidForHours);
2544         settings.setStringIfNotNull(Settings.KEYS.HOSTED_SUPPRESSIONS_URL, hostedSuppressionsUrl);
2545         settings.setBooleanIfNotNull(Settings.KEYS.HOSTED_SUPPRESSIONS_FORCEUPDATE, hostedSuppressionsForceUpdate);
2546         settings.setBooleanIfNotNull(Settings.KEYS.HOSTED_SUPPRESSIONS_ENABLED, hostedSuppressionsEnabled);
2547         try {
2548             configureCredentials(hostedSuppressionsServerId, hostedSuppressionsUser, hostedSuppressionsPassword, hostedSuppressionsBearerToken,
2549                     Settings.KEYS.HOSTED_SUPPRESSIONS_USER, Settings.KEYS.HOSTED_SUPPRESSIONS_PASSWORD, Settings.KEYS.HOSTED_SUPPRESSIONS_BEARER_TOKEN);
2550         } catch (InitializationException ex) {
2551             if (this.failOnError) {
2552                 throw new MojoFailureException("Invalid plugin configuration specified for hostedSuppressions authentication", ex);
2553             } else {
2554                 throw new MojoExecutionException("Invalid plugin configuration specified for hostedSuppressions authentication", ex);
2555             }
2556         }
2557     }
2558     //CSON: MethodLength
2559 
2560     /**
2561      * Configure the credentials in the settings for a certain connection.<br/>
2562      * <p>
2563      * When a serverId is given, then its values are used instead of the less secure direct values.<br />
2564      * A serverId with username/password will fill the `userKey` and `passwordKey` settings for Basic Auth. A serverId with only password
2565      * filled will fill the `tokenKey` from Bearer Auth.<br/>
2566      * In absence of the serverId, any non-null value will be transferred to the settings.
2567      *
2568      * @param serverId The serverId specified for the connection or {@code null}
2569      * @param usernameValue The username specified for the connection or {@code null}
2570      * @param passwordValue The password specified for the connection or {@code null}
2571      * @param tokenValue The token specified for the connection or {@code null}
2572      * @param userKey The settings key that configures the user or {@code null} when Basic auth is not configurable for the connection
2573      * @param passwordKey The settings key that configures the password or {@code null} when Basic auth is not configurable for the connection
2574      * @param tokenKey The settings key that configures the token or {@code null} when Bearer auth is not configurable for the connection
2575      * @throws InitializationException When both serverId and at least one other property value are filled.
2576      */
2577     private void configureCredentials(String serverId, String usernameValue, String passwordValue, String tokenValue,
2578                                       String userKey, String passwordKey, String tokenKey) throws InitializationException {
2579         if (serverId != null) {
2580             if (usernameValue != null || passwordValue != null || tokenValue != null) {
2581                 throw new InitializationException(
2582                         "Username/password/token configurations should be left out when a serverId (" + serverId + ") is configured");
2583             }
2584             final Server server = settingsXml.getServer(serverId);
2585             if (server != null) {
2586                 configureFromServer(server, userKey, passwordKey, tokenKey, serverId);
2587             } else {
2588                 getLog().error(String.format("Server '%s' not found in the settings.xml file", serverId));
2589             }
2590         } else {
2591             settings.setStringIfNotEmpty(userKey, usernameValue);
2592             settings.setStringIfNotEmpty(passwordKey, passwordValue);
2593             settings.setStringIfNotEmpty(tokenKey, tokenValue);
2594         }
2595     }
2596 
2597     /**
2598      * Configure the credentials in the settings for a certain connection from a settings Server object.<br/>
2599      * <p>
2600      * A serverId with username/password will fill the `userKey` and `passwordKey` settings for Basic Auth.<br/>
2601      * A serverId with only password filled will fill the `tokenKey` fro Bearer Auth.<br/>
2602      *
2603      * @param server The server entry from the settings to configure authentication
2604      * @param userKey The settings key that configures the user or {@code null} when Basic auth is not configurable for the connection
2605      * @param passwordKey The settings key that configures the password or {@code null} when Basic auth is not configurable for the connection
2606      * @param tokenKey The settings key that configures the token or {@code null} when Bearer auth is not configurable for the connection
2607      * @param serverId The serverId specified for the connection or {@code null}
2608      * @throws InitializationException When both serverId and at least one other property value are filled.
2609      */
2610     private void configureFromServer(Server server, String userKey, String passwordKey, String tokenKey, String serverId) throws InitializationException {
2611         final SettingsDecryptionResult result = settingsDecrypter.decrypt(new DefaultSettingsDecryptionRequest(server));
2612         final String username = server.getUsername();
2613         final String password;
2614         if (result.getProblems().isEmpty()) {
2615             password = result.getServer().getPassword();
2616         } else {
2617             logProblems(result.getProblems(), "server setting for " + serverId);
2618             getLog().debug("Using raw password from settings.xml for server " + serverId);
2619             password = server.getPassword();
2620         }
2621         if (username != null) {
2622             if (userKey != null && passwordKey != null) {
2623                 settings.setStringIfNotEmpty(userKey, username);
2624                 settings.setStringIfNotEmpty(passwordKey, password);
2625             } else {
2626                 getLog().warn("Basic type server authentication encountered in serverId " + serverId + ", but only Bearer authentication is "
2627                         + "supported for the resource. For Bearer authentication tokens you should leave out the username in the server-entry in"
2628                         + " settings.xml");
2629                 settings.setStringIfNotEmpty(tokenKey, password);
2630             }
2631         } else {
2632             if (tokenKey != null) {
2633                 settings.setStringIfNotEmpty(tokenKey, password);
2634             } else {
2635                 throw new InitializationException(
2636                         "Bearer type server authentication encountered in serverId " + serverId + ", but only Basic authentication is supported for "
2637                                 + "the  resource. Looks like the username was forgotten to be added in the server-entry in settings.xml");
2638             }
2639         }
2640     }
2641 
2642     private String mergeNonProxyHosts(String existingNonProxyHosts, String httpNonProxyHosts, String httpsNonProxyHosts) {
2643         final HashSet<String> mergedNonProxyHosts = new HashSet<>();
2644         mergedNonProxyHosts.addAll(Arrays.asList(StringUtils.trimToEmpty(existingNonProxyHosts).split("\\|")));
2645         mergedNonProxyHosts.addAll(Arrays.asList(StringUtils.trimToEmpty(httpNonProxyHosts).split("\\|")));
2646         mergedNonProxyHosts.addAll(Arrays.asList(StringUtils.trimToEmpty(httpsNonProxyHosts).split("\\|")));
2647         return String.join("|", mergedNonProxyHosts);
2648     }
2649 
2650     private void setProxyServerSysPropsFromMavenProxy(Proxy mavenProxy, String protocol) {
2651         System.setProperty(protocol + ".proxyHost", mavenProxy.getHost());
2652         if (mavenProxy.getPort() > 0) {
2653             System.setProperty(protocol + ".proxyPort", String.valueOf(mavenProxy.getPort()));
2654         }
2655         if (mavenProxy.getUsername() != null && !mavenProxy.getUsername().isEmpty()) {
2656             System.setProperty(protocol + ".proxyUser", mavenProxy.getUsername());
2657         }
2658         final SettingsDecryptionResult result = settingsDecrypter.decrypt(new DefaultSettingsDecryptionRequest(mavenProxy));
2659         final String password;
2660         if (result.getProblems().isEmpty()) {
2661             password = result.getProxy().getPassword();
2662         } else {
2663             logProblems(result.getProblems(), "proxy settings for " + mavenProxy.getId());
2664             getLog().debug("Using raw password from settings.xml for proxy " + mavenProxy.getId());
2665             password = mavenProxy.getPassword();
2666         }
2667         if (password != null && !password.isEmpty()) {
2668             System.setProperty(protocol + ".proxyPassword", password);
2669         }
2670     }
2671 
2672     /**
2673      * Retrieves the server credentials from the settings.xml, decrypts the
2674      * password, and places the values into the settings under the given key
2675      * names.
2676      *
2677      * @param serverId the server id
2678      * @param userSettingKey the property name for the username
2679      * @param passwordSettingKey the property name for the password
2680      */
2681     private void configureServerCredentials(String serverId, String userSettingKey, String passwordSettingKey) throws MojoFailureException, MojoExecutionException {
2682         try {
2683             configureCredentials(serverId, null, null, null, userSettingKey, passwordSettingKey, null);
2684         } catch (InitializationException ex) {
2685             if (this.failOnError) {
2686                 throw new MojoFailureException(String.format("Error setting credentials (%s, %s) from serverId %s", userSettingKey, passwordSettingKey, serverId), ex);
2687             } else {
2688                 throw new MojoExecutionException(String.format("Error setting credentials (%s, %s) from serverId %s", userSettingKey, passwordSettingKey, serverId), ex);
2689             }
2690         }
2691     }
2692 
2693     /**
2694      * Retrieves the server credentials from the settings.xml, decrypts the
2695      * password, and places the values into the settings under the given key
2696      * names. This is used to retrieve an encrypted password as an API key.
2697      *
2698      * @param serverId the server id
2699      * @param apiKeySetting the property name for the API key
2700      */
2701     private void configureServerCredentialsApiKey(String serverId, String apiKeySetting) throws InitializationException {
2702         configureCredentials(serverId, null, null, null, null, null, apiKeySetting);
2703     }
2704 
2705     /**
2706      * Logs the problems encountered during settings decryption of a {@code <}server>} or {@code <proxy>} config
2707      * from the maven settings.<br/>
2708      * Logs a generic message about decryption problems at WARN level. If debug logging is enabled a additional message is logged at DEBUG level
2709      * detailing all the encountered problems and their underlying exceptions.
2710      *
2711      * @param problems The problems as reported by the settingsDecrypter.
2712      * @param credentialDesc an identification of what was attempted to be decrypted
2713      */
2714     private void logProblems(List<SettingsProblem> problems, String credentialDesc) {
2715         final String message = "Problems while decrypting " + credentialDesc;
2716         getLog().warn(message);
2717         if (getLog().isDebugEnabled()) {
2718             final StringBuilder dbgMessage = new StringBuilder("Problems while decrypting ").append(credentialDesc).append(": ");
2719             boolean first = true;
2720             for (SettingsProblem problem : problems) {
2721                 dbgMessage.append(first ? "" : ", ").append(problem.getMessage());
2722                 dbgMessage.append("caused by ").append(problem.getException());
2723                 first = false;
2724             }
2725             getLog().debug(dbgMessage.toString());
2726         }
2727     }
2728 
2729     /**
2730      * Combines the configured suppressionFile and suppressionFiles into a
2731      * single array.
2732      *
2733      * @return an array of suppression file paths
2734      */
2735     private String[] determineSuppressions() {
2736         String[] suppressions = suppressionFiles;
2737         if (suppressionFile != null) {
2738             if (suppressions == null) {
2739                 suppressions = new String[]{suppressionFile};
2740             } else {
2741                 suppressions = Arrays.copyOf(suppressions, suppressions.length + 1);
2742                 suppressions[suppressions.length - 1] = suppressionFile;
2743             }
2744         }
2745         return suppressions;
2746     }
2747 
2748     /**
2749      * Hacky method of muting the noisy logging from certain libraries.
2750      */
2751     void muteNoisyLoggers() {
2752         // Mirrors the configuration within cli/src/main/resources/logback.xml
2753         final List<String> noisyLoggers = List.of(
2754                 "org.apache.lucene",
2755                 "org.apache.commons.jcs3",
2756                 "org.apache.hc"
2757         );
2758         for (String loggerName : noisyLoggers) {
2759             System.setProperty("org.slf4j.simpleLogger.log." + loggerName, "error");
2760         }
2761     }
2762 
2763     /**
2764      * Returns the maven proxy.
2765      *
2766      * @param protocol The protocol of the target URL.
2767      * @return the maven proxy configured for that protocol
2768      */
2769     private Proxy getMavenProxy(String protocol) {
2770         if (mavenSettings != null) {
2771             final List<Proxy> proxies = mavenSettings.getProxies();
2772             if (proxies != null && !proxies.isEmpty()) {
2773                 if (mavenSettingsProxyId != null) {
2774                     for (Proxy proxy : proxies) {
2775                         if (mavenSettingsProxyId.equalsIgnoreCase(proxy.getId())) {
2776                             return proxy;
2777                         }
2778                     }
2779                 } else {
2780                     for (Proxy aProxy : proxies) {
2781                         if (aProxy.isActive() && aProxy.getProtocol().equals(protocol)) {
2782                             return aProxy;
2783                         }
2784                     }
2785                 }
2786             }
2787         }
2788         return null;
2789     }
2790 
2791     /**
2792      * Returns a reference to the current project. This method is used instead
2793      * of auto-binding the project via component annotation in concrete
2794      * implementations of this. If the child has a
2795      * <code>@Component MavenProject project;</code> defined then the abstract
2796      * class (i.e. this class) will not have access to the current project (just
2797      * the way Maven works with the binding).
2798      *
2799      * @return returns a reference to the current project
2800      */
2801     protected MavenProject getProject() {
2802         return project;
2803     }
2804 
2805     /**
2806      * Returns the list of Maven Projects in this build.
2807      *
2808      * @return the list of Maven Projects in this build
2809      */
2810     protected List<MavenProject> getReactorProjects() {
2811         return reactorProjects;
2812     }
2813 
2814     /**
2815      * Combines the format and formats properties into a single collection.
2816      *
2817      * @return the selected report formats
2818      */
2819     private Set<String> getFormats() {
2820         final Set<String> invalid = new HashSet<>();
2821         final Set<String> selectedFormats = formats == null || formats.length == 0 ? new HashSet<>() : new HashSet<>(Arrays.asList(formats));
2822         selectedFormats.forEach((s) -> {
2823             try {
2824                 ReportGenerator.Format.valueOf(s.toUpperCase());
2825             } catch (IllegalArgumentException ex) {
2826                 invalid.add(s);
2827             }
2828         });
2829         invalid.forEach((s) -> getLog().warn("Invalid report format specified: " + s));
2830         if (selectedFormats.contains("true")) {
2831             selectedFormats.remove("true");
2832         }
2833         if (format != null && selectedFormats.isEmpty()) {
2834             selectedFormats.add(format);
2835         }
2836         return selectedFormats;
2837     }
2838 
2839     /**
2840      * Returns the list of excluded artifacts based on either artifact id or
2841      * group id and artifact id.
2842      *
2843      * @return a list of artifact to exclude
2844      */
2845     public List<String> getExcludes() {
2846         if (excludes == null) {
2847             excludes = new ArrayList<>();
2848         }
2849         return excludes;
2850     }
2851 
2852     /**
2853      * Returns the artifact scope excluded filter.
2854      *
2855      * @return the artifact scope excluded filter
2856      */
2857     protected Filter<String> getArtifactScopeExcluded() {
2858         return artifactScopeExcluded;
2859     }
2860 
2861     /**
2862      * Returns the configured settings.
2863      *
2864      * @return the configured settings
2865      */
2866     protected Settings getSettings() {
2867         return settings;
2868     }
2869 
2870     //<editor-fold defaultstate="collapsed" desc="Methods to fail build or show summary">
2871 
2872     /**
2873      * Checks to see if a vulnerability has been identified with a CVSS score
2874      * that is above the threshold set in the configuration.
2875      *
2876      * @param dependencies the list of dependency objects
2877      * @throws MojoFailureException thrown if a CVSS score is found that is
2878      * higher than the threshold set
2879      */
2880     protected void checkForFailure(Dependency[] dependencies) throws MojoFailureException {
2881         final StringBuilder ids = new StringBuilder();
2882         for (Dependency d : dependencies) {
2883             boolean addName = true;
2884             for (Vulnerability v : d.getVulnerabilities()) {
2885                 final double cvssV2 = v.getCvssV2() != null && v.getCvssV2().getCvssData() != null && v.getCvssV2().getCvssData().getBaseScore() != null ? v.getCvssV2().getCvssData().getBaseScore() : -1;
2886                 final double cvssV3 = v.getCvssV3() != null && v.getCvssV3().getCvssData() != null && v.getCvssV3().getCvssData().getBaseScore() != null ? v.getCvssV3().getCvssData().getBaseScore() : -1;
2887                 final double cvssV4 = v.getCvssV4() != null && v.getCvssV4().getCvssData() != null && v.getCvssV4().getCvssData().getBaseScore() != null ? v.getCvssV4().getCvssData().getBaseScore() : -1;
2888                 final boolean useUnscored = cvssV2 == -1 && cvssV3 == -1 && cvssV4 == -1;
2889                 final double unscoredCvss = (useUnscored && v.getUnscoredSeverity() != null) ? SeverityUtil.estimateCvssV2(v.getUnscoredSeverity()) : -1;
2890 
2891                 if (failBuildOnAnyVulnerability
2892                         || cvssV2 >= failBuildOnCVSS
2893                         || cvssV3 >= failBuildOnCVSS
2894                         || cvssV4 >= failBuildOnCVSS
2895                         || unscoredCvss >= failBuildOnCVSS
2896                         //safety net to fail on any if for some reason the above misses on 0
2897                         || failBuildOnCVSS <= 0.0
2898                 ) {
2899                     String name = v.getName();
2900                     if (cvssV4 >= 0.0) {
2901                         name += "(" + cvssV4 + ")";
2902                     } else if (cvssV3 >= 0.0) {
2903                         name += "(" + cvssV3 + ")";
2904                     } else if (cvssV2 >= 0.0) {
2905                         name += "(" + cvssV2 + ")";
2906                     } else if (unscoredCvss >= 0.0) {
2907                         name += "(" + unscoredCvss + ")";
2908                     }
2909                     if (addName) {
2910                         addName = false;
2911                         ids.append(NEW_LINE).append(d.getFileName()).append(" (")
2912                                 .append(Stream.concat(d.getSoftwareIdentifiers().stream(), d.getVulnerableSoftwareIdentifiers().stream())
2913                                         .map(Identifier::getValue)
2914                                         .collect(Collectors.joining(", ")))
2915                                 .append("): ")
2916                                 .append(name);
2917                     } else {
2918                         ids.append(", ").append(name);
2919                     }
2920                 }
2921             }
2922         }
2923         if (ids.length() > 0) {
2924             final String msg;
2925             if (showSummary) {
2926                 if (failBuildOnAnyVulnerability) {
2927                     msg = String.format("%n%nOne or more dependencies were identified with vulnerabilities: %n%s%n%n"
2928                             + "See the dependency-check report for more details.%n%n", ids);
2929                 } else {
2930                     msg = String.format("%n%nOne or more dependencies were identified with vulnerabilities that have a CVSS score greater than or "
2931                             + "equal to '%.1f': %n%s%n%nSee the dependency-check report for more details.%n%n", failBuildOnCVSS, ids);
2932                 }
2933             } else {
2934                 msg = String.format("%n%nOne or more dependencies were identified with vulnerabilities.%n%n"
2935                         + "See the dependency-check report for more details.%n%n");
2936             }
2937             throw new MojoFailureException(msg);
2938         }
2939     }
2940 
2941     /**
2942      * Generates a warning message listing a summary of dependencies and their
2943      * associated CPE and CVE entries.
2944      *
2945      * @param mp the Maven project for which the summary is shown
2946      * @param dependencies a list of dependency objects
2947      */
2948     protected void showSummary(MavenProject mp, Dependency[] dependencies) {
2949         if (showSummary) {
2950             DependencyCheckScanAgent.showSummary(mp.getName(), dependencies);
2951         }
2952     }
2953 
2954     //</editor-fold>
2955     //CSOFF: ParameterNumber
2956     private ExceptionCollection scanDependencyNode(DependencyNode dependencyNode, DependencyNode root,
2957                                                    Engine engine, MavenProject project, List<ArtifactResult> allResolvedDeps,
2958                                                    ProjectBuildingRequest buildingRequest, boolean aggregate, ExceptionCollection exceptionCollection) {
2959         ExceptionCollection exCol = exceptionCollection;
2960         if (artifactScopeExcluded.passes(dependencyNode.getArtifact().getScope())
2961                 || artifactTypeExcluded.passes(dependencyNode.getArtifact().getType())) {
2962             return exCol;
2963         }
2964 
2965         boolean isResolved = false;
2966         File artifactFile = null;
2967         String artifactId = null;
2968         String groupId = null;
2969         String version = null;
2970         List<ArtifactVersion> availableVersions = null;
2971         if (org.apache.maven.artifact.Artifact.SCOPE_SYSTEM.equals(dependencyNode.getArtifact().getScope())) {
2972             final Artifact a = dependencyNode.getArtifact();
2973             if (a.isResolved() && a.getFile().isFile()) {
2974                 artifactFile = a.getFile();
2975                 isResolved = artifactFile.isFile();
2976                 groupId = a.getGroupId();
2977                 artifactId = a.getArtifactId();
2978                 version = a.getVersion();
2979                 availableVersions = a.getAvailableVersions();
2980             } else {
2981                 for (org.apache.maven.model.Dependency d : project.getDependencies()) {
2982                     if (d.getSystemPath() != null && artifactsMatch(d, a)) {
2983                         artifactFile = new File(d.getSystemPath());
2984                         isResolved = artifactFile.isFile();
2985                         groupId = a.getGroupId();
2986                         artifactId = a.getArtifactId();
2987                         version = a.getVersion();
2988                         availableVersions = a.getAvailableVersions();
2989                         break;
2990                     }
2991                 }
2992             }
2993             Throwable ignored = null;
2994             if (!isResolved) {
2995                 // Issue #4969 Tycho appears to add System-scoped libraries in reactor projects in unresolved state
2996                 // so attempt to do a resolution for system-scoped too if still nothing found
2997                 try {
2998                     tryResolutionOnce(project, allResolvedDeps, buildingRequest);
2999                     final Artifact result = findInAllDeps(allResolvedDeps, dependencyNode.getArtifact(), project);
3000                     isResolved = result.isResolved();
3001                     artifactFile = result.getFile();
3002                     groupId = result.getGroupId();
3003                     artifactId = result.getArtifactId();
3004                     version = result.getVersion();
3005                     availableVersions = result.getAvailableVersions();
3006                 } catch (DependencyNotFoundException | DependencyResolverException e) {
3007                     getLog().warn("Error performing last-resort System-scoped dependency resolution: " + e.getMessage());
3008                     ignored = e;
3009                 }
3010             }
3011             if (!isResolved) {
3012                 final StringBuilder message = new StringBuilder("Unable to resolve system scoped dependency: ");
3013                 if (artifactFile != null) {
3014                     message.append(dependencyNode.toNodeString()).append(" at path ").append(artifactFile);
3015                 } else {
3016                     message.append(dependencyNode.toNodeString()).append(" at path ").append(a.getFile());
3017                 }
3018                 getLog().error(message);
3019                 if (exCol == null) {
3020                     exCol = new ExceptionCollection();
3021                 }
3022                 final Exception thrown = new DependencyNotFoundException(message.toString());
3023                 if (ignored != null) {
3024                     thrown.addSuppressed(ignored);
3025                 }
3026                 exCol.addException(thrown);
3027             }
3028         } else {
3029             final Artifact dependencyArtifact = dependencyNode.getArtifact();
3030             final Artifact result;
3031             if (dependencyArtifact.isResolved()) {
3032                 //All transitive dependencies, excluding reactor and dependencyManagement artifacts should
3033                 //have been resolved by Maven prior to invoking the plugin - resolving the dependencies
3034                 //manually is unnecessary, and does not work in some cases (issue-1751)
3035                 getLog().debug(String.format("Skipping artifact %s, already resolved", dependencyArtifact.getArtifactId()));
3036                 result = dependencyArtifact;
3037             } else {
3038                 try {
3039                     tryResolutionOnce(project, allResolvedDeps, buildingRequest);
3040                     result = findInAllDeps(allResolvedDeps, dependencyNode.getArtifact(), project);
3041                 } catch (DependencyNotFoundException | DependencyResolverException ex) {
3042                     getLog().debug(String.format("Aggregate : %s", aggregate));
3043                     boolean addException = true;
3044                     //CSOFF: EmptyBlock
3045                     if (!aggregate) {
3046                         // do nothing - the exception is to be reported
3047                     } else if (addReactorDependency(engine, dependencyNode.getArtifact(), project)) {
3048                         // successfully resolved as a reactor dependency - swallow the exception
3049                         addException = false;
3050                     }
3051                     if (addException) {
3052                         if (exCol == null) {
3053                             exCol = new ExceptionCollection();
3054                         }
3055                         exCol.addException(ex);
3056                     }
3057                     return exCol;
3058                 }
3059             }
3060             if (aggregate && virtualSnapshotsFromReactor
3061                     && dependencyNode.getArtifact().isSnapshot()
3062                     && addSnapshotReactorDependency(engine, dependencyNode.getArtifact(), project)) {
3063                 return exCol;
3064             }
3065             isResolved = result.isResolved();
3066             artifactFile = result.getFile();
3067             groupId = result.getGroupId();
3068             artifactId = result.getArtifactId();
3069             version = result.getVersion();
3070             availableVersions = result.getAvailableVersions();
3071         }
3072         if (isResolved && artifactFile != null) {
3073             final List<Dependency> deps = engine.scan(artifactFile.getAbsoluteFile(),
3074                     createProjectReferenceName(project, dependencyNode));
3075             if (deps != null) {
3076                 processResolvedArtifact(artifactFile, deps, groupId, artifactId, version, root, project, availableVersions, dependencyNode);
3077             } else if ("import".equals(dependencyNode.getArtifact().getScope())) {
3078                 final String msg = String.format("Skipping '%s:%s' in project %s as it uses an `import` scope",
3079                         dependencyNode.getArtifact().getId(), dependencyNode.getArtifact().getScope(), project.getName());
3080                 getLog().debug(msg);
3081             } else if ("pom".equals(dependencyNode.getArtifact().getType())) {
3082                 exCol = processPomArtifact(artifactFile, root, project, engine, exCol);
3083             } else {
3084                 if (!scannedFiles.contains(artifactFile)) {
3085                     final String msg = String.format("No analyzer could be found or the artifact has been scanned twice for '%s:%s' in project %s",
3086                             dependencyNode.getArtifact().getId(), dependencyNode.getArtifact().getScope(), project.getName());
3087                     getLog().warn(msg);
3088                 }
3089             }
3090         } else {
3091             final String msg = String.format("Unable to resolve '%s' in project %s",
3092                     dependencyNode.getArtifact().getId(), project.getName());
3093             getLog().debug(msg);
3094             if (exCol == null) {
3095                 exCol = new ExceptionCollection();
3096             }
3097         }
3098         return exCol;
3099     }
3100 
3101     /**
3102      * Try resolution of artifacts once, allowing for
3103      * DependencyResolutionException due to reactor-dependencies not being
3104      * resolvable.
3105      * <br>
3106      * The resolution is attempted only if allResolvedDeps is still empty. The
3107      * assumption is that for any given project at least one of the dependencies
3108      * will successfully resolve. If not, resolution will be attempted once for
3109      * every dependency (as allResolvedDeps remains empty).
3110      *
3111      * @param project The project to dependencies for
3112      * @param allResolvedDeps The collection of successfully resolved
3113      * dependencies, will be filled with the successfully resolved dependencies,
3114      * even in case of resolution failures.
3115      * @param buildingRequest The buildingRequest to hand to Maven's
3116      * DependencyResolver.
3117      * @throws DependencyResolverException For any DependencyResolverException
3118      * other than an Eclipse Aether DependencyResolutionException
3119      */
3120     private void tryResolutionOnce(MavenProject project, List<ArtifactResult> allResolvedDeps, ProjectBuildingRequest buildingRequest) throws DependencyResolverException {
3121         if (allResolvedDeps.isEmpty()) { // no (partially successful) resolution attempt done
3122             try {
3123                 final List<org.apache.maven.model.Dependency> dependencies = project.getDependencies();
3124                 final List<org.apache.maven.model.Dependency> managedDependencies = project
3125                         .getDependencyManagement() == null ? null : project.getDependencyManagement().getDependencies();
3126                 final Iterable<ArtifactResult> allDeps = dependencyResolver
3127                         .resolveDependencies(buildingRequest, dependencies, managedDependencies, null);
3128                 allDeps.forEach(allResolvedDeps::add);
3129             } catch (DependencyResolverException dre) {
3130                 if (dre.getCause() instanceof org.eclipse.aether.resolution.DependencyResolutionException) {
3131                     final List<ArtifactResult> successResults = Mshared998Util
3132                             .getResolutionResults((org.eclipse.aether.resolution.DependencyResolutionException) dre.getCause());
3133                     allResolvedDeps.addAll(successResults);
3134                 } else {
3135                     throw dre;
3136                 }
3137             }
3138         }
3139     }
3140     //CSON: ParameterNumber
3141 
3142     //CSOFF: ParameterNumber
3143     private void processResolvedArtifact(File artifactFile, final List<Dependency> deps,
3144                                          String groupId, String artifactId, String version, DependencyNode root,
3145                                          MavenProject project1, List<ArtifactVersion> availableVersions,
3146                                          DependencyNode dependencyNode) {
3147         scannedFiles.add(artifactFile);
3148         Dependency d = null;
3149         if (deps.size() == 1) {
3150             d = deps.get(0);
3151 
3152         } else {
3153             for (Dependency possible : deps) {
3154                 if (artifactFile.getAbsoluteFile().equals(possible.getActualFile())) {
3155                     d = possible;
3156                     break;
3157                 }
3158             }
3159             for (Dependency dep : deps) {
3160                 if (d != null && d != dep) {
3161                     final String includedBy = buildReference(groupId, artifactId, version);
3162                     dep.addIncludedBy(includedBy);
3163                 }
3164             }
3165         }
3166         if (d != null) {
3167             final MavenArtifact ma = new MavenArtifact(groupId, artifactId, version);
3168             d.addAsEvidence("pom", ma, Confidence.HIGHEST);
3169             if (root != null) {
3170                 final String includedby = buildReference(
3171                         root.getArtifact().getGroupId(),
3172                         root.getArtifact().getArtifactId(),
3173                         root.getArtifact().getVersion());
3174                 d.addIncludedBy(includedby);
3175             } else {
3176                 final String includedby = buildReference(project1.getGroupId(), project1.getArtifactId(), project1.getVersion());
3177                 d.addIncludedBy(includedby);
3178             }
3179             if (availableVersions != null) {
3180                 for (ArtifactVersion av : availableVersions) {
3181                     d.addAvailableVersion(av.toString());
3182                 }
3183             }
3184             getLog().debug(String.format("Adding project reference %s on dependency %s", project1.getName(), d.getDisplayFileName()));
3185         } else if (getLog().isDebugEnabled()) {
3186             final String msg = String.format("More than 1 dependency was identified in first pass scan of '%s' in project %s", dependencyNode.getArtifact().getId(), project1.getName());
3187             getLog().debug(msg);
3188         }
3189     }
3190     //CSON: ParameterNumber
3191 
3192     private ExceptionCollection processPomArtifact(File artifactFile, DependencyNode root,
3193                                                    MavenProject project1, Engine engine, ExceptionCollection exCollection) {
3194         ExceptionCollection exCol = exCollection;
3195         try {
3196             final Dependency d = new Dependency(artifactFile.getAbsoluteFile());
3197             final Model pom = PomUtils.readPom(artifactFile.getAbsoluteFile());
3198             JarAnalyzer.setPomEvidence(d, pom, null, true);
3199             if (root != null) {
3200                 final String includedby = buildReference(
3201                         root.getArtifact().getGroupId(),
3202                         root.getArtifact().getArtifactId(),
3203                         root.getArtifact().getVersion());
3204                 d.addIncludedBy(includedby);
3205             } else {
3206                 final String includedby = buildReference(project1.getGroupId(), project1.getArtifactId(), project1.getVersion());
3207                 d.addIncludedBy(includedby);
3208             }
3209             engine.addDependency(d);
3210         } catch (AnalysisException ex) {
3211             if (exCol == null) {
3212                 exCol = new ExceptionCollection();
3213             }
3214             exCol.addException(ex);
3215             getLog().debug("Error reading pom " + artifactFile.getAbsoluteFile(), ex);
3216         }
3217         return exCol;
3218     }
3219 
3220 
3221     private void checkForDeprecatedParameters() {
3222         warnIfDeprecatedParamUsed("ossIndexAnalyzerEnabled", "ossindexAnalyzerEnabled");
3223         warnIfDeprecatedParamUsed("ossIndexAnalyzerUseCache", "ossindexAnalyzerUseCache");
3224         warnIfDeprecatedParamUsed("ossIndexAnalyzerUrl", "ossindexAnalyzerUrl");
3225     }
3226 
3227     /**
3228      * Checks if the deprecated (aka aliased) parameter is used in the plugin configuration and logs a warning if so.
3229      *
3230      * @param currentName the name of the current parameter (the one that should be used)
3231      * @param deprecatedName the name of the deprecated parameter (the one that should not be used anymore)
3232      */
3233     private void warnIfDeprecatedParamUsed(String currentName, String deprecatedName) {
3234         final org.apache.maven.model.Plugin plugin = project.getBuild().getPluginsAsMap()
3235                 .get(mojoExecution.getGroupId() + ":" + mojoExecution.getArtifactId());
3236         if (plugin == null) {
3237             return;
3238         }
3239         final Object cfg = plugin.getConfiguration();
3240         if (cfg instanceof org.codehaus.plexus.util.xml.Xpp3Dom) {
3241             final org.codehaus.plexus.util.xml.Xpp3Dom dom = (org.codehaus.plexus.util.xml.Xpp3Dom) cfg;
3242             if (dom.getChild(deprecatedName) != null) {
3243                 getLog().warn(String.format(
3244                         "The parameter '%s' is deprecated and should not be used anymore. Please use '%s' instead.",
3245                         deprecatedName, currentName));
3246             }
3247         }
3248     }
3249 }
3250 //CSON: FileLength