All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.jboss.modules.maven.MavenArtifactUtil Maven / Gradle / Ivy

There is a newer version: 2.1.5.Final
Show newest version
/*
 * JBoss, Home of Professional Open Source.
 * Copyright 2015 Red Hat, Inc., and individual contributors
 * as indicated by the @author tags.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.jboss.modules.maven;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.UndeclaredThrowableException;
import java.net.HttpURLConnection;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.StandardCopyOption;
import java.security.AccessControlContext;
import java.security.AccessController;
import java.security.PrivilegedActionException;
import java.security.PrivilegedExceptionAction;
import java.util.List;
import java.util.jar.JarFile;

import org.jboss.modules.Module;
import org.jboss.modules.ResourceLoader;
import org.jboss.modules.ResourceLoaders;

/**
 * Helper class to resolve a maven artifact.
 *
 * @author Bill Burke
 * @author Tomaz Cerar
 * @author David M. Lloyd
 */
public final class MavenArtifactUtil {

    static final Object artifactLock = new Object();

    /**
     * Try to resolve a Maven JAR artifact.  Calling this method is identical to calling
     * {@code resolveJarArtifact(qualifier, "jar")}.
     *
     * @param coordinates the non-{@code null} Maven coordinates object
     * @return the absolute path to the artifact, or {@code null} if none exists
     * @throws IOException if acquiring the artifact path failed for some reason
     */
    public static File resolveJarArtifact(final ArtifactCoordinates coordinates) throws IOException {
        return resolveArtifact(coordinates, "jar");
    }

    /**
     * Tries to find a maven jar artifact from the system property {@code "maven.repo.local"} This property is a list of
     * platform separated directory names.  If not specified, then it looks in {@code ${user.home}/.m2/repository} by default.
     * 

* If it can't find it in local paths, then will try to download from a remote repository from the system property * {@code "remote.maven.repo"}. There is no default remote repository. It will download both the pom and jar and put it * into the first directory listed in {@code "maven.repo.local"} (or the default directory). This directory will be * created if it doesn't exist. *

* Finally, if you do not want a message to console, then set the system property {@code "maven.download.message"} to * {@code "false"}. * * @param coordinates the non-{@code null} Maven coordinates object * @param packaging a non-{@code null} string with the exact packaging type desired (e.g. {@code pom}, {@code jar}, etc.) * @return the absolute path to the artifact, or {@code null} if none exists * @throws IOException if acquiring the artifact path failed for some reason */ public static File resolveArtifact(final ArtifactCoordinates coordinates, final String packaging) throws IOException { String artifactRelativePath = coordinates.relativeArtifactPath(File.separatorChar); String artifactRelativeHttpPath = coordinates.relativeArtifactPath('/'); final MavenSettings settings = MavenSettings.getSettings(); final Path localRepository = settings.getLocalRepository(); final File localRepositoryFile = localRepository.toFile(); final String pomPath = artifactRelativePath + ".pom"; // serialize artifact lookup because we want to prevent parallel download synchronized (artifactLock) { if ("pom".equals(packaging)) { // ignore classifier Path fp = localRepository.resolve(pomPath); if (Files.exists(fp)) { return fp.toFile(); } List remoteRepos = settings.getRemoteRepositories(); if (remoteRepos.isEmpty()) { return null; } final File pomFile = new File(localRepositoryFile, pomPath); for (String remoteRepository : remoteRepos) { try { String remotePomPath = remoteRepository + artifactRelativeHttpPath + ".pom"; downloadFile(coordinates + ":" + packaging, remotePomPath, pomFile); if (pomFile.exists()) { //download successful return pomFile; } } catch (IOException e) { Module.getModuleLogger().trace(e, "Could not download '%s' from '%s' repository", artifactRelativePath, remoteRepository); // try next one } } } else { final String coordinatesClassifier = coordinates.getClassifier(); String classifier = coordinatesClassifier.isEmpty() ? "" : "-" + coordinatesClassifier; String artifactPath = artifactRelativePath + classifier + "." + packaging; Path fp = localRepository.resolve(artifactPath); if (Files.exists(fp)) { return fp.toFile(); } List remoteRepos = settings.getRemoteRepositories(); if (remoteRepos.isEmpty()) { return null; } final File artifactFile = new File(localRepositoryFile, artifactPath); final File pomFile = new File(localRepositoryFile, pomPath); for (String remoteRepository : remoteRepos) { try { String remotePomPath = remoteRepository + artifactRelativeHttpPath + ".pom"; String remoteArtifactPath = remoteRepository + artifactRelativeHttpPath + classifier + "." + packaging; downloadFile(coordinates + ":pom", remotePomPath, pomFile); if (! pomFile.exists()) { // no POM; skip it continue; } downloadFile(coordinates + ":" + packaging, remoteArtifactPath, artifactFile); if (artifactFile.exists()) { //download successful return artifactFile; } } catch (IOException e) { Module.getModuleLogger().trace(e, "Could not download '%s' from '%s' repository", artifactRelativePath, remoteRepository); // } } } //could not find it in remote Module.getModuleLogger().trace("Could not find in any remote repository"); return null; } } static void downloadFile(String artifact, String src, File dest) throws IOException { if (dest.exists()){ return; } URL url = new URL(src); HttpURLConnection connection = (HttpURLConnection)MavenSettings.getSettings().openConnection(url); boolean message = Boolean.getBoolean("maven.download.message"); int statusCode = connection.getResponseCode(); if (statusCode == HttpURLConnection.HTTP_NOT_FOUND) { return; } if (statusCode == HttpURLConnection.HTTP_MOVED_TEMP || statusCode == HttpURLConnection.HTTP_MOVED_PERM) { src = connection.getHeaderField("Location"); url = new URL(src); connection = (HttpURLConnection) url.openConnection(); } try (InputStream bis = connection.getInputStream()){ dest.getParentFile().mkdirs(); if (message) { System.out.println("Downloading " + artifact); } Files.copy(bis, dest.toPath(), StandardCopyOption.REPLACE_EXISTING); } } /** * A utility method to create a Maven artifact resource loader for the given artifact name. * * @param name the artifact name * @return the resource loader * @throws IOException if the artifact could not be resolved */ public static ResourceLoader createMavenArtifactLoader(final String name) throws IOException { return createMavenArtifactLoader(MavenResolver.createDefaultResolver(), name); } /** * A utility method to create a Maven artifact resource loader for the given artifact name. * * @param mavenResolver the Maven resolver to use (must not be {@code null}) * @param name the artifact name * @return the resource loader * @throws IOException if the artifact could not be resolved */ public static ResourceLoader createMavenArtifactLoader(final MavenResolver mavenResolver, final String name) throws IOException { return createMavenArtifactLoader(mavenResolver, ArtifactCoordinates.fromString(name), name); } /** * A utility method to create a Maven artifact resource loader for the given artifact coordinates. * * @param rootName the resource root name to use (must not be {@code null}) * @param coordinates the artifact coordinates to use (must not be {@code null}) * @param mavenResolver the Maven resolver to use (must not be {@code null}) * @return the resource loader * @throws IOException if the artifact could not be resolved */ public static ResourceLoader createMavenArtifactLoader(final MavenResolver mavenResolver, final ArtifactCoordinates coordinates, final String rootName) throws IOException { File fp = mavenResolver.resolveJarArtifact(coordinates); if (fp == null) return null; JarFile jarFile = JDKSpecific.getJarFile(fp, true); return ResourceLoaders.createJarResourceLoader(rootName, jarFile); } static T doIo(PrivilegedExceptionAction action) throws IOException { try { return AccessController.doPrivileged(action); } catch (PrivilegedActionException e) { try { throw e.getCause(); } catch (IOException | RuntimeException | Error e1) { throw e1; } catch (Throwable t) { throw new UndeclaredThrowableException(t); } } } static T doIo(PrivilegedExceptionAction action, AccessControlContext context) throws IOException { try { return AccessController.doPrivileged(action, context); } catch (PrivilegedActionException e) { try { throw e.getCause(); } catch (IOException | RuntimeException | Error e1) { throw e1; } catch (Throwable t) { throw new UndeclaredThrowableException(t); } } } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy