blob: 72e7c15fcd7dd1ecce253d61e86457934b42000a [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2000, 2009 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;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.SortedSet;
import java.util.TreeSet;
import org.eclipse.core.commands.common.EventManager;
import org.eclipse.core.runtime.Assert;
import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.core.runtime.IExtension;
import org.eclipse.core.runtime.IExtensionPoint;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.ISafeRunnable;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.SafeRunner;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.dynamichelpers.ExtensionTracker;
import org.eclipse.core.runtime.dynamichelpers.IExtensionChangeHandler;
import org.eclipse.core.runtime.dynamichelpers.IExtensionTracker;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.jface.util.IPropertyChangeListener;
import org.eclipse.jface.util.PropertyChangeEvent;
import org.eclipse.osgi.util.NLS;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.IElementFactory;
import org.eclipse.ui.IMemento;
import org.eclipse.ui.IPersistableElement;
import org.eclipse.ui.IWorkingSet;
import org.eclipse.ui.IWorkingSetElementAdapter;
import org.eclipse.ui.IWorkingSetManager;
import org.eclipse.ui.IWorkingSetUpdater;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.XMLMemento;
import org.eclipse.ui.dialogs.IWorkingSetEditWizard;
import org.eclipse.ui.dialogs.IWorkingSetNewWizard;
import org.eclipse.ui.dialogs.IWorkingSetPage;
import org.eclipse.ui.dialogs.IWorkingSetSelectionDialog;
import org.eclipse.ui.internal.dialogs.WorkingSetEditWizard;
import org.eclipse.ui.internal.dialogs.WorkingSetNewWizard;
import org.eclipse.ui.internal.dialogs.WorkingSetSelectionDialog;
import org.eclipse.ui.internal.misc.StatusUtil;
import org.eclipse.ui.internal.registry.IWorkbenchRegistryConstants;
import org.eclipse.ui.internal.registry.WorkingSetDescriptor;
import org.eclipse.ui.internal.registry.WorkingSetRegistry;
import org.eclipse.ui.progress.WorkbenchJob;
import org.eclipse.ui.statushandlers.StatusManager;
import org.osgi.framework.Bundle;
import org.osgi.framework.BundleContext;
import org.osgi.framework.BundleEvent;
import org.osgi.framework.BundleListener;
/**
* Abstract implementation of <code>IWorkingSetManager</code>.
*/
public abstract class AbstractWorkingSetManager extends EventManager implements
IWorkingSetManager, BundleListener, IExtensionChangeHandler {
static abstract class WorkingSetRunnable implements ISafeRunnable {
/* (non-Javadoc)
* @see org.eclipse.core.runtime.ISafeRunnable#handleException(java.lang.Throwable)
*/
public void handleException(Throwable exception) {
StatusManager.getManager().handle(
StatusUtil.newStatus(PlatformUI.PLUGIN_ID, exception));
}
}
private SortedSet workingSets = new TreeSet(new Comparator() {
public int compare(Object o1, Object o2) {
// Cast and compare directly
return ((AbstractWorkingSet) o1).getUniqueId().compareTo(
((AbstractWorkingSet) o2).getUniqueId());
}
});
/**
* Size of the list of most recently used working sets.
*/
private static final int MRU_SIZE = 5;
private List recentWorkingSets = new ArrayList();
private BundleContext bundleContext;
private Map/*<String, IWorkingSetUpdater>*/ updaters= new HashMap();
private Map/*<String, IWorkingSetElementAdapter>*/ elementAdapters = new HashMap();
private static final IWorkingSetUpdater NULL_UPDATER= new IWorkingSetUpdater() {
public void add(IWorkingSet workingSet) {
}
public boolean remove(IWorkingSet workingSet) {
return true;
}
public boolean contains(IWorkingSet workingSet) {
return true;
}
public void dispose() {
}
};
private static final IWorkingSetElementAdapter IDENTITY_ADAPTER = new IWorkingSetElementAdapter() {
public IAdaptable[] adaptElements(IWorkingSet ws, IAdaptable[] elements) {
return elements;
}
public void dispose() {
}
};
/**
* Returns the descriptors for the given editable working set ids. If an id
* refers to a missing descriptor, or one that is non-editable, it is
* skipped. If <code>null</code> is passed, all editable descriptors are
* returned.
*
* @param supportedWorkingSetIds
* the ids for the working set descriptors, or <code>null</code>
* for all editable descriptors
* @return the descriptors corresponding to the given editable working set
* ids
*/
private static WorkingSetDescriptor[] getSupportedEditableDescriptors(
String[] supportedWorkingSetIds) {
WorkingSetRegistry registry = WorkbenchPlugin.getDefault()
.getWorkingSetRegistry();
if (supportedWorkingSetIds == null) {
return registry.getNewPageWorkingSetDescriptors();
}
List result = new ArrayList(supportedWorkingSetIds.length);
for (int i = 0; i < supportedWorkingSetIds.length; i++) {
WorkingSetDescriptor desc = registry
.getWorkingSetDescriptor(supportedWorkingSetIds[i]);
if (desc != null && desc.isEditable()) {
result.add(desc);
}
}
return (WorkingSetDescriptor[]) result
.toArray(new WorkingSetDescriptor[result.size()]);
}
protected AbstractWorkingSetManager(BundleContext context) {
bundleContext= context;
bundleContext.addBundleListener(this);
PlatformUI.getWorkbench().getExtensionTracker().registerHandler(this, ExtensionTracker
.createExtensionPointFilter(getExtensionPointFilter()));
}
/**
* Returns the working sets extension point.
*
* @return the working sets extension point
* @since 3.3
*/
private IExtensionPoint getExtensionPointFilter() {
return Platform.getExtensionRegistry().getExtensionPoint(
PlatformUI.PLUGIN_ID,
IWorkbenchRegistryConstants.PL_WORKINGSETS);
}
public void dispose() {
bundleContext.removeBundleListener(this);
for (final Iterator iter= updaters.values().iterator(); iter.hasNext();) {
SafeRunner.run(new WorkingSetRunnable() {
public void run() throws Exception {
((IWorkingSetUpdater) iter.next()).dispose();
}
});
}
for (final Iterator iter= elementAdapters.values().iterator(); iter.hasNext();) {
SafeRunner.run(new WorkingSetRunnable() {
public void run() throws Exception {
((IWorkingSetElementAdapter)iter.next()).dispose();
}
});
}
}
//---- working set creation -----------------------------------------------------
/* (non-Javadoc)
* @see org.eclipse.ui.IWorkingSetManager
*/
public IWorkingSet createWorkingSet(String name, IAdaptable[] elements) {
return new WorkingSet(name, name, elements);
}
public IWorkingSet createAggregateWorkingSet(String name, String label,
IWorkingSet[] components) {
return new AggregateWorkingSet(name, label, components);
}
/*
* (non-Javadoc)
*
* @see org.eclipse.ui.IWorkingSetManager
*/
public IWorkingSet createWorkingSet(IMemento memento) {
return restoreWorkingSet(memento);
}
//---- working set management ---------------------------------------------------
/* (non-Javadoc)
* @see org.eclipse.ui.IWorkingSetManager
*/
public void addWorkingSet(IWorkingSet workingSet) {
IWorkingSet wSet=getWorkingSet(workingSet.getName());
Assert.isTrue(wSet==null,"working set with same name already registered"); //$NON-NLS-1$
internalAddWorkingSet(workingSet);
}
private void internalAddWorkingSet(IWorkingSet workingSet) {
workingSets.add(workingSet);
((AbstractWorkingSet)workingSet).connect(this);
addToUpdater(workingSet);
firePropertyChange(CHANGE_WORKING_SET_ADD, null, workingSet);
}
/* (non-Javadoc)
* @see org.eclipse.ui.IWorkingSetManager
*/
protected boolean internalRemoveWorkingSet(IWorkingSet workingSet) {
boolean workingSetRemoved = workingSets.remove(workingSet);
boolean recentWorkingSetRemoved = recentWorkingSets.remove(workingSet);
if (workingSetRemoved) {
((AbstractWorkingSet)workingSet).disconnect();
removeFromUpdater(workingSet);
firePropertyChange(CHANGE_WORKING_SET_REMOVE, workingSet, null);
}
return workingSetRemoved || recentWorkingSetRemoved;
}
/* (non-Javadoc)
* @see org.eclipse.ui.IWorkingSetManager
*/
public IWorkingSet[] getWorkingSets() {
SortedSet visibleSubset = new TreeSet(WorkingSetComparator
.getInstance());
for (Iterator i = workingSets.iterator(); i.hasNext();) {
IWorkingSet workingSet = (IWorkingSet) i.next();
if (workingSet.isVisible()) {
visibleSubset.add(workingSet);
}
}
return (IWorkingSet[]) visibleSubset.toArray(new IWorkingSet[visibleSubset.size()]);
}
public IWorkingSet[] getAllWorkingSets() {
IWorkingSet[] sets = (IWorkingSet[]) workingSets
.toArray(new IWorkingSet[workingSets.size()]);
Arrays.sort(sets, WorkingSetComparator.getInstance());
return sets;
}
/* (non-Javadoc)
* @see org.eclipse.ui.IWorkingSetManager
*/
public IWorkingSet getWorkingSet(String name) {
if (name == null || workingSets == null) {
return null;
}
Iterator iter = workingSets.iterator();
while (iter.hasNext()) {
IWorkingSet workingSet = (IWorkingSet) iter.next();
if (name.equals(workingSet.getName())) {
return workingSet;
}
}
return null;
}
// ---- recent working set management --------------------------------------
/* (non-Javadoc)
* @see org.eclipse.ui.IWorkingSetManager
*/
public IWorkingSet[] getRecentWorkingSets() {
return (IWorkingSet[]) recentWorkingSets.toArray(new IWorkingSet[recentWorkingSets.size()]);
}
/**
* Adds the specified working set to the list of recently used
* working sets.
*
* @param workingSet working set to added to the list of recently
* used working sets.
*/
protected void internalAddRecentWorkingSet(IWorkingSet workingSet) {
if (!workingSet.isVisible()) {
return;
}
recentWorkingSets.remove(workingSet);
recentWorkingSets.add(0, workingSet);
if (recentWorkingSets.size() > MRU_SIZE) {
recentWorkingSets.remove(MRU_SIZE);
}
}
//---- equals and hash code -----------------------------------------------
/**
* Tests the receiver and the object for equality
*
* @param object object to compare the receiver to
* @return true=the object equals the receiver, it has the same
* working sets. false otherwise
*/
public boolean equals(Object object) {
if (this == object) {
return true;
}
if (!getClass().getName().equals(object.getClass().getName())) {
return false;
}
AbstractWorkingSetManager other= (AbstractWorkingSetManager)object;
return other.workingSets.equals(workingSets);
}
/**
* Returns the hash code.
*
* @return the hash code.
*/
public int hashCode() {
return workingSets.hashCode();
}
//---- property listeners -------------------------------------------------
/* (non-Javadoc)
* @see org.eclipse.ui.IWorkingSetManager
*/
public void addPropertyChangeListener(IPropertyChangeListener listener) {
addListenerObject(listener);
}
/* (non-Javadoc)
* @see org.eclipse.ui.IWorkingSetManager
*/
public void removePropertyChangeListener(IPropertyChangeListener listener) {
removeListenerObject(listener);
}
/**
* Notify property change listeners about a change to the list of
* working sets.
*
* @param changeId one of
* IWorkingSetManager#CHANGE_WORKING_SET_ADD
* IWorkingSetManager#CHANGE_WORKING_SET_REMOVE
* IWorkingSetManager#CHANGE_WORKING_SET_CONTENT_CHANGE
* IWorkingSetManager#CHANGE_WORKING_SET_NAME_CHANGE
* @param oldValue the removed working set or null if a working set
* was added or changed.
* @param newValue the new or changed working set or null if a working
* set was removed.
*/
protected void firePropertyChange(String changeId, Object oldValue,
Object newValue) {
final Object[] listeners = getListeners();
if (listeners.length == 0) {
return;
}
final PropertyChangeEvent event = new PropertyChangeEvent(this,
changeId, oldValue, newValue);
Runnable notifier = new Runnable() {
public void run() {
for (int i = 0; i < listeners.length; i++) {
final IPropertyChangeListener listener = (IPropertyChangeListener) listeners[i];
ISafeRunnable safetyWrapper = new ISafeRunnable() {
public void run() throws Exception {
listener.propertyChange(event);
}
public void handleException(Throwable exception) {
// logged by the runner
}
};
SafeRunner.run(safetyWrapper);
}
}
};
// Notifications are sent on the UI thread.
if (Display.getCurrent() != null) {
notifier.run();
} else {
// Use an asyncExec to avoid deadlocks.
Display.getDefault().asyncExec(notifier);
}
}
/**
* Fires a property change event for the changed working set. Should only be
* called by org.eclipse.ui.internal.WorkingSet.
*
* @param changedWorkingSet
* the working set that has changed
* @param propertyChangeId
* the changed property. one of
* CHANGE_WORKING_SET_CONTENT_CHANGE,
* CHANGE_WORKING_SET_LABEL_CHANGE, and
* CHANGE_WORKING_SET_NAME_CHANGE
* @param oldValue
* the old value
*/
public void workingSetChanged(IWorkingSet changedWorkingSet,
String propertyChangeId, Object oldValue) {
firePropertyChange(propertyChangeId, oldValue, changedWorkingSet);
}
// ---- Persistence
// ----------------------------------------------------------------
/**
* Saves all persistable working sets in the persistence store.
*
* @param memento the persistence store
* @see IPersistableElement
*/
public void saveWorkingSetState(IMemento memento) {
Iterator iterator = workingSets.iterator();
// break the sets into aggregates and non aggregates. The aggregates should be saved after the non-aggregates
// so that on restoration all necessary aggregate components can be found.
ArrayList standardSets = new ArrayList();
ArrayList aggregateSets = new ArrayList();
while (iterator.hasNext()) {
IWorkingSet set = (IWorkingSet) iterator.next();
if (set instanceof AggregateWorkingSet) {
aggregateSets.add(set);
} else {
standardSets.add(set);
}
}
saveWorkingSetState(memento, standardSets);
saveWorkingSetState(memento, aggregateSets);
}
/**
* @param memento the memento to save to
* @param list the working sets to save
* @since 3.2
*/
private void saveWorkingSetState(final IMemento memento, List list) {
for (Iterator i = list.iterator(); i.hasNext();) {
final IPersistableElement persistable = (IWorkingSet) i.next();
SafeRunner.run(new WorkingSetRunnable() {
public void run() throws Exception {
// create a dummy node to write too - the write could fail so we
// shouldn't soil the final memento until we're sure it succeeds.
XMLMemento dummy = XMLMemento.createWriteRoot(IWorkbenchConstants.TAG_WORKING_SET);
dummy.putString(IWorkbenchConstants.TAG_FACTORY_ID,
persistable.getFactoryId());
persistable.saveState(dummy);
// if the dummy was created successfully copy it to the real output
IMemento workingSetMemento = memento
.createChild(IWorkbenchConstants.TAG_WORKING_SET);
workingSetMemento.putMemento(dummy);
}
});
}
}
/**
* Recreates all working sets from the persistence store
* and adds them to the receiver.
*
* @param memento the persistence store
*/
protected void restoreWorkingSetState(IMemento memento) {
IMemento[] children = memento
.getChildren(IWorkbenchConstants.TAG_WORKING_SET);
for (int i = 0; i < children.length; i++) {
IWorkingSet workingSet = restoreWorkingSet(children[i]);
if (workingSet != null) {
internalAddWorkingSet(workingSet);
}
}
}
/**
* Recreates a working set from the persistence store.
*
* @param memento the persistence store
* @return the working set created from the memento or null if
* creation failed.
*/
protected IWorkingSet restoreWorkingSet(final IMemento memento) {
String factoryID = memento
.getString(IWorkbenchConstants.TAG_FACTORY_ID);
if (factoryID == null) {
// if the factory id was not set in the memento
// then assume that the memento was created using
// IMemento.saveState, and should be restored using WorkingSetFactory
factoryID = AbstractWorkingSet.FACTORY_ID;
}
final IElementFactory factory = PlatformUI.getWorkbench().getElementFactory(
factoryID);
if (factory == null) {
WorkbenchPlugin
.log("Unable to restore working set - cannot instantiate factory: " + factoryID); //$NON-NLS-1$
return null;
}
final IAdaptable[] adaptable = new IAdaptable[1];
SafeRunner.run(new WorkingSetRunnable() {
public void run() throws Exception {
adaptable[0] = factory.createElement(memento);
}
});
if (adaptable[0] == null) {
WorkbenchPlugin
.log("Unable to restore working set - cannot instantiate working set: " + factoryID); //$NON-NLS-1$
return null;
}
if ((adaptable[0] instanceof IWorkingSet) == false) {
WorkbenchPlugin
.log("Unable to restore working set - element is not an IWorkingSet: " + factoryID); //$NON-NLS-1$
return null;
}
return (IWorkingSet) adaptable[0];
}
/**
* Saves the list of most recently used working sets in the persistence
* store.
*
* @param memento the persistence store
*/
protected void saveMruList(IMemento memento) {
Iterator iterator = recentWorkingSets.iterator();
while (iterator.hasNext()) {
IWorkingSet workingSet = (IWorkingSet) iterator.next();
IMemento mruMemento = memento
.createChild(IWorkbenchConstants.TAG_MRU_LIST);
mruMemento.putString(IWorkbenchConstants.TAG_NAME, workingSet
.getName());
}
}
/**
* Restores the list of most recently used working sets from the
* persistence store.
*
* @param memento the persistence store
*/
protected void restoreMruList(IMemento memento) {
IMemento[] mruWorkingSets = memento
.getChildren(IWorkbenchConstants.TAG_MRU_LIST);
for (int i = mruWorkingSets.length - 1; i >= 0; i--) {
String workingSetName = mruWorkingSets[i]
.getString(IWorkbenchConstants.TAG_NAME);
if (workingSetName != null) {
IWorkingSet workingSet = getWorkingSet(workingSetName);
if (workingSet != null) {
internalAddRecentWorkingSet(workingSet);
}
}
}
}
//---- user interface support -----------------------------------------------------
/**
* @see org.eclipse.ui.IWorkingSetManager#createWorkingSetEditWizard(org.eclipse.ui.IWorkingSet)
* @since 2.1
*/
public IWorkingSetEditWizard createWorkingSetEditWizard(
IWorkingSet workingSet) {
String editPageId = workingSet.getId();
WorkingSetRegistry registry = WorkbenchPlugin.getDefault()
.getWorkingSetRegistry();
IWorkingSetPage editPage = null;
if (editPageId != null) {
editPage = registry.getWorkingSetPage(editPageId);
}
// the following block kind of defeats IWorkingSet.isEditable() and it
// doesn't make sense for there to be a default page in such a case.
if (editPage == null) {
editPage = registry.getDefaultWorkingSetPage();
if (editPage == null) {
return null;
}
}
WorkingSetEditWizard editWizard = new WorkingSetEditWizard(editPage);
editWizard.setSelection(workingSet);
return editWizard;
}
/**
* @deprecated use createWorkingSetSelectionDialog(parent, true) instead
*/
public IWorkingSetSelectionDialog createWorkingSetSelectionDialog(
Shell parent) {
return createWorkingSetSelectionDialog(parent, true);
}
/* (non-Javadoc)
* @see org.eclipse.ui.IWorkingSetManager
*/
public IWorkingSetSelectionDialog createWorkingSetSelectionDialog(
Shell parent, boolean multi) {
return createWorkingSetSelectionDialog(parent, multi, null);
}
/**
* {@inheritDoc}
*/
public IWorkingSetNewWizard createWorkingSetNewWizard(String[] workingSetIds) {
WorkingSetDescriptor[] descriptors= getSupportedEditableDescriptors(workingSetIds);
if (descriptors.length == 0) {
return null;
}
return new WorkingSetNewWizard(descriptors);
}
//---- working set delta handling -------------------------------------------------
public void bundleChanged(BundleEvent event) {
String symbolicName = event.getBundle().getSymbolicName();
if (symbolicName == null)
return;
// If the workbench isn't running anymore simply return.
if (!PlatformUI.isWorkbenchRunning()) {
return;
}
if (event.getBundle().getState() == Bundle.ACTIVE) {
final WorkingSetDescriptor[] descriptors = WorkbenchPlugin.getDefault()
.getWorkingSetRegistry().getUpdaterDescriptorsForNamespace(
symbolicName);
Job job = new WorkbenchJob(
NLS
.bind(
WorkbenchMessages.AbstractWorkingSetManager_updatersActivating,
symbolicName)) {
public IStatus runInUIThread(IProgressMonitor monitor) {
synchronized (updaters) {
for (int i = 0; i < descriptors.length; i++) {
WorkingSetDescriptor descriptor = descriptors[i];
List workingSets = getWorkingSetsForId(descriptor
.getId());
if (workingSets.size() == 0) {
continue;
}
final IWorkingSetUpdater updater = getUpdater(descriptor);
for (Iterator iter = workingSets.iterator(); iter
.hasNext();) {
final IWorkingSet workingSet = (IWorkingSet) iter
.next();
SafeRunner.run(new WorkingSetRunnable() {
public void run() throws Exception {
if (!updater.contains(workingSet)) {
updater.add(workingSet);
}
}
});
}
}
}
return Status.OK_STATUS;
}
};
job.setSystem(true);
job.schedule();
}
}
private List getWorkingSetsForId(String id) {
List result= new ArrayList();
for (Iterator iter= workingSets.iterator(); iter.hasNext();) {
IWorkingSet ws= (IWorkingSet)iter.next();
if (id.equals(ws.getId())) {
result.add(ws);
}
}
return result;
}
private void addToUpdater(final IWorkingSet workingSet) {
WorkingSetDescriptor descriptor= WorkbenchPlugin.getDefault()
.getWorkingSetRegistry().getWorkingSetDescriptor(workingSet.getId());
if (descriptor == null || !descriptor.isUpdaterClassLoaded()) {
return;
}
synchronized(updaters) {
final IWorkingSetUpdater updater= getUpdater(descriptor);
SafeRunner.run(new WorkingSetRunnable() {
public void run() throws Exception {
if (!updater.contains(workingSet)) {
updater.add(workingSet);
}
}});
}
}
private IWorkingSetUpdater getUpdater(WorkingSetDescriptor descriptor) {
IWorkingSetUpdater updater= (IWorkingSetUpdater)updaters.get(descriptor.getId());
if (updater == null) {
updater= descriptor.createWorkingSetUpdater();
if (updater == null) {
updater= NULL_UPDATER;
} else {
firePropertyChange(CHANGE_WORKING_SET_UPDATER_INSTALLED, null, updater);
PlatformUI.getWorkbench().getExtensionTracker().registerObject(
descriptor.getConfigurationElement()
.getDeclaringExtension(), updater,
IExtensionTracker.REF_WEAK);
}
updaters.put(descriptor.getId(), updater);
}
return updater;
}
IWorkingSetElementAdapter getElementAdapter(WorkingSetDescriptor descriptor) {
IWorkingSetElementAdapter elementAdapter = (IWorkingSetElementAdapter) elementAdapters
.get(descriptor.getId());
if (elementAdapter == null) {
elementAdapter = descriptor.createWorkingSetElementAdapter();
if (elementAdapter == null) {
elementAdapter = IDENTITY_ADAPTER;
} else {
elementAdapters.put(descriptor.getId(), elementAdapter);
}
}
return elementAdapter;
}
private void removeFromUpdater(final IWorkingSet workingSet) {
synchronized (updaters) {
final IWorkingSetUpdater updater = (IWorkingSetUpdater) updaters
.get(workingSet.getId());
if (updater != null) {
SafeRunner.run(new WorkingSetRunnable() {
public void run() throws Exception {
updater.remove(workingSet);
}});
}
}
}
/* (non-Javadoc)
* @see org.eclipse.ui.IWorkingSetManager#createWorkingSetSelectionDialog(org.eclipse.swt.widgets.Shell, boolean, java.lang.String[])
*/
public IWorkingSetSelectionDialog createWorkingSetSelectionDialog(Shell parent, boolean multi, String[] workingsSetIds) {
return new WorkingSetSelectionDialog(parent, multi, workingsSetIds);
}
/**
* Save the state to the state file.
*
* @param stateFile
* @throws IOException
*/
public void saveState(File stateFile) throws IOException {
XMLMemento memento = XMLMemento
.createWriteRoot(IWorkbenchConstants.TAG_WORKING_SET_MANAGER);
saveWorkingSetState(memento);
saveMruList(memento);
FileOutputStream stream = new FileOutputStream(stateFile);
OutputStreamWriter writer = new OutputStreamWriter(stream, "utf-8"); //$NON-NLS-1$
memento.save(writer);
writer.close();
}
/* (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 extension) {
// nothing - this is handled lazily. These items are only created as needed by the getUpdater() and getElementAdapter() methods
}
/* (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++) {
Object object = objects[i];
if (object instanceof IWorkingSetUpdater) {
removeUpdater((IWorkingSetUpdater)object);
}
if (object instanceof IWorkingSetElementAdapter) {
removeElementAdapter((IWorkingSetElementAdapter) object);
}
}
}
/**
* Remove the element adapter from the manager and dispose of it.
*
* @param elementAdapter
* @since 3.3
*/
private void removeElementAdapter(
final IWorkingSetElementAdapter elementAdapter) {
SafeRunner.run(new WorkingSetRunnable() {
public void run() throws Exception {
elementAdapter.dispose();
}
});
synchronized (elementAdapters) {
elementAdapters.values().remove(elementAdapter);
}
}
/**
* Remove the updater from the manager and dispose of it.
*
* @param updater
* @since 3.3
*/
private void removeUpdater(final IWorkingSetUpdater updater) {
SafeRunner.run(new WorkingSetRunnable() {
public void run() throws Exception {
updater.dispose();
}
});
synchronized (updaters) {
updaters.values().remove(updater);
}
firePropertyChange(IWorkingSetManager.CHANGE_WORKING_SET_UPDATER_UNINSTALLED, updater, null);
}
/*
* (non-Javadoc)
*
* @see org.eclipse.ui.IWorkingSetManager#addToWorkingSets(org.eclipse.core.runtime.IAdaptable,
* org.eclipse.ui.IWorkingSet[])
*/
public void addToWorkingSets(final IAdaptable element, IWorkingSet[] workingSets) {
// ideally this method would be in a static util class of some kind but
// we dont have any such beast for working sets and making one for one
// method is overkill.
for (int i = 0; i < workingSets.length; i++) {
final IWorkingSet workingSet = workingSets[i];
SafeRunner.run(new WorkingSetRunnable() {
public void run() throws Exception {
IAdaptable[] adaptedNewElements = workingSet
.adaptElements(new IAdaptable[] { element });
if (adaptedNewElements.length == 1) {
IAdaptable[] elements = workingSet.getElements();
IAdaptable[] newElements = new IAdaptable[elements.length + 1];
System.arraycopy(elements, 0, newElements, 0,
elements.length);
newElements[newElements.length - 1] = adaptedNewElements[0];
workingSet.setElements(newElements);
}
}});
}
}
}