blob: 22f7f2e2885b68b59a6d40da2dce2e4353e1cce9 [file] [log] [blame]
package org.eclipse.ui.internal;
/*
* (c) Copyright IBM Corp. 2002.
* All Rights Reserved.
*/
import java.io.*;
import java.util.*;
import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.core.runtime.IPath;
import org.eclipse.jface.dialogs.ErrorDialog;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.util.*;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.*;
import org.eclipse.ui.dialogs.*;
import org.eclipse.ui.internal.dialogs.WorkingSetEditWizard;
import org.eclipse.ui.internal.dialogs.WorkingSetSelectionDialog;
import org.eclipse.ui.internal.registry.WorkingSetRegistry;
/**
* A working set manager stores working sets and provides property
* change notification when a working set is added or removed.
* Working sets are persisted whenever one is added or removed.
*
* @see IWorkingSetManager
* @since 2.0
*/
public class WorkingSetManager implements IWorkingSetManager {
// Working set persistence
private static final String WORKING_SET_STATE_FILENAME = "workingsets.xml"; //$NON-NLS-1$
/**
* Size of the list of most recently used working sets.
*/
private static final int MRU_SIZE = 5;
private SortedSet workingSets = new TreeSet(new WorkingSetComparator());
private List recentWorkingSets = new ArrayList();
private ListenerList propertyChangeListeners = new ListenerList();
/**
* Implements IWorkingSetManager.
*
* @see org.eclipse.ui.IWorkingSetManager#addRecentWorkingSet(IWorkingSet)
*/
public void addRecentWorkingSet(IWorkingSet workingSet) {
recentWorkingSets.remove(workingSet);
recentWorkingSets.add(0, workingSet);
if (recentWorkingSets.size() > MRU_SIZE) {
recentWorkingSets.remove(MRU_SIZE);
}
saveState();
}
/**
* Implements IWorkingSetManager.
*
* @see org.eclipse.ui.IWorkingSetManager#addWorkingSet(IWorkingSet)
*/
public void addWorkingSet(IWorkingSet workingSet) {
Assert.isTrue(!workingSets.contains(workingSet), "working set already registered"); //$NON-NLS-1$
workingSets.add(workingSet);
saveState();
firePropertyChange(CHANGE_WORKING_SET_ADD, null, workingSet);
}
/**
* Implements IWorkingSetManager.
*
* @see org.eclipse.ui.IWorkingSetManager#addPropertyChangeListener(IPropertyChangeListener)
*/
public void addPropertyChangeListener(IPropertyChangeListener listener) {
propertyChangeListeners.add(listener);
}
/**
* Implements IWorkingSetManager.
*
* @see org.eclipse.ui.IWorkingSetManager#createWorkingSet(String, IAdaptable[])
*/
public IWorkingSet createWorkingSet(String name, IAdaptable[] elements) {
return new WorkingSet(name, elements);
}
/**
* @see org.eclipse.ui.IWorkingSetManager#createWorkingSetEditWizard(org.eclipse.ui.IWorkingSet)
* @since 2.1
*/
public IWorkingSetEditWizard createWorkingSetEditWizard(IWorkingSet workingSet) {
String editPageId = ((WorkingSet) workingSet).getEditPageId();
WorkingSetRegistry registry = WorkbenchPlugin.getDefault().getWorkingSetRegistry();
IWorkingSetPage editPage = null;
if (editPageId != null) {
editPage = registry.getWorkingSetPage(editPageId);
}
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);
}
/**
* Implements IWorkingSetManager.
*
* @see org.eclipse.ui.IWorkingSetManager#createWorkingSetSelectionDialog(Shell, boolean)
*/
public IWorkingSetSelectionDialog createWorkingSetSelectionDialog(Shell parent, boolean multi) {
return new WorkingSetSelectionDialog(parent, multi);
}
/**
* 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 (object instanceof WorkingSetManager) {
WorkingSetManager workingSetManager = (WorkingSetManager) object;
return workingSetManager.workingSets.equals(workingSets);
}
return false;
}
/**
* 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.
*/
private void firePropertyChange(String changeId, Object oldValue, Object newValue) {
final PropertyChangeEvent event = new PropertyChangeEvent(this, changeId, oldValue, newValue);
Display.getDefault().syncExec(new Runnable() {
public void run() {
Object[] listeners = propertyChangeListeners.getListeners();
for (int i = 0; i < listeners.length; i++) {
((IPropertyChangeListener) listeners[i]).propertyChange(event);
}
}
});
}
/**
* Implements IWorkingSetManager.
*
* @see org.eclipse.ui.IWorkingSetManager#getRecentWorkingSets()
*/
public IWorkingSet[] getRecentWorkingSets() {
return (IWorkingSet[]) recentWorkingSets.toArray(new IWorkingSet[recentWorkingSets.size()]);
}
/**
* Implements IWorkingSetManager.
*
* @see org.eclipse.ui.IWorkingSetManager#getWorkingSet(String)
*/
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;
}
/**
* Returns the hash code.
*
* @return the hash code.
*/
public int hashCode() {
return workingSets.hashCode();
}
/**
* Implements IWorkingSetManager.
*
* @see org.eclipse.ui.IWorkingSetManager#getWorkingSets()
*/
public IWorkingSet[] getWorkingSets() {
return (IWorkingSet[]) workingSets.toArray(new IWorkingSet[workingSets.size()]);
}
/**
* Returns the file used as the persistence store
*
* @return the file used as the persistence store
*/
private File getWorkingSetStateFile() {
IPath path = WorkbenchPlugin.getDefault().getStateLocation();
path = path.append(WORKING_SET_STATE_FILENAME);
return path.toFile();
}
/**
* Implements IWorkingSetManager.
*
* @see org.eclipse.ui.IWorkingSetManager#removePropertyChangeListener(IPropertyChangeListener)
*/
public void removePropertyChangeListener(IPropertyChangeListener listener) {
propertyChangeListeners.remove(listener);
}
/**
* Implements IWorkingSetManager.
*
* @see org.eclipse.ui.IWorkingSetManager#removeWorkingSet(IWorkingSet)
*/
public void removeWorkingSet(IWorkingSet workingSet) {
workingSets.remove(workingSet);
recentWorkingSets.remove(workingSet);
saveState();
firePropertyChange(CHANGE_WORKING_SET_REMOVE, workingSet, null);
}
/**
* Restores the list of most recently used working sets from the
* persistence store.
*
* @param memento the persistence store
*/
private 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) {
addRecentWorkingSet(workingSet);
}
}
}
}
/**
* Reads the persistence store and creates the working sets
* stored in it.
*/
public void restoreState() {
File stateFile = getWorkingSetStateFile();
if (stateFile.exists()) {
try {
FileInputStream input = new FileInputStream(stateFile);
InputStreamReader reader = new InputStreamReader(input, "utf-8"); //$NON-NLS-1$
IMemento memento = XMLMemento.createReadRoot(reader);
restoreWorkingSetState(memento);
restoreMruList(memento);
reader.close();
} catch (IOException e) {
MessageDialog.openError(
(Shell) null,
WorkbenchMessages.getString("ProblemRestoringWorkingSetState.title"), //$NON-NLS-1$
WorkbenchMessages.getString("ProblemRestoringWorkingSetState.message")); //$NON-NLS-1$
} catch (WorkbenchException e) {
ErrorDialog.openError(
(Shell) null,
WorkbenchMessages.getString("ProblemRestoringWorkingSetState.title"),//$NON-NLS-1$
WorkbenchMessages.getString("ProblemRestoringWorkingSetState.message"), //$NON-NLS-1$
e.getStatus());
}
}
}
/**
* 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.
*/
private IWorkingSet restoreWorkingSet(IMemento memento) {
String factoryID = memento.getString(IWorkbenchConstants.TAG_FACTORY_ID);
if (factoryID == null) {
WorkbenchPlugin.log("Unable to restore working set - no factory ID."); //$NON-NLS-1$
return null;
}
IElementFactory factory = WorkbenchPlugin.getDefault().getElementFactory(factoryID);
if (factory == null) {
WorkbenchPlugin.log("Unable to restore working set - cannot instantiate factory: " + factoryID); //$NON-NLS-1$
return null;
}
IAdaptable adaptable = factory.createElement(memento);
if (adaptable == null) {
WorkbenchPlugin.log("Unable to restore working set - cannot instantiate working set: " + factoryID); //$NON-NLS-1$
return null;
}
if ((adaptable instanceof IWorkingSet) == false) {
WorkbenchPlugin.log("Unable to restore working set - element is not an IWorkingSet: " + factoryID); //$NON-NLS-1$
return null;
}
return (IWorkingSet) adaptable;
}
/**
* Recreates all working sets from the persistence store
* and adds them to the receiver.
*
* @param memento the persistence store
*/
private void restoreWorkingSetState(IMemento memento) {
IMemento[] workingSets = memento.getChildren(IWorkbenchConstants.TAG_WORKING_SET);
for (int i = 0; i < workingSets.length; i++) {
IWorkingSet workingSet = restoreWorkingSet(workingSets[i]);
if (workingSet != null) {
addWorkingSet(workingSet);
}
}
}
/**
* Saves the working sets in the persistence store
*/
private void saveState() {
XMLMemento memento = XMLMemento.createWriteRoot(IWorkbenchConstants.TAG_WORKING_SET_MANAGER);
File stateFile = getWorkingSetStateFile();
saveWorkingSetState(memento);
saveMruList(memento);
try {
FileOutputStream stream = new FileOutputStream(stateFile);
OutputStreamWriter writer = new OutputStreamWriter(stream, "utf-8"); //$NON-NLS-1$
memento.save(writer);
writer.close();
} catch (IOException e) {
stateFile.delete();
MessageDialog.openError((Shell) null, WorkbenchMessages.getString("ProblemSavingWorkingSetState.title"), //$NON-NLS-1$
WorkbenchMessages.getString("ProblemSavingWorkingSetState.message")); //$NON-NLS-1$
}
}
/**
* Saves the list of most recently used working sets in the persistence
* store.
*
* @param memento the persistence store
*/
private 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());
}
}
/**
* Saves all persistable working sets in the persistence store.
*
* @param memento the persistence store
* @see IPersistableElement
*/
private void saveWorkingSetState(IMemento memento) {
Iterator iterator = workingSets.iterator();
while (iterator.hasNext()) {
IWorkingSet workingSet = (IWorkingSet) iterator.next();
IPersistableElement persistable = null;
if (workingSet instanceof IPersistableElement) {
persistable = (IPersistableElement) workingSet;
} else if (workingSet instanceof IAdaptable) {
persistable = (IPersistableElement) ((IAdaptable) workingSet).getAdapter(IPersistableElement.class);
}
if (persistable != null) {
IMemento workingSetMemento = memento.createChild(IWorkbenchConstants.TAG_WORKING_SET);
workingSetMemento.putString(IWorkbenchConstants.TAG_FACTORY_ID, persistable.getFactoryId());
persistable.saveState(workingSetMemento);
}
}
}
/**
* Persists all working sets and 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 and CHANGE_WORKING_SET_NAME_CHANGE
*/
public void workingSetChanged(IWorkingSet changedWorkingSet, String propertyChangeId) {
saveState();
firePropertyChange(propertyChangeId, null, changedWorkingSet);
}
}