1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.owasp.dependencycheck.maven;
19
20 import java.io.BufferedOutputStream;
21 import java.io.File;
22 import java.io.FileInputStream;
23 import java.io.FileNotFoundException;
24 import java.io.FileOutputStream;
25 import java.io.IOException;
26 import java.io.InputStream;
27 import java.io.ObjectInputStream;
28 import java.io.ObjectOutputStream;
29 import java.io.OutputStream;
30 import java.util.List;
31 import java.util.Locale;
32 import org.apache.maven.artifact.Artifact;
33 import org.apache.maven.doxia.sink.Sink;
34 import org.apache.maven.plugin.AbstractMojo;
35 import org.apache.maven.plugin.MojoExecutionException;
36 import org.apache.maven.plugin.MojoFailureException;
37 import org.apache.maven.plugins.annotations.Parameter;
38 import org.apache.maven.project.MavenProject;
39 import org.apache.maven.reporting.MavenReport;
40 import org.apache.maven.reporting.MavenReportException;
41 import org.apache.maven.settings.Proxy;
42 import org.owasp.dependencycheck.data.nexus.MavenArtifact;
43 import org.owasp.dependencycheck.data.nvdcve.CveDB;
44 import org.owasp.dependencycheck.data.nvdcve.DatabaseException;
45 import org.owasp.dependencycheck.data.nvdcve.DatabaseProperties;
46 import org.owasp.dependencycheck.dependency.Confidence;
47 import org.owasp.dependencycheck.dependency.Dependency;
48 import org.owasp.dependencycheck.dependency.Identifier;
49 import org.owasp.dependencycheck.dependency.Vulnerability;
50 import org.owasp.dependencycheck.reporting.ReportGenerator;
51 import org.owasp.dependencycheck.utils.Settings;
52
53
54
55
56
57 public abstract class BaseDependencyCheckMojo extends AbstractMojo implements MavenReport {
58
59
60
61
62
63 private static final String PROPERTIES_FILE = "mojo.properties";
64
65
66
67 private static final String NEW_LINE = System.getProperty("line.separator", "\n").intern();
68
69
70
71 @Parameter(property = "metaFileName", defaultValue = "dependency-check.ser", required = true)
72 private String dataFileName;
73
74
75
76
77
78
79 @Parameter(property = "project", required = true, readonly = true)
80 private MavenProject project;
81
82
83
84 @Parameter(readonly = true, required = true, property = "reactorProjects")
85 private List<MavenProject> reactorProjects;
86
87
88
89
90 @Parameter(defaultValue = "${project.build.directory}", required = true)
91 private File outputDirectory;
92
93
94
95 @Parameter(property = "project.reporting.outputDirectory", required = true)
96 private File reportOutputDirectory;
97
98
99
100
101 @SuppressWarnings("CanBeFinal")
102 @Parameter(property = "failBuildOnCVSS", defaultValue = "11", required = true)
103 private float failBuildOnCVSS = 11;
104
105
106
107
108 @SuppressWarnings("CanBeFinal")
109 @Parameter(property = "autoupdate", defaultValue = "true", required = true)
110 private boolean autoUpdate = true;
111
112
113
114
115
116 @Parameter(property = "aggregate", defaultValue = "false")
117 @Deprecated
118 private boolean aggregate;
119
120
121
122
123 @SuppressWarnings("CanBeFinal")
124 @Parameter(property = "format", defaultValue = "HTML", required = true)
125 private String format = "HTML";
126
127
128
129 @Parameter(property = "mavenSettings", defaultValue = "${settings}", required = false)
130 private org.apache.maven.settings.Settings mavenSettings;
131
132
133
134
135 @SuppressWarnings("CanBeFinal")
136 @Parameter(property = "mavenSettingsProxyId", required = false)
137 private String mavenSettingsProxyId;
138
139
140
141
142 @SuppressWarnings("CanBeFinal")
143 @Parameter(property = "connectionTimeout", defaultValue = "", required = false)
144 private String connectionTimeout = null;
145
146
147
148 @SuppressWarnings("CanBeFinal")
149 @Parameter(property = "suppressionFile", defaultValue = "", required = false)
150 private String suppressionFile = null;
151
152
153
154 @SuppressWarnings("CanBeFinal")
155 @Parameter(property = "showSummary", defaultValue = "true", required = false)
156 private boolean showSummary = true;
157
158
159
160
161 @SuppressWarnings("CanBeFinal")
162 @Parameter(property = "jarAnalyzerEnabled", defaultValue = "true", required = false)
163 private boolean jarAnalyzerEnabled = true;
164
165
166
167
168 @SuppressWarnings("CanBeFinal")
169 @Parameter(property = "archiveAnalyzerEnabled", defaultValue = "true", required = false)
170 private boolean archiveAnalyzerEnabled = true;
171
172
173
174
175 @SuppressWarnings("CanBeFinal")
176 @Parameter(property = "assemblyAnalyzerEnabled", defaultValue = "true", required = false)
177 private boolean assemblyAnalyzerEnabled = true;
178
179
180
181
182 @SuppressWarnings("CanBeFinal")
183 @Parameter(property = "nuspecAnalyzerEnabled", defaultValue = "true", required = false)
184 private boolean nuspecAnalyzerEnabled = true;
185
186
187
188
189 @SuppressWarnings("CanBeFinal")
190 @Parameter(property = "centralAnalyzerEnabled", defaultValue = "true", required = false)
191 private boolean centralAnalyzerEnabled = true;
192
193
194
195
196 @SuppressWarnings("CanBeFinal")
197 @Parameter(property = "nexusAnalyzerEnabled", defaultValue = "true", required = false)
198 private boolean nexusAnalyzerEnabled = true;
199
200
201
202
203 @Parameter(property = "nexusUrl", defaultValue = "", required = false)
204 private String nexusUrl;
205
206
207
208 @Parameter(property = "nexusUsesProxy", defaultValue = "true", required = false)
209 private boolean nexusUsesProxy = true;
210
211
212
213 @Parameter(property = "connectionString", defaultValue = "", required = false)
214 private String connectionString;
215
216
217
218
219
220
221 protected String getConnectionString() {
222 return connectionString;
223 }
224
225
226
227 @Parameter(property = "databaseDriverName", defaultValue = "", required = false)
228 private String databaseDriverName;
229
230
231
232 @Parameter(property = "databaseDriverPath", defaultValue = "", required = false)
233 private String databaseDriverPath;
234
235
236
237 @Parameter(property = "databaseUser", defaultValue = "", required = false)
238 private String databaseUser;
239
240
241
242 @Parameter(property = "databasePassword", defaultValue = "", required = false)
243 private String databasePassword;
244
245
246
247 @Parameter(property = "zipExtensions", required = false)
248 private String zipExtensions;
249
250
251
252 @SuppressWarnings("CanBeFinal")
253 @Parameter(property = "skipTestScope", defaultValue = "true", required = false)
254 private boolean skipTestScope = true;
255
256
257
258 @SuppressWarnings("CanBeFinal")
259 @Parameter(property = "skipRuntimeScope", defaultValue = "false", required = false)
260 private boolean skipRuntimeScope = false;
261
262
263
264 @SuppressWarnings("CanBeFinal")
265 @Parameter(property = "skipProvidedScope", defaultValue = "false", required = false)
266 private boolean skipProvidedScope = false;
267
268
269
270 @Parameter(property = "dataDirectory", defaultValue = "", required = false)
271 private String dataDirectory;
272
273
274
275 @Parameter(property = "cveUrl12Modified", defaultValue = "", required = false)
276 private String cveUrl12Modified;
277
278
279
280 @Parameter(property = "cveUrl20Modified", defaultValue = "", required = false)
281 private String cveUrl20Modified;
282
283
284
285 @Parameter(property = "cveUrl12Base", defaultValue = "", required = false)
286 private String cveUrl12Base;
287
288
289
290 @Parameter(property = "cveUrl20Base", defaultValue = "", required = false)
291 private String cveUrl20Base;
292
293
294
295
296 @Parameter(property = "pathToMono", defaultValue = "", required = false)
297 private String pathToMono;
298
299
300
301
302
303
304 @SuppressWarnings("CanBeFinal")
305 @Parameter(property = "proxyUrl", defaultValue = "", required = false)
306 @Deprecated
307 private String proxyUrl = null;
308
309
310
311
312
313 @SuppressWarnings("CanBeFinal")
314 @Parameter(property = "externalReport")
315 @Deprecated
316 private String externalReport = null;
317
318
319
320
321
322
323
324
325
326 @Override
327 public void execute() throws MojoExecutionException, MojoFailureException {
328 validateAggregate();
329 project.setContextValue(getOutputDirectoryContextKey(), this.outputDirectory);
330 runCheck();
331 }
332
333
334
335
336
337
338
339 private void validateAggregate() throws MojoExecutionException {
340 if (aggregate) {
341 final String msg = "Aggregate configuration detected - as of dependency-check 1.2.8 this no longer supported. "
342 + "Please use the aggregate goal instead.";
343 throw new MojoExecutionException(msg);
344 }
345 }
346
347
348
349
350
351
352
353
354
355 @Override
356 @Deprecated
357 public final void generate(@SuppressWarnings("deprecation") org.codehaus.doxia.sink.Sink sink, Locale locale) throws MavenReportException {
358 generate((Sink) sink, locale);
359 }
360
361
362
363
364
365
366
367
368 public void generate(Sink sink, Locale locale) throws MavenReportException {
369 try {
370 validateAggregate();
371 } catch (MojoExecutionException ex) {
372 throw new MavenReportException(ex.getMessage());
373 }
374 project.setContextValue(getOutputDirectoryContextKey(), getReportOutputDirectory());
375 try {
376 runCheck();
377 } catch (MojoExecutionException ex) {
378 throw new MavenReportException(ex.getMessage(), ex);
379 } catch (MojoFailureException ex) {
380 getLog().warn("Vulnerabilities were identifies that exceed the CVSS threshold for failing the build");
381 }
382 }
383
384
385
386
387
388
389
390 protected File getCorrectOutputDirectory() throws MojoExecutionException {
391 return getCorrectOutputDirectory(this.project);
392 }
393
394
395
396
397
398
399
400 protected File getCorrectOutputDirectory(MavenProject current) {
401 final Object obj = current.getContextValue(getOutputDirectoryContextKey());
402 if (obj != null && obj instanceof File) {
403 return (File) obj;
404 }
405 File target = new File(current.getBuild().getDirectory());
406 if (target.getParentFile() != null && "target".equals(target.getParentFile().getName())) {
407 target = target.getParentFile();
408 }
409 return target;
410 }
411
412
413
414
415
416
417
418 protected File getDataFile(MavenProject current) {
419 if (getLog().isDebugEnabled()) {
420 getLog().debug(String.format("Getting data filefor %s using key '%s'", current.getName(), getDataFileContextKey()));
421 }
422 final Object obj = current.getContextValue(getDataFileContextKey());
423 if (obj != null) {
424 if (obj instanceof String) {
425 final File f = new File((String) obj);
426 return f;
427 }
428 } else {
429 if (getLog().isDebugEnabled()) {
430 getLog().debug("Context value not found");
431 }
432 }
433 return null;
434 }
435
436
437
438
439
440
441
442 protected void scanArtifacts(MavenProject project, Engine engine) {
443 for (Artifact a : project.getArtifacts()) {
444 if (excludeFromScan(a)) {
445 continue;
446 }
447 final List<Dependency> deps = engine.scan(a.getFile().getAbsoluteFile());
448 if (deps != null) {
449 if (deps.size() == 1) {
450 final Dependency d = deps.get(0);
451 if (d != null) {
452 final MavenArtifact ma = new MavenArtifact(a.getGroupId(), a.getArtifactId(), a.getVersion());
453 d.addAsEvidence("pom", ma, Confidence.HIGHEST);
454 d.addProjectReference(project.getName());
455 if (getLog().isDebugEnabled()) {
456 getLog().debug(String.format("Adding project reference %s on dependency %s", project.getName(),
457 d.getDisplayFileName()));
458 }
459 }
460 } else {
461 if (getLog().isDebugEnabled()) {
462 final String msg = String.format("More then 1 dependency was identified in first pass scan of '%s:%s:%s'",
463 a.getGroupId(), a.getArtifactId(), a.getVersion());
464 getLog().debug(msg);
465 }
466 }
467 }
468 }
469 }
470
471
472
473
474
475
476
477 public abstract void runCheck() throws MojoExecutionException, MojoFailureException;
478
479
480
481
482
483
484 @Override
485 public void setReportOutputDirectory(File directory) {
486 reportOutputDirectory = directory;
487 }
488
489
490
491
492
493
494 @Override
495 public File getReportOutputDirectory() {
496 return reportOutputDirectory;
497 }
498
499
500
501
502
503
504 public File getOutputDirectory() {
505 return outputDirectory;
506 }
507
508
509
510
511
512
513 @Override
514 public final boolean isExternalReport() {
515 return true;
516 }
517
518
519
520
521
522
523 @Override
524 public String getOutputName() {
525 if ("HTML".equalsIgnoreCase(this.format) || "ALL".equalsIgnoreCase(this.format)) {
526 return "dependency-check-report";
527 } else if ("XML".equalsIgnoreCase(this.format)) {
528 return "dependency-check-report.xml#";
529 } else if ("VULN".equalsIgnoreCase(this.format)) {
530 return "dependency-check-vulnerability";
531 } else {
532 getLog().warn("Unknown report format used during site generation.");
533 return "dependency-check-report";
534 }
535 }
536
537
538
539
540
541
542 @Override
543 public String getCategoryName() {
544 return MavenReport.CATEGORY_PROJECT_REPORTS;
545 }
546
547
548
549
550
551
552
553
554 protected Engine initializeEngine() throws DatabaseException {
555 populateSettings();
556 return new Engine(this.project,
557 this.reactorProjects);
558 }
559
560
561
562
563
564 protected void populateSettings() {
565 Settings.initialize();
566 InputStream mojoProperties = null;
567 try {
568 mojoProperties = this.getClass().getClassLoader().getResourceAsStream(PROPERTIES_FILE);
569 Settings.mergeProperties(mojoProperties);
570 } catch (IOException ex) {
571 getLog().warn("Unable to load the dependency-check ant task.properties file.");
572 if (getLog().isDebugEnabled()) {
573 getLog().debug("", ex);
574 }
575 } finally {
576 if (mojoProperties != null) {
577 try {
578 mojoProperties.close();
579 } catch (IOException ex) {
580 if (getLog().isDebugEnabled()) {
581 getLog().debug("", ex);
582 }
583 }
584 }
585 }
586
587 Settings.setBoolean(Settings.KEYS.AUTO_UPDATE, autoUpdate);
588 if (externalReport != null) {
589 getLog().warn("The 'externalReport' option was set; this configuration option has been removed. "
590 + "Please update the dependency-check-maven plugin's configuration");
591 }
592
593 if (proxyUrl != null && !proxyUrl.isEmpty()) {
594 getLog().warn("Deprecated configuration detected, proxyUrl will be ignored; use the maven settings " + "to configure the proxy instead");
595 }
596 final Proxy proxy = getMavenProxy();
597 if (proxy != null) {
598 Settings.setString(Settings.KEYS.PROXY_SERVER, proxy.getHost());
599 Settings.setString(Settings.KEYS.PROXY_PORT, Integer.toString(proxy.getPort()));
600 final String userName = proxy.getUsername();
601 final String password = proxy.getPassword();
602 if (userName != null) {
603 Settings.setString(Settings.KEYS.PROXY_USERNAME, userName);
604 }
605 if (password != null) {
606 Settings.setString(Settings.KEYS.PROXY_PASSWORD, password);
607 }
608
609 }
610
611 if (connectionTimeout != null && !connectionTimeout.isEmpty()) {
612 Settings.setString(Settings.KEYS.CONNECTION_TIMEOUT, connectionTimeout);
613 }
614 if (suppressionFile != null && !suppressionFile.isEmpty()) {
615 Settings.setString(Settings.KEYS.SUPPRESSION_FILE, suppressionFile);
616 }
617
618
619
620 Settings.setBoolean(Settings.KEYS.ANALYZER_JAR_ENABLED, jarAnalyzerEnabled);
621
622 Settings.setBoolean(Settings.KEYS.ANALYZER_NUSPEC_ENABLED, nuspecAnalyzerEnabled);
623
624 Settings.setBoolean(Settings.KEYS.ANALYZER_CENTRAL_ENABLED, centralAnalyzerEnabled);
625
626 Settings.setBoolean(Settings.KEYS.ANALYZER_NEXUS_ENABLED, nexusAnalyzerEnabled);
627 if (nexusUrl != null && !nexusUrl.isEmpty()) {
628 Settings.setString(Settings.KEYS.ANALYZER_NEXUS_URL, nexusUrl);
629 }
630 Settings.setBoolean(Settings.KEYS.ANALYZER_NEXUS_PROXY, nexusUsesProxy);
631
632 Settings.setBoolean(Settings.KEYS.ANALYZER_ARCHIVE_ENABLED, archiveAnalyzerEnabled);
633 if (zipExtensions != null && !zipExtensions.isEmpty()) {
634 Settings.setString(Settings.KEYS.ADDITIONAL_ZIP_EXTENSIONS, zipExtensions);
635 }
636
637 Settings.setBoolean(Settings.KEYS.ANALYZER_ASSEMBLY_ENABLED, assemblyAnalyzerEnabled);
638 if (pathToMono != null && !pathToMono.isEmpty()) {
639 Settings.setString(Settings.KEYS.ANALYZER_ASSEMBLY_MONO_PATH, pathToMono);
640 }
641
642
643 if (databaseDriverName != null && !databaseDriverName.isEmpty()) {
644 Settings.setString(Settings.KEYS.DB_DRIVER_NAME, databaseDriverName);
645 }
646 if (databaseDriverPath != null && !databaseDriverPath.isEmpty()) {
647 Settings.setString(Settings.KEYS.DB_DRIVER_PATH, databaseDriverPath);
648 }
649 if (connectionString != null && !connectionString.isEmpty()) {
650 Settings.setString(Settings.KEYS.DB_CONNECTION_STRING, connectionString);
651 }
652 if (databaseUser != null && !databaseUser.isEmpty()) {
653 Settings.setString(Settings.KEYS.DB_USER, databaseUser);
654 }
655 if (databasePassword != null && !databasePassword.isEmpty()) {
656 Settings.setString(Settings.KEYS.DB_PASSWORD, databasePassword);
657 }
658
659 if (dataDirectory != null && !dataDirectory.isEmpty()) {
660 Settings.setString(Settings.KEYS.DATA_DIRECTORY, dataDirectory);
661 }
662
663
664 Settings.setBoolean(Settings.KEYS.SKIP_TEST_SCOPE, skipTestScope);
665 Settings.setBoolean(Settings.KEYS.SKIP_RUNTIME_SCOPE, skipRuntimeScope);
666 Settings.setBoolean(Settings.KEYS.SKIP_PROVIDED_SCOPE, skipProvidedScope);
667
668
669 if (cveUrl12Modified != null && !cveUrl12Modified.isEmpty()) {
670 Settings.setString(Settings.KEYS.CVE_MODIFIED_12_URL, cveUrl12Modified);
671 }
672 if (cveUrl20Modified != null && !cveUrl20Modified.isEmpty()) {
673 Settings.setString(Settings.KEYS.CVE_MODIFIED_20_URL, cveUrl20Modified);
674 }
675 if (cveUrl12Base != null && !cveUrl12Base.isEmpty()) {
676 Settings.setString(Settings.KEYS.CVE_SCHEMA_1_2, cveUrl12Base);
677 }
678 if (cveUrl20Base != null && !cveUrl20Base.isEmpty()) {
679 Settings.setString(Settings.KEYS.CVE_SCHEMA_2_0, cveUrl20Base);
680 }
681 }
682
683
684
685
686
687
688 private Proxy getMavenProxy() {
689 if (mavenSettings != null) {
690 final List<Proxy> proxies = mavenSettings.getProxies();
691 if (proxies != null && !proxies.isEmpty()) {
692 if (mavenSettingsProxyId != null) {
693 for (Proxy proxy : proxies) {
694 if (mavenSettingsProxyId.equalsIgnoreCase(proxy.getId())) {
695 return proxy;
696 }
697 }
698 } else if (proxies.size() == 1) {
699 return proxies.get(0);
700 } else {
701 getLog().warn("Multiple proxy definitions exist in the Maven settings. In the dependency-check "
702 + "configuration set the mavenSettingsProxyId so that the correct proxy will be used.");
703 throw new IllegalStateException("Ambiguous proxy definition");
704 }
705 }
706 }
707 return null;
708 }
709
710
711
712
713
714
715
716 protected boolean excludeFromScan(Artifact a) {
717 if (skipTestScope && Artifact.SCOPE_TEST.equals(a.getScope())) {
718 return true;
719 }
720 if (skipProvidedScope && Artifact.SCOPE_PROVIDED.equals(a.getScope())) {
721 return true;
722 }
723 if (skipRuntimeScope && !Artifact.SCOPE_RUNTIME.equals(a.getScope())) {
724 return true;
725 }
726 return false;
727 }
728
729
730
731
732
733
734
735
736
737 protected MavenProject getProject() {
738 return project;
739 }
740
741
742
743
744
745
746 protected List<MavenProject> getReactorProjects() {
747 return reactorProjects;
748 }
749
750
751
752
753
754
755 protected String getFormat() {
756 return format;
757 }
758
759
760
761
762
763
764
765
766 protected void writeReports(Engine engine, MavenProject p, File outputDir) {
767 DatabaseProperties prop = null;
768 CveDB cve = null;
769 try {
770 cve = new CveDB();
771 cve.open();
772 prop = cve.getDatabaseProperties();
773 } catch (DatabaseException ex) {
774 if (getLog().isDebugEnabled()) {
775 getLog().debug("Unable to retrieve DB Properties", ex);
776 }
777 } finally {
778 if (cve != null) {
779 cve.close();
780 }
781 }
782 final ReportGenerator r = new ReportGenerator(p.getName(), engine.getDependencies(), engine.getAnalyzers(), prop);
783 try {
784 r.generateReports(outputDir.getAbsolutePath(), format);
785 } catch (IOException ex) {
786 getLog().error(
787 "Unexpected exception occurred during analysis; please see the verbose error log for more details.");
788 if (getLog().isDebugEnabled()) {
789 getLog().debug("", ex);
790 }
791 } catch (Throwable ex) {
792 getLog().error(
793 "Unexpected exception occurred during analysis; please see the verbose error log for more details.");
794 if (getLog().isDebugEnabled()) {
795 getLog().debug("", ex);
796 }
797 }
798 }
799
800
801
802
803
804
805
806
807
808 protected void checkForFailure(List<Dependency> dependencies) throws MojoFailureException {
809 if (failBuildOnCVSS <= 10) {
810 final StringBuilder ids = new StringBuilder();
811 for (Dependency d : dependencies) {
812 boolean addName = true;
813 for (Vulnerability v : d.getVulnerabilities()) {
814 if (v.getCvssScore() >= failBuildOnCVSS) {
815 if (addName) {
816 addName = false;
817 ids.append(NEW_LINE).append(d.getFileName()).append(": ");
818 ids.append(v.getName());
819 } else {
820 ids.append(", ").append(v.getName());
821 }
822 }
823 }
824 }
825 if (ids.length() > 0) {
826 final String msg = String.format("%n%nDependency-Check Failure:%n"
827 + "One or more dependencies were identified with vulnerabilities that have a CVSS score greater then '%.1f': %s%n"
828 + "See the dependency-check report for more details.%n%n", failBuildOnCVSS, ids.toString());
829 throw new MojoFailureException(msg);
830 }
831 }
832 }
833
834
835
836
837
838
839
840 protected void showSummary(MavenProject mp, List<Dependency> dependencies) {
841 if (showSummary) {
842 final StringBuilder summary = new StringBuilder();
843 for (Dependency d : dependencies) {
844 boolean firstEntry = true;
845 final StringBuilder ids = new StringBuilder();
846 for (Vulnerability v : d.getVulnerabilities()) {
847 if (firstEntry) {
848 firstEntry = false;
849 } else {
850 ids.append(", ");
851 }
852 ids.append(v.getName());
853 }
854 if (ids.length() > 0) {
855 summary.append(d.getFileName()).append(" (");
856 firstEntry = true;
857 for (Identifier id : d.getIdentifiers()) {
858 if (firstEntry) {
859 firstEntry = false;
860 } else {
861 summary.append(", ");
862 }
863 summary.append(id.getValue());
864 }
865 summary.append(") : ").append(ids).append(NEW_LINE);
866 }
867 }
868 if (summary.length() > 0) {
869 final String msg = String.format("%n%n" + "One or more dependencies were identified with known vulnerabilities in %s:%n%n%s"
870 + "%n%nSee the dependency-check report for more details.%n%n", mp.getName(), summary.toString());
871 getLog().warn(msg);
872 }
873 }
874 }
875
876
877
878
879
880
881
882
883
884 protected String getDataFileContextKey() {
885 return "dependency-check-path-" + dataFileName;
886 }
887
888
889
890
891
892
893
894 protected String getOutputDirectoryContextKey() {
895 return "dependency-output-dir-" + dataFileName;
896 }
897
898
899
900
901
902
903
904
905 protected void writeDataFile(MavenProject mp, File writeTo, List<Dependency> dependencies) {
906 File file;
907
908 if (mp.getContextValue(this.getDataFileContextKey()) == null) {
909 if (writeTo == null) {
910 file = new File(mp.getBuild().getDirectory());
911 file = new File(file, dataFileName);
912 } else {
913 file = new File(writeTo, dataFileName);
914 }
915 final File parent = file.getParentFile();
916 if (!parent.isDirectory() && parent.mkdirs()) {
917 getLog().error(String.format("Directory '%s' does not exist and cannot be created; unable to write data file.",
918 parent.getAbsolutePath()));
919 }
920
921 OutputStream os = null;
922 OutputStream bos = null;
923 ObjectOutputStream out = null;
924 try {
925 if (dependencies != null) {
926 os = new FileOutputStream(file);
927 bos = new BufferedOutputStream(os);
928 out = new ObjectOutputStream(bos);
929 out.writeObject(dependencies);
930 out.flush();
931
932
933
934 out.reset();
935 }
936 if (getLog().isDebugEnabled()) {
937 getLog().debug(String.format("Serialized data file written to '%s' for %s, referenced by key %s",
938 file.getAbsolutePath(), mp.getName(), this.getDataFileContextKey()));
939 }
940 mp.setContextValue(this.getDataFileContextKey(), file.getAbsolutePath());
941 } catch (IOException ex) {
942 getLog().warn("Unable to create data file used for report aggregation; "
943 + "if report aggregation is being used the results may be incomplete.");
944 if (getLog().isDebugEnabled()) {
945 getLog().debug(ex.getMessage(), ex);
946 }
947 } finally {
948 if (out != null) {
949 try {
950 out.close();
951 } catch (IOException ex) {
952 if (getLog().isDebugEnabled()) {
953 getLog().debug("ignore", ex);
954 }
955 }
956 }
957 if (bos != null) {
958 try {
959 bos.close();
960 } catch (IOException ex) {
961 if (getLog().isDebugEnabled()) {
962 getLog().debug("ignore", ex);
963 }
964 }
965 }
966 if (os != null) {
967 try {
968 os.close();
969 } catch (IOException ex) {
970 if (getLog().isDebugEnabled()) {
971 getLog().debug("ignore", ex);
972 }
973 }
974 }
975 }
976 }
977 }
978
979
980
981
982
983
984
985
986
987 protected List<Dependency> readDataFile(MavenProject project) {
988 final Object oPath = project.getContextValue(this.getDataFileContextKey());
989 if (oPath == null) {
990 return null;
991 }
992 List<Dependency> ret = null;
993 final String path = (String) oPath;
994 ObjectInputStream ois = null;
995 try {
996 ois = new ObjectInputStream(new FileInputStream(path));
997 ret = (List<Dependency>) ois.readObject();
998 } catch (FileNotFoundException ex) {
999
1000 getLog().error("", ex);
1001 } catch (IOException ex) {
1002 getLog().error("", ex);
1003 } catch (ClassNotFoundException ex) {
1004 getLog().error("", ex);
1005 } finally {
1006 if (ois != null) {
1007 try {
1008 ois.close();
1009 } catch (IOException ex) {
1010 getLog().error("", ex);
1011 }
1012 }
1013 }
1014 return ret;
1015 }
1016
1017 }