Coverage Report - org.owasp.dependencycheck.dependency.Dependency
 
Classes in this File Line Coverage Branch Coverage Complexity
Dependency
60%
124/205
20%
34/162
2.621
 
 1  
 /*
 2  
  * This file is part of dependency-check-core.
 3  
  *
 4  
  * Licensed under the Apache License, Version 2.0 (the "License");
 5  
  * you may not use this file except in compliance with the License.
 6  
  * You may obtain a copy of the License at
 7  
  *
 8  
  *     http://www.apache.org/licenses/LICENSE-2.0
 9  
  *
 10  
  * Unless required by applicable law or agreed to in writing, software
 11  
  * distributed under the License is distributed on an "AS IS" BASIS,
 12  
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 13  
  * See the License for the specific language governing permissions and
 14  
  * limitations under the License.
 15  
  *
 16  
  * Copyright (c) 2012 Jeremy Long. All Rights Reserved.
 17  
  */
 18  
 package org.owasp.dependencycheck.dependency;
 19  
 
 20  
 import java.io.File;
 21  
 import java.io.IOException;
 22  
 import java.io.Serializable;
 23  
 import java.security.NoSuchAlgorithmException;
 24  
 import java.util.ArrayList;
 25  
 import java.util.HashSet;
 26  
 import java.util.List;
 27  
 import java.util.Set;
 28  
 import java.util.SortedSet;
 29  
 import java.util.TreeSet;
 30  
 import java.util.logging.Level;
 31  
 import java.util.logging.Logger;
 32  
 import org.owasp.dependencycheck.data.nexus.MavenArtifact;
 33  
 import org.owasp.dependencycheck.utils.Checksum;
 34  
 import org.owasp.dependencycheck.utils.FileUtils;
 35  
 
 36  
 /**
 37  
  * A program dependency. This object is one of the core components within DependencyCheck. It is used to collect information about
 38  
  * the dependency in the form of evidence. The Evidence is then used to determine if there are any known, published,
 39  
  * vulnerabilities associated with the program dependency.
 40  
  *
 41  
  * @author Jeremy Long
 42  
  */
 43  2
 public class Dependency implements Serializable, Comparable<Dependency> {
 44  
 
 45  
     /**
 46  
      * The logger.
 47  
      */
 48  1
     private static final Logger LOGGER = Logger.getLogger(Dependency.class.getName());
 49  
     /**
 50  
      * The actual file path of the dependency on disk.
 51  
      */
 52  
     private String actualFilePath;
 53  
     /**
 54  
      * The file path to display.
 55  
      */
 56  
     private String filePath;
 57  
     /**
 58  
      * The file name of the dependency.
 59  
      */
 60  
     private String fileName;
 61  
     /**
 62  
      * The file extension of the dependency.
 63  
      */
 64  
     private String fileExtension;
 65  
     /**
 66  
      * The md5 hash of the dependency.
 67  
      */
 68  
     private String md5sum;
 69  
     /**
 70  
      * The SHA1 hash of the dependency.
 71  
      */
 72  
     private String sha1sum;
 73  
     /**
 74  
      * A list of Identifiers.
 75  
      */
 76  
     private Set<Identifier> identifiers;
 77  
     /**
 78  
      * A collection of vendor evidence.
 79  
      */
 80  
     private final EvidenceCollection vendorEvidence;
 81  
     /**
 82  
      * A collection of product evidence.
 83  
      */
 84  
     private final EvidenceCollection productEvidence;
 85  
     /**
 86  
      * A collection of version evidence.
 87  
      */
 88  
     private final EvidenceCollection versionEvidence;
 89  
 
 90  
     /**
 91  
      * Constructs a new Dependency object.
 92  
      */
 93  47
     public Dependency() {
 94  47
         vendorEvidence = new EvidenceCollection();
 95  47
         productEvidence = new EvidenceCollection();
 96  47
         versionEvidence = new EvidenceCollection();
 97  47
         identifiers = new TreeSet<Identifier>();
 98  47
         vulnerabilities = new TreeSet<Vulnerability>(new VulnerabilityComparator());
 99  47
         suppressedIdentifiers = new TreeSet<Identifier>();
 100  47
         suppressedVulnerabilities = new TreeSet<Vulnerability>(new VulnerabilityComparator());
 101  47
     }
 102  
 
 103  
     /**
 104  
      * Constructs a new Dependency object.
 105  
      *
 106  
      * @param file the File to create the dependency object from.
 107  
      */
 108  
     public Dependency(File file) {
 109  24
         this();
 110  24
         this.actualFilePath = file.getPath();
 111  24
         this.filePath = this.actualFilePath;
 112  24
         this.fileName = file.getName();
 113  24
         this.fileExtension = FileUtils.getFileExtension(fileName);
 114  24
         determineHashes(file);
 115  24
     }
 116  
 
 117  
     /**
 118  
      * Returns the file name of the dependency.
 119  
      *
 120  
      * @return the file name of the dependency
 121  
      */
 122  
     public String getFileName() {
 123  28
         return this.fileName;
 124  
     }
 125  
 
 126  
     /**
 127  
      * Returns the file name of the dependency with the backslash escaped for use in JavaScript. This is a complete hack as I
 128  
      * could not get the replace to work in the template itself.
 129  
      *
 130  
      * @return the file name of the dependency with the backslash escaped for use in JavaScript
 131  
      */
 132  
     public String getFileNameForJavaScript() {
 133  0
         return this.fileName.replace("\\", "\\\\");
 134  
     }
 135  
 
 136  
     /**
 137  
      * Sets the file name of the dependency.
 138  
      *
 139  
      * @param fileName the file name of the dependency
 140  
      */
 141  
     public void setFileName(String fileName) {
 142  7
         this.fileName = fileName;
 143  7
     }
 144  
 
 145  
     /**
 146  
      * Sets the actual file path of the dependency on disk.
 147  
      *
 148  
      * @param actualFilePath the file path of the dependency
 149  
      */
 150  
     public void setActualFilePath(String actualFilePath) {
 151  2
         this.actualFilePath = actualFilePath;
 152  2
         if (this.sha1sum == null) {
 153  2
             final File file = new File(this.actualFilePath);
 154  2
             determineHashes(file);
 155  
         }
 156  2
     }
 157  
 
 158  
     /**
 159  
      * Gets the file path of the dependency.
 160  
      *
 161  
      * @return the file path of the dependency
 162  
      */
 163  
     public String getActualFilePath() {
 164  49
         return this.actualFilePath;
 165  
     }
 166  
 
 167  
     /**
 168  
      * Gets a reference to the File object.
 169  
      *
 170  
      * @return the File object
 171  
      */
 172  
     public File getActualFile() {
 173  11
         return new File(this.actualFilePath);
 174  
     }
 175  
 
 176  
     /**
 177  
      * Sets the file path of the dependency.
 178  
      *
 179  
      * @param filePath the file path of the dependency
 180  
      */
 181  
     public void setFilePath(String filePath) {
 182  3
         this.filePath = filePath;
 183  3
     }
 184  
 
 185  
     /**
 186  
      * The file name to display in reports.
 187  
      */
 188  47
     private String displayName = null;
 189  
 
 190  
     /**
 191  
      * Sets the file name to display in reports.
 192  
      *
 193  
      * @param displayName the name to display
 194  
      */
 195  
     public void setDisplayFileName(String displayName) {
 196  4
         this.displayName = displayName;
 197  4
     }
 198  
 
 199  
     /**
 200  
      * Returns the file name to display in reports; if no display file name has been set it will default to the actual file name.
 201  
      *
 202  
      * @return the file name to display
 203  
      */
 204  
     public String getDisplayFileName() {
 205  1
         if (displayName == null) {
 206  0
             return this.fileName;
 207  
         }
 208  1
         return this.displayName;
 209  
     }
 210  
 
 211  
     /**
 212  
      * <p>
 213  
      * Gets the file path of the dependency.</p>
 214  
      * <p>
 215  
      * <b>NOTE:</b> This may not be the actual path of the file on disk. The actual path of the file on disk can be obtained via
 216  
      * the getActualFilePath().</p>
 217  
      *
 218  
      * @return the file path of the dependency
 219  
      */
 220  
     public String getFilePath() {
 221  24
         return this.filePath;
 222  
     }
 223  
 
 224  
     /**
 225  
      * Sets the file extension of the dependency.
 226  
      *
 227  
      * @param fileExtension the file name of the dependency
 228  
      */
 229  
     public void setFileExtension(String fileExtension) {
 230  2
         this.fileExtension = fileExtension;
 231  2
     }
 232  
 
 233  
     /**
 234  
      * Gets the file extension of the dependency.
 235  
      *
 236  
      * @return the file extension of the dependency
 237  
      */
 238  
     public String getFileExtension() {
 239  35
         return this.fileExtension;
 240  
     }
 241  
 
 242  
     /**
 243  
      * Returns the MD5 Checksum of the dependency file.
 244  
      *
 245  
      * @return the MD5 Checksum
 246  
      */
 247  
     public String getMd5sum() {
 248  2
         return this.md5sum;
 249  
     }
 250  
 
 251  
     /**
 252  
      * Sets the MD5 Checksum of the dependency.
 253  
      *
 254  
      * @param md5sum the MD5 Checksum
 255  
      */
 256  
     public void setMd5sum(String md5sum) {
 257  27
         this.md5sum = md5sum;
 258  27
     }
 259  
 
 260  
     /**
 261  
      * Returns the SHA1 Checksum of the dependency.
 262  
      *
 263  
      * @return the SHA1 Checksum
 264  
      */
 265  
     public String getSha1sum() {
 266  9
         return this.sha1sum;
 267  
     }
 268  
 
 269  
     /**
 270  
      * Sets the SHA1 Checksum of the dependency.
 271  
      *
 272  
      * @param sha1sum the SHA1 Checksum
 273  
      */
 274  
     public void setSha1sum(String sha1sum) {
 275  29
         this.sha1sum = sha1sum;
 276  29
     }
 277  
 
 278  
     /**
 279  
      * Returns a List of Identifiers.
 280  
      *
 281  
      * @return an ArrayList of Identifiers
 282  
      */
 283  
     public Set<Identifier> getIdentifiers() {
 284  102
         return this.identifiers;
 285  
     }
 286  
 
 287  
     /**
 288  
      * Sets a List of Identifiers.
 289  
      *
 290  
      * @param identifiers A list of Identifiers
 291  
      */
 292  
     public void setIdentifiers(Set<Identifier> identifiers) {
 293  1
         this.identifiers = identifiers;
 294  1
     }
 295  
 
 296  
     /**
 297  
      * Adds an entry to the list of detected Identifiers for the dependency file.
 298  
      *
 299  
      * @param type the type of identifier (such as CPE)
 300  
      * @param value the value of the identifier
 301  
      * @param url the URL of the identifier
 302  
      */
 303  
     public void addIdentifier(String type, String value, String url) {
 304  11
         final Identifier i = new Identifier(type, value, url);
 305  11
         this.identifiers.add(i);
 306  11
     }
 307  
 
 308  
     /**
 309  
      * Adds an entry to the list of detected Identifiers for the dependency file.
 310  
      *
 311  
      * @param type the type of identifier (such as CPE)
 312  
      * @param value the value of the identifier
 313  
      * @param url the URL of the identifier
 314  
      * @param confidence the confidence in the Identifier being accurate
 315  
      */
 316  
     public void addIdentifier(String type, String value, String url, Confidence confidence) {
 317  2
         final Identifier i = new Identifier(type, value, url);
 318  2
         i.setConfidence(confidence);
 319  2
         this.identifiers.add(i);
 320  2
     }
 321  
 
 322  
     /**
 323  
      * Adds the maven artifact as evidence.
 324  
      *
 325  
      * @param source The source of the evidence
 326  
      * @param mavenArtifact The maven artifact
 327  
      * @param confidence The confidence level of this evidence
 328  
      */
 329  
     public void addAsEvidence(String source, MavenArtifact mavenArtifact, Confidence confidence) {
 330  2
         if (mavenArtifact.getGroupId() != null && !mavenArtifact.getGroupId().isEmpty()) {
 331  1
             this.getVendorEvidence().addEvidence(source, "groupid", mavenArtifact.getGroupId(), confidence);
 332  
         }
 333  2
         if (mavenArtifact.getArtifactId() != null && !mavenArtifact.getArtifactId().isEmpty()) {
 334  1
             this.getProductEvidence().addEvidence(source, "artifactid", mavenArtifact.getArtifactId(), confidence);
 335  
         }
 336  2
         if (mavenArtifact.getVersion() != null && !mavenArtifact.getVersion().isEmpty()) {
 337  1
             this.getVersionEvidence().addEvidence(source, "version", mavenArtifact.getVersion(), confidence);
 338  
         }
 339  2
         if (mavenArtifact.getArtifactUrl() != null && !mavenArtifact.getArtifactUrl().isEmpty()) {
 340  1
             boolean found = false;
 341  1
             for (Identifier i : this.getIdentifiers()) {
 342  0
                 if ("maven".equals(i.getType()) && i.getValue().equals(mavenArtifact.toString())) {
 343  0
                     found = true;
 344  0
                     i.setConfidence(Confidence.HIGHEST);
 345  0
                     final String url = "http://search.maven.org/#search|ga|1|1%3A%22" + this.getSha1sum() + "%22";
 346  0
                     i.setUrl(url);
 347  
                     //i.setUrl(mavenArtifact.getArtifactUrl());
 348  0
                     LOGGER.fine(String.format("Already found identifier %s. Confidence set to highest", i.getValue()));
 349  0
                     break;
 350  
                 }
 351  0
             }
 352  1
             if (!found) {
 353  1
                 LOGGER.fine(String.format("Adding new maven identifier %s", mavenArtifact.toString()));
 354  1
                 this.addIdentifier("maven", mavenArtifact.toString(), mavenArtifact.getArtifactUrl(), Confidence.HIGHEST);
 355  
             }
 356  
         }
 357  2
     }
 358  
 
 359  
     /**
 360  
      * Adds an entry to the list of detected Identifiers for the dependency file.
 361  
      *
 362  
      * @param identifier the identifier to add
 363  
      */
 364  
     public void addIdentifier(Identifier identifier) {
 365  2
         this.identifiers.add(identifier);
 366  2
     }
 367  
 
 368  
     /**
 369  
      * A set of identifiers that have been suppressed.
 370  
      */
 371  
     private Set<Identifier> suppressedIdentifiers;
 372  
 
 373  
     /**
 374  
      * Get the value of suppressedIdentifiers.
 375  
      *
 376  
      * @return the value of suppressedIdentifiers
 377  
      */
 378  
     public Set<Identifier> getSuppressedIdentifiers() {
 379  5
         return suppressedIdentifiers;
 380  
     }
 381  
 
 382  
     /**
 383  
      * Set the value of suppressedIdentifiers.
 384  
      *
 385  
      * @param suppressedIdentifiers new value of suppressedIdentifiers
 386  
      */
 387  
     public void setSuppressedIdentifiers(Set<Identifier> suppressedIdentifiers) {
 388  0
         this.suppressedIdentifiers = suppressedIdentifiers;
 389  0
     }
 390  
 
 391  
     /**
 392  
      * Adds an identifier to the list of suppressed identifiers.
 393  
      *
 394  
      * @param identifier an identifier that was suppressed.
 395  
      */
 396  
     public void addSuppressedIdentifier(Identifier identifier) {
 397  4
         this.suppressedIdentifiers.add(identifier);
 398  4
     }
 399  
 
 400  
     /**
 401  
      * A set of vulnerabilities that have been suppressed.
 402  
      */
 403  
     private SortedSet<Vulnerability> suppressedVulnerabilities;
 404  
 
 405  
     /**
 406  
      * Get the value of suppressedVulnerabilities.
 407  
      *
 408  
      * @return the value of suppressedVulnerabilities
 409  
      */
 410  
     public SortedSet<Vulnerability> getSuppressedVulnerabilities() {
 411  3
         return suppressedVulnerabilities;
 412  
     }
 413  
 
 414  
     /**
 415  
      * Set the value of suppressedVulnerabilities.
 416  
      *
 417  
      * @param suppressedVulnerabilities new value of suppressedVulnerabilities
 418  
      */
 419  
     public void setSuppressedVulnerabilities(SortedSet<Vulnerability> suppressedVulnerabilities) {
 420  0
         this.suppressedVulnerabilities = suppressedVulnerabilities;
 421  0
     }
 422  
 
 423  
     /**
 424  
      * Adds a vulnerability to the set of suppressed vulnerabilities.
 425  
      *
 426  
      * @param vulnerability the vulnerability that was suppressed
 427  
      */
 428  
     public void addSuppressedVulnerability(Vulnerability vulnerability) {
 429  3
         this.suppressedVulnerabilities.add(vulnerability);
 430  3
     }
 431  
 
 432  
     /**
 433  
      * Returns the evidence used to identify this dependency.
 434  
      *
 435  
      * @return an EvidenceCollection.
 436  
      */
 437  
     public EvidenceCollection getEvidence() {
 438  11
         return EvidenceCollection.merge(this.productEvidence, this.vendorEvidence, this.versionEvidence);
 439  
     }
 440  
 
 441  
     /**
 442  
      * Returns the evidence used to identify this dependency.
 443  
      *
 444  
      * @return an EvidenceCollection.
 445  
      */
 446  
     public Set<Evidence> getEvidenceForDisplay() {
 447  0
         return EvidenceCollection.mergeForDisplay(this.productEvidence, this.vendorEvidence, this.versionEvidence);
 448  
     }
 449  
 
 450  
     /**
 451  
      * Returns the evidence used to identify this dependency.
 452  
      *
 453  
      * @return an EvidenceCollection.
 454  
      */
 455  
     public EvidenceCollection getEvidenceUsed() {
 456  1
         return EvidenceCollection.mergeUsed(this.productEvidence, this.vendorEvidence, this.versionEvidence);
 457  
     }
 458  
 
 459  
     /**
 460  
      * Gets the Vendor Evidence.
 461  
      *
 462  
      * @return an EvidenceCollection.
 463  
      */
 464  
     public EvidenceCollection getVendorEvidence() {
 465  86
         return this.vendorEvidence;
 466  
     }
 467  
 
 468  
     /**
 469  
      * Gets the Product Evidence.
 470  
      *
 471  
      * @return an EvidenceCollection.
 472  
      */
 473  
     public EvidenceCollection getProductEvidence() {
 474  121
         return this.productEvidence;
 475  
     }
 476  
 
 477  
     /**
 478  
      * Gets the Version Evidence.
 479  
      *
 480  
      * @return an EvidenceCollection.
 481  
      */
 482  
     public EvidenceCollection getVersionEvidence() {
 483  46
         return this.versionEvidence;
 484  
     }
 485  
 
 486  
     /**
 487  
      * The description of the JAR file.
 488  
      */
 489  
     private String description;
 490  
 
 491  
     /**
 492  
      * Get the value of description.
 493  
      *
 494  
      * @return the value of description
 495  
      */
 496  
     public String getDescription() {
 497  9
         return description;
 498  
     }
 499  
 
 500  
     /**
 501  
      * Set the value of description.
 502  
      *
 503  
      * @param description new value of description
 504  
      */
 505  
     public void setDescription(String description) {
 506  18
         this.description = description;
 507  18
     }
 508  
 
 509  
     /**
 510  
      * The license that this dependency uses.
 511  
      */
 512  
     private String license;
 513  
 
 514  
     /**
 515  
      * Get the value of license.
 516  
      *
 517  
      * @return the value of license
 518  
      */
 519  
     public String getLicense() {
 520  2
         return license;
 521  
     }
 522  
 
 523  
     /**
 524  
      * Set the value of license.
 525  
      *
 526  
      * @param license new value of license
 527  
      */
 528  
     public void setLicense(String license) {
 529  2
         this.license = license;
 530  2
     }
 531  
 
 532  
     /**
 533  
      * A list of vulnerabilities for this dependency.
 534  
      */
 535  
     private SortedSet<Vulnerability> vulnerabilities;
 536  
 
 537  
     /**
 538  
      * Get the list of vulnerabilities.
 539  
      *
 540  
      * @return the list of vulnerabilities
 541  
      */
 542  
     public SortedSet<Vulnerability> getVulnerabilities() {
 543  13
         return vulnerabilities;
 544  
     }
 545  
 
 546  
     /**
 547  
      * Set the value of vulnerabilities.
 548  
      *
 549  
      * @param vulnerabilities new value of vulnerabilities
 550  
      */
 551  
     public void setVulnerabilities(SortedSet<Vulnerability> vulnerabilities) {
 552  0
         this.vulnerabilities = vulnerabilities;
 553  0
     }
 554  
 
 555  
     /**
 556  
      * Determines the sha1 and md5 sum for the given file.
 557  
      *
 558  
      * @param file the file to create checksums for
 559  
      */
 560  
     private void determineHashes(File file) {
 561  26
         String md5 = null;
 562  26
         String sha1 = null;
 563  
         try {
 564  26
             md5 = Checksum.getMD5Checksum(file);
 565  23
             sha1 = Checksum.getSHA1Checksum(file);
 566  3
         } catch (IOException ex) {
 567  3
             final String msg = String.format("Unable to read '%s' to determine hashes.", file.getName());
 568  3
             LOGGER.log(Level.WARNING, msg);
 569  3
             LOGGER.log(Level.FINE, null, ex);
 570  0
         } catch (NoSuchAlgorithmException ex) {
 571  0
             final String msg = "Unable to use MD5 of SHA1 checksums.";
 572  0
             LOGGER.log(Level.WARNING, msg);
 573  0
             LOGGER.log(Level.FINE, null, ex);
 574  26
         }
 575  26
         this.setMd5sum(md5);
 576  26
         this.setSha1sum(sha1);
 577  26
     }
 578  
 
 579  
     /**
 580  
      * Adds a vulnerability to the dependency.
 581  
      *
 582  
      * @param vulnerability a vulnerability outlining a vulnerability.
 583  
      */
 584  
     public void addVulnerability(Vulnerability vulnerability) {
 585  3
         this.vulnerabilities.add(vulnerability);
 586  3
     }
 587  
 
 588  
     /**
 589  
      * A collection of related dependencies.
 590  
      */
 591  47
     private Set<Dependency> relatedDependencies = new TreeSet<Dependency>();
 592  
 
 593  
     /**
 594  
      * Get the value of relatedDependencies.
 595  
      *
 596  
      * @return the value of relatedDependencies
 597  
      */
 598  
     public Set<Dependency> getRelatedDependencies() {
 599  0
         return relatedDependencies;
 600  
     }
 601  
 
 602  
     /**
 603  
      * A list of projects that reference this dependency.
 604  
      */
 605  47
     private Set<String> projectReferences = new HashSet<String>();
 606  
 
 607  
     /**
 608  
      * Get the value of projectReferences.
 609  
      *
 610  
      * @return the value of projectReferences
 611  
      */
 612  
     public Set<String> getProjectReferences() {
 613  0
         return projectReferences;
 614  
     }
 615  
 
 616  
     /**
 617  
      * Set the value of projectReferences.
 618  
      *
 619  
      * @param projectReferences new value of projectReferences
 620  
      */
 621  
     public void setProjectReferences(Set<String> projectReferences) {
 622  0
         this.projectReferences = projectReferences;
 623  0
     }
 624  
 
 625  
     /**
 626  
      * Adds a project reference.
 627  
      *
 628  
      * @param projectReference a project reference
 629  
      */
 630  
     public void addProjectReference(String projectReference) {
 631  0
         this.projectReferences.add(projectReference);
 632  0
     }
 633  
 
 634  
     /**
 635  
      * Add a collection of project reference.
 636  
      *
 637  
      * @param projectReferences a set of project references
 638  
      */
 639  
     public void addAllProjectReferences(Set<String> projectReferences) {
 640  0
         this.projectReferences.addAll(projectReferences);
 641  0
     }
 642  
 
 643  
     /**
 644  
      * Set the value of relatedDependencies.
 645  
      *
 646  
      * @param relatedDependencies new value of relatedDependencies
 647  
      */
 648  
     public void setRelatedDependencies(Set<Dependency> relatedDependencies) {
 649  0
         this.relatedDependencies = relatedDependencies;
 650  0
     }
 651  
 
 652  
     /**
 653  
      * Adds a related dependency.
 654  
      *
 655  
      * @param dependency a reference to the related dependency
 656  
      */
 657  
     public void addRelatedDependency(Dependency dependency) {
 658  0
         if (this == dependency) {
 659  0
             LOGGER.warning("Attempted to add a circular reference - please post the log file to issue #172 here "
 660  
                     + "https://github.com/jeremylong/DependencyCheck/issues/172 ");
 661  0
             LOGGER.log(Level.FINE, "this: {0}", this.toString());
 662  0
             LOGGER.log(Level.FINE, "dependency: {0}", dependency.toString());
 663  
         } else {
 664  0
             relatedDependencies.add(dependency);
 665  
         }
 666  0
     }
 667  
 
 668  
     /**
 669  
      * A list of available versions.
 670  
      */
 671  47
     private List<String> availableVersions = new ArrayList<String>();
 672  
 
 673  
     /**
 674  
      * Get the value of availableVersions.
 675  
      *
 676  
      * @return the value of availableVersions
 677  
      */
 678  
     public List<String> getAvailableVersions() {
 679  0
         return availableVersions;
 680  
     }
 681  
 
 682  
     /**
 683  
      * Set the value of availableVersions.
 684  
      *
 685  
      * @param availableVersions new value of availableVersions
 686  
      */
 687  
     public void setAvailableVersions(List<String> availableVersions) {
 688  0
         this.availableVersions = availableVersions;
 689  0
     }
 690  
 
 691  
     /**
 692  
      * Adds a version to the available version list.
 693  
      *
 694  
      * @param version the version to add to the list
 695  
      */
 696  
     public void addAvailableVersion(String version) {
 697  0
         this.availableVersions.add(version);
 698  0
     }
 699  
 
 700  
     /**
 701  
      * Implementation of the Comparable<Dependency> interface. The comparison is solely based on the file name.
 702  
      *
 703  
      * @param o a dependency to compare
 704  
      * @return an integer representing the natural ordering
 705  
      */
 706  
     public int compareTo(Dependency o) {
 707  2
         return this.getFilePath().compareToIgnoreCase(o.getFilePath());
 708  
     }
 709  
 
 710  
     /**
 711  
      * Implementation of the equals method.
 712  
      *
 713  
      * @param obj the object to compare
 714  
      * @return true if the objects are equal, otherwise false
 715  
      */
 716  
     @Override
 717  
     public boolean equals(Object obj) {
 718  0
         if (obj == null) {
 719  0
             return false;
 720  
         }
 721  0
         if (getClass() != obj.getClass()) {
 722  0
             return false;
 723  
         }
 724  0
         final Dependency other = (Dependency) obj;
 725  0
         if ((this.actualFilePath == null) ? (other.actualFilePath != null) : !this.actualFilePath.equals(other.actualFilePath)) {
 726  0
             return false;
 727  
         }
 728  0
         if ((this.filePath == null) ? (other.filePath != null) : !this.filePath.equals(other.filePath)) {
 729  0
             return false;
 730  
         }
 731  0
         if ((this.fileName == null) ? (other.fileName != null) : !this.fileName.equals(other.fileName)) {
 732  0
             return false;
 733  
         }
 734  0
         if ((this.fileExtension == null) ? (other.fileExtension != null) : !this.fileExtension.equals(other.fileExtension)) {
 735  0
             return false;
 736  
         }
 737  0
         if ((this.md5sum == null) ? (other.md5sum != null) : !this.md5sum.equals(other.md5sum)) {
 738  0
             return false;
 739  
         }
 740  0
         if ((this.sha1sum == null) ? (other.sha1sum != null) : !this.sha1sum.equals(other.sha1sum)) {
 741  0
             return false;
 742  
         }
 743  0
         if (this.identifiers != other.identifiers && (this.identifiers == null || !this.identifiers.equals(other.identifiers))) {
 744  0
             return false;
 745  
         }
 746  0
         if (this.vendorEvidence != other.vendorEvidence && (this.vendorEvidence == null || !this.vendorEvidence.equals(other.vendorEvidence))) {
 747  0
             return false;
 748  
         }
 749  0
         if (this.productEvidence != other.productEvidence && (this.productEvidence == null || !this.productEvidence.equals(other.productEvidence))) {
 750  0
             return false;
 751  
         }
 752  0
         if (this.versionEvidence != other.versionEvidence && (this.versionEvidence == null || !this.versionEvidence.equals(other.versionEvidence))) {
 753  0
             return false;
 754  
         }
 755  0
         if ((this.description == null) ? (other.description != null) : !this.description.equals(other.description)) {
 756  0
             return false;
 757  
         }
 758  0
         if ((this.license == null) ? (other.license != null) : !this.license.equals(other.license)) {
 759  0
             return false;
 760  
         }
 761  0
         if (this.vulnerabilities != other.vulnerabilities && (this.vulnerabilities == null || !this.vulnerabilities.equals(other.vulnerabilities))) {
 762  0
             return false;
 763  
         }
 764  0
         if (this.relatedDependencies != other.relatedDependencies
 765  
                 && (this.relatedDependencies == null || !this.relatedDependencies.equals(other.relatedDependencies))) {
 766  0
             return false;
 767  
         }
 768  0
         if (this.projectReferences != other.projectReferences
 769  
                 && (this.projectReferences == null || !this.projectReferences.equals(other.projectReferences))) {
 770  0
             return false;
 771  
         }
 772  0
         if (this.availableVersions != other.availableVersions
 773  
                 && (this.availableVersions == null || !this.availableVersions.equals(other.availableVersions))) {
 774  0
             return false;
 775  
         }
 776  
 
 777  0
         return true;
 778  
     }
 779  
 
 780  
     /**
 781  
      * Generates the HashCode.
 782  
      *
 783  
      * @return the HashCode
 784  
      */
 785  
     @Override
 786  
     public int hashCode() {
 787  32
         int hash = 3;
 788  32
         hash = 47 * hash + (this.actualFilePath != null ? this.actualFilePath.hashCode() : 0);
 789  32
         hash = 47 * hash + (this.filePath != null ? this.filePath.hashCode() : 0);
 790  32
         hash = 47 * hash + (this.fileName != null ? this.fileName.hashCode() : 0);
 791  32
         hash = 47 * hash + (this.fileExtension != null ? this.fileExtension.hashCode() : 0);
 792  32
         hash = 47 * hash + (this.md5sum != null ? this.md5sum.hashCode() : 0);
 793  32
         hash = 47 * hash + (this.sha1sum != null ? this.sha1sum.hashCode() : 0);
 794  32
         hash = 47 * hash + (this.identifiers != null ? this.identifiers.hashCode() : 0);
 795  32
         hash = 47 * hash + (this.vendorEvidence != null ? this.vendorEvidence.hashCode() : 0);
 796  32
         hash = 47 * hash + (this.productEvidence != null ? this.productEvidence.hashCode() : 0);
 797  32
         hash = 47 * hash + (this.versionEvidence != null ? this.versionEvidence.hashCode() : 0);
 798  32
         hash = 47 * hash + (this.description != null ? this.description.hashCode() : 0);
 799  32
         hash = 47 * hash + (this.license != null ? this.license.hashCode() : 0);
 800  32
         hash = 47 * hash + (this.vulnerabilities != null ? this.vulnerabilities.hashCode() : 0);
 801  32
         hash = 47 * hash + (this.relatedDependencies != null ? this.relatedDependencies.hashCode() : 0);
 802  32
         hash = 47 * hash + (this.projectReferences != null ? this.projectReferences.hashCode() : 0);
 803  32
         hash = 47 * hash + (this.availableVersions != null ? this.availableVersions.hashCode() : 0);
 804  32
         return hash;
 805  
     }
 806  
 
 807  
     /**
 808  
      * Standard toString() implementation showing the filename, actualFilePath, and filePath.
 809  
      *
 810  
      * @return the string representation of the file
 811  
      */
 812  
     @Override
 813  
     public String toString() {
 814  0
         return "Dependency{ fileName='" + fileName + "', actualFilePath='" + actualFilePath + "', filePath='" + filePath + "'}";
 815  
     }
 816  
 }