blob: effb11983b15486009b43c5de7a6f95f645ed518 [file] [log] [blame]
/************************************************************************
Copyright (c) 2002, 2003 IBM Corporation and others.
All rights reserved. This program and the accompanying materials
are made available under the terms of the Common Public License v1.0
which accompanies this distribution, and is available at
http://www.eclipse.org/legal/cpl-v10.html
Contributors:
IBM - Initial implementation
************************************************************************/
package org.eclipse.ui.internal;
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) {
internalAddRecentWorkingSet(workingSet);
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.getId();
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();
}
/**
* 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.
*/
private void internalAddRecentWorkingSet(IWorkingSet workingSet) {
recentWorkingSets.remove(workingSet);
recentWorkingSets.add(0, workingSet);
if (recentWorkingSets.size() > MRU_SIZE) {
recentWorkingSets.remove(MRU_SIZE);
}
}
/**
* 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) {
boolean workingSetRemoved = workingSets.remove(workingSet);
boolean recentWorkingSetRemoved = recentWorkingSets.remove(workingSet);
if (workingSetRemoved || recentWorkingSetRemoved) {
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) {
internalAddRecentWorkingSet(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);
BufferedReader reader = new BufferedReader(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) {
this.workingSets.add(workingSet);
firePropertyChange(CHANGE_WORKING_SET_ADD, null, 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);
}
}