blob: 80bcf70893139399e79cb5389598c838e0ca0a52 [file] [log] [blame]
/*************************************************************************************
* Copyright (c) 2011-2014 Red Hat, Inc. and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Fred Bricon / JBoss by Red Hat - Initial implementation.
************************************************************************************/
package org.eclipse.m2e.profiles.core.internal.management;
import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.osgi.util.NLS;
import org.codehaus.plexus.component.repository.exception.ComponentLookupException;
import org.apache.maven.artifact.Artifact;
import org.apache.maven.artifact.InvalidRepositoryException;
import org.apache.maven.artifact.repository.ArtifactRepository;
import org.apache.maven.model.Model;
import org.apache.maven.model.Parent;
import org.apache.maven.model.Profile;
import org.apache.maven.model.Repository;
import org.apache.maven.project.MavenProject;
import org.apache.maven.repository.RepositorySystem;
import org.apache.maven.settings.Settings;
import org.apache.maven.settings.SettingsUtils;
import org.eclipse.m2e.core.MavenPlugin;
import org.eclipse.m2e.core.embedder.IMaven;
import org.eclipse.m2e.core.internal.MavenPluginActivator;
import org.eclipse.m2e.core.internal.NoSuchComponentException;
import org.eclipse.m2e.core.project.IMavenProjectFacade;
import org.eclipse.m2e.core.project.IProjectConfigurationManager;
import org.eclipse.m2e.core.project.MavenUpdateRequest;
import org.eclipse.m2e.core.project.ResolverConfiguration;
import org.eclipse.m2e.profiles.core.internal.IProfileManager;
import org.eclipse.m2e.profiles.core.internal.MavenProfilesCoreActivator;
import org.eclipse.m2e.profiles.core.internal.ProfileData;
import org.eclipse.m2e.profiles.core.internal.ProfileState;
/**
* Maven Profile Manager
*
* @author Fred Bricon
* @since 1.5.0
*/
public class ProfileManager implements IProfileManager {
public void updateActiveProfiles(final IMavenProjectFacade mavenProjectFacade, final List<String> profiles,
final boolean isOffline, final boolean isForceUpdate, IProgressMonitor monitor) throws CoreException {
if(mavenProjectFacade == null) {
return;
}
final IProjectConfigurationManager configurationManager = MavenPlugin.getProjectConfigurationManager();
IProject project = mavenProjectFacade.getProject();
final ResolverConfiguration configuration = configurationManager.getResolverConfiguration(project);
final String profilesAsString = String.join(", ", profiles);
if(profilesAsString.equals(configuration.getSelectedProfiles())) {
//Nothing changed
return;
}
configuration.setSelectedProfiles(profilesAsString);
boolean isSet = configurationManager.setResolverConfiguration(project, configuration);
if(isSet) {
MavenUpdateRequest request = new MavenUpdateRequest(project, isOffline, isForceUpdate);
configurationManager.updateProjectConfiguration(request, monitor);
}
}
public Map<Profile, Boolean> getAvailableSettingsProfiles() throws CoreException {
Map<Profile, Boolean> settingsProfiles = new LinkedHashMap<>();
Settings settings = MavenPlugin.getMaven().getSettings();
List<String> activeProfiles = settings.getActiveProfiles();
for(org.apache.maven.settings.Profile sp : settings.getProfiles()) {
Profile p = SettingsUtils.convertFromSettingsProfile(sp);
boolean isAutomaticallyActivated = isActive(sp, activeProfiles);
settingsProfiles.put(p, isAutomaticallyActivated);
}
return Collections.unmodifiableMap(settingsProfiles);
}
private boolean isActive(org.apache.maven.settings.Profile p, List<String> activeProfiles) {
if(p.getActivation() != null && p.getActivation().isActiveByDefault()) {
return true;
}
return activeProfiles.stream().anyMatch(ap -> ap.equals(p.getId()));
}
public List<ProfileData> getProfileDatas(IMavenProjectFacade facade, IProgressMonitor monitor) throws CoreException {
if(facade == null) {
return Collections.emptyList();
}
ResolverConfiguration resolverConfiguration = MavenPlugin.getProjectConfigurationManager()
.getResolverConfiguration(facade.getProject());
List<String> configuredProfiles = toList(resolverConfiguration.getSelectedProfiles());
MavenProject mavenProject = facade.getMavenProject(monitor);
List<Model> modelHierarchy = new ArrayList<>();
getModelHierarchy(modelHierarchy, mavenProject.getModel(), monitor);
List<Profile> availableProfiles = collectAvailableProfiles(modelHierarchy, monitor);
final Map<Profile, Boolean> availableSettingsProfiles = getAvailableSettingsProfiles();
availableProfiles.addAll(availableSettingsProfiles.keySet());
List<ProfileData> statuses = new ArrayList<>();
Map<String, List<String>> allActiveProfiles = mavenProject.getInjectedProfileIds();
for(Profile p : availableProfiles) {
String pId = p.getId();
ProfileData status = new ProfileData(pId);
boolean isDisabled = configuredProfiles.contains("!" + pId);
if(isActive(pId, allActiveProfiles)) {
status.setActivationState(ProfileState.Active);
} else if(isDisabled) {
status.setActivationState(ProfileState.Disabled);
}
boolean isUserSelected = isDisabled || configuredProfiles.contains(pId);
status.setUserSelected(isUserSelected);
Boolean isAutoActiveSettingProfile = availableSettingsProfiles.get(p);
boolean isAutoActive = (isAutoActiveSettingProfile != null && isAutoActiveSettingProfile)
|| (status.getActivationState().isActive() && !isUserSelected);
status.setAutoActive(isAutoActive);
status.setSource(findSource(p, modelHierarchy));
statuses.add(status);
}
return Collections.unmodifiableList(statuses);
}
private boolean isActive(String profileId, Map<String, List<String>> profilesMap) {
for(Map.Entry<String, List<String>> entry : profilesMap.entrySet()) {
for(String pId : entry.getValue()) {
if(pId.equals(profileId)) {
return true;
}
}
}
return false;
}
private List<String> toList(String profilesAsText) {
List<String> profiles = new ArrayList<>();
if(profilesAsText != null && profilesAsText.trim().length() > 0) {
profiles.addAll(Arrays.asList(profilesAsText.split("[,\\s\\|]")));
}
return profiles;
}
private String findSource(Profile profile, List<Model> modelHierarchy) {
if(profile != null) {
if("settings.xml".equals(profile.getSource())) { //$NON-NLS-1$
return profile.getSource();
}
for(Model m : modelHierarchy) {
for(Profile p : m.getProfiles()) {
if(p.equals(profile)) {
return m.getArtifactId();
}
}
}
}
return "undefined"; //$NON-NLS-1$
}
protected List<Profile> collectAvailableProfiles(List<Model> models, IProgressMonitor monitor) throws CoreException {
List<Profile> profiles = new ArrayList<Profile>();
for(Model m : models) {
profiles.addAll(m.getProfiles());
}
return profiles;
}
protected List<Model> getModelHierarchy(List<Model> models, Model projectModel, IProgressMonitor monitor)
throws CoreException {
if(projectModel == null) {
return null;
}
models.add(projectModel);
Parent p = projectModel.getParent();
if(p != null) {
IMaven maven = MavenPlugin.getMaven();
List<ArtifactRepository> repositories = new ArrayList<>();
repositories.addAll(getProjectRepositories(projectModel));
repositories.addAll(maven.getArtifactRepositories());
Model parentModel = resolvePomModel(p.getGroupId(), p.getArtifactId(), p.getVersion(), repositories, monitor);
if(parentModel != null) {
getModelHierarchy(models, parentModel, monitor);
}
}
return models;
}
private List<ArtifactRepository> getProjectRepositories(Model projectModel) {
List<ArtifactRepository> repos = new ArrayList<>();
List<Repository> modelRepos = projectModel.getRepositories();
if(modelRepos != null && !modelRepos.isEmpty()) {
RepositorySystem repositorySystem = getRepositorySystem();
for(Repository modelRepo : modelRepos) {
ArtifactRepository ar;
try {
ar = repositorySystem.buildArtifactRepository(modelRepo);
if(ar != null) {
repos.add(ar);
}
} catch(InvalidRepositoryException e) {
MavenProfilesCoreActivator.log(e);
}
}
}
return repos;
}
private RepositorySystem getRepositorySystem() {
try {
//TODO find an alternative way to get the Maven RepositorySystem, or use Aether directly to resolve models??
return MavenPluginActivator.getDefault().getPlexusContainer().lookup(RepositorySystem.class);
} catch(ComponentLookupException e) {
throw new NoSuchComponentException(e);
}
}
private Model resolvePomModel(String groupId, String artifactId, String version,
List<ArtifactRepository> repositories, IProgressMonitor monitor) throws CoreException {
monitor.subTask(NLS.bind("Resolving {0}:{1}:{2}", new Object[] {groupId, artifactId, version}));
IMavenProjectFacade facade = MavenPlugin.getMavenProjectRegistry().getMavenProject(groupId, artifactId, version);
IMaven maven = MavenPlugin.getMaven();
if(facade != null) {
return facade.getMavenProject(monitor).getModel();
}
Artifact artifact = maven.resolve(groupId, artifactId, version, "pom", null, repositories, monitor); //$NON-NLS-1$
File file = artifact.getFile();
if(file == null) {
return null;
}
return maven.readModel(file);
}
}