| Classes in this File | Line Coverage | Branch Coverage | Complexity | ||||
| NexusSearch |
|
| 5.0;5 |
| 1 | /* | |
| 2 | * This file is part of dependency-check-core. | |
| 3 | * | |
| 4 | * Dependency-check-core is free software: you can redistribute it and/or modify it | |
| 5 | * under the terms of the GNU General Public License as published by the Free | |
| 6 | * Software Foundation, either version 3 of the License, or (at your option) any | |
| 7 | * later version. | |
| 8 | * | |
| 9 | * Dependency-check-core is distributed in the hope that it will be useful, but | |
| 10 | * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
| 11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more | |
| 12 | * details. | |
| 13 | * | |
| 14 | * You should have received a copy of the GNU General Public License along with | |
| 15 | * dependency-check-core. If not, see http://www.gnu.org/licenses/. | |
| 16 | * | |
| 17 | * Copyright (c) 2012 Jeremy Long. All Rights Reserved. | |
| 18 | */ | |
| 19 | package org.owasp.dependencycheck.data.nexus; | |
| 20 | ||
| 21 | import java.io.FileNotFoundException; | |
| 22 | import java.io.IOException; | |
| 23 | import java.net.URL; | |
| 24 | import java.net.URLConnection; | |
| 25 | import java.util.logging.Logger; | |
| 26 | import javax.xml.parsers.DocumentBuilder; | |
| 27 | import javax.xml.parsers.DocumentBuilderFactory; | |
| 28 | import javax.xml.xpath.XPath; | |
| 29 | import javax.xml.xpath.XPathFactory; | |
| 30 | import org.w3c.dom.Document; | |
| 31 | ||
| 32 | /** | |
| 33 | * Class of methods to search Nexus repositories. | |
| 34 | * | |
| 35 | * @author colezlaw | |
| 36 | */ | |
| 37 | public class NexusSearch { | |
| 38 | /** | |
| 39 | * The root URL for the Nexus repository service | |
| 40 | */ | |
| 41 | private final URL rootURL; | |
| 42 | ||
| 43 | /** | |
| 44 | * Used for logging. | |
| 45 | */ | |
| 46 | 1 | private static final Logger LOGGER = Logger.getLogger(NexusSearch.class.getName()); |
| 47 | ||
| 48 | /** | |
| 49 | * Creates a NexusSearch for the given repository URL. | |
| 50 | * | |
| 51 | * @param rootURL the root URL of the repository on which searches should execute. | |
| 52 | * full URL's are calculated relative to this URL, so it should end with a / | |
| 53 | */ | |
| 54 | 2 | public NexusSearch(URL rootURL) { |
| 55 | 2 | this.rootURL = rootURL; |
| 56 | 2 | } |
| 57 | ||
| 58 | /** | |
| 59 | * Searches the configured Nexus repository for the given sha1 | |
| 60 | * hash. If the artifact is found, a <code>MavenArtifact</code> is populated | |
| 61 | * with the coordinate information. | |
| 62 | * | |
| 63 | * @param sha1 The SHA-1 hash string for which to search | |
| 64 | * @return the populated Maven coordinates | |
| 65 | * @throws IOException if it's unable to connect to the specified repositor or | |
| 66 | * if the specified artifact is not found. | |
| 67 | */ | |
| 68 | public MavenArtifact searchSha1(String sha1) throws IOException { | |
| 69 | 2 | if (null == sha1 || !sha1.matches("^[0-9A-Fa-f]{40}$")) { |
| 70 | 2 | throw new IllegalArgumentException("Invalid SHA1 format"); |
| 71 | } | |
| 72 | ||
| 73 | 0 | final URL url = new URL(rootURL, String.format("identify/sha1/%s", sha1.toLowerCase())); |
| 74 | ||
| 75 | 0 | LOGGER.fine(String.format("Searching Nexus url %s", url.toString())); |
| 76 | ||
| 77 | 0 | final URLConnection conn = url.openConnection(); |
| 78 | 0 | conn.setDoOutput(true); |
| 79 | ||
| 80 | // JSON would be more elegant, but there's not currently a dependency | |
| 81 | // on JSON, so don't want to add one just for this | |
| 82 | 0 | conn.addRequestProperty("Accept", "application/xml"); |
| 83 | 0 | conn.connect(); |
| 84 | ||
| 85 | try { | |
| 86 | 0 | final DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder(); |
| 87 | 0 | final Document doc = builder.parse(conn.getInputStream()); |
| 88 | 0 | final XPath xpath = XPathFactory.newInstance().newXPath(); |
| 89 | 0 | final String groupId = xpath.evaluate("/org.sonatype.nexus.rest.model.NexusArtifact/groupId", doc); |
| 90 | 0 | final String artifactId = xpath.evaluate("/org.sonatype.nexus.rest.model.NexusArtifact/artifactId", doc); |
| 91 | 0 | final String version = xpath.evaluate("/org.sonatype.nexus.rest.model.NexusArtifact/version", doc); |
| 92 | 0 | final String link = xpath.evaluate("/org.sonatype.nexus.rest.model.NexusArtifact/artifactLink", doc); |
| 93 | 0 | return new MavenArtifact(groupId, artifactId, version, link); |
| 94 | 0 | } catch (FileNotFoundException fnfe) { |
| 95 | // This is what we get when the SHA1 they sent doesn't exist in Nexus. This | |
| 96 | // is useful upstream for recovery, so we just re-throw it | |
| 97 | 0 | throw fnfe; |
| 98 | 0 | } catch (Exception e) { |
| 99 | // Anything else is jacked-up XML stuff that we really can't recover from well | |
| 100 | 0 | throw new IOException(e.getMessage(), e); |
| 101 | } | |
| 102 | } | |
| 103 | } | |
| 104 | ||
| 105 | // vim: cc=120:sw=4:ts=4:sts=4 |