From d450d1f1b8a1bfa3872b2f04cdae6888a8f01450 Mon Sep 17 00:00:00 2001 From: Michael Valenta Date: Tue, 28 Sep 2004 20:30:41 +0000 Subject: Starting to generalize change sets --- .../team/core/subscribers/ActiveChangeSet.java | 8 +- .../team/core/subscribers/ChangeSetCollector.java | 201 +++++++ .../subscribers/CheckedInChangeSetCollector.java | 65 +++ .../core/subscribers/IChangeSetChangeListener.java | 10 +- .../subscribers/SubscriberChangeSetCollector.java | 505 +++++++++++++++++ .../subscribers/SubscriberChangeSetManager.java | 620 --------------------- .../eclipse/team/internal/ccvs/ui/CVSUIPlugin.java | 21 +- .../ccvs/ui/subscriber/CVSParticipant.java | 2 +- .../subscriber/CVSParticipantLabelDecorator.java | 4 +- .../ccvs/ui/subscriber/ChangeLogModelProvider.java | 119 +--- .../ccvs/ui/subscriber/ChangeLogModelSorter.java | 113 ---- .../ccvs/ui/subscriber/ChangeSetModelSorter.java | 113 ++++ .../ccvs/ui/subscriber/CommitSetManager.java | 30 - .../ui/subscriber/WorkspaceCommitOperation.java | 18 +- .../WorkspaceSynchronizeParticipant.java | 3 +- .../ui/synchronize/ChangeSetActionGroup.java | 377 +++++++++++++ .../ChangeSetManagementActionGroup.java | 278 --------- .../ui/synchronize/ChangeSetModelProvider.java | 112 ++++ .../ui/synchronize/ChangeSetModelSorter.java | 113 ++++ .../.settings/org.eclipse.jdt.core.prefs | 18 +- .../launchConfigurations/One CVS Test.launch | 6 +- .../eclipse/team/tests/ccvs/core/EclipseTest.java | 8 +- .../ccvs/core/subscriber/CVSChangeSetTests.java | 149 ++++- .../eclipse/team/tests/ccvs/ui/CommitSetTests.java | 20 +- 24 files changed, 1709 insertions(+), 1204 deletions(-) create mode 100644 bundles/org.eclipse.team.core/src/org/eclipse/team/core/subscribers/ChangeSetCollector.java create mode 100644 bundles/org.eclipse.team.core/src/org/eclipse/team/core/subscribers/CheckedInChangeSetCollector.java create mode 100644 bundles/org.eclipse.team.core/src/org/eclipse/team/core/subscribers/SubscriberChangeSetCollector.java delete mode 100644 bundles/org.eclipse.team.core/src/org/eclipse/team/core/subscribers/SubscriberChangeSetManager.java delete mode 100644 bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/subscriber/ChangeLogModelSorter.java create mode 100644 bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/subscriber/ChangeSetModelSorter.java delete mode 100644 bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/subscriber/CommitSetManager.java create mode 100644 bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/ChangeSetActionGroup.java delete mode 100644 bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/ChangeSetManagementActionGroup.java create mode 100644 bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/ChangeSetModelProvider.java create mode 100644 bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/ChangeSetModelSorter.java diff --git a/bundles/org.eclipse.team.core/src/org/eclipse/team/core/subscribers/ActiveChangeSet.java b/bundles/org.eclipse.team.core/src/org/eclipse/team/core/subscribers/ActiveChangeSet.java index 57dc1a4f7..7243fecd9 100644 --- a/bundles/org.eclipse.team.core/src/org/eclipse/team/core/subscribers/ActiveChangeSet.java +++ b/bundles/org.eclipse.team.core/src/org/eclipse/team/core/subscribers/ActiveChangeSet.java @@ -30,14 +30,14 @@ public class ActiveChangeSet extends ChangeSet { private static final String CTX_RESOURCES = "resources"; //$NON-NLS-1$ private String comment; - private final SubscriberChangeSetManager manager; + private final SubscriberChangeSetCollector manager; /** * Create a change set with the given title * @param manager the manager that owns this set * @param title the title of the set */ - public ActiveChangeSet(SubscriberChangeSetManager manager, String title) { + public ActiveChangeSet(SubscriberChangeSetCollector manager, String title) { super(title); this.manager = manager; } @@ -60,7 +60,7 @@ public class ActiveChangeSet extends ChangeSet { */ public void setTitle(String title) { setName(title); - getManager().titleChanged(this); + getManager().fireNameChangedEvent(this); } /** @@ -105,7 +105,7 @@ public class ActiveChangeSet extends ChangeSet { } } - private SubscriberChangeSetManager getManager() { + private SubscriberChangeSetCollector getManager() { return manager; } diff --git a/bundles/org.eclipse.team.core/src/org/eclipse/team/core/subscribers/ChangeSetCollector.java b/bundles/org.eclipse.team.core/src/org/eclipse/team/core/subscribers/ChangeSetCollector.java new file mode 100644 index 000000000..e2115674e --- /dev/null +++ b/bundles/org.eclipse.team.core/src/org/eclipse/team/core/subscribers/ChangeSetCollector.java @@ -0,0 +1,201 @@ +/******************************************************************************* + * Copyright (c) 2000, 2004 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 Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.team.core.subscribers; + +import java.util.*; + +import org.eclipse.core.internal.runtime.ListenerList; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.runtime.ISafeRunnable; +import org.eclipse.core.runtime.Platform; +import org.eclipse.team.core.synchronize.ISyncInfoSetChangeListener; +import org.eclipse.team.core.synchronize.SyncInfoSet; + +/** + * This class defines the common aspects of collecting a set of change + * sets, including event notification. + * + * @since 3.1 + */ +public abstract class ChangeSetCollector implements ISyncInfoSetChangeListener { + + private ListenerList listeners = new ListenerList(); + private Set sets = new HashSet(); + + private Object[] getListeners() { + return listeners.getListeners(); + } + + /** + * Method that can be invoked by subclasses when the name of + * a managed change set changes. + * @param set the set whose title has changed + */ + protected void fireNameChangedEvent(final ChangeSet set) { + if (contains(set)) { + Object[] listeners = getListeners(); + for (int i = 0; i < listeners.length; i++) { + final IChangeSetChangeListener listener = (IChangeSetChangeListener)listeners[i]; + Platform.run(new ISafeRunnable() { + public void handleException(Throwable exception) { + // Exceptions are logged by the platform + } + public void run() throws Exception { + listener.nameChanged(set); + } + }); + } + } + } + + /** + * Method which allows subclasses to notify listeners that the default + * set has changed. + * @param oldSet the previous default + * @param defaultSet the new default + */ + protected void fireDefaultChangedEvent(final ChangeSet oldSet, final ChangeSet defaultSet) { + Object[] listeners = getListeners(); + for (int i = 0; i < listeners.length; i++) { + final IChangeSetChangeListener listener = (IChangeSetChangeListener)listeners[i]; + Platform.run(new ISafeRunnable() { + public void handleException(Throwable exception) { + // Exceptions are logged by the platform + } + public void run() throws Exception { + listener.defaultSetChanged(oldSet, defaultSet); + } + }); + } + } + + /** + * Add the set to the list of active sets. This method + * can be made public by subclasses. + * @param set the set to be added + */ + protected void add(final ChangeSet set) { + if (!contains(set)) { + sets.add(set); + set.getSyncInfoSet().addSyncSetChangedListener(this); + Object[] listeners = getListeners(); + for (int i = 0; i < listeners.length; i++) { + final IChangeSetChangeListener listener = (IChangeSetChangeListener)listeners[i]; + Platform.run(new ISafeRunnable() { + public void handleException(Throwable exception) { + // Exceptions are logged by the platform + } + public void run() throws Exception { + listener.setAdded(set); + } + }); + } + } + } + + /** + * Remove the set from the list of active sets. + * @param set the set to be removed + */ + public void remove(final ChangeSet set) { + if (contains(set)) { + set.getSyncInfoSet().removeSyncSetChangedListener(this); + sets.remove(set); + Object[] listeners = getListeners(); + for (int i = 0; i < listeners.length; i++) { + final IChangeSetChangeListener listener = (IChangeSetChangeListener)listeners[i]; + Platform.run(new ISafeRunnable() { + public void handleException(Throwable exception) { + // Exceptions are logged by the platform + } + public void run() throws Exception { + listener.setRemoved(set); + } + }); + } + } + } + + /** + * Return whether the manager contains the given commit set + * @param set the commit set being tested + * @return whether the set is contained in the manager's list of active sets + */ + public boolean contains(ChangeSet set) { + return sets.contains(set); + } + + /** + * Add the listener to the set of registered listeners. + * @param listener the listener to be added + */ + public void addListener(IChangeSetChangeListener listener) { + listeners.add(listener); + } + + /** + * Remove the listener from the set of registered listeners. + * @param listener the listener to remove + */ + public void removeListener(IChangeSetChangeListener listener) { + listeners.remove(listener); + } + + /** + * Return the list of active commit sets. + * @return the list of active commit sets + */ + public ChangeSet[] getSets() { + return (ChangeSet[]) sets.toArray(new ChangeSet[sets.size()]); + } + + /** + * Dispose of any resources maintained by the manager + */ + public void dispose() { + // Nothing to do + } + + /** + * @param changeSet + * @param allAffectedResources + */ + protected void fireResourcesChangedEvent(final ChangeSet changeSet, final IResource[] allAffectedResources) { + Object[] listeners = getListeners(); + for (int i = 0; i < listeners.length; i++) { + final IChangeSetChangeListener listener = (IChangeSetChangeListener)listeners[i]; + Platform.run(new ISafeRunnable() { + public void handleException(Throwable exception) { + // Exceptions are logged by the platform + } + public void run() throws Exception { + listener.resourcesChanged(changeSet, allAffectedResources); + } + }); + } + } + + /** + * Return the Change Set whose sync info set is the + * one given. + * @param set a sync info set + * @return the change set for the given sync info set + */ + protected ChangeSet getChangeSet(SyncInfoSet set) { + for (Iterator iter = sets.iterator(); iter.hasNext();) { + ChangeSet changeSet = (ChangeSet) iter.next(); + if (changeSet.getSyncInfoSet() == set) { + return changeSet; + } + } + return null; + } +} diff --git a/bundles/org.eclipse.team.core/src/org/eclipse/team/core/subscribers/CheckedInChangeSetCollector.java b/bundles/org.eclipse.team.core/src/org/eclipse/team/core/subscribers/CheckedInChangeSetCollector.java new file mode 100644 index 000000000..e4fa61a14 --- /dev/null +++ b/bundles/org.eclipse.team.core/src/org/eclipse/team/core/subscribers/CheckedInChangeSetCollector.java @@ -0,0 +1,65 @@ +/******************************************************************************* + * Copyright (c) 2000, 2004 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 Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.team.core.subscribers; + +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.team.core.ITeamStatus; +import org.eclipse.team.core.synchronize.ISyncInfoSetChangeEvent; +import org.eclipse.team.core.synchronize.SyncInfoSet; + +/** + * Contains a set of CheckedInChangeSets. + * @since 3.1 + */ +public class CheckedInChangeSetCollector extends ChangeSetCollector { + + /* (non-Javadoc) + * @see org.eclipse.team.core.subscribers.ChangeSetCollector#add(org.eclipse.team.core.subscribers.ChangeSet) + */ + public void add(CheckedInChangeSet set) { + super.add(set); + } + + /* (non-Javadoc) + * @see org.eclipse.team.core.synchronize.ISyncInfoSetChangeListener#syncInfoSetReset(org.eclipse.team.core.synchronize.SyncInfoSet, org.eclipse.core.runtime.IProgressMonitor) + */ + public void syncInfoSetReset(SyncInfoSet set, IProgressMonitor monitor) { + handleChangeEvent(set); + + } + + /* (non-Javadoc) + * @see org.eclipse.team.core.synchronize.ISyncInfoSetChangeListener#syncInfoChanged(org.eclipse.team.core.synchronize.ISyncInfoSetChangeEvent, org.eclipse.core.runtime.IProgressMonitor) + */ + public void syncInfoChanged(ISyncInfoSetChangeEvent event, IProgressMonitor monitor) { + handleChangeEvent(event.getSet()); + } + + /* (non-Javadoc) + * @see org.eclipse.team.core.synchronize.ISyncInfoSetChangeListener#syncInfoSetErrors(org.eclipse.team.core.synchronize.SyncInfoSet, org.eclipse.team.core.ITeamStatus[], org.eclipse.core.runtime.IProgressMonitor) + */ + public void syncInfoSetErrors(SyncInfoSet set, ITeamStatus[] errors, IProgressMonitor monitor) { + // TODO Auto-generated method stub + } + + /* + * The collector removes change sets once they are empty + */ + private void handleChangeEvent(SyncInfoSet set) { + if (set.isEmpty()) { + ChangeSet changeSet = getChangeSet(set); + if (changeSet != null) { + remove(changeSet); + } + } + } + +} diff --git a/bundles/org.eclipse.team.core/src/org/eclipse/team/core/subscribers/IChangeSetChangeListener.java b/bundles/org.eclipse.team.core/src/org/eclipse/team/core/subscribers/IChangeSetChangeListener.java index 0d9012d66..090fc84ea 100644 --- a/bundles/org.eclipse.team.core/src/org/eclipse/team/core/subscribers/IChangeSetChangeListener.java +++ b/bundles/org.eclipse.team.core/src/org/eclipse/team/core/subscribers/IChangeSetChangeListener.java @@ -23,7 +23,7 @@ public interface IChangeSetChangeListener { * The given set has been added to the set manager. * @param set the added set */ - void setAdded(ActiveChangeSet set); + void setAdded(ChangeSet set); /** * The default change set has change to be the given set. @@ -31,19 +31,19 @@ public interface IChangeSetChangeListener { * set. * @param set the default set */ - void defaultSetChanged(ActiveChangeSet previousDefault, ActiveChangeSet set); + void defaultSetChanged(ChangeSet previousDefault, ChangeSet set); /** * The given set has been removed from the set manager. * @param set the removed set */ - void setRemoved(ActiveChangeSet set); + void setRemoved(ChangeSet set); /** * The title of the given set has changed. * @param set the set whose title changed */ - void titleChanged(ActiveChangeSet set); + void nameChanged(ChangeSet set); /** * The state of the given resources have change with respect to the @@ -53,6 +53,6 @@ public interface IChangeSetChangeListener { * @param set the set that has changed * @param resources the resources whose containment state has changed w.r.t the set */ - void resourcesChanged(ActiveChangeSet set, IResource[] resources); + void resourcesChanged(ChangeSet set, IResource[] resources); } diff --git a/bundles/org.eclipse.team.core/src/org/eclipse/team/core/subscribers/SubscriberChangeSetCollector.java b/bundles/org.eclipse.team.core/src/org/eclipse/team/core/subscribers/SubscriberChangeSetCollector.java new file mode 100644 index 000000000..80d141faf --- /dev/null +++ b/bundles/org.eclipse.team.core/src/org/eclipse/team/core/subscribers/SubscriberChangeSetCollector.java @@ -0,0 +1,505 @@ +/******************************************************************************* + * Copyright (c) 2000, 2004 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 Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.team.core.subscribers; + +import java.util.*; + +import org.eclipse.core.internal.runtime.ListenerList; +import org.eclipse.core.resources.IFile; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.runtime.*; +import org.eclipse.core.runtime.preferences.*; +import org.eclipse.team.core.ITeamStatus; +import org.eclipse.team.core.TeamException; +import org.eclipse.team.core.synchronize.*; +import org.eclipse.team.internal.core.*; +import org.eclipse.team.internal.core.subscribers.SubscriberResourceCollector; +import org.osgi.service.prefs.BackingStoreException; +import org.osgi.service.prefs.Preferences; + +/** + * This class manages the active change sets associated with a subscriber. + */ +public class SubscriberChangeSetCollector extends ChangeSetCollector { + + private static final String PREF_CHANGE_SETS = "changeSets"; //$NON-NLS-1$ + private static final String CTX_DEFAULT_SET = "defaultSet"; //$NON-NLS-1$ + + private static final int RESOURCE_REMOVAL = 1; + private static final int RESOURCE_CHANGE = 2; + + private List activeSets; + private ListenerList listeners = new ListenerList(); + private ActiveChangeSet defaultSet; + private EventHandler handler; + private ResourceCollector collector; + + /* + * Background event handler for serializing and batching change set changes + */ + private class EventHandler extends BackgroundEventHandler { + + private List dispatchEvents = new ArrayList(); + + protected EventHandler(String jobName, String errorTitle) { + super(jobName, errorTitle); + } + + /* (non-Javadoc) + * @see org.eclipse.team.internal.core.BackgroundEventHandler#processEvent(org.eclipse.team.internal.core.BackgroundEventHandler.Event, org.eclipse.core.runtime.IProgressMonitor) + */ + protected void processEvent(Event event, IProgressMonitor monitor) throws CoreException { + // Handle everything in the dispatch + dispatchEvents.add(event); + } + + /* (non-Javadoc) + * @see org.eclipse.team.internal.core.BackgroundEventHandler#doDispatchEvents(org.eclipse.core.runtime.IProgressMonitor) + */ + protected boolean doDispatchEvents(IProgressMonitor monitor) throws TeamException { + if (dispatchEvents.isEmpty()) { + return false; + } + try { + beginDispath(); + for (Iterator iter = dispatchEvents.iterator(); iter.hasNext();) { + Event event = (Event) iter.next(); + switch (event.getType()) { + case RESOURCE_REMOVAL: + handleRemove(event.getResource()); + break; + case RESOURCE_CHANGE: + handleChange(event.getResource(), event.getDepth()); + break; + default: + break; + } + } + } finally { + try { + endDispatch(monitor); + } finally { + dispatchEvents.clear(); + } + } + return true; + } + + private void beginDispath() { + for (Iterator iter = activeSets.iterator(); iter.hasNext();) { + ActiveChangeSet set = (ActiveChangeSet) iter.next(); + set.getSyncInfoSet().beginInput(); + } + } + + private void endDispatch(IProgressMonitor monitor) { + monitor.beginTask(null, 100 * activeSets.size()); + for (Iterator iter = activeSets.iterator(); iter.hasNext();) { + ActiveChangeSet set = (ActiveChangeSet) iter.next(); + try { + set.getSyncInfoSet().endInput(Policy.subMonitorFor(monitor, 100)); + } catch (RuntimeException e) { + // Don't worry about ending every set if an error occurs. + // Instead, log the error and suggest a restart. + TeamPlugin.log(IStatus.ERROR, "An error occurred while reconciling change sets. Restarting the application is recommended.", e); + throw e; + } + } + monitor.done(); + } + + /* (non-Javadoc) + * @see org.eclipse.team.internal.core.BackgroundEventHandler#queueEvent(org.eclipse.team.internal.core.BackgroundEventHandler.Event, boolean) + */ + protected synchronized void queueEvent(Event event, boolean front) { + // Override to allow access from enclosing class + super.queueEvent(event, front); + } + + /* + * Handle the removal + */ + private void handleRemove(IResource resource) { + for (Iterator iter = activeSets.iterator(); iter.hasNext();) { + ActiveChangeSet set = (ActiveChangeSet) iter.next(); + // This will remove any descendants from the set and callback to + // resourcesChanged which will batch changes + if (!set.isEmpty()) { + set.rootRemoved(resource, IResource.DEPTH_INFINITE); + if (set.isEmpty()) { + remove(set); + } + } + } + } + + /* + * Handle the change + */ + private void handleChange(IResource resource, int depth) throws TeamException { + SyncInfo syncInfo = getSyncInfo(resource); + if (isModified(syncInfo)) { + ActiveChangeSet[] containingSets = getContainingSets(resource); + if (containingSets.length == 0) { + // Consider for inclusion in the default set + // if the resource is not already a memebr of another set + if (defaultSet != null) { + defaultSet.add(syncInfo); + } + } else { + for (int i = 0; i < containingSets.length; i++) { + ActiveChangeSet set = containingSets[i]; + // Update the sync info in the set + set.getSyncInfoSet().add(syncInfo); + } + } + } else { + removeFromAllSets(resource); + } + if (depth != IResource.DEPTH_ZERO) { + IResource[] members = getSubscriber().members(resource); + for (int i = 0; i < members.length; i++) { + IResource member = members[i]; + handleChange(member, depth == IResource.DEPTH_ONE ? IResource.DEPTH_ZERO : IResource.DEPTH_INFINITE); + } + } + } + + private void removeFromAllSets(IResource resource) { + List toRemove = new ArrayList(); + for (Iterator iter = activeSets.iterator(); iter.hasNext();) { + ActiveChangeSet set = (ActiveChangeSet) iter.next(); + if (set.contains(resource)) { + set.remove(resource); + if (set.isEmpty()) { + toRemove.add(set); + } + } + } + for (Iterator iter = toRemove.iterator(); iter.hasNext();) { + ActiveChangeSet set = (ActiveChangeSet) iter.next(); + remove(set); + } + } + + private ActiveChangeSet[] getContainingSets(IResource resource) { + Set sets = new HashSet(); + for (Iterator iter = activeSets.iterator(); iter.hasNext();) { + ActiveChangeSet set = (ActiveChangeSet) iter.next(); + if (set.contains(resource)) { + sets.add(set); + } + } + return (ActiveChangeSet[]) sets.toArray(new ActiveChangeSet[sets.size()]); + } + } + + private class ResourceCollector extends SubscriberResourceCollector { + + public ResourceCollector(Subscriber subscriber) { + super(subscriber); + } + + /* (non-Javadoc) + * @see org.eclipse.team.internal.core.subscribers.SubscriberResourceCollector#remove(org.eclipse.core.resources.IResource) + */ + protected void remove(IResource resource) { + handler.queueEvent(new BackgroundEventHandler.Event(resource, RESOURCE_REMOVAL, IResource.DEPTH_INFINITE), false); + } + + /* (non-Javadoc) + * @see org.eclipse.team.internal.core.subscribers.SubscriberResourceCollector#change(org.eclipse.core.resources.IResource, int) + */ + protected void change(IResource resource, int depth) { + handler.queueEvent(new BackgroundEventHandler.Event(resource, RESOURCE_CHANGE, depth), false); + } + + } + + public SubscriberChangeSetCollector(Subscriber subscriber) { + collector = new ResourceCollector(subscriber); + load(); + handler = new EventHandler("Updating Change Sets for {0}" + subscriber.getName(), "Errors occurred while updating the change sets for {0}" + subscriber.getName()); + } + + /** + * Add the active change set to this collector. + * @param set the active change set being added + */ + public void add(ActiveChangeSet set) { + if (!contains(set)) { + super.add(set); + handleAddedResources(set, set.getSyncInfoSet().getSyncInfos()); + } + } + + /** + * Return whether the manager allows a resource to + * be in mulitple sets. By default, a resource + * may only be in one set. + * @return whether the manager allows a resource to + * be in mulitple sets. + */ + protected boolean isSingleSetPerResource() { + return true; + } + + /** + * Create a commit set with the given title and files. The created + * set is not added to the control of the commit set manager + * so no events are fired. The set can be added using the + * add method. + * @param title the title of the commit set + * @param files the files contained in the set + * @return the created set + * @throws CVSException + */ + public ActiveChangeSet createSet(String title, SyncInfo[] infos) { + ActiveChangeSet commitSet = new ActiveChangeSet(this, title); + if (infos != null && infos.length > 0) { + commitSet.add(infos); + } + return commitSet; + } + + /** + * Create a change set containing the given files if + * they have been modified locally. + * @param title the title of the commit set + * @param files the files contained in the set + * @return the created set + * @throws TeamException + */ + public ActiveChangeSet createSet(String title, IFile[] files) throws TeamException { + List infos = new ArrayList(); + for (int i = 0; i < files.length; i++) { + IFile file = files[i]; + SyncInfo info = getSyncInfo(file); + if (info != null) { + infos.add(info); + } + } + return createSet(title, (SyncInfo[]) infos.toArray(new SyncInfo[infos.size()])); + } + + /** + * Make the given set the default set into which all new modifications + * that ae not already in another set go. + * @param set the set which is to become the default set + */ + public void makeDefault(ActiveChangeSet set) { + // The default set must be an active set + if (!contains(set)) { + add(set); + } + ActiveChangeSet oldSet = defaultSet; + defaultSet = set; + fireDefaultChangedEvent(oldSet, defaultSet); + } + + /** + * Retrn the set which is currently the default or + * null if there is no default set. + * @return + */ + public ActiveChangeSet getDefaultSet() { + return defaultSet; + } + /** + * Return whether the given set is the default set into which all + * new modifications will be placed. + * @param set the set to test + * @return whether the set is the default set + */ + public boolean isDefault(ActiveChangeSet set) { + return set == defaultSet; + } + + /** + * Return the sync info for the given resource obtained + * from the subscriber. + * @param resource the resource + * @return the sync info for the resource + * @throws TeamException + */ + protected SyncInfo getSyncInfo(IResource resource) throws TeamException { + Subscriber subscriber = getSubscriber(); + SyncInfo info = subscriber.getSyncInfo(resource); + return info; + } + + /** + * Return the subscriber associated with this collector. + * @return the subscriber associated with this collector + */ + public Subscriber getSubscriber() { + return collector.getSubscriber(); + } + + protected boolean isModified(SyncInfo info) { + if (info != null) { + if (info.getComparator().isThreeWay()) { + int dir = (info.getKind() & SyncInfo.DIRECTION_MASK); + return dir == SyncInfo.OUTGOING || dir == SyncInfo.CONFLICTING; + } else { + return (info.getKind() & SyncInfo.CHANGE_MASK) == SyncInfo.CHANGE; + } + } + return false; + } + + /* (non-Javadoc) + * @see org.eclipse.team.internal.core.subscribers.SubscriberResourceCollector#dispose() + */ + public void dispose() { + handler.shutdown(); + collector.dispose(); + super.dispose(); + save(); + } + + private void save() { + Preferences prefs = getPreferences(); + for (Iterator it = activeSets.iterator(); it.hasNext(); ) { + ActiveChangeSet set = (ActiveChangeSet) it.next(); + if (!set.isEmpty()) { + Preferences child = prefs.node(set.getTitle()); + set.save(child); + } + } + if (defaultSet != null) { + prefs.put(CTX_DEFAULT_SET, defaultSet.getTitle()); + } + try { + prefs.flush(); + } catch (BackingStoreException e) { + TeamPlugin.log(IStatus.ERROR, "An error occurred saving the change set state for {0}" + getSubscriber().getName(), e); + } + } + + private void load() { + activeSets = new ArrayList(); + Preferences prefs = getPreferences(); + String defaultSetTitle = prefs.get(CTX_DEFAULT_SET, null); + try { + String[] childNames = prefs.childrenNames(); + for (int i = 0; i < childNames.length; i++) { + String string = childNames[i]; + Preferences childPrefs = prefs.node(string); + ActiveChangeSet set = createSet(string, childPrefs); + if (defaultSet == null && defaultSetTitle != null && set.getTitle().equals(defaultSetTitle)) { + defaultSet = set; + } + activeSets.add(set); + } + } catch (BackingStoreException e) { + TeamPlugin.log(IStatus.ERROR, "An error occurred restoring the change set state for {0}" + getSubscriber().getName(), e); + } + } + + /** + * Create a change set from the given preferences that were + * previously saved. + * @param childPrefs the previously saved preferences + * @return the created change set + */ + protected ActiveChangeSet createSet(String title, Preferences childPrefs) { + ActiveChangeSet changeSet = new ActiveChangeSet(this, title); + changeSet.init(childPrefs); + return changeSet; + } + + private Preferences getPreferences() { + return getParentPreferences().node(getSubscriberIdentifier()); + } + + private static Preferences getParentPreferences() { + return getTeamPreferences().node(PREF_CHANGE_SETS); + } + + private static Preferences getTeamPreferences() { + IPreferencesService service = Platform.getPreferencesService(); + IEclipsePreferences root = service.getRootNode(); + return root.node(InstanceScope.SCOPE).node(TeamPlugin.getPlugin().getBundle().getSymbolicName()); + } + + /** + * Return the id that will uniquely identify the subscriber accross + * restarts. + * @return + */ + protected String getSubscriberIdentifier() { + return getSubscriber().getName(); + } + + /* (non-Javadoc) + * @see org.eclipse.team.core.synchronize.ISyncInfoSetChangeListener#syncInfoSetReset(org.eclipse.team.core.synchronize.SyncInfoSet, org.eclipse.core.runtime.IProgressMonitor) + */ + public void syncInfoSetReset(SyncInfoSet set, IProgressMonitor monitor) { + handleSyncSetChange(set, set.getSyncInfos(), set.getResources()); + } + + /* (non-Javadoc) + * @see org.eclipse.team.core.synchronize.ISyncInfoSetChangeListener#syncInfoChanged(org.eclipse.team.core.synchronize.ISyncInfoSetChangeEvent, org.eclipse.core.runtime.IProgressMonitor) + */ + public void syncInfoChanged(ISyncInfoSetChangeEvent event, IProgressMonitor monitor) { + SyncInfoSet set = event.getSet(); + handleSyncSetChange(set, event.getAddedResources(), getAllResources(event)); + } + + private IResource[] getAllResources(ISyncInfoSetChangeEvent event) { + Set allResources = new HashSet(); + SyncInfo[] addedResources = event.getAddedResources(); + for (int i = 0; i < addedResources.length; i++) { + SyncInfo info = addedResources[i]; + allResources.add(info.getLocal()); + } + SyncInfo[] changedResources = event.getChangedResources(); + for (int i = 0; i < changedResources.length; i++) { + SyncInfo info = changedResources[i]; + allResources.add(info.getLocal()); + } + allResources.addAll(Arrays.asList(event.getRemovedResources())); + return (IResource[]) allResources.toArray(new IResource[allResources.size()]); + } + + private void handleAddedResources(ChangeSet set, SyncInfo[] infos) { + if (isSingleSetPerResource()) { + IResource[] resources = new IResource[infos.length]; + for (int i = 0; i < infos.length; i++) { + resources[i] = infos[i].getLocal(); + } + // Remove the added files from any other set that contains them + for (Iterator iter = activeSets.iterator(); iter.hasNext();) { + ChangeSet otherSet = (ChangeSet) iter.next(); + if (otherSet != set) { + otherSet.remove(resources); + } + } + } + } + + private void handleSyncSetChange(SyncInfoSet set, SyncInfo[] addedInfos, IResource[] allAffectedResources) { + ChangeSet changeSet = getChangeSet(set); + if (set.isEmpty() && changeSet != null) { + remove(changeSet); + } + fireResourcesChangedEvent(changeSet, allAffectedResources); + handleAddedResources(changeSet, addedInfos); + } + + /* (non-Javadoc) + * @see org.eclipse.team.core.synchronize.ISyncInfoSetChangeListener#syncInfoSetErrors(org.eclipse.team.core.synchronize.SyncInfoSet, org.eclipse.team.core.ITeamStatus[], org.eclipse.core.runtime.IProgressMonitor) + */ + public void syncInfoSetErrors(SyncInfoSet set, ITeamStatus[] errors, IProgressMonitor monitor) { + // Nothing to do + } +} diff --git a/bundles/org.eclipse.team.core/src/org/eclipse/team/core/subscribers/SubscriberChangeSetManager.java b/bundles/org.eclipse.team.core/src/org/eclipse/team/core/subscribers/SubscriberChangeSetManager.java deleted file mode 100644 index 6da1a62ac..000000000 --- a/bundles/org.eclipse.team.core/src/org/eclipse/team/core/subscribers/SubscriberChangeSetManager.java +++ /dev/null @@ -1,620 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2000, 2004 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 Corporation - initial API and implementation - *******************************************************************************/ -package org.eclipse.team.core.subscribers; - -import java.util.*; - -import org.eclipse.core.internal.runtime.ListenerList; -import org.eclipse.core.resources.IFile; -import org.eclipse.core.resources.IResource; -import org.eclipse.core.runtime.*; -import org.eclipse.core.runtime.preferences.*; -import org.eclipse.team.core.ITeamStatus; -import org.eclipse.team.core.TeamException; -import org.eclipse.team.core.synchronize.*; -import org.eclipse.team.internal.core.*; -import org.eclipse.team.internal.core.subscribers.SubscriberResourceCollector; -import org.osgi.service.prefs.BackingStoreException; -import org.osgi.service.prefs.Preferences; - -/** - * This class manages the change sets associated with a subscriber. - */ -public class SubscriberChangeSetManager extends SubscriberResourceCollector implements ISyncInfoSetChangeListener { - - private static final String PREF_CHANGE_SETS = "changeSets"; //$NON-NLS-1$ - private static final String CTX_DEFAULT_SET = "defaultSet"; //$NON-NLS-1$ - - private static final int RESOURCE_REMOVAL = 1; - private static final int RESOURCE_CHANGE = 2; - - private List activeSets; - private ListenerList listeners = new ListenerList(); - private ActiveChangeSet defaultSet; - private EventHandler handler; - - /* - * Background event handler for serializing and batching change set changes - */ - private class EventHandler extends BackgroundEventHandler { - - private List dispatchEvents = new ArrayList(); - - protected EventHandler(String jobName, String errorTitle) { - super(jobName, errorTitle); - } - - /* (non-Javadoc) - * @see org.eclipse.team.internal.core.BackgroundEventHandler#processEvent(org.eclipse.team.internal.core.BackgroundEventHandler.Event, org.eclipse.core.runtime.IProgressMonitor) - */ - protected void processEvent(Event event, IProgressMonitor monitor) throws CoreException { - // Handle everything in the dispatch - dispatchEvents.add(event); - } - - /* (non-Javadoc) - * @see org.eclipse.team.internal.core.BackgroundEventHandler#doDispatchEvents(org.eclipse.core.runtime.IProgressMonitor) - */ - protected boolean doDispatchEvents(IProgressMonitor monitor) throws TeamException { - if (dispatchEvents.isEmpty()) { - return false; - } - try { - beginDispath(); - for (Iterator iter = dispatchEvents.iterator(); iter.hasNext();) { - Event event = (Event) iter.next(); - switch (event.getType()) { - case RESOURCE_REMOVAL: - handleRemove(event.getResource()); - break; - case RESOURCE_CHANGE: - handleChange(event.getResource(), event.getDepth()); - break; - default: - break; - } - } - } finally { - try { - endDispatch(monitor); - } finally { - dispatchEvents.clear(); - } - } - return true; - } - - private void beginDispath() { - for (Iterator iter = activeSets.iterator(); iter.hasNext();) { - ActiveChangeSet set = (ActiveChangeSet) iter.next(); - set.getSyncInfoSet().beginInput(); - } - } - - private void endDispatch(IProgressMonitor monitor) { - monitor.beginTask(null, 100 * activeSets.size()); - for (Iterator iter = activeSets.iterator(); iter.hasNext();) { - ActiveChangeSet set = (ActiveChangeSet) iter.next(); - try { - set.getSyncInfoSet().endInput(Policy.subMonitorFor(monitor, 100)); - } catch (RuntimeException e) { - // Don't worry about ending every set if an error occurs. - // Instead, log the error and suggest a restart. - TeamPlugin.log(IStatus.ERROR, "An error occurred while reconciling change sets. Restarting the application is recommended.", e); - throw e; - } - } - monitor.done(); - } - - /* (non-Javadoc) - * @see org.eclipse.team.internal.core.BackgroundEventHandler#queueEvent(org.eclipse.team.internal.core.BackgroundEventHandler.Event, boolean) - */ - protected synchronized void queueEvent(Event event, boolean front) { - // Override to allow access from enclosing class - super.queueEvent(event, front); - } - - /* - * Handle the removal - */ - private void handleRemove(IResource resource) { - for (Iterator iter = activeSets.iterator(); iter.hasNext();) { - ActiveChangeSet set = (ActiveChangeSet) iter.next(); - // This will remove any descendants from the set and callback to - // resourcesChanged which will batch changes - if (!set.isEmpty()) { - set.rootRemoved(resource, IResource.DEPTH_INFINITE); - if (set.isEmpty()) { - remove(set); - } - } - } - } - - /* - * Handle the change - */ - private void handleChange(IResource resource, int depth) throws TeamException { - SyncInfo syncInfo = getSyncInfo(resource); - if (isModified(syncInfo)) { - ActiveChangeSet[] containingSets = getContainingSets(resource); - if (containingSets.length == 0) { - // Consider for inclusion in the default set - // if the resource is not already a memebr of another set - if (defaultSet != null) { - defaultSet.add(syncInfo); - } - } else { - for (int i = 0; i < containingSets.length; i++) { - ActiveChangeSet set = containingSets[i]; - // Update the sync info in the set - set.getSyncInfoSet().add(syncInfo); - } - } - } else { - removeFromAllSets(resource); - } - if (depth != IResource.DEPTH_ZERO) { - IResource[] members = getSubscriber().members(resource); - for (int i = 0; i < members.length; i++) { - IResource member = members[i]; - handleChange(member, depth == IResource.DEPTH_ONE ? IResource.DEPTH_ZERO : IResource.DEPTH_INFINITE); - } - } - } - - private void removeFromAllSets(IResource resource) { - List toRemove = new ArrayList(); - for (Iterator iter = activeSets.iterator(); iter.hasNext();) { - ActiveChangeSet set = (ActiveChangeSet) iter.next(); - if (set.contains(resource)) { - set.remove(resource); - if (set.isEmpty()) { - toRemove.add(set); - } - } - } - for (Iterator iter = toRemove.iterator(); iter.hasNext();) { - ActiveChangeSet set = (ActiveChangeSet) iter.next(); - remove(set); - } - } - - private ActiveChangeSet[] getContainingSets(IResource resource) { - Set sets = new HashSet(); - for (Iterator iter = activeSets.iterator(); iter.hasNext();) { - ActiveChangeSet set = (ActiveChangeSet) iter.next(); - if (set.contains(resource)) { - sets.add(set); - } - } - return (ActiveChangeSet[]) sets.toArray(new ActiveChangeSet[sets.size()]); - } - } - - public SubscriberChangeSetManager(Subscriber subscriber) { - super(subscriber); - load(); - handler = new EventHandler("Updating Change Sets for {0}" + subscriber.getName(), "Errors occurred while updating the change sets for {0}" + subscriber.getName()); - } - - /* (non-Javadoc) - * @see org.eclipse.team.internal.core.subscribers.SubscriberResourceCollector#remove(org.eclipse.core.resources.IResource) - */ - protected void remove(IResource resource) { - handler.queueEvent(new BackgroundEventHandler.Event(resource, RESOURCE_REMOVAL, IResource.DEPTH_INFINITE), false); - } - - /* (non-Javadoc) - * @see org.eclipse.team.internal.core.subscribers.SubscriberResourceCollector#change(org.eclipse.core.resources.IResource, int) - */ - protected void change(IResource resource, int depth) { - handler.queueEvent(new BackgroundEventHandler.Event(resource, RESOURCE_CHANGE, depth), false); - } - - private Object[] getListeners() { - return listeners.getListeners(); - } - - /** - * The title of the given set has changed. Notify any listeners. - */ - /* package */ void titleChanged(final ActiveChangeSet set) { - if (activeSets.contains(set)) { - Object[] listeners = getListeners(); - for (int i = 0; i < listeners.length; i++) { - final IChangeSetChangeListener listener = (IChangeSetChangeListener)listeners[i]; - Platform.run(new ISafeRunnable() { - public void handleException(Throwable exception) { - // Exceptions are logged by the platform - } - public void run() throws Exception { - listener.titleChanged(set); - } - }); - } - } - } - - /** - * Return whether the manager allows a resource to - * be in mulitple sets. By default, a resource - * may only be in one set. - * @return whether the manager allows a resource to - * be in mulitple sets. - */ - protected boolean isSingleSetPerResource() { - return true; - } - - /** - * Create a commit set with the given title and files. The created - * set is not added to the control of the commit set manager - * so no events are fired. The set can be added using the - * add method. - * @param title the title of the commit set - * @param files the files contained in the set - * @return the created set - * @throws CVSException - */ - public ActiveChangeSet createSet(String title, SyncInfo[] infos) { - ActiveChangeSet commitSet = new ActiveChangeSet(this, title); - if (infos != null && infos.length > 0) { - commitSet.add(infos); - } - return commitSet; - } - - /** - * Create a change set containing the given files if - * they have been modified locally. - * @param title the title of the commit set - * @param files the files contained in the set - * @return the created set - * @throws TeamException - */ - public ActiveChangeSet createSet(String title, IFile[] files) throws TeamException { - List infos = new ArrayList(); - for (int i = 0; i < files.length; i++) { - IFile file = files[i]; - SyncInfo info = getSyncInfo(file); - if (info != null) { - infos.add(info); - } - } - return createSet(title, (SyncInfo[]) infos.toArray(new SyncInfo[infos.size()])); - } - - /** - * Add the set to the list of active sets. - * @param set the set to be added - */ - public void add(final ActiveChangeSet set) { - if (!contains(set)) { - activeSets.add(set); - set.getSyncInfoSet().addSyncSetChangedListener(this); - Object[] listeners = getListeners(); - for (int i = 0; i < listeners.length; i++) { - final IChangeSetChangeListener listener = (IChangeSetChangeListener)listeners[i]; - Platform.run(new ISafeRunnable() { - public void handleException(Throwable exception) { - // Exceptions are logged by the platform - } - public void run() throws Exception { - listener.setAdded(set); - } - }); - } - handleAddedResources(set, set.getSyncInfoSet().getSyncInfos()); - } - } - - /** - * Remove the set from the list of active sets. - * @param set the set to be removed - */ - public void remove(final ActiveChangeSet set) { - if (contains(set)) { - set.getSyncInfoSet().removeSyncSetChangedListener(this); - activeSets.remove(set); - Object[] listeners = getListeners(); - for (int i = 0; i < listeners.length; i++) { - final IChangeSetChangeListener listener = (IChangeSetChangeListener)listeners[i]; - Platform.run(new ISafeRunnable() { - public void handleException(Throwable exception) { - // Exceptions are logged by the platform - } - public void run() throws Exception { - listener.setRemoved(set); - } - }); - } - } - } - - /** - * Return whether the manager contains the given commit set - * @param set the commit set being tested - * @return whether the set is contained in the manager's list of active sets - */ - public boolean contains(ActiveChangeSet set) { - return activeSets.contains(set); - } - - /** - * Add the listener to the set of registered listeners. - * @param listener the listener to be added - */ - public void addListener(IChangeSetChangeListener listener) { - listeners.add(listener); - } - - /** - * Remove the listener from the set of registered listeners. - * @param listener the listener to remove - */ - public void removeListener(IChangeSetChangeListener listener) { - listeners.remove(listener); - } - - /** - * Return the list of active commit sets. - * @return the list of active commit sets - */ - public ActiveChangeSet[] getSets() { - return (ActiveChangeSet[]) activeSets.toArray(new ActiveChangeSet[activeSets.size()]); - } - - /** - * Make the given set the default set into which all new modifications - * that ae not already in another set go. - * @param set the set which is to become the default set - */ - public void makeDefault(ActiveChangeSet set) { - // The default set must be an active set - if (!contains(set)) { - add(set); - } - final ActiveChangeSet oldSet = defaultSet; - defaultSet = set; - Object[] listeners = getListeners(); - for (int i = 0; i < listeners.length; i++) { - final IChangeSetChangeListener listener = (IChangeSetChangeListener)listeners[i]; - Platform.run(new ISafeRunnable() { - public void handleException(Throwable exception) { - // Exceptions are logged by the platform - } - public void run() throws Exception { - listener.defaultSetChanged(oldSet, defaultSet); - } - }); - } - } - - /** - * Retrn the set which is currently the default or - * null if there is no default set. - * @return - */ - public ActiveChangeSet getDefaultSet() { - return defaultSet; - } - /** - * Return whether the given set is the default set into which all - * new modifications will be placed. - * @param set the set to test - * @return whether the set is the default set - */ - public boolean isDefault(ActiveChangeSet set) { - return set == defaultSet; - } - - /** - * Return the sync info for the given resource obtained - * from the subscriber. - * @param resource the resource - * @return the sync info for the resource - * @throws TeamException - */ - protected SyncInfo getSyncInfo(IResource resource) throws TeamException { - Subscriber subscriber = getSubscriber(); - SyncInfo info = subscriber.getSyncInfo(resource); - return info; - } - - protected boolean isModified(SyncInfo info) { - if (info != null) { - if (info.getComparator().isThreeWay()) { - int dir = (info.getKind() & SyncInfo.DIRECTION_MASK); - return dir == SyncInfo.OUTGOING || dir == SyncInfo.CONFLICTING; - } else { - return (info.getKind() & SyncInfo.CHANGE_MASK) == SyncInfo.CHANGE; - } - } - return false; - } - - /* (non-Javadoc) - * @see org.eclipse.team.internal.core.subscribers.SubscriberResourceCollector#dispose() - */ - public void dispose() { - handler.shutdown(); - super.dispose(); - save(); - } - - private void save() { - Preferences prefs = getPreferences(); - for (Iterator it = activeSets.iterator(); it.hasNext(); ) { - ActiveChangeSet set = (ActiveChangeSet) it.next(); - if (!set.isEmpty()) { - Preferences child = prefs.node(set.getTitle()); - set.save(child); - } - } - if (defaultSet != null) { - prefs.put(CTX_DEFAULT_SET, defaultSet.getTitle()); - } - try { - prefs.flush(); - } catch (BackingStoreException e) { - TeamPlugin.log(IStatus.ERROR, "An error occurred saving the change set state for {0}" + getSubscriber().getName(), e); - } - } - - private void load() { - activeSets = new ArrayList(); - Preferences prefs = getPreferences(); - String defaultSetTitle = prefs.get(CTX_DEFAULT_SET, null); - try { - String[] childNames = prefs.childrenNames(); - for (int i = 0; i < childNames.length; i++) { - String string = childNames[i]; - Preferences childPrefs = prefs.node(string); - ActiveChangeSet set = createSet(string, childPrefs); - if (defaultSet == null && defaultSetTitle != null && set.getTitle().equals(defaultSetTitle)) { - defaultSet = set; - } - activeSets.add(set); - } - } catch (BackingStoreException e) { - TeamPlugin.log(IStatus.ERROR, "An error occurred restoring the change set state for {0}" + getSubscriber().getName(), e); - } - } - - /** - * Create a change set from the given preferences that were - * previously saved. - * @param childPrefs the previously saved preferences - * @return the created change set - */ - protected ActiveChangeSet createSet(String title, Preferences childPrefs) { - ActiveChangeSet changeSet = new ActiveChangeSet(this, title); - changeSet.init(childPrefs); - return changeSet; - } - - private Preferences getPreferences() { - return getParentPreferences().node(getSubscriberIdentifier()); - } - - private static Preferences getParentPreferences() { - return getTeamPreferences().node(PREF_CHANGE_SETS); - } - - private static Preferences getTeamPreferences() { - IPreferencesService service = Platform.getPreferencesService(); - IEclipsePreferences root = service.getRootNode(); - return root.node(InstanceScope.SCOPE).node(TeamPlugin.getPlugin().getBundle().getSymbolicName()); - } - - /** - * Return the id that will uniquely identify the subscriber accross - * restarts. - * @return - */ - protected String getSubscriberIdentifier() { - return getSubscriber().getName(); - } - - /* (non-Javadoc) - * @see org.eclipse.team.core.synchronize.ISyncInfoSetChangeListener#syncInfoSetReset(org.eclipse.team.core.synchronize.SyncInfoSet, org.eclipse.core.runtime.IProgressMonitor) - */ - public void syncInfoSetReset(SyncInfoSet set, IProgressMonitor monitor) { - handleSyncSetChange(set, set.getSyncInfos(), set.getResources()); - } - - /* (non-Javadoc) - * @see org.eclipse.team.core.synchronize.ISyncInfoSetChangeListener#syncInfoChanged(org.eclipse.team.core.synchronize.ISyncInfoSetChangeEvent, org.eclipse.core.runtime.IProgressMonitor) - */ - public void syncInfoChanged(ISyncInfoSetChangeEvent event, IProgressMonitor monitor) { - SyncInfoSet set = event.getSet(); - handleSyncSetChange(set, event.getAddedResources(), getAllResources(event)); - } - - private IResource[] getAllResources(ISyncInfoSetChangeEvent event) { - Set allResources = new HashSet(); - SyncInfo[] addedResources = event.getAddedResources(); - for (int i = 0; i < addedResources.length; i++) { - SyncInfo info = addedResources[i]; - allResources.add(info.getLocal()); - } - SyncInfo[] changedResources = event.getChangedResources(); - for (int i = 0; i < changedResources.length; i++) { - SyncInfo info = changedResources[i]; - allResources.add(info.getLocal()); - } - allResources.addAll(Arrays.asList(event.getRemovedResources())); - return (IResource[]) allResources.toArray(new IResource[allResources.size()]); - } - - private void handleAddedResources(ActiveChangeSet set, SyncInfo[] infos) { - if (isSingleSetPerResource()) { - IResource[] resources = new IResource[infos.length]; - for (int i = 0; i < infos.length; i++) { - resources[i] = infos[i].getLocal(); - } - // Remove the added files from any other set that contains them - for (Iterator iter = activeSets.iterator(); iter.hasNext();) { - ActiveChangeSet otherSet = (ActiveChangeSet) iter.next(); - if (otherSet != set) { - otherSet.remove(resources); - } - } - } - } - - private void handleSyncSetChange(SyncInfoSet set, SyncInfo[] addedInfos, IResource[] allAffectedResources) { - ActiveChangeSet changeSet = getChangeSet(set); - if (set.isEmpty() && changeSet != null) { - remove(changeSet); - } - fireResourcesChangedEvent(changeSet, allAffectedResources); - handleAddedResources(changeSet, addedInfos); - } - - /** - * @param changeSet - * @param allAffectedResources - */ - private void fireResourcesChangedEvent(final ActiveChangeSet changeSet, final IResource[] allAffectedResources) { - Object[] listeners = getListeners(); - for (int i = 0; i < listeners.length; i++) { - final IChangeSetChangeListener listener = (IChangeSetChangeListener)listeners[i]; - Platform.run(new ISafeRunnable() { - public void handleException(Throwable exception) { - // Exceptions are logged by the platform - } - public void run() throws Exception { - listener.resourcesChanged(changeSet, allAffectedResources); - } - }); - } - } - - private ActiveChangeSet getChangeSet(SyncInfoSet set) { - for (Iterator iter = activeSets.iterator(); iter.hasNext();) { - ActiveChangeSet changeSet = (ActiveChangeSet) iter.next(); - if (changeSet.getSyncInfoSet() == set) { - return changeSet; - } - } - return null; - } - - /* (non-Javadoc) - * @see org.eclipse.team.core.synchronize.ISyncInfoSetChangeListener#syncInfoSetErrors(org.eclipse.team.core.synchronize.SyncInfoSet, org.eclipse.team.core.ITeamStatus[], org.eclipse.core.runtime.IProgressMonitor) - */ - public void syncInfoSetErrors(SyncInfoSet set, ITeamStatus[] errors, IProgressMonitor monitor) { - // Nothing to do - } -} diff --git a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/CVSUIPlugin.java b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/CVSUIPlugin.java index fd1ee9071..c192e4fe5 100644 --- a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/CVSUIPlugin.java +++ b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/CVSUIPlugin.java @@ -15,12 +15,11 @@ import java.lang.reflect.InvocationTargetException; import java.net.MalformedURLException; import java.net.URL; import java.util.*; + import org.eclipse.core.resources.IResource; import org.eclipse.core.resources.IResourceStatus; import org.eclipse.core.runtime.*; -import org.eclipse.jface.dialogs.ErrorDialog; -import org.eclipse.jface.dialogs.MessageDialog; -import org.eclipse.jface.dialogs.MessageDialogWithToggle; +import org.eclipse.jface.dialogs.*; import org.eclipse.jface.operation.IRunnableWithProgress; import org.eclipse.jface.preference.IPreferenceStore; import org.eclipse.jface.preference.PreferenceConverter; @@ -31,6 +30,7 @@ import org.eclipse.swt.graphics.RGB; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Shell; import org.eclipse.team.core.TeamException; +import org.eclipse.team.core.subscribers.SubscriberChangeSetCollector; import org.eclipse.team.internal.ccvs.core.*; import org.eclipse.team.internal.ccvs.core.client.Command.KSubstOption; import org.eclipse.team.internal.ccvs.core.connection.CVSRepositoryLocation; @@ -38,7 +38,6 @@ import org.eclipse.team.internal.ccvs.ui.console.CVSOutputConsole; import org.eclipse.team.internal.ccvs.ui.model.CVSAdapterFactory; import org.eclipse.team.internal.ccvs.ui.repo.RepositoryManager; import org.eclipse.team.internal.ccvs.ui.repo.RepositoryRoot; -import org.eclipse.team.internal.ccvs.ui.subscriber.CommitSetManager; import org.eclipse.team.internal.ccvs.ui.subscriber.WorkspaceSynchronizeParticipant; import org.eclipse.team.internal.ui.TeamUIPlugin; import org.eclipse.team.internal.ui.Utils; @@ -81,6 +80,8 @@ public class CVSUIPlugin extends AbstractUIPlugin { */ private RepositoryManager repositoryManager; + private SubscriberChangeSetCollector changeSetManager; + /** * CVSUIPlugin constructor * @@ -342,6 +343,13 @@ public class CVSUIPlugin extends AbstractUIPlugin { return repositoryManager; } + public synchronized SubscriberChangeSetCollector getChangeSetManager() { + if (changeSetManager == null) { + changeSetManager = new SubscriberChangeSetCollector(CVSProviderPlugin.getPlugin().getCVSWorkspaceSubscriber()); + } + return changeSetManager; + } + /** * Initializes the table of images used in this plugin. */ @@ -667,7 +675,8 @@ public class CVSUIPlugin extends AbstractUIPlugin { console = new CVSOutputConsole(); - CommitSetManager.getInstance(); + // Must load the change set manager on startup since it listens to deltas + getChangeSetManager(); IPreferenceStore store = getPreferenceStore(); if (store.getBoolean(ICVSUIConstants.PREF_FIRST_STARTUP)) { @@ -707,7 +716,7 @@ public class CVSUIPlugin extends AbstractUIPlugin { } console.shutdown(); - CommitSetManager.getInstance().dispose(); + getChangeSetManager().dispose(); } finally { super.stop(context); } diff --git a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/subscriber/CVSParticipant.java b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/subscriber/CVSParticipant.java index 3c1238db2..354a09202 100644 --- a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/subscriber/CVSParticipant.java +++ b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/subscriber/CVSParticipant.java @@ -37,7 +37,7 @@ public class CVSParticipant extends SubscriberParticipant { // The decorator adds itself to the configuration ILabelDecorator labelDecorator = new CVSParticipantLabelDecorator(configuration); configuration.addLabelDecorator(labelDecorator); - configuration.setProperty(ISynchronizePageConfiguration.P_CHANGE_SET_MANAGER, CommitSetManager.getInstance()); + configuration.setProperty(ISynchronizePageConfiguration.P_CHANGE_SET_MANAGER, CVSUIPlugin.getPlugin().getChangeSetManager()); } /* (non-Javadoc) diff --git a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/subscriber/CVSParticipantLabelDecorator.java b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/subscriber/CVSParticipantLabelDecorator.java index 9f2ba7b57..259e67134 100644 --- a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/subscriber/CVSParticipantLabelDecorator.java +++ b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/subscriber/CVSParticipantLabelDecorator.java @@ -68,7 +68,7 @@ class CVSParticipantLabelDecorator extends LabelProvider implements IPropertyCha } if (element instanceof ChangeSetDiffNode) { ActiveChangeSet set = (ActiveChangeSet)((ChangeSetDiffNode)element).getSet(); - if (CommitSetManager.getInstance().isDefault(set)) { + if (CVSUIPlugin.getPlugin().getChangeSetManager().isDefault(set)) { text = Policy.bind("CommitSetDiffNode.0", text); //$NON-NLS-1$ } } @@ -137,7 +137,7 @@ class CVSParticipantLabelDecorator extends LabelProvider implements IPropertyCha public Font decorateFont(Object element) { if (element instanceof ChangeSetDiffNode) { ActiveChangeSet set = (ActiveChangeSet)((ChangeSetDiffNode)element).getSet(); - if (CommitSetManager.getInstance().isDefault(set)) { + if (CVSUIPlugin.getPlugin().getChangeSetManager().isDefault(set)) { if (boldFont == null) { Font defaultFont = JFaceResources.getDefaultFont(); FontData[] data = defaultFont.getFontData(); diff --git a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/subscriber/ChangeLogModelProvider.java b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/subscriber/ChangeLogModelProvider.java index 2285390c6..e6559dab2 100644 --- a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/subscriber/ChangeLogModelProvider.java +++ b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/subscriber/ChangeLogModelProvider.java @@ -19,9 +19,6 @@ import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IResource; import org.eclipse.core.runtime.*; import org.eclipse.core.runtime.jobs.Job; -import org.eclipse.jface.action.Action; -import org.eclipse.jface.action.MenuManager; -import org.eclipse.jface.dialogs.IDialogSettings; import org.eclipse.jface.dialogs.InputDialog; import org.eclipse.jface.resource.ImageDescriptor; import org.eclipse.jface.util.IPropertyChangeListener; @@ -79,46 +76,8 @@ public class ChangeLogModelProvider extends CompositeModelProvider implements IC private Map rootToProvider = new HashMap(); // Maps ISynchronizeModelElement -> AbstractSynchronizeModelProvider - private int sortCriteria = ChangeLogModelSorter.DATE; - private ViewerSorter embeddedSorter; - // Constants for persisting sorting options - private static final String P_LAST_COMMENTSORT = TeamUIPlugin.ID + ".P_LAST_COMMENT_SORT"; //$NON-NLS-1$ - - /* ***************************************************************************** - * Action that allows changing the model providers sort order. - */ - private class ToggleSortOrderAction extends Action { - private int criteria; - protected ToggleSortOrderAction(String name, int criteria) { - super(name, Action.AS_RADIO_BUTTON); - this.criteria = criteria; - update(); - } - - public void run() { - if (isChecked() && sortCriteria != criteria) { - sortCriteria = criteria; - String key = getSettingsKey(); - IDialogSettings pageSettings = getConfiguration().getSite().getPageSettings(); - if(pageSettings != null) { - pageSettings.put(key, criteria); - } - update(); - ChangeLogModelProvider.this.firePropertyChange(P_VIEWER_SORTER, null, null); - } - } - - public void update() { - setChecked(criteria == sortCriteria); - } - - protected String getSettingsKey() { - return P_LAST_COMMENTSORT; - } - } - /* ***************************************************************************** * Action that will open a commit set in a compare editor. * It provides a comparison between the files in the @@ -270,40 +229,19 @@ public class ChangeLogModelProvider extends CompositeModelProvider implements IC /* ***************************************************************************** * Action group for this layout. It is added and removed for this layout only. */ - public class ChangeLogActionGroup extends ChangeSetManagementActionGroup { - private MenuManager sortByComment; + public class ChangeLogActionGroup extends ChangeSetActionGroup { private OpenCommitSetAction openCommitSet; public void initialize(ISynchronizePageConfiguration configuration) { super.initialize(configuration); - sortByComment = new MenuManager(Policy.bind("ChangeLogModelProvider.0a")); //$NON-NLS-1$ openCommitSet = new OpenCommitSetAction(configuration); appendToGroup( ISynchronizePageConfiguration.P_CONTEXT_MENU, ISynchronizePageConfiguration.FILE_GROUP, openCommitSet); - - appendToGroup( - ISynchronizePageConfiguration.P_CONTEXT_MENU, - ISynchronizePageConfiguration.SORT_GROUP, - sortByComment); - - ChangeLogModelProvider.this.initialize(configuration); - - sortByComment.add(new ToggleSortOrderAction(Policy.bind("ChangeLogModelProvider.1a"), ChangeLogModelSorter.COMMENT)); //$NON-NLS-1$ - sortByComment.add(new ToggleSortOrderAction(Policy.bind("ChangeLogModelProvider.2a"), ChangeLogModelSorter.DATE)); //$NON-NLS-1$ - sortByComment.add(new ToggleSortOrderAction(Policy.bind("ChangeLogModelProvider.3a"), ChangeLogModelSorter.USER)); //$NON-NLS-1$ } - /* (non-Javadoc) - * @see org.eclipse.team.ui.synchronize.SynchronizePageActionGroup#dispose() - */ - public void dispose() { - sortByComment.dispose(); - sortByComment.removeAll(); - super.dispose(); - } - protected ActiveChangeSet createChangeSet(final SubscriberChangeSetManager manager, final SyncInfo[] infos) { + protected ActiveChangeSet createChangeSet(final SubscriberChangeSetCollector manager, final SyncInfo[] infos) { ActiveChangeSet set = manager.createSet(Policy.bind("ChangeLogModelProvider.1"), new SyncInfo[0]); //$NON-NLS-1$ CommitSetDialog dialog = new CommitSetDialog(getConfiguration().getSite().getShell(), set, getResources(infos), Policy.bind("ChangeLogModelProvider.2"), Policy.bind("ChangeLogModelProvider.3")); //$NON-NLS-1$ //$NON-NLS-2$ @@ -412,32 +350,11 @@ public class ChangeLogModelProvider extends CompositeModelProvider implements IC super(configuration, set); Assert.isNotNull(id); this.id = id; - configuration.addMenuGroup(ISynchronizePageConfiguration.P_CONTEXT_MENU, ChangeSetManagementActionGroup.CHANGE_SET_GROUP); + configuration.addMenuGroup(ISynchronizePageConfiguration.P_CONTEXT_MENU, ChangeSetActionGroup.CHANGE_SET_GROUP); if (configuration.getComparisonType() == ISynchronizePageConfiguration.THREE_WAY) { - CommitSetManager.getInstance().addListener(this); + getActiveChangeSetManager().addListener(this); } - initialize(configuration); } - - private void initialize(ISynchronizePageConfiguration configuration) { - try { - IDialogSettings pageSettings = getConfiguration().getSite().getPageSettings(); - if(pageSettings != null) { - sortCriteria = pageSettings.getInt(P_LAST_COMMENTSORT); - } - } catch(NumberFormatException e) { - // ignore and use the defaults. - } - switch (sortCriteria) { - case ChangeLogModelSorter.COMMENT: - case ChangeLogModelSorter.DATE: - case ChangeLogModelSorter.USER: - break; - default: - sortCriteria = ChangeLogModelSorter.DATE; - break; - } - } /* (non-Javadoc) * @see org.eclipse.team.internal.ui.synchronize.AbstractSynchronizeModelProvider#createActionGroup() @@ -662,7 +579,7 @@ public class ChangeLogModelProvider extends CompositeModelProvider implements IC * Add the local change to the appropriate outgoing commit set */ private void addLocalChange(SyncInfo info) { - ActiveChangeSet set = getCommitSetFor(info); + ChangeSet set = getCommitSetFor(info); if (set == null) { // The change is not part of a change set so add it to the root provider addToCommitSetProvider(info, getModelRoot()); @@ -769,7 +686,7 @@ public class ChangeLogModelProvider extends CompositeModelProvider implements IC * Find an existing comment set * TODO: we could do better than a linear lookup? */ - private ChangeSetDiffNode getDiffNodeFor(ActiveChangeSet set) { + private ChangeSetDiffNode getDiffNodeFor(ChangeSet set) { if (set == null) return null; IDiffElement[] elements = getModelRoot().getChildren(); for (int i = 0; i < elements.length; i++) { @@ -789,10 +706,10 @@ public class ChangeLogModelProvider extends CompositeModelProvider implements IC * TODO: we could do better than a linear lookup? * TODO: can a file be in multiple sets? */ - private ActiveChangeSet getCommitSetFor(SyncInfo info) { - ActiveChangeSet[] sets = CommitSetManager.getInstance().getSets(); + private ChangeSet getCommitSetFor(SyncInfo info) { + ChangeSet[] sets = getActiveChangeSetManager().getSets(); for (int i = 0; i < sets.length; i++) { - ActiveChangeSet set = sets[i]; + ChangeSet set = sets[i]; if (set.contains(info.getLocal())) { return set; } @@ -800,6 +717,10 @@ public class ChangeLogModelProvider extends CompositeModelProvider implements IC return null; } + public SubscriberChangeSetCollector getActiveChangeSetManager() { + return CVSUIPlugin.getPlugin().getChangeSetManager(); + } + /* * Return if this sync info should be considered as part of a remote change * meaning that it can be placed inside an incoming commit set (i.e. the @@ -1013,7 +934,7 @@ public class ChangeLogModelProvider extends CompositeModelProvider implements IC if (logs != null) { logs.clearEntries(); } - CommitSetManager.getInstance().removeListener(this); + getActiveChangeSetManager().removeListener(this); super.dispose(); } @@ -1021,7 +942,7 @@ public class ChangeLogModelProvider extends CompositeModelProvider implements IC * @see org.eclipse.team.ui.synchronize.viewers.SynchronizeModelProvider#getViewerSorter() */ public ViewerSorter getViewerSorter() { - return new ChangeLogModelSorter(this, sortCriteria); + return new ChangeSetModelSorter(this, sortCriteria); } /* (non-Javadoc) @@ -1062,21 +983,21 @@ public class ChangeLogModelProvider extends CompositeModelProvider implements IC /* (non-Javadoc) * @see org.eclipse.team.internal.ccvs.ui.subscriber.ICommitSetChangeListener#setAdded(org.eclipse.team.internal.ccvs.ui.subscriber.CommitSet) */ - public void setAdded(ActiveChangeSet set) { + public void setAdded(ChangeSet set) { refresh(set.getResources(), true /* we may not be in the UI thread */); } /* (non-Javadoc) * @see org.eclipse.team.internal.ccvs.ui.subscriber.ICommitSetChangeListener#setRemoved(org.eclipse.team.internal.ccvs.ui.subscriber.CommitSet) */ - public void setRemoved(ActiveChangeSet set) { + public void setRemoved(ChangeSet set) { refresh(set.getResources(), true /* we may not be in the UI thread */); } /* (non-Javadoc) * @see org.eclipse.team.internal.ccvs.ui.subscriber.ICommitSetChangeListener#titleChanged(org.eclipse.team.internal.ccvs.ui.subscriber.CommitSet) */ - public void titleChanged(ActiveChangeSet set) { + public void nameChanged(ChangeSet set) { // We need to refresh all the files because the title is used // to cache the commit set (i.e. used as the hashCode in various maps) refresh(set.getResources(), true /* we may not be in the UI thread */); @@ -1197,7 +1118,7 @@ public class ChangeLogModelProvider extends CompositeModelProvider implements IC /* (non-Javadoc) * @see org.eclipse.team.core.change.IChangeSetChangeListener#defaultSetChanged(org.eclipse.team.core.change.ChangeSet) */ - public void defaultSetChanged(ActiveChangeSet oldDefault, ActiveChangeSet set) { + public void defaultSetChanged(ChangeSet oldDefault, ChangeSet set) { if (oldDefault != null) { refreshNode(getDiffNodeFor(oldDefault)); } @@ -1209,7 +1130,7 @@ public class ChangeLogModelProvider extends CompositeModelProvider implements IC /* (non-Javadoc) * @see org.eclipse.team.core.change.IChangeSetChangeListener#resourcesChanged(org.eclipse.team.core.change.ChangeSet, org.eclipse.core.resources.IResource[]) */ - public void resourcesChanged(ActiveChangeSet set, IResource[] resources) { + public void resourcesChanged(ChangeSet set, IResource[] resources) { // Any element that has been added to the set sould be removed // from the root set ISynchronizeModelProvider provider = getProviderRootedAt(getModelRoot()); diff --git a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/subscriber/ChangeLogModelSorter.java b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/subscriber/ChangeLogModelSorter.java deleted file mode 100644 index 8f8009ac8..000000000 --- a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/subscriber/ChangeLogModelSorter.java +++ /dev/null @@ -1,113 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2000, 2004 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 Corporation - initial API and implementation - *******************************************************************************/ -package org.eclipse.team.internal.ccvs.ui.subscriber; - -import org.eclipse.jface.viewers.Viewer; -import org.eclipse.jface.viewers.ViewerSorter; -import org.eclipse.team.core.subscribers.ActiveChangeSet; -import org.eclipse.team.internal.ccvs.core.ILogEntry; -import org.eclipse.team.internal.ui.synchronize.ChangeSetDiffNode; -import org.eclipse.team.ui.synchronize.ISynchronizeModelElement; - -/** - * Sorter for the change log model provider. - * - * @since 3.0 - */ -public class ChangeLogModelSorter extends ViewerSorter { - - private int commentCriteria; - private ChangeLogModelProvider provider; - - // Comment sorting options - public final static int DATE = 1; - public final static int COMMENT = 2; - public final static int USER = 3; - - public ChangeLogModelSorter(ChangeLogModelProvider provider, int commentCriteria) { - this.provider = provider; - this.commentCriteria = commentCriteria; - } - - protected int classComparison(Object element) { - if (element instanceof ChangeSetDiffNode) { - return 0; - } - if (element instanceof ChangeLogDiffNode) { - return 1; - } - return 2; - } - - protected int compareClass(Object element1, Object element2) { - return classComparison(element1) - classComparison(element2); - } - - protected int compareNames(String s1, String s2) { - return collator.compare(s1, s2); - } - - /* (non-Javadoc) - * Method declared on ViewerSorter. - */ - public int compare(Viewer viewer, Object o1, Object o2) { - //have to deal with non-resources in navigator - //if one or both objects are not resources, returned a comparison - //based on class. - if (o1 instanceof ChangeSetDiffNode && o2 instanceof ChangeSetDiffNode) { - ActiveChangeSet s1 = (ActiveChangeSet)((ChangeSetDiffNode) o1).getSet(); - ActiveChangeSet s2 = (ActiveChangeSet)((ChangeSetDiffNode) o2).getSet(); - return compareNames(s1.getTitle(), s2.getTitle()); - } - - if (o1 instanceof ChangeLogDiffNode && o2 instanceof ChangeLogDiffNode) { - ILogEntry r1 = ((ChangeLogDiffNode) o1).getComment(); - ILogEntry r2 = ((ChangeLogDiffNode) o2).getComment(); - - if (commentCriteria == DATE) - return r1.getDate().compareTo(r2.getDate()); - else if (commentCriteria == COMMENT) - return compareNames(r1.getComment(), r2.getComment()); - else if (commentCriteria == USER) - return compareNames(r1.getAuthor(), r2.getAuthor()); - else - return 0; - } - - if (o1 instanceof ChangeSetDiffNode) - return 1; - else if (o2 instanceof ChangeSetDiffNode) - return -1; - - if (o1 instanceof ChangeLogDiffNode) - return 1; - else if (o2 instanceof ChangeLogDiffNode) - return -1; - - if (o1 instanceof ISynchronizeModelElement && o2 instanceof ISynchronizeModelElement) { - ViewerSorter embeddedSorter = provider.getEmbeddedSorter(); - if (embeddedSorter != null) { - return embeddedSorter.compare(viewer, o1, o2); - } else { - compareNames(((ISynchronizeModelElement)o1).getName(), ((ISynchronizeModelElement)o2).getName()); - } - } else if (o1 instanceof ISynchronizeModelElement) - return 1; - else if (o2 instanceof ISynchronizeModelElement) - return -1; - - return 0; - } - - public int getCommentCriteria() { - return commentCriteria; - } -} diff --git a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/subscriber/ChangeSetModelSorter.java b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/subscriber/ChangeSetModelSorter.java new file mode 100644 index 000000000..ebd77282b --- /dev/null +++ b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/subscriber/ChangeSetModelSorter.java @@ -0,0 +1,113 @@ +/******************************************************************************* + * Copyright (c) 2000, 2004 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 Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.team.internal.ccvs.ui.subscriber; + +import org.eclipse.jface.viewers.Viewer; +import org.eclipse.jface.viewers.ViewerSorter; +import org.eclipse.team.core.subscribers.ActiveChangeSet; +import org.eclipse.team.internal.ccvs.core.ILogEntry; +import org.eclipse.team.internal.ui.synchronize.ChangeSetDiffNode; +import org.eclipse.team.ui.synchronize.ISynchronizeModelElement; + +/** + * Sorter for the change log model provider. + * + * @since 3.0 + */ +public class ChangeSetModelSorter extends ViewerSorter { + + private int commentCriteria; + private ChangeLogModelProvider provider; + + // Comment sorting options + public final static int DATE = 1; + public final static int COMMENT = 2; + public final static int USER = 3; + + public ChangeSetModelSorter(ChangeLogModelProvider provider, int commentCriteria) { + this.provider = provider; + this.commentCriteria = commentCriteria; + } + + protected int classComparison(Object element) { + if (element instanceof ChangeSetDiffNode) { + return 0; + } + if (element instanceof ChangeLogDiffNode) { + return 1; + } + return 2; + } + + protected int compareClass(Object element1, Object element2) { + return classComparison(element1) - classComparison(element2); + } + + protected int compareNames(String s1, String s2) { + return collator.compare(s1, s2); + } + + /* (non-Javadoc) + * Method declared on ViewerSorter. + */ + public int compare(Viewer viewer, Object o1, Object o2) { + //have to deal with non-resources in navigator + //if one or both objects are not resources, returned a comparison + //based on class. + if (o1 instanceof ChangeSetDiffNode && o2 instanceof ChangeSetDiffNode) { + ActiveChangeSet s1 = (ActiveChangeSet)((ChangeSetDiffNode) o1).getSet(); + ActiveChangeSet s2 = (ActiveChangeSet)((ChangeSetDiffNode) o2).getSet(); + return compareNames(s1.getTitle(), s2.getTitle()); + } + + if (o1 instanceof ChangeLogDiffNode && o2 instanceof ChangeLogDiffNode) { + ILogEntry r1 = ((ChangeLogDiffNode) o1).getComment(); + ILogEntry r2 = ((ChangeLogDiffNode) o2).getComment(); + + if (commentCriteria == DATE) + return r1.getDate().compareTo(r2.getDate()); + else if (commentCriteria == COMMENT) + return compareNames(r1.getComment(), r2.getComment()); + else if (commentCriteria == USER) + return compareNames(r1.getAuthor(), r2.getAuthor()); + else + return 0; + } + + if (o1 instanceof ChangeSetDiffNode) + return 1; + else if (o2 instanceof ChangeSetDiffNode) + return -1; + + if (o1 instanceof ChangeLogDiffNode) + return 1; + else if (o2 instanceof ChangeLogDiffNode) + return -1; + + if (o1 instanceof ISynchronizeModelElement && o2 instanceof ISynchronizeModelElement) { + ViewerSorter embeddedSorter = provider.getEmbeddedSorter(); + if (embeddedSorter != null) { + return embeddedSorter.compare(viewer, o1, o2); + } else { + compareNames(((ISynchronizeModelElement)o1).getName(), ((ISynchronizeModelElement)o2).getName()); + } + } else if (o1 instanceof ISynchronizeModelElement) + return 1; + else if (o2 instanceof ISynchronizeModelElement) + return -1; + + return 0; + } + + public int getCommentCriteria() { + return commentCriteria; + } +} diff --git a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/subscriber/CommitSetManager.java b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/subscriber/CommitSetManager.java deleted file mode 100644 index 5cb074ce2..000000000 --- a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/subscriber/CommitSetManager.java +++ /dev/null @@ -1,30 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2000, 2004 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 Corporation - initial API and implementation - *******************************************************************************/ -package org.eclipse.team.internal.ccvs.ui.subscriber; - -import org.eclipse.team.core.subscribers.SubscriberChangeSetManager; -import org.eclipse.team.internal.ccvs.core.CVSProviderPlugin; - -/** - * Thsi class keeps the active commit sets up-to-date. - */ -public class CommitSetManager { - - private static SubscriberChangeSetManager instance; - - public synchronized static SubscriberChangeSetManager getInstance() { - if (instance == null) { - instance = new SubscriberChangeSetManager(CVSProviderPlugin.getPlugin().getCVSWorkspaceSubscriber()); - } - return instance; - } - -} diff --git a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/subscriber/WorkspaceCommitOperation.java b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/subscriber/WorkspaceCommitOperation.java index 7b3795ade..5079542d6 100644 --- a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/subscriber/WorkspaceCommitOperation.java +++ b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/subscriber/WorkspaceCommitOperation.java @@ -22,7 +22,7 @@ import org.eclipse.jface.dialogs.IDialogConstants; import org.eclipse.jface.dialogs.MessageDialog; import org.eclipse.swt.widgets.Shell; import org.eclipse.team.core.TeamException; -import org.eclipse.team.core.subscribers.ActiveChangeSet; +import org.eclipse.team.core.subscribers.ChangeSet; import org.eclipse.team.core.synchronize.SyncInfo; import org.eclipse.team.core.synchronize.SyncInfoSet; import org.eclipse.team.internal.ccvs.core.*; @@ -267,10 +267,10 @@ public class WorkspaceCommitOperation extends CVSSubscriberOperation { private String getProposedComment(IResource[] resourcesToCommit) { StringBuffer comment = new StringBuffer(); - ActiveChangeSet[] sets = CommitSetManager.getInstance().getSets(); + ChangeSet[] sets = CVSUIPlugin.getPlugin().getChangeSetManager().getSets(); int numMatchedSets = 0; for (int i = 0; i < sets.length; i++) { - ActiveChangeSet set = sets[i]; + ChangeSet set = sets[i]; if (containsOne(set, resourcesToCommit)) { if(numMatchedSets > 0) comment.append(System.getProperty("line.separator")); //$NON-NLS-1$ comment.append(set.getComment()); @@ -279,18 +279,8 @@ public class WorkspaceCommitOperation extends CVSSubscriberOperation { } return comment.toString(); } - - private boolean containsAll(ActiveChangeSet set, IResource[] resourcesToCommit) { - for (int j = 0; j < resourcesToCommit.length; j++) { - IResource resource = resourcesToCommit[j]; - if (!set.contains(resource)) { - return false; - } - } - return true; - } - private boolean containsOne(ActiveChangeSet set, IResource[] resourcesToCommit) { + private boolean containsOne(ChangeSet set, IResource[] resourcesToCommit) { for (int j = 0; j < resourcesToCommit.length; j++) { IResource resource = resourcesToCommit[j]; if (set.contains(resource)) { diff --git a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/subscriber/WorkspaceSynchronizeParticipant.java b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/subscriber/WorkspaceSynchronizeParticipant.java index fcde2b625..b52bf3338 100644 --- a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/subscriber/WorkspaceSynchronizeParticipant.java +++ b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/subscriber/WorkspaceSynchronizeParticipant.java @@ -16,6 +16,7 @@ import org.eclipse.jface.preference.PreferencePage; import org.eclipse.jface.viewers.ILabelDecorator; import org.eclipse.team.core.TeamException; import org.eclipse.team.internal.ccvs.core.CVSProviderPlugin; +import org.eclipse.team.internal.ccvs.ui.CVSUIPlugin; import org.eclipse.team.internal.ccvs.ui.Policy; import org.eclipse.team.internal.ccvs.ui.actions.*; import org.eclipse.team.internal.ui.synchronize.ScopableSubscriberParticipant; @@ -151,7 +152,7 @@ public class WorkspaceSynchronizeParticipant extends ScopableSubscriberParticipa // The manager adds itself to the configuration in it's constructor new ChangeLogModelManager(configuration); - configuration.setProperty(ISynchronizePageConfiguration.P_CHANGE_SET_MANAGER, CommitSetManager.getInstance()); + configuration.setProperty(ISynchronizePageConfiguration.P_CHANGE_SET_MANAGER, CVSUIPlugin.getPlugin().getChangeSetManager()); // Add context menu groups here to give the client displaying the // page a chance to remove the context menu diff --git a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/ChangeSetActionGroup.java b/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/ChangeSetActionGroup.java new file mode 100644 index 000000000..8c9d08b78 --- /dev/null +++ b/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/ChangeSetActionGroup.java @@ -0,0 +1,377 @@ +/******************************************************************************* + * Copyright (c) 2000, 2004 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 Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.team.internal.ui.synchronize; + +import java.lang.reflect.InvocationTargetException; + +import org.eclipse.compare.structuremergeviewer.IDiffElement; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.jface.action.*; +import org.eclipse.jface.dialogs.IDialogSettings; +import org.eclipse.jface.viewers.*; +import org.eclipse.swt.widgets.Control; +import org.eclipse.team.core.subscribers.*; +import org.eclipse.team.core.synchronize.FastSyncInfoFilter; +import org.eclipse.team.core.synchronize.SyncInfo; +import org.eclipse.team.core.synchronize.FastSyncInfoFilter.AndSyncInfoFilter; +import org.eclipse.team.core.synchronize.FastSyncInfoFilter.SyncInfoDirectionFilter; +import org.eclipse.team.internal.core.Policy; +import org.eclipse.team.internal.ui.TeamUIPlugin; +import org.eclipse.team.internal.ui.actions.TeamAction; +import org.eclipse.team.ui.synchronize.*; +import org.eclipse.ui.actions.BaseSelectionListenerAction; + +/** + * This action group contributes actions that support the management + * of Change sets to a synchronize page. + */ +public abstract class ChangeSetActionGroup extends SynchronizePageActionGroup { + + /** + * Menu group that can be added to the context menu + */ + public final static String CHANGE_SET_GROUP = "change_set_group"; //$NON-NLS-1$ + + // Constants for persisting sorting options + private static final String P_LAST_COMMENTSORT = TeamUIPlugin.ID + ".P_LAST_COMMENT_SORT"; //$NON-NLS-1$ + + public static final AndSyncInfoFilter OUTGOING_FILE_FILTER = new AndSyncInfoFilter(new FastSyncInfoFilter[] { + new FastSyncInfoFilter() { + public boolean select(SyncInfo info) { + return info.getLocal().getType() == IResource.FILE; + } + }, + new SyncInfoDirectionFilter(new int[] { SyncInfo.OUTGOING, SyncInfo.CONFLICTING }) + }); + + private class CreateChangeSetAction extends SynchronizeModelAction { + + public CreateChangeSetAction(ISynchronizePageConfiguration configuration) { + super(Policy.bind("ChangeLogModelProvider.0"), configuration); //$NON-NLS-1$ + } + + /* (non-Javadoc) + * @see org.eclipse.team.ui.synchronize.SynchronizeModelAction#needsToSaveDirtyEditors() + */ + protected boolean needsToSaveDirtyEditors() { + return false; + } + + /* (non-Javadoc) + * @see org.eclipse.team.ui.synchronize.SynchronizeModelAction#getSyncInfoFilter() + */ + protected FastSyncInfoFilter getSyncInfoFilter() { + return OUTGOING_FILE_FILTER; + } + + /* (non-Javadoc) + * @see org.eclipse.team.ui.synchronize.SynchronizeModelAction#getSubscriberOperation(org.eclipse.team.ui.synchronize.ISynchronizePageConfiguration, org.eclipse.compare.structuremergeviewer.IDiffElement[]) + */ + protected SynchronizeModelOperation getSubscriberOperation(ISynchronizePageConfiguration configuration, IDiffElement[] elements) { + return new SynchronizeModelOperation(configuration, elements) { + public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException { + syncExec(new Runnable() { + public void run() { + SyncInfo[] infos = getSyncInfoSet().getSyncInfos(); + ActiveChangeSet set = createChangeSet(getChangeSetManager(), infos); + getChangeSetManager().add(set); + } + }); + } + }; + } + } + + private abstract class ChangeSetAction extends BaseSelectionListenerAction { + + public ChangeSetAction(String title, ISynchronizePageConfiguration configuration) { + super(title); + } + + /* (non-Javadoc) + * @see org.eclipse.ui.actions.BaseSelectionListenerAction#updateSelection(org.eclipse.jface.viewers.IStructuredSelection) + */ + protected boolean updateSelection(IStructuredSelection selection) { + return getSelectedSet() != null; + } + + protected ActiveChangeSet getSelectedSet() { + IStructuredSelection selection = getStructuredSelection(); + if (selection.size() == 1) { + Object first = selection.getFirstElement(); + return (ActiveChangeSet)TeamAction.getAdapter(first, ActiveChangeSet.class); + } + return null; + } + } + + private class EditChangeSetAction extends ChangeSetAction { + + public EditChangeSetAction(ISynchronizePageConfiguration configuration) { + super(Policy.bind("ChangeLogModelProvider.6"), configuration); //$NON-NLS-1$ + } + + public void run() { + ActiveChangeSet set = getSelectedSet(); + if (set == null) return; + editChangeSet(set); + } + } + + private class MakeDefaultChangeSetAction extends ChangeSetAction { + + public MakeDefaultChangeSetAction(ISynchronizePageConfiguration configuration) { + super(Policy.bind("ChangeLogModelProvider.9"), configuration); //$NON-NLS-1$ + } + + public void run() { + ActiveChangeSet set = getSelectedSet(); + if (set == null) return; + getChangeSetManager().makeDefault(set); + } + + } + + private class AddToChangeSetAction extends SynchronizeModelAction { + + private final ActiveChangeSet set; + + public AddToChangeSetAction(ISynchronizePageConfiguration configuration, ActiveChangeSet set, ISelection selection) { + super(set.getTitle(), configuration); + this.set = set; + selectionChanged(selection); + } + + /* (non-Javadoc) + * @see org.eclipse.team.ui.synchronize.SynchronizeModelAction#getSyncInfoFilter() + */ + protected FastSyncInfoFilter getSyncInfoFilter() { + return OUTGOING_FILE_FILTER; + } + + protected boolean needsToSaveDirtyEditors() { + return false; + } + + /* (non-Javadoc) + * @see org.eclipse.team.ui.synchronize.SynchronizeModelAction#getSubscriberOperation(org.eclipse.team.ui.synchronize.ISynchronizePageConfiguration, org.eclipse.compare.structuremergeviewer.IDiffElement[]) + */ + protected SynchronizeModelOperation getSubscriberOperation(ISynchronizePageConfiguration configuration, IDiffElement[] elements) { + return new SynchronizeModelOperation(configuration, elements) { + public void run(IProgressMonitor monitor) + throws InvocationTargetException, InterruptedException { + set.add(getSyncInfoSet().getSyncInfos()); + } + }; + } + } + + /* ***************************************************************************** + * Action that allows changing the model providers sort order. + */ + private class ToggleSortOrderAction extends Action { + private int criteria; + protected ToggleSortOrderAction(String name, int criteria) { + super(name, Action.AS_RADIO_BUTTON); + this.criteria = criteria; + update(); + } + + public void run() { + if (isChecked() && sortCriteria != criteria) { + sortCriteria = criteria; + String key = getSettingsKey(); + IDialogSettings pageSettings = getConfiguration().getSite().getPageSettings(); + if(pageSettings != null) { + pageSettings.put(key, criteria); + } + update(); + provider.setViewerSorter(getViewerSorter()); + } + } + + public void update() { + setChecked(criteria == sortCriteria); + } + + protected String getSettingsKey() { + return P_LAST_COMMENTSORT; + } + } + + /* + * The model provider for this action group + */ + private ChangeSetModelProvider provider; + + /* + * The actions created by this group + */ + private MenuManager sortByComment; + private CreateChangeSetAction createChangeSet; + private MenuManager addToChangeSet; + private EditChangeSetAction editChangeSet; + private MakeDefaultChangeSetAction makeDefault; + + /* + * Flag indicating whether the active change sets are included + */ + private boolean includesActive = false; + + /* + * The currently chosen sort criteria + */ + private int sortCriteria = ChangeSetModelSorter.DATE; + + public void initialize(ISynchronizePageConfiguration configuration) { + super.initialize(configuration); + sortByComment = new MenuManager(Policy.bind("ChangeLogModelProvider.0a")); //$NON-NLS-1$ + appendToGroup( + ISynchronizePageConfiguration.P_CONTEXT_MENU, + ISynchronizePageConfiguration.SORT_GROUP, + sortByComment); + initializeSortCriteria(configuration); + + sortByComment.add(new ToggleSortOrderAction(Policy.bind("ChangeLogModelProvider.1a"), ChangeSetModelSorter.COMMENT)); //$NON-NLS-1$ + sortByComment.add(new ToggleSortOrderAction(Policy.bind("ChangeLogModelProvider.2a"), ChangeSetModelSorter.DATE)); //$NON-NLS-1$ + sortByComment.add(new ToggleSortOrderAction(Policy.bind("ChangeLogModelProvider.3a"), ChangeSetModelSorter.USER)); //$NON-NLS-1$ + + if (getChangeSetManager() != null) { + includesActive = true; + addToChangeSet = new MenuManager(Policy.bind("ChangeLogModelProvider.12")); //$NON-NLS-1$ + addToChangeSet.setRemoveAllWhenShown(true); + addToChangeSet.addMenuListener(new IMenuListener() { + public void menuAboutToShow(IMenuManager manager) { + addChangeSets(manager); + } + }); + createChangeSet = new CreateChangeSetAction(configuration); + addToChangeSet.add(createChangeSet); + addToChangeSet.add(new Separator()); + editChangeSet = new EditChangeSetAction(configuration); + makeDefault = new MakeDefaultChangeSetAction(configuration); + + appendToGroup( + ISynchronizePageConfiguration.P_CONTEXT_MENU, + CHANGE_SET_GROUP, + addToChangeSet); + appendToGroup( + ISynchronizePageConfiguration.P_CONTEXT_MENU, + CHANGE_SET_GROUP, + editChangeSet); + appendToGroup( + ISynchronizePageConfiguration.P_CONTEXT_MENU, + CHANGE_SET_GROUP, + makeDefault); + } + } + + private void initializeSortCriteria(ISynchronizePageConfiguration configuration) { + try { + IDialogSettings pageSettings = getConfiguration().getSite().getPageSettings(); + if(pageSettings != null) { + sortCriteria = pageSettings.getInt(P_LAST_COMMENTSORT); + } + } catch(NumberFormatException e) { + // ignore and use the defaults. + } + switch (sortCriteria) { + case ChangeSetModelSorter.COMMENT: + case ChangeSetModelSorter.DATE: + case ChangeSetModelSorter.USER: + break; + default: + sortCriteria = ChangeSetModelSorter.DATE; + break; + } + } + + protected void addChangeSets(IMenuManager manager) { + ChangeSet[] sets = getChangeSetManager().getSets(); + ISelection selection = getContext().getSelection(); + createChangeSet.selectionChanged(selection); + addToChangeSet.add(createChangeSet); + addToChangeSet.add(new Separator()); + for (int i = 0; i < sets.length; i++) { + ActiveChangeSet set = (ActiveChangeSet)sets[i]; + AddToChangeSetAction action = new AddToChangeSetAction(getConfiguration(), set, selection); + manager.add(action); + } + } + + /** + * Return the change set manager for the current page. + * @return the change set manager for the current page + */ + protected SubscriberChangeSetCollector getChangeSetManager() { + return (SubscriberChangeSetCollector)getConfiguration().getProperty(ISynchronizePageConfiguration.P_CHANGE_SET_MANAGER); + } + + /* (non-Javadoc) + * @see org.eclipse.team.ui.synchronize.SynchronizePageActionGroup#dispose() + */ + public void dispose() { + if (includesActive) { + addToChangeSet.dispose(); + addToChangeSet.removeAll(); + } + sortByComment.dispose(); + sortByComment.removeAll(); + super.dispose(); + } + + + public void updateActionBars() { + if (includesActive) { + editChangeSet.selectionChanged((IStructuredSelection)getContext().getSelection()); + makeDefault.selectionChanged((IStructuredSelection)getContext().getSelection()); + } + super.updateActionBars(); + } + + private void syncExec(final Runnable runnable) { + final Control ctrl = getConfiguration().getPage().getViewer().getControl(); + if (ctrl != null && !ctrl.isDisposed()) { + ctrl.getDisplay().syncExec(new Runnable() { + public void run() { + if (!ctrl.isDisposed()) { + runnable.run(); + } + } + }); + } + } + + /** + * Return a viewer sorter that utilizes the sort criteria + * selected by the user. + */ + public ViewerSorter getViewerSorter() { + return new ChangeSetModelSorter(provider, sortCriteria); + } + + /** + * Create a change set from the given manager that contains the given sync info. + * This method is invoked from the UI thread. + * @param manager a change set manager + * @param infos the sync info to be added to the change set + * @return the created set. + */ + protected abstract ActiveChangeSet createChangeSet(SubscriberChangeSetCollector manager, SyncInfo[] infos); + + /** + * Edit the title and comment of the given change set. + * This method is invoked from the UI thread. + * @param set the set to be edited + */ + protected abstract void editChangeSet(ActiveChangeSet set); +} diff --git a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/ChangeSetManagementActionGroup.java b/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/ChangeSetManagementActionGroup.java deleted file mode 100644 index 0554a1f1f..000000000 --- a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/ChangeSetManagementActionGroup.java +++ /dev/null @@ -1,278 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2000, 2004 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 Corporation - initial API and implementation - *******************************************************************************/ -package org.eclipse.team.internal.ui.synchronize; - -import java.lang.reflect.InvocationTargetException; - -import org.eclipse.compare.structuremergeviewer.IDiffElement; -import org.eclipse.core.resources.IResource; -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.jface.action.*; -import org.eclipse.jface.viewers.ISelection; -import org.eclipse.jface.viewers.IStructuredSelection; -import org.eclipse.swt.widgets.Control; -import org.eclipse.team.core.subscribers.ActiveChangeSet; -import org.eclipse.team.core.subscribers.SubscriberChangeSetManager; -import org.eclipse.team.core.synchronize.FastSyncInfoFilter; -import org.eclipse.team.core.synchronize.SyncInfo; -import org.eclipse.team.core.synchronize.FastSyncInfoFilter.AndSyncInfoFilter; -import org.eclipse.team.core.synchronize.FastSyncInfoFilter.SyncInfoDirectionFilter; -import org.eclipse.team.internal.core.Policy; -import org.eclipse.team.internal.ui.actions.TeamAction; -import org.eclipse.team.ui.synchronize.*; -import org.eclipse.ui.actions.BaseSelectionListenerAction; - -/** - * This action group contributes actions that support the management - * of Change sets to a synchronize page. - */ -public abstract class ChangeSetManagementActionGroup extends SynchronizePageActionGroup { - - public final static String CHANGE_SET_GROUP = "chaneg_set_group"; //$NON-NLS-1$ - - public static final AndSyncInfoFilter OUTGOING_FILE_FILTER = new AndSyncInfoFilter(new FastSyncInfoFilter[] { - new FastSyncInfoFilter() { - public boolean select(SyncInfo info) { - return info.getLocal().getType() == IResource.FILE; - } - }, - new SyncInfoDirectionFilter(new int[] { SyncInfo.OUTGOING, SyncInfo.CONFLICTING }) - }); - - private class CreateChangeSetAction extends SynchronizeModelAction { - - public CreateChangeSetAction(ISynchronizePageConfiguration configuration) { - super(Policy.bind("ChangeLogModelProvider.0"), configuration); //$NON-NLS-1$ - } - - /* (non-Javadoc) - * @see org.eclipse.team.ui.synchronize.SynchronizeModelAction#needsToSaveDirtyEditors() - */ - protected boolean needsToSaveDirtyEditors() { - return false; - } - - /* (non-Javadoc) - * @see org.eclipse.team.ui.synchronize.SynchronizeModelAction#getSyncInfoFilter() - */ - protected FastSyncInfoFilter getSyncInfoFilter() { - return OUTGOING_FILE_FILTER; - } - - /* (non-Javadoc) - * @see org.eclipse.team.ui.synchronize.SynchronizeModelAction#getSubscriberOperation(org.eclipse.team.ui.synchronize.ISynchronizePageConfiguration, org.eclipse.compare.structuremergeviewer.IDiffElement[]) - */ - protected SynchronizeModelOperation getSubscriberOperation(ISynchronizePageConfiguration configuration, IDiffElement[] elements) { - return new SynchronizeModelOperation(configuration, elements) { - public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException { - syncExec(new Runnable() { - public void run() { - SyncInfo[] infos = getSyncInfoSet().getSyncInfos(); - ActiveChangeSet set = createChangeSet(getChangeSetManager(), infos); - getChangeSetManager().add(set); - } - }); - } - }; - } - } - - private abstract class ChangeSetAction extends BaseSelectionListenerAction { - - public ChangeSetAction(String title, ISynchronizePageConfiguration configuration) { - super(title); - } - - /* (non-Javadoc) - * @see org.eclipse.ui.actions.BaseSelectionListenerAction#updateSelection(org.eclipse.jface.viewers.IStructuredSelection) - */ - protected boolean updateSelection(IStructuredSelection selection) { - return getSelectedSet() != null; - } - - protected ActiveChangeSet getSelectedSet() { - IStructuredSelection selection = getStructuredSelection(); - if (selection.size() == 1) { - Object first = selection.getFirstElement(); - return (ActiveChangeSet)TeamAction.getAdapter(first, ActiveChangeSet.class); - } - return null; - } - } - - private class EditChangeSetAction extends ChangeSetAction { - - public EditChangeSetAction(ISynchronizePageConfiguration configuration) { - super(Policy.bind("ChangeLogModelProvider.6"), configuration); //$NON-NLS-1$ - } - - public void run() { - ActiveChangeSet set = getSelectedSet(); - if (set == null) return; - editChangeSet(set); - } - } - - private class MakeDefaultChangeSetAction extends ChangeSetAction { - - public MakeDefaultChangeSetAction(ISynchronizePageConfiguration configuration) { - super(Policy.bind("ChangeLogModelProvider.9"), configuration); //$NON-NLS-1$ - } - - public void run() { - ActiveChangeSet set = getSelectedSet(); - if (set == null) return; - getChangeSetManager().makeDefault(set); - } - - } - - private class AddToChangeSetAction extends SynchronizeModelAction { - - private final ActiveChangeSet set; - - public AddToChangeSetAction(ISynchronizePageConfiguration configuration, ActiveChangeSet set, ISelection selection) { - super(set.getTitle(), configuration); - this.set = set; - selectionChanged(selection); - } - - /* (non-Javadoc) - * @see org.eclipse.team.ui.synchronize.SynchronizeModelAction#getSyncInfoFilter() - */ - protected FastSyncInfoFilter getSyncInfoFilter() { - return OUTGOING_FILE_FILTER; - } - - protected boolean needsToSaveDirtyEditors() { - return false; - } - - /* (non-Javadoc) - * @see org.eclipse.team.ui.synchronize.SynchronizeModelAction#getSubscriberOperation(org.eclipse.team.ui.synchronize.ISynchronizePageConfiguration, org.eclipse.compare.structuremergeviewer.IDiffElement[]) - */ - protected SynchronizeModelOperation getSubscriberOperation(ISynchronizePageConfiguration configuration, IDiffElement[] elements) { - return new SynchronizeModelOperation(configuration, elements) { - public void run(IProgressMonitor monitor) - throws InvocationTargetException, InterruptedException { - set.add(getSyncInfoSet().getSyncInfos()); - } - }; - } - } - - private CreateChangeSetAction createChangeSet; - private MenuManager addToChangeSet; - private EditChangeSetAction editChangeSet; - private MakeDefaultChangeSetAction makeDefault; - private boolean alive = false; - - public void initialize(ISynchronizePageConfiguration configuration) { - super.initialize(configuration); - if (getChangeSetManager() == null) return; - alive = true; - addToChangeSet = new MenuManager(Policy.bind("ChangeLogModelProvider.12")); //$NON-NLS-1$ - addToChangeSet.setRemoveAllWhenShown(true); - addToChangeSet.addMenuListener(new IMenuListener() { - public void menuAboutToShow(IMenuManager manager) { - addChangeSets(manager); - } - }); - createChangeSet = new CreateChangeSetAction(configuration); - addToChangeSet.add(createChangeSet); - addToChangeSet.add(new Separator()); - editChangeSet = new EditChangeSetAction(configuration); - makeDefault = new MakeDefaultChangeSetAction(configuration); - - appendToGroup( - ISynchronizePageConfiguration.P_CONTEXT_MENU, - CHANGE_SET_GROUP, - addToChangeSet); - appendToGroup( - ISynchronizePageConfiguration.P_CONTEXT_MENU, - CHANGE_SET_GROUP, - editChangeSet); - appendToGroup( - ISynchronizePageConfiguration.P_CONTEXT_MENU, - CHANGE_SET_GROUP, - makeDefault); - } - - protected void addChangeSets(IMenuManager manager) { - ActiveChangeSet[] sets = getChangeSetManager().getSets(); - ISelection selection = getContext().getSelection(); - createChangeSet.selectionChanged(selection); - addToChangeSet.add(createChangeSet); - addToChangeSet.add(new Separator()); - for (int i = 0; i < sets.length; i++) { - ActiveChangeSet set = sets[i]; - AddToChangeSetAction action = new AddToChangeSetAction(getConfiguration(), set, selection); - manager.add(action); - } - } - - /** - * Return the change set manager for the current page. - * @return the change set manager for the current page - */ - protected SubscriberChangeSetManager getChangeSetManager() { - return (SubscriberChangeSetManager)getConfiguration().getProperty(ISynchronizePageConfiguration.P_CHANGE_SET_MANAGER); - } - - /* (non-Javadoc) - * @see org.eclipse.team.ui.synchronize.SynchronizePageActionGroup#dispose() - */ - public void dispose() { - if (alive) { - addToChangeSet.dispose(); - addToChangeSet.removeAll(); - } - super.dispose(); - } - - - public void updateActionBars() { - if (alive) { - editChangeSet.selectionChanged((IStructuredSelection)getContext().getSelection()); - makeDefault.selectionChanged((IStructuredSelection)getContext().getSelection()); - } - super.updateActionBars(); - } - - private void syncExec(final Runnable runnable) { - final Control ctrl = getConfiguration().getPage().getViewer().getControl(); - if (ctrl != null && !ctrl.isDisposed()) { - ctrl.getDisplay().syncExec(new Runnable() { - public void run() { - if (!ctrl.isDisposed()) { - runnable.run(); - } - } - }); - } - } - - /** - * Create a change set from the given manager that contains the given sync info. - * This method is invoked from the UI thread. - * @param manager a change set manager - * @param infos the sync info to be added to the change set - * @return the created set. - */ - protected abstract ActiveChangeSet createChangeSet(SubscriberChangeSetManager manager, SyncInfo[] infos); - - /** - * Edit the title and comment of the given change set. - * This method is invoked from the UI thread. - * @param set the set to be edited - */ - protected abstract void editChangeSet(ActiveChangeSet set); -} diff --git a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/ChangeSetModelProvider.java b/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/ChangeSetModelProvider.java new file mode 100644 index 000000000..3026c7d36 --- /dev/null +++ b/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/ChangeSetModelProvider.java @@ -0,0 +1,112 @@ +/******************************************************************************* + * Copyright (c) 2000, 2004 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 Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.team.internal.ui.synchronize; + +import org.eclipse.compare.structuremergeviewer.IDiffElement; +import org.eclipse.core.resources.IResource; +import org.eclipse.jface.resource.ImageDescriptor; +import org.eclipse.jface.viewers.ViewerSorter; +import org.eclipse.team.core.synchronize.SyncInfo; +import org.eclipse.team.core.synchronize.SyncInfoSet; +import org.eclipse.team.internal.ui.*; +import org.eclipse.team.ui.synchronize.ISynchronizeModelElement; +import org.eclipse.team.ui.synchronize.ISynchronizePageConfiguration; + +/** + * @author Administrator + * + * To change the template for this generated type comment go to + * Window - Preferences - Java - Code Generation - Code and Comments + */ +public class ChangeSetModelProvider extends CompositeModelProvider { + + private ViewerSorter viewerSorter; + + /* ***************************************************************************** + * Descriptor for this model provider + */ + public static class ChangeSetModelProviderDescriptor implements ISynchronizeModelProviderDescriptor { + public static final String ID = TeamUIPlugin.ID + ".modelprovider_cvs_changelog"; //$NON-NLS-1$ + public String getId() { + return ID; + } + public String getName() { + return Policy.bind("ChangeLogModelProvider.5"); //$NON-NLS-1$ + } + public ImageDescriptor getImageDescriptor() { + return TeamUIPlugin.getImageDescriptor(ITeamUIImages.IMG_CHANGE_SET); + } + }; + private static final ChangeSetModelProviderDescriptor descriptor = new ChangeSetModelProviderDescriptor(); + + protected ChangeSetModelProvider(ISynchronizePageConfiguration configuration, SyncInfoSet set) { + super(configuration, set); + } + + /* (non-Javadoc) + * @see org.eclipse.team.internal.ui.synchronize.CompositeModelProvider#handleAddition(org.eclipse.team.core.synchronize.SyncInfo) + */ + protected void handleAddition(SyncInfo info) { + if (isLocalChange(info)) { + handleLocalChange(info); + } + if (isRemoteChange(info)) { + handleRemoteChange(info); + } + } + + /* (non-Javadoc) + * @see org.eclipse.team.internal.ui.synchronize.CompositeModelProvider#handleChange(org.eclipse.team.core.synchronize.SyncInfo) + */ + protected void handleChange(SyncInfo info) { + // TODO Auto-generated method stub + super.handleChange(info); + } + + /* (non-Javadoc) + * @see org.eclipse.team.internal.ui.synchronize.CompositeModelProvider#handleRemoval(org.eclipse.core.resources.IResource) + */ + protected void handleRemoval(IResource resource) { + // TODO Auto-generated method stub + super.handleRemoval(resource); + } + + /* (non-Javadoc) + * @see org.eclipse.team.internal.ui.synchronize.AbstractSynchronizeModelProvider#buildModelObjects(org.eclipse.team.ui.synchronize.ISynchronizeModelElement) + */ + protected IDiffElement[] buildModelObjects(ISynchronizeModelElement node) { + // TODO Auto-generated method stub + return null; + } + + /* (non-Javadoc) + * @see org.eclipse.team.internal.ui.synchronize.ISynchronizeModelProvider#getDescriptor() + */ + public ISynchronizeModelProviderDescriptor getDescriptor() { + return descriptor; + } + + /* (non-Javadoc) + * @see org.eclipse.team.internal.ui.synchronize.ISynchronizeModelProvider#getViewerSorter() + */ + public ViewerSorter getViewerSorter() { + return viewerSorter; + } + + /* + * Method to allow ChangeSetActionGroup to set the viewer sorter of this provider. + */ + /* package */ void setViewerSorter(ViewerSorter viewerSorter) { + this.viewerSorter = viewerSorter; + firePropertyChange(ISynchronizeModelProvider.P_VIEWER_SORTER, null, null); + } + +} diff --git a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/ChangeSetModelSorter.java b/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/ChangeSetModelSorter.java new file mode 100644 index 000000000..d16f8006b --- /dev/null +++ b/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/ChangeSetModelSorter.java @@ -0,0 +1,113 @@ +/******************************************************************************* + * Copyright (c) 2000, 2004 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 Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.team.internal.ui.synchronize; + +import org.eclipse.jface.viewers.Viewer; +import org.eclipse.jface.viewers.ViewerSorter; +import org.eclipse.team.core.subscribers.ActiveChangeSet; +import org.eclipse.team.internal.ccvs.core.ILogEntry; +import org.eclipse.team.internal.ui.synchronize.ChangeSetDiffNode; +import org.eclipse.team.ui.synchronize.ISynchronizeModelElement; + +/** + * Sorter for the change log model provider. + * + * @since 3.0 + */ +public class ChangeSetModelSorter extends ViewerSorter { + + private int commentCriteria; + private ChangeSetModelProvider provider; + + // Comment sorting options + public final static int DATE = 1; + public final static int COMMENT = 2; + public final static int USER = 3; + + public ChangeSetModelSorter(ChangeSetModelProvider provider, int commentCriteria) { + this.provider = provider; + this.commentCriteria = commentCriteria; + } + + protected int classComparison(Object element) { + if (element instanceof ChangeSetDiffNode) { + return 0; + } + if (element instanceof ChangeLogDiffNode) { + return 1; + } + return 2; + } + + protected int compareClass(Object element1, Object element2) { + return classComparison(element1) - classComparison(element2); + } + + protected int compareNames(String s1, String s2) { + return collator.compare(s1, s2); + } + + /* (non-Javadoc) + * Method declared on ViewerSorter. + */ + public int compare(Viewer viewer, Object o1, Object o2) { + //have to deal with non-resources in navigator + //if one or both objects are not resources, returned a comparison + //based on class. + if (o1 instanceof ChangeSetDiffNode && o2 instanceof ChangeSetDiffNode) { + ActiveChangeSet s1 = (ActiveChangeSet)((ChangeSetDiffNode) o1).getSet(); + ActiveChangeSet s2 = (ActiveChangeSet)((ChangeSetDiffNode) o2).getSet(); + return compareNames(s1.getTitle(), s2.getTitle()); + } + + if (o1 instanceof ChangeLogDiffNode && o2 instanceof ChangeLogDiffNode) { + ILogEntry r1 = ((ChangeLogDiffNode) o1).getComment(); + ILogEntry r2 = ((ChangeLogDiffNode) o2).getComment(); + + if (commentCriteria == DATE) + return r1.getDate().compareTo(r2.getDate()); + else if (commentCriteria == COMMENT) + return compareNames(r1.getComment(), r2.getComment()); + else if (commentCriteria == USER) + return compareNames(r1.getAuthor(), r2.getAuthor()); + else + return 0; + } + + if (o1 instanceof ChangeSetDiffNode) + return 1; + else if (o2 instanceof ChangeSetDiffNode) + return -1; + + if (o1 instanceof ChangeLogDiffNode) + return 1; + else if (o2 instanceof ChangeLogDiffNode) + return -1; + + if (o1 instanceof ISynchronizeModelElement && o2 instanceof ISynchronizeModelElement) { + ViewerSorter embeddedSorter = provider.getEmbeddedSorter(); + if (embeddedSorter != null) { + return embeddedSorter.compare(viewer, o1, o2); + } else { + compareNames(((ISynchronizeModelElement)o1).getName(), ((ISynchronizeModelElement)o2).getName()); + } + } else if (o1 instanceof ISynchronizeModelElement) + return 1; + else if (o2 instanceof ISynchronizeModelElement) + return -1; + + return 0; + } + + public int getCommentCriteria() { + return commentCriteria; + } +} diff --git a/tests/org.eclipse.team.tests.cvs.core/.settings/org.eclipse.jdt.core.prefs b/tests/org.eclipse.team.tests.cvs.core/.settings/org.eclipse.jdt.core.prefs index 6a15e9705..a1b8cb5a1 100644 --- a/tests/org.eclipse.team.tests.cvs.core/.settings/org.eclipse.jdt.core.prefs +++ b/tests/org.eclipse.team.tests.cvs.core/.settings/org.eclipse.jdt.core.prefs @@ -1,4 +1,4 @@ -#Wed Aug 11 09:24:44 EDT 2004 +#Tue Sep 28 13:57:33 EDT 2004 org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=disabled org.eclipse.jdt.core.compiler.debug.lineNumber=generate org.eclipse.jdt.core.compiler.problem.indirectStaticAccess=ignore @@ -32,25 +32,25 @@ org.eclipse.jdt.core.compiler.problem.unnecessaryTypeCheck=warning org.eclipse.jdt.core.compiler.problem.assertIdentifier=warning org.eclipse.jdt.core.compiler.problem.fieldHiding=ignore org.eclipse.jdt.core.compiler.problem.possibleAccidentalBooleanAssignment=ignore -org.eclipse.jdt.core.classpath.exclusionPatterns=enabled -org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.2 org.eclipse.jdt.core.compiler.problem.methodWithConstructorName=warning +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.2 +org.eclipse.jdt.core.classpath.exclusionPatterns=enabled org.eclipse.jdt.core.compiler.problem.deprecationInDeprecatedCode=disabled org.eclipse.jdt.core.compiler.problem.missingJavadocCommentsVisibility=public -org.eclipse.jdt.core.compiler.problem.invalidJavadocTagsVisibility=private -org.eclipse.jdt.core.compiler.problem.localVariableHiding=ignore org.eclipse.jdt.core.compiler.problem.overridingPackageDefaultMethod=warning +org.eclipse.jdt.core.compiler.problem.localVariableHiding=ignore +org.eclipse.jdt.core.compiler.problem.invalidJavadocTagsVisibility=private org.eclipse.jdt.core.compiler.problem.deprecationWhenOverridingDeprecatedMethod=disabled org.eclipse.jdt.core.incompatibleJDKLevel=ignore eclipse.preferences.version=1 org.eclipse.jdt.core.circularClasspath=error -org.eclipse.jdt.core.compiler.problem.missingJavadocCommentsOverriding=enabled org.eclipse.jdt.core.compiler.maxProblemPerUnit=100 +org.eclipse.jdt.core.compiler.problem.missingJavadocCommentsOverriding=enabled org.eclipse.jdt.core.compiler.problem.syntheticAccessEmulation=ignore -org.eclipse.jdt.core.compiler.problem.missingJavadocComments=ignore org.eclipse.jdt.core.compiler.problem.missingJavadocTagsVisibility=private -org.eclipse.jdt.core.classpath.multipleOutputLocations=enabled +org.eclipse.jdt.core.compiler.problem.missingJavadocComments=ignore org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownException=warning +org.eclipse.jdt.core.classpath.multipleOutputLocations=enabled org.eclipse.jdt.core.compiler.problem.staticAccessReceiver=warning org.eclipse.jdt.core.compiler.debug.sourceFile=generate org.eclipse.jdt.core.compiler.doc.comment.support=enabled @@ -58,7 +58,7 @@ org.eclipse.jdt.core.compiler.problem.noEffectAssignment=warning org.eclipse.jdt.core.incompleteClasspath=error org.eclipse.jdt.core.compiler.problem.invalidJavadoc=ignore org.eclipse.jdt.core.compiler.problem.missingJavadocTagsOverriding=enabled -org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionWhenOverriding=disabled org.eclipse.jdt.core.compiler.problem.nonExternalizedStringLiteral=ignore +org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionWhenOverriding=disabled org.eclipse.jdt.core.builder.duplicateResourceTask=warning org.eclipse.jdt.core.compiler.problem.unusedParameterWhenOverridingConcrete=disabled diff --git a/tests/org.eclipse.team.tests.cvs.core/launchConfigurations/One CVS Test.launch b/tests/org.eclipse.team.tests.cvs.core/launchConfigurations/One CVS Test.launch index b00b64999..b0ab96d21 100644 --- a/tests/org.eclipse.team.tests.cvs.core/launchConfigurations/One CVS Test.launch +++ b/tests/org.eclipse.team.tests.cvs.core/launchConfigurations/One CVS Test.launch @@ -3,14 +3,14 @@ - + - - + + diff --git a/tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/core/EclipseTest.java b/tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/core/EclipseTest.java index 412a0655c..53ada45f6 100644 --- a/tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/core/EclipseTest.java +++ b/tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/core/EclipseTest.java @@ -381,25 +381,25 @@ public class EclipseTest extends EclipseWorkspaceTest { /* * Create a test project using the currently running test case as the project name prefix */ - protected IProject createProject(String[] strings) throws TeamException, CoreException { + protected IProject createProject(String[] strings) throws CoreException { return createProject(getName(), strings); } /* * Compare two projects by comparing thier providers */ - protected void assertEquals(IProject project1, IProject project2) throws CoreException, TeamException, IOException { + protected void assertEquals(IProject project1, IProject project2) throws CoreException, IOException { assertEquals(project1, project2, false, false); } - protected void assertEquals(IProject project1, IProject project2, boolean includeTimestamps, boolean includeTags) throws CoreException, TeamException, IOException { + protected void assertEquals(IProject project1, IProject project2, boolean includeTimestamps, boolean includeTags) throws CoreException, IOException { assertEquals(getProvider(project1), getProvider(project2), includeTimestamps, includeTags); } /* * Compare CVS team providers by comparing the cvs resource corresponding to the provider's project */ - protected void assertEquals(CVSTeamProvider provider1, CVSTeamProvider provider2, boolean includeTimestamps, boolean includeTags) throws CoreException, TeamException, IOException { + protected void assertEquals(CVSTeamProvider provider1, CVSTeamProvider provider2, boolean includeTimestamps, boolean includeTags) throws CoreException, IOException { assertEquals(Path.EMPTY, CVSWorkspaceRoot.getCVSFolderFor(provider1.getProject()), CVSWorkspaceRoot.getCVSFolderFor(provider2.getProject()), includeTimestamps, includeTags); diff --git a/tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/core/subscriber/CVSChangeSetTests.java b/tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/core/subscriber/CVSChangeSetTests.java index c71fdb45b..bcdb87872 100644 --- a/tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/core/subscriber/CVSChangeSetTests.java +++ b/tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/core/subscriber/CVSChangeSetTests.java @@ -10,6 +10,7 @@ *******************************************************************************/ package org.eclipse.team.tests.ccvs.core.subscriber; +import java.io.ByteArrayInputStream; import java.util.ArrayList; import java.util.List; @@ -17,18 +18,20 @@ import junit.framework.Test; import org.eclipse.compare.structuremergeviewer.IDiffElement; import org.eclipse.core.resources.*; +import org.eclipse.core.runtime.*; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.swt.widgets.Display; import org.eclipse.team.core.TeamException; -import org.eclipse.team.core.subscribers.Subscriber; +import org.eclipse.team.core.subscribers.*; +import org.eclipse.team.core.synchronize.SyncInfo; import org.eclipse.team.internal.ccvs.core.CVSTag; +import org.eclipse.team.internal.ccvs.ui.CVSUIPlugin; import org.eclipse.team.internal.ccvs.ui.subscriber.ChangeLogDiffNode; import org.eclipse.team.internal.ccvs.ui.subscriber.ChangeLogModelManager; import org.eclipse.team.internal.ui.synchronize.*; import org.eclipse.team.tests.ccvs.ui.SynchronizeViewTestAdapter; -import org.eclipse.team.ui.synchronize.ISynchronizeModelElement; -import org.eclipse.team.ui.synchronize.ISynchronizeParticipant; +import org.eclipse.team.ui.synchronize.*; import org.eclipse.ui.PartInitException; /** @@ -51,7 +54,7 @@ public class CVSChangeSetTests extends CVSSyncSubscriberTest { private void assertIncomingChangesInSets(IFile[][] files, String[] messages) throws CoreException { // Get the workspace subscriber which also creates a participant and page in the sync view Subscriber workspaceSubscriber = getWorkspaceSubscriber(); - enableCommitSets(workspaceSubscriber); + enableChangeSets(workspaceSubscriber); refresh(workspaceSubscriber); ISynchronizeModelElement root = getModelRoot(workspaceSubscriber); for (int i = 0; i < messages.length; i++) { @@ -102,11 +105,12 @@ public class CVSChangeSetTests extends CVSSyncSubscriberTest { workspaceSubscriber.refresh(workspaceSubscriber.roots(), IResource.DEPTH_INFINITE, DEFAULT_MONITOR); } - private void enableCommitSets(Subscriber workspaceSubscriber) throws PartInitException { + private void enableChangeSets(Subscriber workspaceSubscriber) throws PartInitException { ISynchronizeParticipant participant = SynchronizeViewTestAdapter.getParticipant(workspaceSubscriber); SubscriberParticipantPage page = (SubscriberParticipantPage)SynchronizeViewTestAdapter.getSyncViewPage(participant); ChangeLogModelManager manager = (ChangeLogModelManager)page.getConfiguration().getProperty(SynchronizePageConfiguration.P_MODEL_MANAGER); manager.setCommitSetsEnabled(true); + page.getConfiguration().setMode(ISynchronizePageConfiguration.BOTH_MODE); } /* @@ -141,6 +145,118 @@ public class CVSChangeSetTests extends CVSSyncSubscriberTest { return provider.getModelRoot(); } + private SubscriberChangeSetCollector getActiveChangeSetManager() { + return CVSUIPlugin.getPlugin().getChangeSetManager(); + } + + /* + * Assert that the given resources make up the given set both directly + * and by what is displayed in the sync view. + */ + private void assertInActiveSet(IResource[] resources, ActiveChangeSet set) throws CoreException { + assertResourcesAreTheSame(resources, set.getResources()); + ISynchronizeModelElement root = getModelRoot(getActiveChangeSetManager().getSubscriber()); + ChangeSetDiffNode node = getChangeSetNodeFor(root, set); + assertNotNull("Change set " + set.getTitle() + " did not appear in the sync view", node); + IResource[] outOfSync = getOutOfSyncResources(node); + assertResourcesAreTheSame(resources, outOfSync); + } + + private ChangeSetDiffNode getChangeSetNodeFor(ISynchronizeModelElement root, ActiveChangeSet set) { + IDiffElement[] children = root.getChildren(); + for (int i = 0; i < children.length; i++) { + IDiffElement element = children[i]; + if (element instanceof ChangeSetDiffNode) { + ChangeSetDiffNode node = (ChangeSetDiffNode)element; + if (node.getSet() == set) { + return node; + } + } + } + return null; + } + + private IResource[] getOutOfSyncResources(ISynchronizeModelElement element) { + ArrayList arrayList = new ArrayList(); + getOutOfSync(element, arrayList); + SyncInfo[] infos = (SyncInfo[]) arrayList.toArray(new SyncInfo[arrayList.size()]); + IResource[] resources = getResources(infos); + return resources; + } + + private IResource[] getResources(SyncInfo[] infos) { + IResource[] resources = new IResource[infos.length]; + for (int i = 0; i < resources.length; i++) { + resources[i] = infos[i].getLocal(); + } + return resources; + } + + private void getOutOfSync(ISynchronizeModelElement node, List list) { + SyncInfo info = getSyncInfo(node); + if (info != null && info.getKind() != SyncInfo.IN_SYNC) { + list.add(info); + } + IDiffElement[] children = node.getChildren(); + for (int i = 0; i < children.length; i++) { + IDiffElement child = children[i]; + getOutOfSync((ISynchronizeModelElement)child, list); + } + return; + } + + private SyncInfo getSyncInfo(ISynchronizeModelElement node) { + if (node instanceof IAdaptable) { + return (SyncInfo)((IAdaptable)node).getAdapter(SyncInfo.class); + } + return null; + } + + private void assertResourcesAreTheSame(IResource[] resources1, IResource[] resources2) { + assertEquals("The number of resources do not match the expected number", resources1.length, resources2.length); + for (int i = 0; i < resources1.length; i++) { + IResource resource = resources1[i]; + boolean found = false; + for (int j = 0; j < resources2.length; j++) { + IResource resource2 = resources2[j]; + if (resource2.equals(resource)) { + found = true; + break; + } + } + assertTrue("Expected resource " + resource.getFullPath().toString() + " was not presebt", found); + } + } + + /* + * Assert that the given resources make up the root set + * displayed in the sync view. The root set is those + * resources that are not part of an active change set. + */ + private void assertInRootSet(IResource[] resources) throws CoreException { + ISynchronizeModelElement[] nodes = getNonChangeSetRoots(getModelRoot(getActiveChangeSetManager().getSubscriber())); + List list = new ArrayList(); + for (int i = 0; i < nodes.length; i++) { + ISynchronizeModelElement element = nodes[i]; + getOutOfSync(element, list); + } + IResource[] outOfSync = getResources((SyncInfo[]) list.toArray(new SyncInfo[list.size()])); + assertResourcesAreTheSame(resources, outOfSync); + + } + + private ISynchronizeModelElement[] getNonChangeSetRoots(ISynchronizeModelElement modelRoot) { + List result = new ArrayList(); + IDiffElement[] children = modelRoot.getChildren(); + for (int i = 0; i < children.length; i++) { + IDiffElement element = children[i]; + if (!(element instanceof ChangeSetDiffNode)) { + result.add(element); + } + } + return (ISynchronizeModelElement[]) result.toArray(new ISynchronizeModelElement[result.size()]); + } + public void testSimpleCommit() throws CoreException { IProject project = createProject(new String[] { "file1.txt", "file2.txt", "folder1/", "folder1/a.txt", "folder1/b.txt"}); @@ -172,4 +288,27 @@ public class CVSChangeSetTests extends CVSSyncSubscriberTest { }, new String[] {message1, message2, message3}); } + public void testSimpleActiveChangeSet() throws CoreException { + IProject project = createProject(new String[] { "file1.txt", "file2.txt", "folder1/", "folder1/a.txt", "folder1/b.txt"}); + // Enable Change Sets + enableChangeSets(getWorkspaceSubscriber()); + // Add a folder and file + IFolder newFolder = project.getFolder("folder2"); + newFolder.create(false, true, null); + IFile newFile = newFolder.getFile("file.txt"); + newFile.create(new ByteArrayInputStream("Hi There".getBytes()), false, null); + // Create an active commit set and assert that it appears in the sync view + SubscriberChangeSetCollector manager = getActiveChangeSetManager(); + ActiveChangeSet set = manager.createSet("test", new SyncInfo[0]); + manager.add(set); + assertInActiveSet(new IResource[] { }, set); + assertInRootSet(new IResource[] {newFolder, newFile}); + // Add the new file to the set and assert that the file is in the set and the folder is still at the root + set.add(new IResource[] { newFile }); + assertInActiveSet(new IResource[] { newFile }, set); + assertInRootSet(new IResource[] {newFolder }); + // Add the folder to the set + set.add(new IResource[] { newFolder }); + assertInActiveSet(new IResource[] { newFolder, newFile }, set); + } } diff --git a/tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/ui/CommitSetTests.java b/tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/ui/CommitSetTests.java index 7af99b722..bc47dd615 100644 --- a/tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/ui/CommitSetTests.java +++ b/tests/org.eclipse.team.tests.cvs.core/src/org/eclipse/team/tests/ccvs/ui/CommitSetTests.java @@ -22,7 +22,7 @@ import org.eclipse.swt.widgets.Display; import org.eclipse.team.core.TeamException; import org.eclipse.team.core.subscribers.*; import org.eclipse.team.internal.ccvs.core.CVSException; -import org.eclipse.team.internal.ccvs.ui.subscriber.CommitSetManager; +import org.eclipse.team.internal.ccvs.ui.CVSUIPlugin; import org.eclipse.team.tests.ccvs.core.EclipseTest; /** @@ -33,21 +33,21 @@ public class CommitSetTests extends EclipseTest { private List addedSets = new ArrayList(); private List removedSets = new ArrayList(); private IChangeSetChangeListener listener = new IChangeSetChangeListener() { - public void setAdded(ActiveChangeSet set) { + public void setAdded(ChangeSet set) { addedSets.add(set); } - public void setRemoved(ActiveChangeSet set) { + public void setRemoved(ChangeSet set) { removedSets.add(set); } - public void titleChanged(ActiveChangeSet set) { + public void nameChanged(ChangeSet set) { // TODO Auto-generated method stub } - public void defaultSetChanged(ActiveChangeSet oldDefault, ActiveChangeSet set) { + public void defaultSetChanged(ChangeSet oldDefault, ChangeSet set) { // TODO Auto-generated method stub } - public void resourcesChanged(ActiveChangeSet set, IResource[] resources) { + public void resourcesChanged(ChangeSet set, IResource[] resources) { // TODO Auto-generated method stub } @@ -74,7 +74,7 @@ public class CommitSetTests extends EclipseTest { */ protected ActiveChangeSet createCommitSet(String title, IFile[] files, boolean manageSet) throws TeamException { assertIsModified(getName(), files); - SubscriberChangeSetManager manager = CommitSetManager.getInstance(); + SubscriberChangeSetCollector manager = CVSUIPlugin.getPlugin().getChangeSetManager(); ActiveChangeSet set = manager.createSet(title, files); assertEquals("Not all files were asdded to the set", files.length, set.getResources().length); if (manageSet) { @@ -101,7 +101,7 @@ public class CommitSetTests extends EclipseTest { } private boolean setIsManaged(ActiveChangeSet set) { - return CommitSetManager.getInstance().contains(set); + return CVSUIPlugin.getPlugin().getChangeSetManager().contains(set); } private void waitForSetAddedEvent(ActiveChangeSet set) { @@ -144,7 +144,7 @@ public class CommitSetTests extends EclipseTest { */ protected void setUp() throws Exception { super.setUp(); - CommitSetManager.getInstance().addListener(listener); + CVSUIPlugin.getPlugin().getChangeSetManager().addListener(listener); } /* (non-Javadoc) @@ -152,7 +152,7 @@ public class CommitSetTests extends EclipseTest { */ protected void tearDown() throws Exception { super.tearDown(); - CommitSetManager.getInstance().removeListener(listener); + CVSUIPlugin.getPlugin().getChangeSetManager().removeListener(listener); } /** -- cgit v1.2.3