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