KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > team > internal > core > subscribers > BatchingChangeSetManager


1 /*******************************************************************************
2  * Copyright (c) 2006, 2007 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.core.subscribers;
12
13 import java.util.*;
14
15 import org.eclipse.core.runtime.*;
16 import org.eclipse.core.runtime.jobs.ILock;
17 import org.eclipse.core.runtime.jobs.Job;
18 import org.eclipse.team.internal.core.Policy;
19
20 /**
21  * A change set manager that batches change event notification.
22  */

23 public class BatchingChangeSetManager extends ChangeSetManager {
24
25     private ILock lock = Job.getJobManager().newLock();
26     
27     public static class CollectorChangeEvent {
28
29         Set added = new HashSet();
30         Set removed = new HashSet();
31         Map changed = new HashMap();
32         private final BatchingChangeSetManager collector;
33         
34         public CollectorChangeEvent(BatchingChangeSetManager collector) {
35             this.collector = collector;
36         }
37
38         private void setAdded(ChangeSet set) {
39             added.add(set);
40             removed.remove(set);
41         }
42
43         private void setRemoved(ChangeSet set) {
44             added.remove(set);
45             removed.add(set);
46             // Do not clear the changes list since clients may want to know what resources
47
// were changed before the set was removed
48
}
49
50         private void changed(ChangeSet changeSet, IPath[] allAffectedResources) {
51             if (added.contains(changeSet))
52                 return;
53             IPath[] paths = (IPath[])changed.get(changeSet);
54             if (paths == null) {
55                 changed.put(changeSet, allAffectedResources);
56             } else {
57                 Set allPaths = new HashSet();
58                 for (int i = 0; i < paths.length; i++) {
59                     IPath path = paths[i];
60                     allPaths.add(path);
61                 }
62                 for (int i = 0; i < allAffectedResources.length; i++) {
63                     IPath path = allAffectedResources[i];
64                     allPaths.add(path);
65                 }
66                 changed.put(changeSet, (IPath[]) allPaths.toArray(new IPath[allPaths.size()]));
67             }
68         }
69
70         public boolean isEmpty() {
71             return changed.isEmpty() && added.isEmpty() && removed.isEmpty();
72         }
73
74         public ChangeSet[] getAddedSets() {
75             return (ChangeSet[]) added.toArray(new ChangeSet[added.size()]);
76         }
77
78         public ChangeSet[] getRemovedSets() {
79             return (ChangeSet[]) removed.toArray(new ChangeSet[removed.size()]);
80         }
81
82         public ChangeSet[] getChangedSets() {
83             return (ChangeSet[]) changed.keySet().toArray(new ChangeSet[changed.size()]);
84         }
85
86         public IPath[] getChangesFor(ChangeSet set) {
87             return (IPath[])changed.get(set);
88         }
89
90         public BatchingChangeSetManager getSource() {
91             return collector;
92         }
93     }
94     
95     public static interface IChangeSetCollectorChangeListener {
96         public void changeSetChanges(CollectorChangeEvent event, IProgressMonitor monitor);
97     }
98     
99     private CollectorChangeEvent changes = new CollectorChangeEvent(this);
100     
101     public void beginInput() {
102         lock.acquire();
103     }
104
105     public void endInput(IProgressMonitor monitor) {
106         try {
107             if (lock.getDepth() == 1) {
108                 // Remain locked while firing the events so the handlers
109
// can expect the set to remain constant while they process the events
110
fireChanges(Policy.monitorFor(monitor));
111             }
112         } finally {
113             lock.release();
114         }
115     }
116     
117     private void fireChanges(final IProgressMonitor monitor) {
118         if (changes.isEmpty()) {
119             return;
120         }
121         final CollectorChangeEvent event = changes;
122         changes = new CollectorChangeEvent(this);
123         Object JavaDoc[] listeners = getListeners();
124         for (int i = 0; i < listeners.length; i++) {
125             final IChangeSetChangeListener listener = (IChangeSetChangeListener)listeners[i];
126             if (listener instanceof IChangeSetCollectorChangeListener) {
127                 final IChangeSetCollectorChangeListener csccl = (IChangeSetCollectorChangeListener) listener;
128                 SafeRunner.run(new ISafeRunnable() {
129                     public void handleException(Throwable JavaDoc exception) {
130                         // Exceptions are logged by the platform
131
}
132                     public void run() throws Exception JavaDoc {
133                         csccl.changeSetChanges(event, monitor);
134                     }
135                 });
136             }
137         }
138     }
139     
140     public void add(ChangeSet set) {
141         try {
142             beginInput();
143             super.add(set);
144             changes.setAdded(set);
145         } finally {
146             endInput(null);
147         }
148     }
149     
150     public void remove(ChangeSet set) {
151         try {
152             beginInput();
153             super.remove(set);
154             changes.setRemoved(set);
155         } finally {
156             endInput(null);
157         }
158     }
159     
160     protected void fireResourcesChangedEvent(ChangeSet changeSet, IPath[] allAffectedResources) {
161         super.fireResourcesChangedEvent(changeSet, allAffectedResources);
162         try {
163             beginInput();
164             changes.changed(changeSet, allAffectedResources);
165         } finally {
166             endInput(null);
167         }
168     }
169     
170     protected void initializeSets() {
171         // Nothing to do
172
}
173 }
174
Popular Tags