| /******************************************************************************* |
| * Copyright (c) 2008-2010 Sonatype, Inc. |
| * 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: |
| * Sonatype, Inc. - initial API and implementation |
| *******************************************************************************/ |
| |
| package org.eclipse.m2e.core.internal.repository; |
| |
| import java.io.File; |
| import java.io.IOException; |
| import java.net.MalformedURLException; |
| import java.util.ArrayList; |
| import java.util.HashMap; |
| import java.util.List; |
| import java.util.Map; |
| import java.util.concurrent.ConcurrentHashMap; |
| |
| import org.slf4j.Logger; |
| import org.slf4j.LoggerFactory; |
| |
| import org.eclipse.core.runtime.CoreException; |
| import org.eclipse.core.runtime.IProgressMonitor; |
| |
| import org.apache.maven.artifact.repository.ArtifactRepository; |
| import org.apache.maven.settings.Mirror; |
| import org.apache.maven.settings.Server; |
| import org.apache.maven.settings.Settings; |
| import org.apache.maven.wagon.authentication.AuthenticationInfo; |
| |
| import org.eclipse.m2e.core.embedder.ArtifactRepositoryRef; |
| import org.eclipse.m2e.core.embedder.IMaven; |
| import org.eclipse.m2e.core.embedder.ISettingsChangeListener; |
| import org.eclipse.m2e.core.project.IMavenProjectChangedListener; |
| import org.eclipse.m2e.core.project.IMavenProjectFacade; |
| import org.eclipse.m2e.core.project.IMavenProjectRegistry; |
| import org.eclipse.m2e.core.project.MavenProjectChangedEvent; |
| import org.eclipse.m2e.core.repository.IRepository; |
| import org.eclipse.m2e.core.repository.IRepositoryRegistry; |
| |
| |
| /** |
| * RepositoryRegistry |
| * |
| * @author igor |
| */ |
| public class RepositoryRegistry implements IRepositoryRegistry, IMavenProjectChangedListener, ISettingsChangeListener { |
| private static final Logger log = LoggerFactory.getLogger(RepositoryRegistry.class); |
| |
| private final IMaven maven; |
| |
| private final IMavenProjectRegistry projectManager; |
| |
| /** |
| * Maps repositoryUrl to IndexInfo of repository index |
| */ |
| private final Map<String, RepositoryInfo> repositories = new ConcurrentHashMap<String, RepositoryInfo>(); |
| |
| /** |
| * Lazy instantiated local repository instance. |
| */ |
| private RepositoryInfo localRepository; |
| |
| /** |
| * Lock guarding lazy instantiation of localRepository instance |
| */ |
| private final Object localRepositoryLock = new Object(); |
| |
| private final RepositoryInfo workspaceRepository; |
| |
| private ArrayList<IRepositoryIndexer> indexers = new ArrayList<IRepositoryIndexer>(); |
| |
| private ArrayList<IRepositoryDiscoverer> discoverers = new ArrayList<IRepositoryDiscoverer>(); |
| |
| private final RepositoryRegistryUpdateJob job = new RepositoryRegistryUpdateJob(this); |
| |
| public RepositoryRegistry(IMaven maven, IMavenProjectRegistry projectManager) { |
| this.maven = maven; |
| this.projectManager = projectManager; |
| |
| this.workspaceRepository = new RepositoryInfo(null/*id*/, |
| "workspace://"/*url*/, null/*basedir*/, SCOPE_WORKSPACE, null/*auth*/); //$NON-NLS-1$ |
| } |
| |
| private RepositoryInfo newLocalRepositoryInfo() { |
| File localBasedir = new File(maven.getLocalRepositoryPath()); |
| try { |
| localBasedir = localBasedir.getCanonicalFile(); |
| } catch(IOException e) { |
| // will never happen |
| localBasedir = localBasedir.getAbsoluteFile(); |
| } |
| |
| String localUrl; |
| try { |
| localUrl = localBasedir.toURL().toExternalForm(); |
| } catch(MalformedURLException ex) { |
| log.error("Could not parse local repository path", ex); |
| localUrl = "file://" + localBasedir.getAbsolutePath(); //$NON-NLS-1$ |
| } |
| |
| // initialize local and workspace repositories |
| RepositoryInfo localRepository = new RepositoryInfo(null/*id*/, localUrl, localBasedir, SCOPE_LOCAL, null/*auth*/); |
| return localRepository; |
| } |
| |
| public void mavenProjectChanged(MavenProjectChangedEvent[] events, IProgressMonitor monitor) { |
| /* |
| * This method is called while holding workspace lock. Avoid long-running operations if possible. |
| */ |
| |
| Settings settings = null; |
| try { |
| settings = maven.getSettings(); |
| } catch(CoreException ex) { |
| log.error(ex.getMessage(), ex); |
| } |
| |
| for(MavenProjectChangedEvent event : events) { |
| IMavenProjectFacade oldFacade = event.getOldMavenProject(); |
| if(oldFacade != null) { |
| removeProjectRepositories(oldFacade, monitor); |
| } |
| IMavenProjectFacade facade = event.getMavenProject(); |
| if(facade != null) { |
| try { |
| addProjectRepositories(settings, facade, null /*asyncUpdate*/); |
| } catch(CoreException ex) { |
| log.error(ex.getMessage(), ex); |
| } |
| } |
| } |
| } |
| |
| private void addProjectRepositories(Settings settings, IMavenProjectFacade facade, IProgressMonitor monitor) |
| throws CoreException { |
| ArrayList<ArtifactRepositoryRef> repositories = getProjectRepositories(facade); |
| |
| for(ArtifactRepositoryRef repo : repositories) { |
| RepositoryInfo repository = getRepository(repo); |
| if(repository != null) { |
| repository.addProject(facade.getPom().getFullPath()); |
| continue; |
| } |
| AuthenticationInfo auth = getAuthenticationInfo(settings, repo.getId()); |
| repository = new RepositoryInfo(repo.getId(), repo.getUrl(), SCOPE_PROJECT, auth); |
| repository.addProject(facade.getPom().getFullPath()); |
| |
| addRepository(repository, monitor); |
| } |
| } |
| |
| public void addRepository(RepositoryInfo repository, IProgressMonitor monitor) { |
| if(!repositories.containsKey(repository.getUid())) { |
| repositories.put(repository.getUid(), repository); |
| |
| for(IRepositoryIndexer indexer : indexers) { |
| try { |
| indexer.repositoryAdded(repository, monitor); |
| } catch(CoreException e) { |
| log.error(e.getMessage(), e); |
| } |
| } |
| } |
| } |
| |
| private void removeProjectRepositories(IMavenProjectFacade facade, IProgressMonitor monitor) { |
| ArrayList<ArtifactRepositoryRef> repositories = getProjectRepositories(facade); |
| |
| for(ArtifactRepositoryRef repo : repositories) { |
| RepositoryInfo repository = getRepository(repo); |
| if(repository != null && repository.isScope(SCOPE_PROJECT)) { |
| repository.removeProject(facade.getPom().getFullPath()); |
| if(repository.getProjects().isEmpty()) { |
| removeRepository(repository, monitor); |
| } |
| } |
| } |
| } |
| |
| private void removeRepository(RepositoryInfo repository, IProgressMonitor monitor) { |
| repositories.remove(repository.getUid()); |
| |
| for(IRepositoryIndexer indexer : indexers) { |
| try { |
| indexer.repositoryRemoved(repository, monitor); |
| } catch(CoreException e) { |
| log.error(e.getMessage(), e); |
| } |
| } |
| } |
| |
| private ArrayList<ArtifactRepositoryRef> getProjectRepositories(IMavenProjectFacade facade) { |
| ArrayList<ArtifactRepositoryRef> repositories = new ArrayList<ArtifactRepositoryRef>(); |
| repositories.addAll(facade.getArtifactRepositoryRefs()); |
| repositories.addAll(facade.getPluginArtifactRepositoryRefs()); |
| return repositories; |
| } |
| |
| public AuthenticationInfo getAuthenticationInfo(Settings settings, String id) throws CoreException { |
| if(settings == null) { |
| return null; |
| } |
| |
| Server server = settings.getServer(id); |
| if(server == null || server.getUsername() == null) { |
| return null; |
| } |
| |
| server = maven.decryptPassword(server); |
| |
| AuthenticationInfo info = new AuthenticationInfo(); |
| info.setUserName(server.getUsername()); |
| info.setPassword(server.getPassword()); |
| return info; |
| } |
| |
| public void updateRegistry(IProgressMonitor monitor) throws CoreException { |
| Settings settings = maven.getSettings(); |
| List<Mirror> mirrors = maven.getMirrors(); |
| |
| // initialize indexers |
| for(IRepositoryIndexer indexer : indexers) { |
| indexer.initialize(monitor); |
| } |
| |
| // process configured repositories |
| |
| Map<String, RepositoryInfo> oldRepositories = new HashMap<String, RepositoryInfo>(repositories); |
| repositories.clear(); |
| |
| addRepository(this.workspaceRepository, monitor); |
| |
| synchronized(localRepositoryLock) { |
| this.localRepository = newLocalRepositoryInfo(); |
| } |
| addRepository(this.localRepository, monitor); |
| |
| // mirrors |
| for(Mirror mirror : mirrors) { |
| AuthenticationInfo auth = getAuthenticationInfo(settings, mirror.getId()); |
| RepositoryInfo repository = new RepositoryInfo(mirror.getId(), mirror.getUrl(), SCOPE_SETTINGS, auth); |
| repository.setMirrorOf(mirror.getMirrorOf()); |
| addRepository(repository, monitor); |
| } |
| |
| // repositories from settings.xml |
| ArrayList<ArtifactRepository> repos = new ArrayList<ArtifactRepository>(); |
| repos.addAll(maven.getArtifactRepositories(false)); |
| repos.addAll(maven.getPluginArtifactRepositories(false)); |
| |
| for(ArtifactRepository repo : repos) { |
| Mirror mirror = maven.getMirror(repo); |
| AuthenticationInfo auth = getAuthenticationInfo(settings, repo.getId()); |
| RepositoryInfo repository = new RepositoryInfo(repo.getId(), repo.getUrl(), SCOPE_SETTINGS, auth); |
| if(mirror != null) { |
| repository.setMirrorId(mirror.getId()); |
| } |
| addRepository(repository, monitor); |
| } |
| |
| // project-specific repositories |
| for(IMavenProjectFacade facade : projectManager.getProjects()) { |
| addProjectRepositories(settings, facade, monitor); |
| } |
| |
| // custom repositories |
| for(IRepositoryDiscoverer discoverer : discoverers) { |
| discoverer.addRepositories(this, monitor); |
| } |
| |
| oldRepositories.keySet().removeAll(repositories.keySet()); |
| for(RepositoryInfo repository : oldRepositories.values()) { |
| removeRepository(repository, monitor); |
| } |
| } |
| |
| public List<IRepository> getRepositories(int scope) { |
| ArrayList<IRepository> result = new ArrayList<IRepository>(); |
| for(RepositoryInfo repository : repositories.values()) { |
| if(repository.isScope(scope)) { |
| result.add(repository); |
| } |
| } |
| return result; |
| } |
| |
| public void updateRegistry() { |
| job.updateRegistry(); |
| } |
| |
| public void addRepositoryIndexer(IRepositoryIndexer indexer) { |
| this.indexers.add(indexer); |
| } |
| |
| public void addRepositoryDiscoverer(IRepositoryDiscoverer discoverer) { |
| this.discoverers.add(discoverer); |
| } |
| |
| public RepositoryInfo getRepository(ArtifactRepositoryRef ref) { |
| String uid = RepositoryInfo.getUid(ref.getId(), ref.getUrl(), ref.getUsername()); |
| return repositories.get(uid); |
| } |
| |
| public IRepository getWorkspaceRepository() { |
| return workspaceRepository; |
| } |
| |
| public IRepository getLocalRepository() { |
| synchronized(localRepositoryLock) { |
| if(localRepository == null) { |
| localRepository = newLocalRepositoryInfo(); |
| } |
| } |
| |
| return localRepository; |
| } |
| |
| public void settingsChanged(Settings settings) { |
| updateRegistry(); |
| } |
| |
| } |