blob: 9976ba087dd252a6853f70bd0c2ad0baaaec100b [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2010 Tasktop Technologies and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Tasktop Technologies - initial API and implementation
*******************************************************************************/
package org.eclipse.equinox.internal.p2.ui.discovery.repository;
import java.net.URI;
import java.util.*;
import org.eclipse.core.runtime.*;
import org.eclipse.equinox.internal.p2.discovery.AbstractCatalogSource;
import org.eclipse.equinox.internal.p2.discovery.AbstractDiscoveryStrategy;
import org.eclipse.equinox.internal.p2.discovery.model.CatalogCategory;
import org.eclipse.equinox.internal.p2.discovery.model.CatalogItem;
import org.eclipse.equinox.internal.p2.metadata.IRequiredCapability;
import org.eclipse.equinox.internal.p2.metadata.TranslationSupport;
import org.eclipse.equinox.p2.core.ProvisionException;
import org.eclipse.equinox.p2.metadata.IInstallableUnit;
import org.eclipse.equinox.p2.metadata.IRequirement;
import org.eclipse.equinox.p2.operations.ProvisioningSession;
import org.eclipse.equinox.p2.operations.RepositoryTracker;
import org.eclipse.equinox.p2.query.*;
import org.eclipse.equinox.p2.repository.metadata.IMetadataRepository;
import org.eclipse.equinox.p2.repository.metadata.IMetadataRepositoryManager;
import org.eclipse.equinox.p2.ui.ProvisioningUI;
/**
* @author Steffen Pingel
*/
public class RepositoryDiscoveryStrategy extends AbstractDiscoveryStrategy {
private static final String IU_PROPERTY_CATEGORY = "org.eclipse.equinox.p2.type.category"; //$NON-NLS-1$
private static final String PLUGIN_ID = "org.eclipse.equinox.p2.discovery.repository"; //$NON-NLS-1$
private final List<URI> locations;
private final Map<IMetadataRepository, RepositorySource> sourceByRepository;
private final Map<String, CatalogCategory> categoryById;
private final Map<String, CatalogItem> catalogItemById;
public RepositoryDiscoveryStrategy() {
this.locations = new ArrayList<URI>();
this.sourceByRepository = new HashMap<IMetadataRepository, RepositorySource>();
this.categoryById = new HashMap<String, CatalogCategory>();
this.catalogItemById = new HashMap<String, CatalogItem>();
}
public void addLocation(URI location) {
locations.add(location);
}
public void removeLocation(URI location) {
locations.remove(location);
}
@Override
public void performDiscovery(IProgressMonitor progressMonitor) throws CoreException {
// ignore
SubMonitor monitor = SubMonitor.convert(progressMonitor);
monitor.setWorkRemaining(100);
try {
List<IMetadataRepository> repositories = addRepositories(monitor.newChild(50));
queryInstallableUnits(monitor.newChild(50), repositories);
connectCategories();
} catch (ProvisionException e) {
throw new CoreException(new Status(IStatus.ERROR, PLUGIN_ID, "Failed to process repository contents", e)); //$NON-NLS-1$
}
}
@SuppressWarnings("restriction")
private void connectCategories() {
for (CatalogCategory category : categories) {
if (category.getData() instanceof IInstallableUnit) {
IInstallableUnit categoryIU = (IInstallableUnit) category.getData();
Collection<IRequirement> required = categoryIU.getRequirements();
for (IRequirement requirement : required) {
if (requirement instanceof IRequiredCapability) {
IRequiredCapability capability = (IRequiredCapability) requirement;
CatalogItem item = catalogItemById.get(capability.getName());
if (item != null) {
item.setCategoryId(category.getId());
}
}
}
}
}
}
private List<IMetadataRepository> addRepositories(SubMonitor monitor) throws ProvisionException {
ProvisioningSession session = ProvisioningUI.getDefaultUI().getSession();
monitor.setWorkRemaining(locations.size());
RepositoryTracker repositoryTracker = ProvisioningUI.getDefaultUI().getRepositoryTracker();
for (URI location : locations) {
repositoryTracker.addRepository(location, null, session);
monitor.worked(1);
}
// fetch meta-data for these repositories
ArrayList<IMetadataRepository> repositories = new ArrayList<IMetadataRepository>();
IMetadataRepositoryManager manager = (IMetadataRepositoryManager) session.getProvisioningAgent().getService(IMetadataRepositoryManager.SERVICE_NAME);
for (URI uri : locations) {
IMetadataRepository repository = manager.loadRepository(uri, monitor.newChild(1));
repositories.add(repository);
}
return repositories;
}
private void checkCancelled(IProgressMonitor monitor) {
if (monitor.isCanceled()) {
throw new OperationCanceledException();
}
}
private void queryInstallableUnits(SubMonitor monitor, List<IMetadataRepository> repositories) {
monitor.setWorkRemaining(repositories.size());
for (final IMetadataRepository repository : repositories) {
checkCancelled(monitor);
IQuery<IInstallableUnit> query = QueryUtil.createMatchQuery(//
"id ~= /*.feature.group/ " + // //$NON-NLS-1$
"? providedCapabilities.exists(p | p.namespace == 'org.eclipse.equinox.p2.iu' && p.name ~= /*.feature.group/) " + // //$NON-NLS-1$
": properties['org.eclipse.equinox.p2.type.category'] == true"); //$NON-NLS-1$
IQueryResult<IInstallableUnit> result = repository.query(query, monitor.newChild(1));
for (Iterator<IInstallableUnit> iter = result.iterator(); iter.hasNext();) {
process(repository, iter.next());
}
}
}
protected void process(IMetadataRepository repository, IInstallableUnit candidate) {
if (isCategory(candidate)) {
processCategory(repository, candidate);
} else {
processCatalogItem(repository, candidate);
}
}
private CatalogItem processCatalogItem(IMetadataRepository repository, IInstallableUnit candidate) {
CatalogItem item = catalogItemById.get(candidate.getId());
if (item != null) {
return item;
}
item = new CatalogItem();
item.setId(candidate.getId());
item.setDescription(getProperty(candidate, IInstallableUnit.PROP_DESCRIPTION));
item.setName(getProperty(candidate, IInstallableUnit.PROP_NAME));
item.setProvider(getProperty(candidate, IInstallableUnit.PROP_PROVIDER));
item.setSource(getSource(repository));
item.setData(candidate);
item.setSiteUrl(repository.getLocation().toString());
item.getInstallableUnits().add(item.getId());
catalogItemById.put(item.getId(), item);
items.add(item);
return item;
}
public String getProperty(IInstallableUnit candidate, String key) {
String value = TranslationSupport.getInstance().getIUProperty(candidate, key);
return (value != null) ? value : "";
}
private AbstractCatalogSource getSource(IMetadataRepository repository) {
RepositorySource source = sourceByRepository.get(repository);
if (source == null) {
source = new RepositorySource(repository);
sourceByRepository.put(repository, source);
}
return source;
}
private CatalogCategory processCategory(IMetadataRepository repository, IInstallableUnit candidate) {
CatalogCategory category = categoryById.get(candidate.getId());
if (category != null) {
return category;
}
category = new CatalogCategory();
category.setId(candidate.getId());
category.setDescription(getProperty(candidate, IInstallableUnit.PROP_DESCRIPTION));
category.setName(getProperty(candidate, IInstallableUnit.PROP_NAME));
category.setSource(getSource(repository));
category.setData(candidate);
categoryById.put(category.getId(), category);
categories.add(category);
return category;
}
private Boolean isCategory(IInstallableUnit candidate) {
return Boolean.valueOf(candidate.getProperty(IU_PROPERTY_CATEGORY));
}
}