KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > team > internal > ui > synchronize > SyncInfoSetChangeSetCollector


1 /*******************************************************************************
2  * Copyright (c) 2000, 2006 IBM Corporation and others.
3  * All rights reserved. This program and the accompanying materials
4  * are made available under the terms of the Eclipse Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/epl-v10.html
7  *
8  * Contributors:
9  * IBM Corporation - initial API and implementation
10  *******************************************************************************/

11 package org.eclipse.team.internal.ui.synchronize;
12
13 import java.util.ArrayList JavaDoc;
14 import java.util.Arrays JavaDoc;
15 import java.util.List JavaDoc;
16
17 import org.eclipse.core.resources.IResource;
18 import org.eclipse.core.resources.IWorkspaceRunnable;
19 import org.eclipse.core.runtime.IProgressMonitor;
20 import org.eclipse.team.core.ITeamStatus;
21 import org.eclipse.team.core.synchronize.*;
22 import org.eclipse.team.internal.core.subscribers.*;
23 import org.eclipse.team.ui.synchronize.ISynchronizePageConfiguration;
24
25 /**
26  * This abstract class provides API for accumulating the <code>SyncInfo</code>
27  * from a seed <code>SyncInfoSet</code> into a set of <code>ChangeSet</code>
28  * instances. It is used to provide the input to a synchronize page when
29  * change sets are enabled.
30  * <p>
31  * This class does not register as a change listener with the seed set. It
32  * is up to clients to invoke either the <code>reset</code> or <code>handleChange</code>
33  * methods in response to seed set changes.
34  * @since 3.1
35  */

36 public abstract class SyncInfoSetChangeSetCollector extends ChangeSetManager {
37     
38     private final ISynchronizePageConfiguration configuration;
39     private ChangeSetModelProvider provider;
40     
41     /*
42      * Listener that will remove sets when they become empty.
43      * The sets in this collector are only modified from either the
44      * UI thread or the provider's event handler thread so updates
45      * done by this listener will update the view properly.
46      */

47     ISyncInfoSetChangeListener changeSetListener = new ISyncInfoSetChangeListener() {
48         
49         /* (non-Javadoc)
50          * @see org.eclipse.team.core.synchronize.ISyncInfoSetChangeListener#syncInfoSetReset(org.eclipse.team.core.synchronize.SyncInfoSet, org.eclipse.core.runtime.IProgressMonitor)
51          */

52         public void syncInfoSetReset(SyncInfoSet set, IProgressMonitor monitor) {
53             handleChangeEvent(set);
54         }
55
56         /* (non-Javadoc)
57          * @see org.eclipse.team.core.synchronize.ISyncInfoSetChangeListener#syncInfoChanged(org.eclipse.team.core.synchronize.ISyncInfoSetChangeEvent, org.eclipse.core.runtime.IProgressMonitor)
58          */

59         public void syncInfoChanged(ISyncInfoSetChangeEvent event, IProgressMonitor monitor) {
60             handleChangeEvent(event.getSet());
61         }
62
63         /* (non-Javadoc)
64          * @see org.eclipse.team.core.synchronize.ISyncInfoSetChangeListener#syncInfoSetErrors(org.eclipse.team.core.synchronize.SyncInfoSet, org.eclipse.team.core.ITeamStatus[], org.eclipse.core.runtime.IProgressMonitor)
65          */

66         public void syncInfoSetErrors(SyncInfoSet set, ITeamStatus[] errors, IProgressMonitor monitor) {
67             // TODO Auto-generated method stub
68
}
69         
70         /*
71          * The collector removes change sets once they are empty
72          */

73         private void handleChangeEvent(SyncInfoSet set) {
74             if (set.isEmpty()) {
75                 ChangeSet changeSet = getChangeSet(set);
76                 if (changeSet != null) {
77                     remove(changeSet);
78                 }
79             }
80         }
81     };
82
83     /**
84      * Create a collector that contains the sync info from the given seed set
85      * @param configuration the set used to determine which sync info
86      * should be included in the change sets.
87      */

88     public SyncInfoSetChangeSetCollector(ISynchronizePageConfiguration configuration) {
89         this.configuration = configuration;
90     }
91
92     /**
93      * Add the given resource sync info nodes to the appropriate
94      * change sets, adding them if necessary.
95      * This method is invoked by the <code>handleChanges</code>
96      * and <code>reset</code> methods
97      * when the model provider changes state. Updates done to the collector
98      * from within this thread will be thread-safe and update the view
99      * properly. Updates done from other threads should perform adds
100      * within a runnable passed to the
101      * <code>performUpdate</code> method to ensure the view is
102      * updated properly.
103      * <p>
104      * Subclasses must override this method.
105      * @param infos the sync infos to add
106      */

107     protected abstract void add(SyncInfo[] infos);
108
109     /**
110      * Remove the given resources from all sets of this collector.
111      * This method is invoked by the <code>handleChanges</code> method
112      * when the model provider changes state. It should not
113      * be invoked by other clients. The model provider
114      * will invoke this method from a particular thread (which may
115      * or may not be the UI thread).
116      * Updates done from other threads should perform removes
117      * within a runnable passed to the
118      * <code>performUpdate</code> method to ensure the view is
119      * updated properly.
120      * <p>
121      * Subclasses may override this method.
122      * @param resources the resources to be removed
123      */

124     protected void remove(IResource[] resources) {
125         ChangeSet[] sets = getSets();
126         for (int i = 0; i < sets.length; i++) {
127             ChangeSet set = sets[i];
128             set.remove(resources);
129         }
130     }
131
132     /* (non-Javadoc)
133      * @see org.eclipse.team.core.subscribers.ChangeSetCollector#getChangeSetChangeListener()
134      */

135     protected ISyncInfoSetChangeListener getChangeSetChangeListener() {
136         return changeSetListener;
137     }
138     
139     /**
140      * Re-populate the change sets from the seed set.
141      * If <code>null</code> is passed, clear any state
142      * but do not re-populate.
143      * <p>
144      * This method is invoked by the model provider when the
145      * model provider changes state. It should not
146      * be invoked by other clients. The model provider
147      * will invoke this method from a particular thread (which may
148      * or may not be the UI thread). Updates done to the collector
149      * from within this thread will be thread-safe and update the view
150      * properly. Updates done from other threads should use the
151      * <code>performUpdate</code> method to ensure the view is
152      * updated properly.
153      * <p>
154      * Subclasses may override this method.
155      * @param seedSet
156      */

157     public void reset(SyncInfoSet seedSet) {
158         // First, remove all the sets
159
ChangeSet[] sets = getSets();
160         for (int i = 0; i < sets.length; i++) {
161             ChangeSet set2 = sets[i];
162             remove(set2);
163         }
164         if (seedSet != null) {
165             add(seedSet.getSyncInfos());
166         }
167     }
168
169     /**
170      * This method is invoked by the model provider when the
171      * seed <code>SyncInfoSet</code> changes. It should not
172      * be invoked by other clients. The model provider
173      * will invoke this method from a particular thread (which may
174      * or may not be the UI thread). Updates done to the collector
175      * from within this thread will be thread-safe and update the view
176      * properly. Updates done from other threads should use the
177      * <code>performUpdate</code> method to ensure the view is
178      * updated properly.
179      * <p>
180      * Subclasses may override this method.
181      * @param event the set change event.
182      */

183     public void handleChange(ISyncInfoSetChangeEvent event) {
184         List JavaDoc removals = new ArrayList JavaDoc();
185         List JavaDoc additions = new ArrayList JavaDoc();
186         removals.addAll(Arrays.asList(event.getRemovedResources()));
187         additions.addAll(Arrays.asList(event.getAddedResources()));
188         SyncInfo[] changed = event.getChangedResources();
189         for (int i = 0; i < changed.length; i++) {
190             SyncInfo info = changed[i];
191             additions.add(info);
192             removals.add(info.getLocal());
193         }
194         if (!removals.isEmpty()) {
195             remove((IResource[]) removals.toArray(new IResource[removals.size()]));
196         }
197         if (!additions.isEmpty()) {
198             add((SyncInfo[]) additions.toArray(new SyncInfo[additions.size()]));
199         }
200     }
201     
202     /**
203      * Return the configuration for the page that is displaying the model created
204      * using this collector.
205      * @return the configuration for the page that is displaying the model created
206      * using this collector
207      */

208     public final ISynchronizePageConfiguration getConfiguration() {
209         return configuration;
210     }
211     
212     /**
213      * Execute the given runnable which updates the sync sets contained
214      * in this collector. This method should be used by subclasses when they
215      * are populating or modifying sets from another thread. In other words,
216      * if the sets of this collector are updated directly in the <code>add</code>
217      * method then this method is not required. However, if sets are created
218      * or modified by another thread, that thread must use this method to ensure
219      * the updates occur in the proper thread in order to ensure thread safety.
220      * <p>
221      * The update may be run in a different thread then the caller.
222      * However, regardless of which thread the update is run in, the view
223      * will be updated once the update is completed.
224      * @param runnable the workspace runnable that updates the sync sets.
225      * @param preserveExpansion whether the expansed items in the view should
226      * remain expanded after the update is performed.
227      * @param monitor a progress monitor
228      */

229     protected final void performUpdate(IWorkspaceRunnable runnable, boolean preserveExpansion, IProgressMonitor monitor) {
230         provider.performUpdate(runnable, preserveExpansion, false /* run in the handler thread and refresh at the end */);
231     }
232     
233     /* (non-javadoc)
234      * Sets the provider for this collector. This method is for internal use only.
235      */

236     public final void setProvider(ChangeSetModelProvider provider) {
237         this.provider = provider;
238     }
239
240     /**
241      * This method should wait until any background processing is
242      * completed. It is for testing purposes. By default, it does not wait at all.
243      * Subclasses that perform work in the background should override.
244      * @param monitor a progress monitor
245      */

246     public void waitUntilDone(IProgressMonitor monitor) {
247         // Do nothing, by default
248
}
249     
250     protected void handleSetAdded(ChangeSet set) {
251         ((CheckedInChangeSet)set).getSyncInfoSet().addSyncSetChangedListener(getChangeSetChangeListener());
252         super.handleSetAdded(set);
253     }
254     
255     protected void handleSetRemoved(ChangeSet set) {
256         ((CheckedInChangeSet)set).getSyncInfoSet().removeSyncSetChangedListener(getChangeSetChangeListener());
257         super.handleSetRemoved(set);
258     }
259     
260     /**
261      * Return the Change Set whose sync info set is the
262      * one given.
263      * @param set a sync info set
264      * @return the change set for the given sync info set
265      */

266     protected ChangeSet getChangeSet(SyncInfoSet set) {
267         ChangeSet[] sets = getSets();
268         for (int i = 0; i < sets.length; i++) {
269             ChangeSet changeSet = sets[i];
270             if (((CheckedInChangeSet)changeSet).getSyncInfoSet() == set) {
271                 return changeSet;
272             }
273         }
274         return null;
275     }
276
277     public SyncInfoTree getSyncInfoSet(ChangeSet set) {
278         return ((CheckedInChangeSet)set).getSyncInfoSet();
279     }
280 }
281
Popular Tags