blob: 32fefad7cf36fc50d56990767ece5d4e43cb0e64 [file] [log] [blame]
/*******************************************************************************
* 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;
}
}