| /******************************************************************************* |
| * Copyright (c) 2000, 2005 IBM Corporation 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: |
| * IBM Corporation - initial API and implementation |
| *******************************************************************************/ |
| package org.eclipse.ui.internal.ide.registry; |
| |
| import java.util.ArrayList; |
| import java.util.HashMap; |
| import java.util.Iterator; |
| |
| import org.eclipse.core.resources.IProject; |
| import org.eclipse.core.resources.IProjectNatureDescriptor; |
| import org.eclipse.core.resources.IWorkspace; |
| import org.eclipse.core.resources.ResourcesPlugin; |
| import org.eclipse.core.runtime.CoreException; |
| import org.eclipse.core.runtime.IAdaptable; |
| import org.eclipse.core.runtime.IStatus; |
| import org.eclipse.core.runtime.Platform; |
| import org.eclipse.ui.internal.ide.Category; |
| import org.eclipse.ui.model.IWorkbenchAdapter; |
| import org.eclipse.ui.model.WorkbenchAdapter; |
| |
| /** |
| * This class represents a registry of project capabilities and categories of |
| * capabilities. |
| */ |
| public class CapabilityRegistry extends WorkbenchAdapter implements IAdaptable { |
| private static final String[] EMPTY_ID_LIST = new String[0]; |
| |
| private static final Capability[] EMPTY_CAP_LIST = new Capability[0]; |
| |
| private HashMap natureToCapability; |
| |
| private ArrayList capabilities; |
| |
| private ArrayList categories; |
| |
| private Category miscCategory; |
| |
| /** |
| * Creates a new instance of <code>CapabilityRegistry</code> |
| */ |
| public CapabilityRegistry() { |
| capabilities = new ArrayList(30); |
| categories = new ArrayList(15); |
| } |
| |
| /** |
| * Adds the given capability to the registry. Called by |
| * the CapabilityRegistryReader. |
| */ |
| /* package */boolean addCapability(Capability capability) { |
| return capabilities.add(capability); |
| } |
| |
| /** |
| * Adds the given capability category to the registry. Called |
| * by the CapabilityRegistryReader. |
| */ |
| /* package */boolean addCategory(Category category) { |
| return categories.add(category); |
| } |
| |
| /** |
| * Finds the capability for the given identifier, or |
| * <code>null</code> if none. |
| */ |
| public Capability findCapability(String id) { |
| Iterator itr = capabilities.iterator(); |
| while (itr.hasNext()) { |
| Capability cap = (Capability) itr.next(); |
| if (id.equals(cap.getId())) { |
| return cap; |
| } |
| } |
| return null; |
| } |
| |
| /** |
| * Finds the category for the given identifier, or |
| * <code>null</code> if none. |
| */ |
| public Category findCategory(String id) { |
| Iterator itr = categories.iterator(); |
| while (itr.hasNext()) { |
| Category cat = (Category) itr.next(); |
| if (id.equals(cat.getRootPath())) { |
| return cat; |
| } |
| } |
| return null; |
| } |
| |
| /** |
| * Finds the capability for each specified identifier. |
| * Any <code>null</code> entries in the resulting array |
| * are for identifiers to which no capability exist. |
| */ |
| public Capability[] findCapabilities(String[] ids) { |
| int count = capabilities.size(); |
| Capability[] results = new Capability[ids.length]; |
| |
| for (int i = 0; i < ids.length; i++) { |
| String id = ids[i]; |
| for (int j = 0; j < count; j++) { |
| Capability cap = (Capability) capabilities.get(j); |
| if (cap.getId().equals(id)) { |
| results[i] = cap; |
| break; |
| } |
| } |
| } |
| |
| return results; |
| } |
| |
| /** |
| * Finds the category for each specified identifier. |
| * Any <code>null</code> entries in the resulting array |
| * are for identifiers to which no category exist. |
| * |
| * @return an array of <code>ICategory</code> |
| */ |
| public Category[] findCategories(String[] ids) { |
| int count = categories.size(); |
| Category[] results = new Category[ids.length]; |
| |
| for (int i = 0; i < ids.length; i++) { |
| String id = ids[i]; |
| for (int j = 0; j < count; j++) { |
| Category cat = (Category) categories.get(j); |
| if (cat.getId().equals(id)) { |
| results[i] = cat; |
| break; |
| } |
| } |
| } |
| |
| return results; |
| } |
| |
| /* (non-Javadoc) |
| * Method declared on IAdaptable. |
| */ |
| public Object getAdapter(Class adapter) { |
| if (adapter == IWorkbenchAdapter.class) |
| return this; |
| else |
| return null; |
| } |
| |
| /** |
| * Returns the list of categories in the registry |
| * which contain at least one capability. Does not |
| * include the misc and unknown categories. |
| */ |
| public ArrayList getUsedCategories() { |
| ArrayList results = new ArrayList(categories.size()); |
| Iterator itr = categories.iterator(); |
| while (itr.hasNext()) { |
| Category cat = (Category) itr.next(); |
| if (cat.hasElements()) |
| results.add(cat); |
| } |
| return results; |
| } |
| |
| /** |
| * Returns the capability for the nature id |
| */ |
| public Capability getCapabilityForNature(String natureId) { |
| return (Capability) natureToCapability.get(natureId); |
| } |
| |
| /** |
| * Returns the list of capabilities in the registry |
| */ |
| public ArrayList getCapabilities() { |
| return capabilities; |
| } |
| |
| /* (non-Javadoc) |
| * Method declared on IWorkbenchAdapter. |
| */ |
| public Object[] getChildren(Object o) { |
| return capabilities.toArray(); |
| } |
| |
| /** |
| * Returns the membership set ids that the specified |
| * capability belongs to. |
| */ |
| public String[] getMembershipSetIds(Capability capability) { |
| IProjectNatureDescriptor desc = capability.getNatureDescriptor(); |
| if (desc == null) |
| return EMPTY_ID_LIST; |
| |
| return desc.getNatureSetIds(); |
| } |
| |
| /** |
| * Returns the miscellaneous category, or <code>null</code> |
| * if none. |
| */ |
| public Category getMiscCategory() { |
| return miscCategory; |
| } |
| |
| /** |
| * Returns the capability ids that are prerequisites |
| * of the specified capability. |
| */ |
| public String[] getPrerequisiteIds(Capability capability) { |
| IProjectNatureDescriptor desc = capability.getNatureDescriptor(); |
| if (desc == null) |
| return EMPTY_ID_LIST; |
| |
| String[] natureIds = desc.getRequiredNatureIds(); |
| if (natureIds.length == 0) |
| return EMPTY_ID_LIST; |
| |
| ArrayList results = new ArrayList(natureIds.length); |
| for (int i = 0; i < natureIds.length; i++) { |
| Capability cap = (Capability) natureToCapability.get(natureIds[i]); |
| if (cap != null) |
| results.add(cap.getId()); |
| } |
| |
| if (results.size() == 0) { |
| return EMPTY_ID_LIST; |
| } else { |
| String[] ids = new String[results.size()]; |
| results.toArray(ids); |
| return ids; |
| } |
| } |
| |
| /** |
| * Returns the capabilities assigned to the specified project |
| */ |
| public Capability[] getProjectCapabilities(IProject project) { |
| try { |
| String[] natureIds = project.getDescription().getNatureIds(); |
| ArrayList results = new ArrayList(natureIds.length); |
| for (int i = 0; i < natureIds.length; i++) { |
| Capability cap = (Capability) natureToCapability |
| .get(natureIds[i]); |
| if (cap == null) { |
| cap = new Capability(natureIds[i]); |
| mapCapability(cap); |
| } |
| results.add(cap); |
| } |
| |
| if (results.size() == 0) { |
| return EMPTY_CAP_LIST; |
| } else { |
| Capability[] caps = new Capability[results.size()]; |
| results.toArray(caps); |
| return caps; |
| } |
| } catch (CoreException e) { |
| return EMPTY_CAP_LIST; |
| } |
| } |
| |
| /** |
| * Returns the capabilities assigned to the specified project |
| * that are consideed disabled by core. |
| */ |
| public Capability[] getProjectDisabledCapabilities(IProject project) { |
| try { |
| String[] natureIds = project.getDescription().getNatureIds(); |
| ArrayList results = new ArrayList(natureIds.length); |
| for (int i = 0; i < natureIds.length; i++) { |
| if (!project.isNatureEnabled(natureIds[i])) { |
| Capability cap = (Capability) natureToCapability |
| .get(natureIds[i]); |
| if (cap == null) { |
| cap = new Capability(natureIds[i]); |
| mapCapability(cap); |
| } |
| results.add(cap); |
| } |
| } |
| |
| if (results.size() == 0) { |
| return EMPTY_CAP_LIST; |
| } else { |
| Capability[] caps = new Capability[results.size()]; |
| results.toArray(caps); |
| return caps; |
| } |
| } catch (CoreException e) { |
| return EMPTY_CAP_LIST; |
| } |
| } |
| |
| /** |
| * Returns whether the registry contains any capabilities. |
| */ |
| public boolean hasCapabilities() { |
| return !capabilities.isEmpty(); |
| } |
| |
| /** |
| * Returns whether the specified capability has any prerequisites. |
| */ |
| public boolean hasPrerequisites(Capability capability) { |
| return getPrerequisiteIds(capability).length > 0; |
| } |
| |
| /** |
| * Loads capabilities and capability categories from the platform's plugin |
| * registry. |
| */ |
| public void load() { |
| CapabilityRegistryReader reader = new CapabilityRegistryReader(); |
| reader.read(Platform.getExtensionRegistry(), this); |
| mapCapabilities(); |
| } |
| |
| /** |
| * Maps each capability in the registry to a particular category. |
| * The category is defined in xml. If the capability's category is |
| * not found, then the capability is added to the "misc" category. |
| * <p> |
| * Maps each capability in the registry to a particular nature |
| * id. |
| */ |
| /* package */void mapCapabilities() { |
| natureToCapability = new HashMap(); |
| |
| Iterator itr = capabilities.iterator(); |
| while (itr.hasNext()) |
| mapCapability((Capability) itr.next()); |
| } |
| |
| private void mapCapability(Capability cap) { |
| // Map to category |
| if (!cap.isValid()) { |
| if (miscCategory == null) |
| miscCategory = new Category(); |
| miscCategory.addElement(cap); |
| } else { |
| Category cat = null; |
| String catPath = cap.getCategoryPath(); |
| if (catPath != null) |
| cat = findCategory(catPath); |
| if (cat != null) { |
| cat.addElement(cap); |
| } else { |
| if (miscCategory == null) |
| miscCategory = new Category(); |
| miscCategory.addElement(cap); |
| } |
| } |
| |
| // Map to nature id |
| natureToCapability.put(cap.getNatureId(), cap); |
| } |
| |
| /** |
| * Removes from the capability collection all capabilities |
| * whose UI is handle by another capability in the collection. |
| * The provided collection must be in proper prerequisite order. |
| * |
| * @param capabilities the capabilities to be pruned |
| * @return a collection of capabilities pruned |
| */ |
| public Capability[] pruneCapabilities(Capability[] capabilities) { |
| ArrayList ids = new ArrayList(capabilities.length); |
| for (int i = 0; i < capabilities.length; i++) |
| ids.add(capabilities[i].getId()); |
| |
| for (int i = 0; i < capabilities.length; i++) { |
| ArrayList handleIds = capabilities[i].getHandleUIs(); |
| if (handleIds != null) |
| ids.removeAll(handleIds); |
| } |
| |
| String[] results = new String[ids.size()]; |
| ids.toArray(results); |
| return findCapabilities(results); |
| } |
| |
| /** |
| * Checks that the collection is valid. If so, the collection is |
| * ordered based on prerequisite. |
| * |
| * @param capabilities the capabilities to be checked and ordered |
| * @return a status object with code <code>IStatus.OK</code> if |
| * the given set of natures is valid, otherwise a status |
| * object indicating what is wrong with the set. Also, the |
| * collection of capabilities specified is ordered based on |
| * prerequisite. |
| */ |
| public IStatus validateCapabilities(Capability[] capabilities) { |
| String natures[] = new String[capabilities.length]; |
| for (int i = 0; i < capabilities.length; i++) |
| natures[i] = capabilities[i].getNatureId(); |
| |
| IWorkspace workspace = ResourcesPlugin.getWorkspace(); |
| IStatus status = workspace.validateNatureSet(natures); |
| if (status.isOK()) { |
| natures = workspace.sortNatureSet(natures); |
| for (int i = 0; i < natures.length; i++) |
| capabilities[i] = (Capability) natureToCapability |
| .get(natures[i]); |
| } |
| |
| return status; |
| } |
| } |