Coverage Report - org.owasp.dependencycheck.dependency.Dependency
 
Classes in this File Line Coverage Branch Coverage Complexity
Dependency
59%
67/113
14%
17/118
2.468
 
 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.security.NoSuchAlgorithmException;
 23  
 import java.util.Set;
 24  
 import java.util.SortedSet;
 25  
 import java.util.TreeSet;
 26  
 import java.util.logging.Level;
 27  
 import java.util.logging.Logger;
 28  
 import org.owasp.dependencycheck.utils.Checksum;
 29  
 import org.owasp.dependencycheck.utils.FileUtils;
 30  
 
 31  
 /**
 32  
  * A program dependency. This object is one of the core components within DependencyCheck. It is used to collect
 33  
  * information about the dependency in the form of evidence. The Evidence is then used to determine if there are any
 34  
  * known, published, vulnerabilities associated with the program dependency.
 35  
  *
 36  
  * @author Jeremy Long <jeremy.long@owasp.org>
 37  
  */
 38  2
 public class Dependency implements Comparable<Dependency> {
 39  
 
 40  
     /**
 41  
      * The logger.
 42  
      */
 43  1
     private static final Logger LOGGER = Logger.getLogger(Dependency.class.getName());
 44  
     /**
 45  
      * The actual file path of the dependency on disk.
 46  
      */
 47  
     private String actualFilePath;
 48  
     /**
 49  
      * The file path to display.
 50  
      */
 51  
     private String filePath;
 52  
     /**
 53  
      * The file name of the dependency.
 54  
      */
 55  
     private String fileName;
 56  
     /**
 57  
      * The file extension of the dependency.
 58  
      */
 59  
     private String fileExtension;
 60  
     /**
 61  
      * The md5 hash of the dependency.
 62  
      */
 63  
     private String md5sum;
 64  
     /**
 65  
      * The SHA1 hash of the dependency.
 66  
      */
 67  
     private String sha1sum;
 68  
     /**
 69  
      * A list of Identifiers.
 70  
      */
 71  
     private Set<Identifier> identifiers;
 72  
     /**
 73  
      * A collection of vendor evidence.
 74  
      */
 75  
     private final EvidenceCollection vendorEvidence;
 76  
     /**
 77  
      * A collection of product evidence.
 78  
      */
 79  
     private final EvidenceCollection productEvidence;
 80  
     /**
 81  
      * A collection of version evidence.
 82  
      */
 83  
     private final EvidenceCollection versionEvidence;
 84  
 
 85  
     /**
 86  
      * Constructs a new Dependency object.
 87  
      */
 88  37
     public Dependency() {
 89  37
         vendorEvidence = new EvidenceCollection();
 90  37
         productEvidence = new EvidenceCollection();
 91  37
         versionEvidence = new EvidenceCollection();
 92  37
         identifiers = new TreeSet<Identifier>();
 93  37
         vulnerabilities = new TreeSet<Vulnerability>(new VulnerabilityComparator());
 94  37
         suppressedIdentifiers = new TreeSet<Identifier>();
 95  37
         suppressedVulnerabilities = new TreeSet<Vulnerability>(new VulnerabilityComparator());
 96  37
     }
 97  
 
 98  
     /**
 99  
      * Constructs a new Dependency object.
 100  
      *
 101  
      * @param file the File to create the dependency object from.
 102  
      */
 103  
     public Dependency(File file) {
 104  16
         this();
 105  16
         this.actualFilePath = file.getPath();
 106  16
         this.filePath = this.actualFilePath;
 107  16
         this.fileName = file.getName();
 108  16
         this.fileExtension = FileUtils.getFileExtension(fileName);
 109  16
         determineHashes(file);
 110  16
     }
 111  
 
 112  
     /**
 113  
      * Returns the file name of the dependency.
 114  
      *
 115  
      * @return the file name of the dependency
 116  
      */
 117  
     public String getFileName() {
 118  
         return this.fileName;
 119  
     }
 120  
 
 121  
     /**
 122  
      * Returns the file name of the dependency with the backslash escaped for use in JavaScript. This is a complete hack
 123  
      * as I could not get the replace to work in the template itself.
 124  
      *
 125  
      * @return the file name of the dependency with the backslash escaped for use in JavaScript
 126  
      */
 127  
     public String getFileNameForJavaScript() {
 128  0
         return this.fileName.replace("\\", "\\\\");
 129  
     }
 130  
 
 131  
     /**
 132  
      * Sets the file name of the dependency.
 133  
      *
 134  
      * @param fileName the file name of the dependency
 135  
      */
 136  
     public void setFileName(String fileName) {
 137  
         this.fileName = fileName;
 138  
     }
 139  
 
 140  
     /**
 141  
      * Sets the actual file path of the dependency on disk.
 142  
      *
 143  
      * @param actualFilePath the file path of the dependency
 144  
      */
 145  
     public void setActualFilePath(String actualFilePath) {
 146  2
         this.actualFilePath = actualFilePath;
 147  2
         if (this.sha1sum == null) {
 148  2
             final File file = new File(this.actualFilePath);
 149  2
             determineHashes(file);
 150  
         }
 151  2
     }
 152  
 
 153  
     /**
 154  
      * Gets the file path of the dependency.
 155  
      *
 156  
      * @return the file path of the dependency
 157  
      */
 158  
     public String getActualFilePath() {
 159  
         return this.actualFilePath;
 160  
     }
 161  
 
 162  
     /**
 163  
      * Gets a reference to the File object.
 164  
      *
 165  
      * @return the File object
 166  
      */
 167  
     public File getActualFile() {
 168  2
         return new File(this.actualFilePath);
 169  
     }
 170  
 
 171  
     /**
 172  
      * Sets the file path of the dependency.
 173  
      *
 174  
      * @param filePath the file path of the dependency
 175  
      */
 176  
     public void setFilePath(String filePath) {
 177  
         this.filePath = filePath;
 178  
     }
 179  
 
 180  
     /**
 181  
      * <p>
 182  
      * Gets the file path of the dependency.</p>
 183  
      * <p>
 184  
      * <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
 185  
      * obtained via the getActualFilePath().</p>
 186  
      *
 187  
      * @return the file path of the dependency
 188  
      */
 189  
     public String getFilePath() {
 190  
         return this.filePath;
 191  
     }
 192  
 
 193  
     /**
 194  
      * Sets the file name of the dependency.
 195  
      *
 196  
      * @param fileExtension the file name of the dependency
 197  
      */
 198  
     public void setFileExtension(String fileExtension) {
 199  
         this.fileExtension = fileExtension;
 200  
     }
 201  
 
 202  
     /**
 203  
      * Gets the file extension of the dependency.
 204  
      *
 205  
      * @return the file extension of the dependency
 206  
      */
 207  
     public String getFileExtension() {
 208  
         return this.fileExtension;
 209  
     }
 210  
 
 211  
     /**
 212  
      * Returns the MD5 Checksum of the dependency file.
 213  
      *
 214  
      * @return the MD5 Checksum
 215  
      */
 216  
     public String getMd5sum() {
 217  
         return this.md5sum;
 218  
     }
 219  
 
 220  
     /**
 221  
      * Sets the MD5 Checksum of the dependency.
 222  
      *
 223  
      * @param md5sum the MD5 Checksum
 224  
      */
 225  
     public void setMd5sum(String md5sum) {
 226  
         this.md5sum = md5sum;
 227  
     }
 228  
 
 229  
     /**
 230  
      * Returns the SHA1 Checksum of the dependency.
 231  
      *
 232  
      * @return the SHA1 Checksum
 233  
      */
 234  
     public String getSha1sum() {
 235  
         return this.sha1sum;
 236  
     }
 237  
 
 238  
     /**
 239  
      * Sets the SHA1 Checksum of the dependency.
 240  
      *
 241  
      * @param sha1sum the SHA1 Checksum
 242  
      */
 243  
     public void setSha1sum(String sha1sum) {
 244  
         this.sha1sum = sha1sum;
 245  
     }
 246  
 
 247  
     /**
 248  
      * Returns a List of Identifiers.
 249  
      *
 250  
      * @return an ArrayList of Identifiers
 251  
      */
 252  
     public Set<Identifier> getIdentifiers() {
 253  
         return this.identifiers;
 254  
     }
 255  
 
 256  
     /**
 257  
      * Sets a List of Identifiers.
 258  
      *
 259  
      * @param identifiers A list of Identifiers
 260  
      */
 261  
     public void setIdentifiers(Set<Identifier> identifiers) {
 262  
         this.identifiers = identifiers;
 263  
     }
 264  
 
 265  
     /**
 266  
      * Adds an entry to the list of detected Identifiers for the dependency file.
 267  
      *
 268  
      * @param type the type of identifier (such as CPE)
 269  
      * @param value the value of the identifier
 270  
      * @param url the URL of the identifier
 271  
      */
 272  
     public void addIdentifier(String type, String value, String url) {
 273  6
         final Identifier i = new Identifier(type, value, url);
 274  6
         this.identifiers.add(i);
 275  6
     }
 276  
 
 277  
     /**
 278  
      * Adds an entry to the list of detected Identifiers for the dependency file.
 279  
      *
 280  
      * @param type the type of identifier (such as CPE)
 281  
      * @param value the value of the identifier
 282  
      * @param url the URL of the identifier
 283  
      * @param confidence the confidence in the Identifier being accurate
 284  
      */
 285  
     public void addIdentifier(String type, String value, String url, Confidence confidence) {
 286  0
         final Identifier i = new Identifier(type, value, url);
 287  0
         i.setConfidence(confidence);
 288  0
         this.identifiers.add(i);
 289  0
     }
 290  
 
 291  
     /**
 292  
      * Adds an entry to the list of detected Identifiers for the dependency file.
 293  
      *
 294  
      * @param identifier the identifier to add
 295  
      */
 296  
     public void addIdentifier(Identifier identifier) {
 297  4
         this.identifiers.add(identifier);
 298  4
     }
 299  
     /**
 300  
      * A set of identifiers that have been suppressed.
 301  
      */
 302  
     private Set<Identifier> suppressedIdentifiers;
 303  
 
 304  
     /**
 305  
      * Get the value of suppressedIdentifiers.
 306  
      *
 307  
      * @return the value of suppressedIdentifiers
 308  
      */
 309  
     public Set<Identifier> getSuppressedIdentifiers() {
 310  
         return suppressedIdentifiers;
 311  
     }
 312  
 
 313  
     /**
 314  
      * Set the value of suppressedIdentifiers.
 315  
      *
 316  
      * @param suppressedIdentifiers new value of suppressedIdentifiers
 317  
      */
 318  
     public void setSuppressedIdentifiers(Set<Identifier> suppressedIdentifiers) {
 319  
         this.suppressedIdentifiers = suppressedIdentifiers;
 320  
     }
 321  
 
 322  
     /**
 323  
      * Adds an identifier to the list of suppressed identifiers.
 324  
      *
 325  
      * @param identifier an identifier that was suppressed.
 326  
      */
 327  
     public void addSuppressedIdentifier(Identifier identifier) {
 328  4
         this.suppressedIdentifiers.add(identifier);
 329  4
     }
 330  
 
 331  
     /**
 332  
      * A set of vulnerabilities that have been suppressed.
 333  
      */
 334  
     private SortedSet<Vulnerability> suppressedVulnerabilities;
 335  
 
 336  
     /**
 337  
      * Get the value of suppressedVulnerabilities.
 338  
      *
 339  
      * @return the value of suppressedVulnerabilities
 340  
      */
 341  
     public SortedSet<Vulnerability> getSuppressedVulnerabilities() {
 342  
         return suppressedVulnerabilities;
 343  
     }
 344  
 
 345  
     /**
 346  
      * Set the value of suppressedVulnerabilities.
 347  
      *
 348  
      * @param suppressedVulnerabilities new value of suppressedVulnerabilities
 349  
      */
 350  
     public void setSuppressedVulnerabilities(SortedSet<Vulnerability> suppressedVulnerabilities) {
 351  
         this.suppressedVulnerabilities = suppressedVulnerabilities;
 352  
     }
 353  
 
 354  
     /**
 355  
      * Adds a vulnerability to the set of suppressed vulnerabilities.
 356  
      *
 357  
      * @param vulnerability the vulnerability that was suppressed
 358  
      */
 359  
     public void addSuppressedVulnerability(Vulnerability vulnerability) {
 360  3
         this.suppressedVulnerabilities.add(vulnerability);
 361  3
     }
 362  
 
 363  
     /**
 364  
      * Returns the evidence used to identify this dependency.
 365  
      *
 366  
      * @return an EvidenceCollection.
 367  
      */
 368  
     public EvidenceCollection getEvidence() {
 369  3
         return EvidenceCollection.merge(this.productEvidence, this.vendorEvidence, this.versionEvidence);
 370  
     }
 371  
 
 372  
     /**
 373  
      * Returns the evidence used to identify this dependency.
 374  
      *
 375  
      * @return an EvidenceCollection.
 376  
      */
 377  
     public EvidenceCollection getEvidenceUsed() {
 378  1
         return EvidenceCollection.mergeUsed(this.productEvidence, this.vendorEvidence, this.versionEvidence);
 379  
     }
 380  
 
 381  
     /**
 382  
      * Gets the Vendor Evidence.
 383  
      *
 384  
      * @return an EvidenceCollection.
 385  
      */
 386  
     public EvidenceCollection getVendorEvidence() {
 387  
         return this.vendorEvidence;
 388  
     }
 389  
 
 390  
     /**
 391  
      * Gets the Product Evidence.
 392  
      *
 393  
      * @return an EvidenceCollection.
 394  
      */
 395  
     public EvidenceCollection getProductEvidence() {
 396  
         return this.productEvidence;
 397  
     }
 398  
 
 399  
     /**
 400  
      * Gets the Version Evidence.
 401  
      *
 402  
      * @return an EvidenceCollection.
 403  
      */
 404  
     public EvidenceCollection getVersionEvidence() {
 405  
         return this.versionEvidence;
 406  
     }
 407  
     /**
 408  
      * The description of the JAR file.
 409  
      */
 410  
     private String description;
 411  
 
 412  
     /**
 413  
      * Get the value of description.
 414  
      *
 415  
      * @return the value of description
 416  
      */
 417  
     public String getDescription() {
 418  
         return description;
 419  
     }
 420  
 
 421  
     /**
 422  
      * Set the value of description.
 423  
      *
 424  
      * @param description new value of description
 425  
      */
 426  
     public void setDescription(String description) {
 427  
         this.description = description;
 428  
     }
 429  
     /**
 430  
      * The license that this dependency uses.
 431  
      */
 432  
     private String license;
 433  
 
 434  
     /**
 435  
      * Get the value of license.
 436  
      *
 437  
      * @return the value of license
 438  
      */
 439  
     public String getLicense() {
 440  
         return license;
 441  
     }
 442  
 
 443  
     /**
 444  
      * Set the value of license.
 445  
      *
 446  
      * @param license new value of license
 447  
      */
 448  
     public void setLicense(String license) {
 449  
         this.license = license;
 450  
     }
 451  
     /**
 452  
      * A list of vulnerabilities for this dependency.
 453  
      */
 454  
     private SortedSet<Vulnerability> vulnerabilities;
 455  
 
 456  
     /**
 457  
      * Get the list of vulnerabilities.
 458  
      *
 459  
      * @return the list of vulnerabilities
 460  
      */
 461  
     public SortedSet<Vulnerability> getVulnerabilities() {
 462  
         return vulnerabilities;
 463  
     }
 464  
 
 465  
     /**
 466  
      * Set the value of vulnerabilities.
 467  
      *
 468  
      * @param vulnerabilities new value of vulnerabilities
 469  
      */
 470  
     public void setVulnerabilities(SortedSet<Vulnerability> vulnerabilities) {
 471  
         this.vulnerabilities = vulnerabilities;
 472  
     }
 473  
 
 474  
     /**
 475  
      * Determines the sha1 and md5 sum for the given file.
 476  
      *
 477  
      * @param file the file to create checksums for
 478  
      */
 479  
     private void determineHashes(File file) {
 480  18
         String md5 = null;
 481  18
         String sha1 = null;
 482  
         try {
 483  18
             md5 = Checksum.getMD5Checksum(file);
 484  15
             sha1 = Checksum.getSHA1Checksum(file);
 485  3
         } catch (IOException ex) {
 486  3
             final String msg = String.format("Unable to read '%s' to determine hashes.", file.getName());
 487  3
             LOGGER.log(Level.WARNING, msg);
 488  3
             LOGGER.log(Level.FINE, null, ex);
 489  0
         } catch (NoSuchAlgorithmException ex) {
 490  0
             final String msg = "Unable to use MD5 of SHA1 checksums.";
 491  0
             LOGGER.log(Level.WARNING, msg);
 492  0
             LOGGER.log(Level.FINE, null, ex);
 493  18
         }
 494  18
         this.setMd5sum(md5);
 495  18
         this.setSha1sum(sha1);
 496  18
     }
 497  
 
 498  
     /**
 499  
      * Adds a vulnerability to the dependency.
 500  
      *
 501  
      * @param vulnerability a vulnerability outlining a vulnerability.
 502  
      */
 503  
     public void addVulnerability(Vulnerability vulnerability) {
 504  3
         this.vulnerabilities.add(vulnerability);
 505  3
     }
 506  
     /**
 507  
      * A collection of related dependencies.
 508  
      */
 509  37
     private Set<Dependency> relatedDependencies = new TreeSet<Dependency>();
 510  
 
 511  
     /**
 512  
      * Get the value of relatedDependencies.
 513  
      *
 514  
      * @return the value of relatedDependencies
 515  
      */
 516  
     public Set<Dependency> getRelatedDependencies() {
 517  
         return relatedDependencies;
 518  
     }
 519  
 
 520  
     /**
 521  
      * Set the value of relatedDependencies.
 522  
      *
 523  
      * @param relatedDependencies new value of relatedDependencies
 524  
      */
 525  
     public void setRelatedDependencies(Set<Dependency> relatedDependencies) {
 526  
         this.relatedDependencies = relatedDependencies;
 527  
     }
 528  
 
 529  
     /**
 530  
      * Adds a related dependency.
 531  
      *
 532  
      * @param dependency a reference to the related dependency
 533  
      */
 534  
     public void addRelatedDependency(Dependency dependency) {
 535  0
         relatedDependencies.add(dependency);
 536  0
     }
 537  
 
 538  
     /**
 539  
      * Implementation of the Comparable<Dependency> interface. The comparison is solely based on the file name.
 540  
      *
 541  
      * @param o a dependency to compare
 542  
      * @return an integer representing the natural ordering
 543  
      */
 544  
     public int compareTo(Dependency o) {
 545  2
         return this.getFileName().compareToIgnoreCase(o.getFileName());
 546  
     }
 547  
 
 548  
     /**
 549  
      * Implementation of the equals method.
 550  
      *
 551  
      * @param obj the object to compare
 552  
      * @return true if the objects are equal, otherwise false
 553  
      */
 554  
     @Override
 555  
     public boolean equals(Object obj) {
 556  0
         if (obj == null) {
 557  0
             return false;
 558  
         }
 559  0
         if (getClass() != obj.getClass()) {
 560  0
             return false;
 561  
         }
 562  0
         final Dependency other = (Dependency) obj;
 563  0
         if ((this.actualFilePath == null) ? (other.actualFilePath != null) : !this.actualFilePath.equals(other.actualFilePath)) {
 564  0
             return false;
 565  
         }
 566  0
         if ((this.filePath == null) ? (other.filePath != null) : !this.filePath.equals(other.filePath)) {
 567  0
             return false;
 568  
         }
 569  0
         if ((this.fileName == null) ? (other.fileName != null) : !this.fileName.equals(other.fileName)) {
 570  0
             return false;
 571  
         }
 572  0
         if ((this.fileExtension == null) ? (other.fileExtension != null) : !this.fileExtension.equals(other.fileExtension)) {
 573  0
             return false;
 574  
         }
 575  0
         if ((this.md5sum == null) ? (other.md5sum != null) : !this.md5sum.equals(other.md5sum)) {
 576  0
             return false;
 577  
         }
 578  0
         if ((this.sha1sum == null) ? (other.sha1sum != null) : !this.sha1sum.equals(other.sha1sum)) {
 579  0
             return false;
 580  
         }
 581  0
         if (this.identifiers != other.identifiers && (this.identifiers == null || !this.identifiers.equals(other.identifiers))) {
 582  0
             return false;
 583  
         }
 584  0
         if (this.vendorEvidence != other.vendorEvidence && (this.vendorEvidence == null || !this.vendorEvidence.equals(other.vendorEvidence))) {
 585  0
             return false;
 586  
         }
 587  0
         if (this.productEvidence != other.productEvidence && (this.productEvidence == null || !this.productEvidence.equals(other.productEvidence))) {
 588  0
             return false;
 589  
         }
 590  0
         if (this.versionEvidence != other.versionEvidence && (this.versionEvidence == null || !this.versionEvidence.equals(other.versionEvidence))) {
 591  0
             return false;
 592  
         }
 593  0
         if ((this.description == null) ? (other.description != null) : !this.description.equals(other.description)) {
 594  0
             return false;
 595  
         }
 596  0
         if ((this.license == null) ? (other.license != null) : !this.license.equals(other.license)) {
 597  0
             return false;
 598  
         }
 599  0
         if (this.vulnerabilities != other.vulnerabilities && (this.vulnerabilities == null || !this.vulnerabilities.equals(other.vulnerabilities))) {
 600  0
             return false;
 601  
         }
 602  0
         if (this.relatedDependencies != other.relatedDependencies
 603  
                 && (this.relatedDependencies == null || !this.relatedDependencies.equals(other.relatedDependencies))) {
 604  0
             return false;
 605  
         }
 606  0
         return true;
 607  
     }
 608  
 
 609  
     /**
 610  
      * Generates the HashCode.
 611  
      *
 612  
      * @return the HashCode
 613  
      */
 614  
     @Override
 615  
     public int hashCode() {
 616  26
         int hash = 3;
 617  26
         hash = 47 * hash + (this.actualFilePath != null ? this.actualFilePath.hashCode() : 0);
 618  26
         hash = 47 * hash + (this.filePath != null ? this.filePath.hashCode() : 0);
 619  26
         hash = 47 * hash + (this.fileName != null ? this.fileName.hashCode() : 0);
 620  26
         hash = 47 * hash + (this.fileExtension != null ? this.fileExtension.hashCode() : 0);
 621  26
         hash = 47 * hash + (this.md5sum != null ? this.md5sum.hashCode() : 0);
 622  26
         hash = 47 * hash + (this.sha1sum != null ? this.sha1sum.hashCode() : 0);
 623  26
         hash = 47 * hash + (this.identifiers != null ? this.identifiers.hashCode() : 0);
 624  26
         hash = 47 * hash + (this.vendorEvidence != null ? this.vendorEvidence.hashCode() : 0);
 625  26
         hash = 47 * hash + (this.productEvidence != null ? this.productEvidence.hashCode() : 0);
 626  26
         hash = 47 * hash + (this.versionEvidence != null ? this.versionEvidence.hashCode() : 0);
 627  26
         hash = 47 * hash + (this.description != null ? this.description.hashCode() : 0);
 628  26
         hash = 47 * hash + (this.license != null ? this.license.hashCode() : 0);
 629  26
         hash = 47 * hash + (this.vulnerabilities != null ? this.vulnerabilities.hashCode() : 0);
 630  26
         hash = 47 * hash + (this.relatedDependencies != null ? this.relatedDependencies.hashCode() : 0);
 631  26
         return hash;
 632  
     }
 633  
 
 634  
     /**
 635  
      * Standard toString() implementation showing the filename, actualFilePath, and filePath.
 636  
      *
 637  
      * @return the string representation of the file
 638  
      */
 639  
     @Override
 640  
     public String toString() {
 641  0
         return "Dependency{ fileName='" + fileName + "', actualFilePath='" + actualFilePath + "', filePath='" + filePath + "'}";
 642  
     }
 643  
 }