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