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

org.mule.maven.client.internal.AetherResolutionContext Maven / Gradle / Ivy

/*
 * Copyright (c) MuleSoft, Inc.  All rights reserved.  http://www.mulesoft.com
 * The software in this package is published under the terms of the CPAL v1.0
 * license, a copy of which has been included with this distribution in the
 * LICENSE.txt file.
 */
package org.mule.maven.client.internal;

import static com.google.common.collect.Lists.newArrayList;
import static java.lang.String.format;
import static java.lang.String.join;
import static java.lang.System.getProperties;
import static java.util.Optional.empty;
import static java.util.Optional.of;
import static java.util.Optional.ofNullable;
import static java.util.stream.Collectors.toList;
import static org.eclipse.aether.repository.RepositoryPolicy.CHECKSUM_POLICY_FAIL;
import static org.eclipse.aether.repository.RepositoryPolicy.CHECKSUM_POLICY_IGNORE;
import static org.eclipse.aether.repository.RepositoryPolicy.UPDATE_POLICY_NEVER;
import static org.mule.maven.client.internal.util.MavenModelUtils.getModelProblemCollector;
import static org.mule.maven.client.internal.util.MavenModelUtils.getProfileActivationContext;
import static org.mule.maven.client.internal.util.MavenModelUtils.getProfileSelector;
import static org.slf4j.LoggerFactory.getLogger;
import org.mule.maven.client.api.BadMavenConfigurationException;
import org.mule.maven.client.api.model.Authentication;
import org.mule.maven.client.api.model.MavenConfiguration;
import org.mule.maven.client.internal.util.MavenModelUtils;

import com.google.common.collect.ImmutableList;

import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;

import org.apache.maven.settings.Activation;
import org.apache.maven.settings.Profile;
import org.apache.maven.settings.Repository;
import org.apache.maven.settings.Settings;
import org.apache.maven.settings.building.DefaultSettingsBuilder;
import org.apache.maven.settings.building.DefaultSettingsBuilderFactory;
import org.apache.maven.settings.building.DefaultSettingsBuildingRequest;
import org.apache.maven.settings.building.SettingsBuildingException;
import org.apache.maven.settings.building.SettingsBuildingRequest;
import org.apache.maven.settings.building.SettingsBuildingResult;
import org.eclipse.aether.repository.AuthenticationSelector;
import org.eclipse.aether.repository.MirrorSelector;
import org.eclipse.aether.repository.Proxy;
import org.eclipse.aether.repository.ProxySelector;
import org.eclipse.aether.repository.RemoteRepository;
import org.eclipse.aether.repository.RepositoryPolicy;
import org.eclipse.aether.util.repository.AuthenticationBuilder;
import org.eclipse.aether.util.repository.DefaultAuthenticationSelector;
import org.eclipse.aether.util.repository.DefaultMirrorSelector;
import org.eclipse.aether.util.repository.DefaultProxySelector;
import org.slf4j.Logger;

/**
 * Represents the context for resolving artifacts using Aether.
 */
public class AetherResolutionContext {

  private static final Logger LOGGER = getLogger(AetherResolutionContext.class);

  private List remoteRepositories = new ArrayList<>();
  private File localRepositoryLocation;
  private Optional authenticationSelector = empty();
  private Optional proxySelector = empty();
  private Optional mirrorSelector = empty();

  public AetherResolutionContext(MavenConfiguration mavenConfiguration) {
    resolveMavenConfiguration(mavenConfiguration);
  }

  public File getLocalRepositoryLocation() {
    return localRepositoryLocation;
  }

  public List getRemoteRepositories() {
    return newArrayList(remoteRepositories);
  }

  private void resolveMavenConfiguration(MavenConfiguration mavenConfiguration) {
    localRepositoryLocation = mavenConfiguration.getLocalMavenRepositoryLocation();

    Optional mavenSettingsOptional =
        getMavenSettings(mavenConfiguration.getUserSettingsLocation(), mavenConfiguration.getGlobalSettingsLocation());
    mavenSettingsOptional.ifPresent(mavenSettings -> {
      createAuthenticatorSelector(mavenConfiguration, mavenSettings);
      createProxySelector(mavenSettings);
      createMirrorSelector(mavenSettings);
    });

    remoteRepositories =
        collectRepositoriesFromConfiguration(mavenConfiguration, authenticationSelector, proxySelector, mirrorSelector);

    mavenSettingsOptional.ifPresent(mavenSettings -> {
      LOGGER.debug("Configuring optional Maven settings...");
      addRepositoriesFromMavenConfig(mavenConfiguration, mavenSettings, authenticationSelector, proxySelector,
                                     mirrorSelector);

      String localRepository = mavenSettings.getLocalRepository();
      if (localRepositoryLocation == null && localRepository != null) {
        File localRepositoryFile = new File(localRepository);
        if (!localRepositoryFile.isDirectory() || !localRepositoryFile.exists()) {
          throw new BadMavenConfigurationException(format(
                                                          "Local repository location %s resolved from maven settings file does not exists or is not a directory",
                                                          localRepository));
        }
        localRepositoryLocation = localRepositoryFile;
      }
    });

    if (LOGGER.isDebugEnabled()) {
      LOGGER.debug("Using {}", toString());
    }
  }

  private List collectRepositoriesFromConfiguration(MavenConfiguration mavenConfiguration,
                                                                      Optional authenticationSelectorOptional,
                                                                      Optional proxySelectorOptional,
                                                                      Optional mirrorSelector) {
    ImmutableList.Builder collectedRepositories = ImmutableList.builder();
    List clientConfiguredRepositories =
        mavenConfiguration.getMavenRemoteRepositories();
    clientConfiguredRepositories.stream().forEachOrdered(remoteRepoConfig -> {
      RemoteRepository.Builder aetherRepoBuilder =
          new RemoteRepository.Builder(remoteRepoConfig.getId(), "default", remoteRepoConfig.getUrl().toString());
      if (remoteRepoConfig.getAuthentication().isPresent()) {
        Authentication authentication = remoteRepoConfig.getAuthentication().get();
        aetherRepoBuilder.setAuthentication(new AuthenticationBuilder().addUsername(authentication.getUsername())
            .addPassword(authentication.getPassword()).build());
      }
      aetherRepoBuilder = processRemoteRepository(mavenConfiguration, authenticationSelectorOptional, proxySelectorOptional,
                                                  mirrorSelector, aetherRepoBuilder);
      if (mavenConfiguration.getForcePolicyUpdateNever()) {
        aetherRepoBuilder.setSnapshotPolicy(new RepositoryPolicy(true, UPDATE_POLICY_NEVER, CHECKSUM_POLICY_IGNORE));
        aetherRepoBuilder.setReleasePolicy(new RepositoryPolicy(true, UPDATE_POLICY_NEVER, CHECKSUM_POLICY_FAIL));
      }
      collectedRepositories.add(aetherRepoBuilder.build());
    });
    return collectedRepositories.build();
  }

  private RemoteRepository.Builder selectAuthenticator(RemoteRepository.Builder aetherRepoBuilder,
                                                       Optional authenticationSelectorOptional) {
    if (authenticationSelectorOptional.isPresent()) {
      RemoteRepository prototypeRepository = aetherRepoBuilder.build();
      org.eclipse.aether.repository.Authentication authentication =
          authenticationSelectorOptional.get().getAuthentication(prototypeRepository);
      if (authentication != null) {
        aetherRepoBuilder = new RemoteRepository.Builder(prototypeRepository);
        aetherRepoBuilder.setAuthentication(authentication);
      }
    }
    return aetherRepoBuilder;
  }

  private void addRepositoriesFromMavenConfig(MavenConfiguration mavenConfiguration, Settings mavenSettings,
                                              Optional authenticationSelectorOptional,
                                              Optional proxySelectorOptional,
                                              Optional mirrorSelectorOptional) {

    List profiles =
        mavenSettings.getProfiles().stream().map(MavenModelUtils::toModelProfile).collect(toList());

    List activeProfiles =
        getProfileSelector().getActiveProfiles(profiles, getProfileActivationContext(mavenSettings), getModelProblemCollector())
            .stream().map(profile -> profile.getId()).collect(toList());

    ImmutableList.Builder remoteRepositoriesFromSettings = ImmutableList.builder();
    for (String profileName : mavenSettings.getProfilesAsMap().keySet()) {
      Profile profile = mavenSettings.getProfilesAsMap().get(profileName);
      if (mavenSettings.getActiveProfiles().contains(profileName)
          || ofNullable(profile.getActivation()).map(Activation::isActiveByDefault).orElse(true)
          || activeProfiles.contains(profileName)) {
        List repositories = profile.getRepositories();
        for (Repository repo : repositories) {
          RemoteRepository.Builder remoteRepo = new RemoteRepository.Builder(repo.getId(), "default", repo.getUrl());
          remoteRepo = processRemoteRepository(mavenConfiguration, authenticationSelectorOptional, proxySelectorOptional,
                                               mirrorSelectorOptional, remoteRepo);
          if (mavenConfiguration.getForcePolicyUpdateNever()) {
            remoteRepo.setSnapshotPolicy(new RepositoryPolicy(true, UPDATE_POLICY_NEVER, CHECKSUM_POLICY_IGNORE));
            remoteRepo.setReleasePolicy(new RepositoryPolicy(true, UPDATE_POLICY_NEVER, CHECKSUM_POLICY_FAIL));
          } else {
            if (repo.getSnapshots() != null) {
              remoteRepo
                  .setSnapshotPolicy(new RepositoryPolicy(repo.getSnapshots().isEnabled(),
                                                          repo.getSnapshots().getUpdatePolicy(),
                                                          repo.getSnapshots().getChecksumPolicy()));

            }
            if (repo.getReleases() != null) {
              remoteRepo
                  .setReleasePolicy(new RepositoryPolicy(repo.getReleases().isEnabled(), repo.getReleases().getUpdatePolicy(),
                                                         repo.getReleases().getChecksumPolicy()));
            }
          }
          remoteRepositoriesFromSettings.add(remoteRepo.build());
        }
      }
    }
    remoteRepositories = new RemoteRepositoriesMerger().merge(remoteRepositories, remoteRepositoriesFromSettings.build());
  }

  private RemoteRepository.Builder processRemoteRepository(MavenConfiguration mavenConfiguration,
                                                           Optional authenticationSelectorOptional,
                                                           Optional proxySelectorOptional,
                                                           Optional mirrorSelectorOptional,
                                                           RemoteRepository.Builder aetherRepoBuilder) {
    aetherRepoBuilder = selectAuthenticator(aetherRepoBuilder, authenticationSelectorOptional);

    if (proxySelectorOptional.isPresent()) {
      RemoteRepository prototypeRepository = aetherRepoBuilder.build();
      Proxy proxy = proxySelectorOptional.get().getProxy(prototypeRepository);
      if (proxy != null) {
        aetherRepoBuilder = new RemoteRepository.Builder(prototypeRepository);
        aetherRepoBuilder.setProxy(proxy);
      }
    }
    if (mirrorSelectorOptional.isPresent()) {
      RemoteRepository prototypeRepository = aetherRepoBuilder.build();
      RemoteRepository mirror = mirrorSelectorOptional.get().getMirror(prototypeRepository);
      if (mirror != null) {
        aetherRepoBuilder = new RemoteRepository.Builder(mirror);
        aetherRepoBuilder = selectAuthenticator(aetherRepoBuilder, authenticationSelectorOptional);
      }
    }

    if (mavenConfiguration.getForcePolicyUpdateNever()) {
      aetherRepoBuilder.setSnapshotPolicy(new RepositoryPolicy(true, UPDATE_POLICY_NEVER, CHECKSUM_POLICY_IGNORE));
      aetherRepoBuilder.setReleasePolicy(new RepositoryPolicy(true, UPDATE_POLICY_NEVER, CHECKSUM_POLICY_FAIL));
    }
    return aetherRepoBuilder;
  }

  private void createAuthenticatorSelector(MavenConfiguration mavenConfiguration, Settings mavenSettings) {
    DefaultAuthenticationSelector defaultAuthenticationSelector = new DefaultAuthenticationSelector();
    mavenSettings.getServers().stream()
        .forEach(server -> defaultAuthenticationSelector.add(server.getId(), new AuthenticationBuilder()
            .addUsername(server.getUsername())
            .addPassword(server.getPassword())
            .addPrivateKey(server.getPrivateKey(), server.getPassphrase())
            .build()));

    // In addition to the serverIds defined on settings file we do append the ones from remote repositories declared
    // through the MavenConfiguration API
    mavenConfiguration.getMavenRemoteRepositories().stream()
        .filter(remoteRepository -> remoteRepository.getAuthentication().isPresent())
        .forEach(remoteRepository -> defaultAuthenticationSelector.add(remoteRepository.getId(), new AuthenticationBuilder()
            .addUsername(remoteRepository.getAuthentication().get().getUsername())
            .addPassword(remoteRepository.getAuthentication().get().getPassword())
            .build()));

    this.authenticationSelector = of(defaultAuthenticationSelector);
  }

  private void createProxySelector(Settings mavenSettings) {
    DefaultProxySelector defaultProxySelector = new DefaultProxySelector();
    mavenSettings.getProxies().stream().filter(proxy -> proxy.isActive())
        .forEach(proxy -> defaultProxySelector.add(
                                                   new Proxy(proxy.getProtocol(), proxy.getHost(), proxy.getPort(),
                                                             new AuthenticationBuilder()
                                                                 .addUsername(proxy.getUsername())
                                                                 .addPassword(proxy.getPassword())
                                                                 .build()),
                                                   proxy.getNonProxyHosts()));
    this.proxySelector = of(defaultProxySelector);
  }

  private void createMirrorSelector(Settings mavenSettings) {
    DefaultMirrorSelector defaultMirrorSelector = new DefaultMirrorSelector();
    mavenSettings.getMirrors().stream()
        .forEachOrdered(mirror ->
    // Repository manager flag is set to false
    // Maven does not support specifying it in the settings.xml
    defaultMirrorSelector.add(mirror.getId(), mirror.getUrl(), mirror.getLayout(), false, mirror.getMirrorOf(),
                              mirror.getMirrorOfLayouts()));
    this.mirrorSelector = of(defaultMirrorSelector);
  }

  private Optional getMavenSettings(Optional userSettingsFile, Optional globalSettingsFile) {
    if (!userSettingsFile.isPresent() && !globalSettingsFile.isPresent()) {
      return empty();
    }
    try {
      SettingsBuildingRequest settingsBuildingRequest = new DefaultSettingsBuildingRequest();
      settingsBuildingRequest.setSystemProperties(getProperties());
      userSettingsFile.ifPresent(settingsBuildingRequest::setUserSettingsFile);
      globalSettingsFile.ifPresent(settingsBuildingRequest::setGlobalSettingsFile);

      DefaultSettingsBuilderFactory mvnSettingBuilderFactory = new DefaultSettingsBuilderFactory();
      DefaultSettingsBuilder settingsBuilder = mvnSettingBuilderFactory.newInstance();
      SettingsBuildingResult settingsBuildingResult = settingsBuilder.build(settingsBuildingRequest);

      return of(settingsBuildingResult.getEffectiveSettings());
    } catch (SettingsBuildingException e) {
      throw new RuntimeException(e);
    }
  }

  public Optional getAuthenticatorSelector() {
    return this.authenticationSelector;
  }

  public Optional getProxySelector() {
    return this.proxySelector;
  }

  public Optional getMirrorSelector() {
    return this.mirrorSelector;
  }

  @Override
  public String toString() {
    return "AetherResolutionContext{" +
        "remoteRepositories=" + repositoriesToString() +
        ", localMavenRepositoryLocation=" + localRepositoryLocation.getAbsolutePath() +
        '}';
  }

  private String repositoriesToString() {
    return join(",\n", remoteRepositories.stream().map(RemoteRepository::toString).collect(toList()));
  }

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy