blob: 034c0b7d732cb43c4696e43971e7d9aef37ae918 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2000, 2007 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.registry;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.Iterator;
import java.util.List;
import java.util.SortedSet;
import java.util.TreeSet;
import org.eclipse.core.runtime.IConfigurationElement;
import org.eclipse.core.runtime.IExtension;
import org.eclipse.core.runtime.IExtensionPoint;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.dynamichelpers.ExtensionTracker;
import org.eclipse.core.runtime.dynamichelpers.IExtensionChangeHandler;
import org.eclipse.core.runtime.dynamichelpers.IExtensionTracker;
import org.eclipse.ui.IPluginContribution;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.internal.WorkbenchPlugin;
import org.eclipse.ui.internal.util.Util;
import org.eclipse.ui.views.IStickyViewDescriptor;
import org.eclipse.ui.views.IViewCategory;
import org.eclipse.ui.views.IViewDescriptor;
import org.eclipse.ui.views.IViewRegistry;
import com.ibm.icu.text.MessageFormat;
/**
* The central manager for view descriptors.
*/
public class ViewRegistry implements IViewRegistry, IExtensionChangeHandler {
/**
* Proxies a Category implementation.
*
* @since 3.1
*/
private static class ViewCategoryProxy implements IViewCategory, IPluginContribution {
private Category rawCategory;
/**
* Create a new instance of this class
*
* @param rawCategory the category
*/
public ViewCategoryProxy(Category rawCategory) {
this.rawCategory = rawCategory;
}
/* (non-Javadoc)
* @see org.eclipse.ui.views.IViewCategory#getViews()
*/
public IViewDescriptor[] getViews() {
ArrayList elements = rawCategory.getElements();
if (elements == null) {
return new IViewDescriptor[0];
}
return (IViewDescriptor[]) elements
.toArray(
new IViewDescriptor[elements.size()]);
}
/* (non-Javadoc)
* @see org.eclipse.ui.views.IViewCategory#getId()
*/
public String getId() {
return rawCategory.getId();
}
/* (non-Javadoc)
* @see org.eclipse.ui.views.IViewCategory#getPath()
*/
public IPath getPath() {
String rawParentPath = rawCategory.getRawParentPath();
if (rawParentPath == null) {
return new Path(""); //$NON-NLS-1$
}
return new Path(rawParentPath);
}
/* (non-Javadoc)
* @see org.eclipse.ui.views.IViewCategory#getLabel()
*/
public String getLabel() {
return rawCategory.getLabel();
}
/* (non-Javadoc)
* @see org.eclipse.ui.IPluginContribution#getLocalId()
*/
public String getLocalId() {
return getId();
}
/* (non-Javadoc)
* @see org.eclipse.ui.IPluginContribution#getPluginId()
*/
public String getPluginId() {
return rawCategory.getPluginId();
}
/* (non-Javadoc)
* @see java.lang.Object#equals(java.lang.Object)
*/
public boolean equals(Object o) {
if (o instanceof IViewCategory) {
return getId().equals(((IViewCategory)o).getId());
}
return false;
}
/* (non-Javadoc)
* @see java.lang.Object#hashCode()
*/
public int hashCode() {
return getId().hashCode();
}
}
private static String EXTENSIONPOINT_UNIQUE_ID = WorkbenchPlugin.PI_WORKBENCH + "." + IWorkbenchRegistryConstants.PL_VIEWS; //$NON-NLS-1$
/**
* A set that will only ever contain ViewDescriptors.
*/
private SortedSet views = new TreeSet(new Comparator() {
public int compare(Object o1, Object o2) {
String id1 = ((ViewDescriptor) o1).getId();
String id2 = ((ViewDescriptor) o2).getId();
return id1.compareTo(id2);
}});
private List categories;
private List sticky;
private Category miscCategory;
protected static final String TAG_DESCRIPTION = "description"; //$NON-NLS-1$
private ViewRegistryReader reader = new ViewRegistryReader();
private boolean dirtyViewCategoryMappings = true;
/**
* Create a new ViewRegistry.
*/
public ViewRegistry() {
super();
categories = new ArrayList();
sticky = new ArrayList();
PlatformUI.getWorkbench().getExtensionTracker().registerHandler(this, ExtensionTracker.createExtensionPointFilter(getExtensionPointFilter()));
reader.readViews(Platform.getExtensionRegistry(), this);
}
/**
* Add a category to the registry.
*
* @param desc the descriptor to add
*/
public void add(Category desc) {
/* fix for 1877 */
if (internalFindCategory(desc.getId()) == null) {
dirtyViewCategoryMappings = true;
// Mark categories list as dirty
categories.add(desc);
IConfigurationElement element = (IConfigurationElement) Util.getAdapter(desc, IConfigurationElement.class);
if (element == null) {
return;
}
PlatformUI.getWorkbench().getExtensionTracker()
.registerObject(
element.getDeclaringExtension(),
desc,
IExtensionTracker.REF_WEAK);
}
}
/**
* Add a descriptor to the registry.
*
* @param desc the descriptor to add
*/
public void add(ViewDescriptor desc) {
if (views.add(desc)) {
dirtyViewCategoryMappings = true;
PlatformUI.getWorkbench().getExtensionTracker().registerObject(
desc.getConfigurationElement().getDeclaringExtension(),
desc, IExtensionTracker.REF_WEAK);
desc.activateHandler();
}
}
/**
* Add a sticky descriptor to the registry.
*
* @param desc the descriptor to add
*/
public void add(StickyViewDescriptor desc) {
if (!sticky.contains(desc)) {
sticky.add(desc);
PlatformUI.getWorkbench().getExtensionTracker()
.registerObject(
desc.getConfigurationElement().getDeclaringExtension(),
desc,
IExtensionTracker.REF_WEAK);
}
}
// /**
// * Return the sticky view descriptor.
// *
// * @param id the id to searc for
// * @return the sticky view descriptor
// */
// private IStickyViewDescriptor findSticky(String id) {
// for (Iterator i = sticky.iterator(); i.hasNext();) {
// IStickyViewDescriptor desc = (IStickyViewDescriptor) i.next();
// if (id.equals(desc.getId()))
// return desc;
// }
// return null;
// }
/**
* Find a descriptor in the registry.
*/
public IViewDescriptor find(String id) {
Iterator itr = views.iterator();
while (itr.hasNext()) {
IViewDescriptor desc = (IViewDescriptor) itr.next();
if (id.equals(desc.getId())) {
return desc;
}
}
return null;
}
/**
* Find a category with a given name.
*
* @param id the id to search for
* @return the category or <code>null</code>
*/
public IViewCategory findCategory(String id) {
mapViewsToCategories();
Category category = internalFindCategory(id);
if (category == null) {
return null;
}
return new ViewCategoryProxy(category);
}
/**
* Returns the category with no updating of the view/category mappings.
*
* @param id the category id
* @return the Category
* @since 3.1
*/
private Category internalFindCategory(String id) {
Iterator itr = categories.iterator();
while (itr.hasNext()) {
Category cat = (Category) itr.next();
if (id.equals(cat.getRootPath())) {
return cat;
}
}
return null;
}
/**
* Get the list of view categories.
*/
public IViewCategory[] getCategories() {
mapViewsToCategories();
int nSize = categories.size();
IViewCategory[] retArray = new IViewCategory[nSize];
int i = 0;
for (Iterator itr = categories.iterator(); itr.hasNext();) {
retArray[i++] = new ViewCategoryProxy((Category) itr.next());
}
return retArray;
}
/**
* Get the list of sticky views.
*/
public IStickyViewDescriptor[] getStickyViews() {
return (IStickyViewDescriptor[]) sticky
.toArray(new IStickyViewDescriptor[sticky.size()]);
}
/**
* Returns the Misc category. This may be <code>null</code> if there are
* no miscellaneous views.
*
* @return the misc category or <code>null</code>
*/
public Category getMiscCategory() {
return miscCategory;
}
/**
* Get an enumeration of view descriptors.
*/
public IViewDescriptor[] getViews() {
return (IViewDescriptor []) views.toArray(new IViewDescriptor [views.size()]);
}
/**
* Adds each view in the registry to a particular category.
* The view category may be defined in xml. If not, the view is
* added to the "misc" category.
*/
public void mapViewsToCategories() {
if (dirtyViewCategoryMappings) {
dirtyViewCategoryMappings = false;
// clear all category mappings
for (Iterator i = categories.iterator(); i.hasNext(); ) {
Category category = (Category) i.next();
category.clear(); // this is bad
}
if (miscCategory != null) {
miscCategory.clear();
}
for (Iterator i = views.iterator(); i.hasNext(); ) {
IViewDescriptor desc = (IViewDescriptor) i.next();
Category cat = null;
String[] catPath = desc.getCategoryPath();
if (catPath != null) {
String rootCat = catPath[0];
cat = internalFindCategory(rootCat);
}
if (cat != null) {
if (!cat.hasElement(desc)) {
cat.addElement(desc);
}
} else {
if (miscCategory == null) {
miscCategory = new Category();
add(miscCategory);
}
if (catPath != null) {
// If we get here, this view specified a category which
// does not exist. Add this view to the 'Other' category
// but give out a message (to the log only) indicating
// this has been done.
String fmt = "Category {0} not found for view {1}. This view added to ''{2}'' category."; //$NON-NLS-1$
WorkbenchPlugin.log(MessageFormat
.format(fmt, new Object[] { catPath[0],
desc.getId(), miscCategory.getLabel() }));
}
miscCategory.addElement(desc);
}
}
}
}
/**
* Dispose of this registry.
*/
public void dispose() {
PlatformUI.getWorkbench().getExtensionTracker().unregisterHandler(this);
}
/* (non-Javadoc)
* @see org.eclipse.core.runtime.dynamicHelpers.IExtensionChangeHandler#removeExtension(org.eclipse.core.runtime.IExtension, java.lang.Object[])
*/
public void removeExtension(IExtension extension,Object[] objects) {
for (int i = 0; i < objects.length; i++) {
if (objects[i] instanceof StickyViewDescriptor) {
sticky.remove(objects[i]);
}
else if (objects[i] instanceof ViewDescriptor) {
views.remove(objects[i]);
((ViewDescriptor) objects[i]).deactivateHandler();
dirtyViewCategoryMappings = true;
}
else if (objects[i] instanceof Category) {
categories.remove(objects[i]);
dirtyViewCategoryMappings = true;
}
}
}
private IExtensionPoint getExtensionPointFilter() {
return Platform.getExtensionRegistry().getExtensionPoint(EXTENSIONPOINT_UNIQUE_ID);
}
/* (non-Javadoc)
* @see org.eclipse.core.runtime.dynamicHelpers.IExtensionChangeHandler#addExtension(org.eclipse.core.runtime.dynamicHelpers.IExtensionTracker, org.eclipse.core.runtime.IExtension)
*/
public void addExtension(IExtensionTracker tracker,IExtension addedExtension){
IConfigurationElement[] addedElements = addedExtension.getConfigurationElements();
for (int i = 0; i < addedElements.length; i++) {
IConfigurationElement element = addedElements[i];
if (element.getName().equals(IWorkbenchRegistryConstants.TAG_VIEW)) {
reader.readView(element);
} else if (element.getName().equals(IWorkbenchRegistryConstants.TAG_CATEGORY)) {
reader.readCategory(element);
} else if (element.getName().equals(IWorkbenchRegistryConstants.TAG_STICKYVIEW)) {
reader.readSticky(element);
}
}
}
}