001/**
002 * Copyright (C) 2006-2019 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
062                        .createRemoteRepository(
063                                parts.length == 1 ? "repo_" + parts[0].replace(':', '_').replace('/', '_') : parts[0],
064                                parts.length == 1 ? parts[0] : parts[1], parts.length < 3 ? "default" : parts[2]);
065                repository.setUpdatePolicy(MavenUpdatePolicy.UPDATE_POLICY_DAILY);
066                repository.setChecksumPolicy(MavenChecksumPolicy.CHECKSUM_POLICY_IGNORE);
067                repositories.add(repository);
068            }
069        } else if (!Boolean.getBoolean("talend.component.junit.maven.skipPomReading")) {
070            // try to grab from the root pom the repos - simplifying maven parsing for speed reasons and enough
071            // generally
072            File current = new File(".").getAbsoluteFile();
073            while (new File(current, "pom.xml").exists()) {
074                final File parent = current.getParentFile();
075                if (parent != null && new File(parent, "pom.xml").exists()) {
076                    current = parent;
077                    continue;
078                }
079                break;
080            }
081            final File pom = new File(current, "pom.xml");
082            if (pom.exists()) {
083                final PomEquippedResolveStage localPom = Maven.configureResolver().loadPomFromFile(pom);
084                final MavenWorkingSession mavenWorkingSession =
085                        PomEquippedResolveStageBaseImpl.class.cast(localPom).getMavenWorkingSession();
086                try {
087                    final Field remoteRepositories =
088                            mavenWorkingSession.getClass().getDeclaredField("remoteRepositories");
089                    if (!remoteRepositories.isAccessible()) {
090                        remoteRepositories.setAccessible(true);
091                    }
092                    final List<RemoteRepository> pomRepos =
093                            List.class.cast(remoteRepositories.get(mavenWorkingSession));
094                    if (pomRepos != null && !pomRepos.isEmpty()) {
095                        pomRepos.forEach(r -> {
096                            final MavenRemoteRepository repository =
097                                    MavenRemoteRepositories.createRemoteRepository(r.getId(), r.getUrl(), "default");
098                            repository.setUpdatePolicy(MavenUpdatePolicy.UPDATE_POLICY_DAILY);
099                            repository.setChecksumPolicy(MavenChecksumPolicy.CHECKSUM_POLICY_IGNORE);
100                            repositories.add(repository);
101                        });
102                    }
103                } catch (final Exception e) {
104                    throw new IllegalStateException("Check your shrinkwrap maven version", e);
105                }
106            }
107        }
108        if (!Boolean.getBoolean("talend.component.junit.maven.central.skip")) {
109            final MavenRemoteRepository central = MavenRemoteRepositories
110                    .createRemoteRepository("central_test_default", "https://repo.maven.apache.org/maven2/", "default");
111            central.setChecksumPolicy(MavenChecksumPolicy.CHECKSUM_POLICY_WARN);
112            central.setUpdatePolicy(MavenUpdatePolicy.UPDATE_POLICY_NEVER);
113            repositories.add(central);
114        }
115
116        return repositories;
117    }
118
119    private static final MavenResolutionStrategy STRATEGY =
120            new AcceptScopesStrategy(ScopeType.COMPILE, ScopeType.RUNTIME);
121
122    public static URL[] resolve(final MavenDependency dep) {
123        return CACHE.computeIfAbsent(dep, d -> {
124            final ConfigurableMavenResolverSystem resolver = Maven
125                    .configureResolver()
126                    .withClassPathResolution(true)
127                    .workOffline(Boolean.getBoolean("talend.component.junit.maven.offline"));
128            REPOSITORIES.forEach(resolver::withRemoteRepo);
129            resolver.addDependency(dep);
130            return Stream.of(resolver.resolve().using(STRATEGY).asFile()).distinct().map(f -> {
131                try {
132                    return f.toURI().toURL();
133                } catch (final MalformedURLException e) {
134                    throw new IllegalStateException(e);
135                }
136            }).toArray(URL[]::new);
137        });
138    }
139}