001/**
002 * Copyright (C) 2006-2018 Talend Inc. - www.talend.com
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 * http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016package org.talend.sdk.component.junit.environment;
017
018import static lombok.AccessLevel.PRIVATE;
019
020import java.io.File;
021import java.lang.reflect.Field;
022import java.net.MalformedURLException;
023import java.net.URL;
024import java.util.ArrayList;
025import java.util.List;
026import java.util.concurrent.ConcurrentHashMap;
027import java.util.concurrent.ConcurrentMap;
028import java.util.stream.Stream;
029
030import org.eclipse.aether.repository.RemoteRepository;
031import org.jboss.shrinkwrap.resolver.api.maven.ConfigurableMavenResolverSystem;
032import org.jboss.shrinkwrap.resolver.api.maven.Maven;
033import org.jboss.shrinkwrap.resolver.api.maven.MavenWorkingSession;
034import org.jboss.shrinkwrap.resolver.api.maven.PomEquippedResolveStage;
035import org.jboss.shrinkwrap.resolver.api.maven.ScopeType;
036import org.jboss.shrinkwrap.resolver.api.maven.coordinate.MavenDependency;
037import org.jboss.shrinkwrap.resolver.api.maven.repository.MavenChecksumPolicy;
038import org.jboss.shrinkwrap.resolver.api.maven.repository.MavenRemoteRepositories;
039import org.jboss.shrinkwrap.resolver.api.maven.repository.MavenRemoteRepository;
040import org.jboss.shrinkwrap.resolver.api.maven.repository.MavenUpdatePolicy;
041import org.jboss.shrinkwrap.resolver.api.maven.strategy.AcceptScopesStrategy;
042import org.jboss.shrinkwrap.resolver.api.maven.strategy.MavenResolutionStrategy;
043import org.jboss.shrinkwrap.resolver.impl.maven.PomEquippedResolveStageBaseImpl;
044
045import lombok.NoArgsConstructor;
046
047@NoArgsConstructor(access = PRIVATE)
048public class Dependencies {
049
050    private static final ConcurrentMap<MavenDependency, URL[]> CACHE = new ConcurrentHashMap<>();
051
052    private static final List<MavenRemoteRepository> REPOSITORIES = findRepositories();
053
054    private static List<MavenRemoteRepository> findRepositories() {
055        final List<MavenRemoteRepository> repositories = new ArrayList<>();
056
057        final String repos = System.getProperty("talend.component.junit.maven.repositories");
058        if (repos != null && !repos.isEmpty()) {
059            for (final String repo : repos.split(",")) {
060                final String[] parts = repo.split("::");
061                final MavenRemoteRepository repository = MavenRemoteRepositories.createRemoteRepository(
062                        parts.length == 1 ? "repo_" + parts[0].replace(':', '_').replace('/', '_') : parts[0],
063                        parts.length == 1 ? parts[0] : parts[1], parts.length < 3 ? "default" : parts[2]);
064                repository.setUpdatePolicy(MavenUpdatePolicy.UPDATE_POLICY_DAILY);
065                repository.setChecksumPolicy(MavenChecksumPolicy.CHECKSUM_POLICY_IGNORE);
066                repositories.add(repository);
067            }
068        } else if (!Boolean.getBoolean("talend.component.junit.maven.skipPomReading")) {
069            // try to grab from the root pom the repos - simplifying maven parsing for speed reasons and enough
070            // generally
071            File current = new File(".").getAbsoluteFile();
072            while (new File(current, "pom.xml").exists()) {
073                final File parent = current.getParentFile();
074                if (parent != null && new File(parent, "pom.xml").exists()) {
075                    current = parent;
076                    continue;
077                }
078                break;
079            }
080            final File pom = new File(current, "pom.xml");
081            if (pom.exists()) {
082                final PomEquippedResolveStage localPom = Maven.configureResolver().loadPomFromFile(pom);
083                final MavenWorkingSession mavenWorkingSession =
084                        PomEquippedResolveStageBaseImpl.class.cast(localPom).getMavenWorkingSession();
085                try {
086                    final Field remoteRepositories =
087                            mavenWorkingSession.getClass().getDeclaredField("remoteRepositories");
088                    if (!remoteRepositories.isAccessible()) {
089                        remoteRepositories.setAccessible(true);
090                    }
091                    final List<RemoteRepository> pomRepos =
092                            List.class.cast(remoteRepositories.get(mavenWorkingSession));
093                    if (pomRepos != null && !pomRepos.isEmpty()) {
094                        pomRepos.forEach(r -> {
095                            final MavenRemoteRepository repository =
096                                    MavenRemoteRepositories.createRemoteRepository(r.getId(), r.getUrl(), "default");
097                            repository.setUpdatePolicy(MavenUpdatePolicy.UPDATE_POLICY_DAILY);
098                            repository.setChecksumPolicy(MavenChecksumPolicy.CHECKSUM_POLICY_IGNORE);
099                            repositories.add(repository);
100                        });
101                    }
102                } catch (final Exception e) {
103                    throw new IllegalStateException("Check your shrinkwrap maven version", e);
104                }
105            }
106        }
107        if (!Boolean.getBoolean("talend.component.junit.maven.central.skip")) {
108            final MavenRemoteRepository central = MavenRemoteRepositories.createRemoteRepository("central_test_default",
109                    "https://repo.maven.apache.org/maven2/", "default");
110            central.setChecksumPolicy(MavenChecksumPolicy.CHECKSUM_POLICY_WARN);
111            central.setUpdatePolicy(MavenUpdatePolicy.UPDATE_POLICY_NEVER);
112            repositories.add(central);
113        }
114
115        return repositories;
116    }
117
118    private static final MavenResolutionStrategy STRATEGY =
119            new AcceptScopesStrategy(ScopeType.COMPILE, ScopeType.RUNTIME);
120
121    public static URL[] resolve(final MavenDependency dep) {
122        return CACHE.computeIfAbsent(dep, d -> {
123            final ConfigurableMavenResolverSystem resolver =
124                    Maven.configureResolver().withClassPathResolution(true).workOffline(
125                            Boolean.getBoolean("talend.component.junit.maven.offline"));
126            REPOSITORIES.forEach(resolver::withRemoteRepo);
127            resolver.addDependency(dep);
128            return Stream.of(resolver.resolve().using(STRATEGY).asFile()).distinct().map(f -> {
129                try {
130                    return f.toURI().toURL();
131                } catch (final MalformedURLException e) {
132                    throw new IllegalStateException(e);
133                }
134            }).toArray(URL[]::new);
135        });
136    }
137}