| /******************************************************************************* |
| * 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)); |
| } |
| |
| } |