source: josm/trunk/src/org/openstreetmap/josm/data/conflict/ConflictCollection.java@ 7509

Last change on this file since 7509 was 7509, checked in by stoecker, 10 years ago

remove tabs

  • Property svn:eol-style set to native
File size: 11.5 KB
Line 
1// License: GPL. For details, see LICENSE file.
2package org.openstreetmap.josm.data.conflict;
3
4import static org.openstreetmap.josm.tools.I18n.tr;
5
6import java.util.ArrayList;
7import java.util.Collection;
8import java.util.HashSet;
9import java.util.Iterator;
10import java.util.List;
11import java.util.Set;
12import java.util.concurrent.CopyOnWriteArrayList;
13
14import org.openstreetmap.josm.data.osm.Node;
15import org.openstreetmap.josm.data.osm.OsmPrimitive;
16import org.openstreetmap.josm.data.osm.Relation;
17import org.openstreetmap.josm.data.osm.Way;
18import org.openstreetmap.josm.tools.CheckParameterUtil;
19import org.openstreetmap.josm.tools.Predicate;
20import org.openstreetmap.josm.tools.Utils;
21
22/**
23 * This is a collection of {@link Conflict}s. This collection is {@link Iterable}, i.e.
24 * it can be used in <code>for</code>-loops as follows:
25 * <pre>
26 * ConflictCollection conflictCollection = ....
27 *
28 * for(Conflict c : conflictCollection) {
29 * // do something
30 * }
31 * </pre>
32 *
33 * This collection emits an event when the content of the collection changes. You can register
34 * and unregister for these events using:
35 * <ul>
36 * <li>{@link #addConflictListener(IConflictListener)}</li>
37 * <li>{@link #removeConflictListener(IConflictListener)}</li>
38 * </ul>
39 */
40public class ConflictCollection implements Iterable<Conflict<? extends OsmPrimitive>>{
41 private final List<Conflict<? extends OsmPrimitive>> conflicts;
42 private CopyOnWriteArrayList<IConflictListener> listeners;
43
44 private static class FilterPredicate implements Predicate<Conflict<? extends OsmPrimitive>> {
45
46 private final Class<? extends OsmPrimitive> c;
47
48 public FilterPredicate(Class<? extends OsmPrimitive> c) {
49 this.c = c;
50 }
51
52 @Override
53 public boolean evaluate(Conflict<? extends OsmPrimitive> conflict) {
54 return conflict != null && c.isInstance(conflict.getMy());
55 }
56 }
57
58 private static final FilterPredicate NODE_FILTER_PREDICATE = new FilterPredicate(Node.class);
59 private static final FilterPredicate WAY_FILTER_PREDICATE = new FilterPredicate(Way.class);
60 private static final FilterPredicate RELATION_FILTER_PREDICATE = new FilterPredicate(Relation.class);
61
62 /**
63 * Constructs a new {@code ConflictCollection}.
64 */
65 public ConflictCollection() {
66 conflicts = new ArrayList<>();
67 listeners = new CopyOnWriteArrayList<>();
68 }
69
70 /**
71 * Adds the specified conflict listener, if not already present.
72 * @param listener The conflict listener to add
73 */
74 public void addConflictListener(IConflictListener listener) {
75 if (listener != null) {
76 listeners.addIfAbsent(listener);
77 }
78 }
79
80 /**
81 * Removes the specified conflict listener.
82 * @param listener The conflict listener to remove
83 */
84 public void removeConflictListener(IConflictListener listener) {
85 listeners.remove(listener);
86 }
87
88 protected void fireConflictAdded() {
89 for (IConflictListener listener : listeners) {
90 listener.onConflictsAdded(this);
91 }
92 }
93
94 protected void fireConflictRemoved() {
95 for (IConflictListener listener : listeners) {
96 listener.onConflictsRemoved(this);
97 }
98 }
99
100 /**
101 * Adds a conflict to the collection
102 *
103 * @param conflict the conflict
104 * @exception IllegalStateException thrown, if this collection already includes a
105 * conflict for conflict.getMy()
106 */
107 protected void addConflict(Conflict<?> conflict) throws IllegalStateException {
108 if (hasConflictForMy(conflict.getMy()))
109 throw new IllegalStateException(tr("Already registered a conflict for primitive ''{0}''.", conflict.getMy().toString()));
110 if (!conflicts.contains(conflict)) {
111 conflicts.add(conflict);
112 }
113 }
114
115 /**
116 * Adds a conflict to the collection of conflicts.
117 *
118 * @param conflict the conflict to add. Must not be null.
119 * @throws IllegalArgumentException thrown, if conflict is null
120 * @throws IllegalStateException thrown if this collection already includes a conflict for conflict.getMy()
121 *
122 */
123 public void add(Conflict<?> conflict) throws IllegalStateException {
124 CheckParameterUtil.ensureParameterNotNull(conflict, "conflict");
125 addConflict(conflict);
126 fireConflictAdded();
127 }
128
129 /**
130 * Add the conflicts in <code>otherConflicts</code> to this collection of conflicts
131 *
132 * @param otherConflicts the collection of conflicts. Does nothing is conflicts is null.
133 */
134 public void add(Collection<Conflict<?>> otherConflicts) {
135 if (otherConflicts == null) return;
136 for(Conflict<?> c : otherConflicts) {
137 addConflict(c);
138 }
139 fireConflictAdded();
140 }
141
142 /**
143 * Adds a conflict for the pair of {@link OsmPrimitive}s given by <code>my</code> and
144 * <code>their</code>.
145 *
146 * @param my my primitive
147 * @param their their primitive
148 */
149 public void add(OsmPrimitive my, OsmPrimitive their) {
150 addConflict(new Conflict<>(my, their));
151 fireConflictAdded();
152 }
153
154 /**
155 * removes a conflict from this collection
156 *
157 * @param conflict the conflict
158 */
159 public void remove(Conflict<?> conflict) {
160 conflicts.remove(conflict);
161 fireConflictRemoved();
162 }
163
164 /**
165 * removes the conflict registered for {@link OsmPrimitive} <code>my</code> if any
166 *
167 * @param my the primitive
168 */
169 public void remove(OsmPrimitive my) {
170 Iterator<Conflict<?>> it = iterator();
171 while(it.hasNext()) {
172 if (it.next().isMatchingMy(my)) {
173 it.remove();
174 }
175 }
176 fireConflictRemoved();
177 }
178
179 /**
180 * Replies the conflict for the {@link OsmPrimitive} <code>my</code>, null
181 * if no such conflict exists.
182 *
183 * @param my my primitive
184 * @return the conflict for the {@link OsmPrimitive} <code>my</code>, null
185 * if no such conflict exists.
186 */
187 public Conflict<?> getConflictForMy(OsmPrimitive my) {
188 for(Conflict<?> c : conflicts) {
189 if (c.isMatchingMy(my))
190 return c;
191 }
192 return null;
193 }
194 /**
195 * Replies the conflict for the {@link OsmPrimitive} <code>their</code>, null
196 * if no such conflict exists.
197 *
198 * @param their their primitive
199 * @return the conflict for the {@link OsmPrimitive} <code>their</code>, null
200 * if no such conflict exists.
201 */
202 public Conflict<?> getConflictForTheir(OsmPrimitive their) {
203 for(Conflict<?> c : conflicts) {
204 if (c.isMatchingTheir(their))
205 return c;
206 }
207 return null;
208 }
209
210 /**
211 * Replies true, if this collection includes a conflict for <code>my</code>.
212 *
213 * @param my my primitive
214 * @return true, if this collection includes a conflict for <code>my</code>; false, otherwise
215 */
216 public boolean hasConflictForMy(OsmPrimitive my) {
217 return getConflictForMy(my) != null;
218 }
219
220 /**
221 * Replies true, if this collection includes a given conflict
222 *
223 * @param c the conflict
224 * @return true, if this collection includes the conflict; false, otherwise
225 */
226 public boolean hasConflict(Conflict<?> c) {
227 return hasConflictForMy(c.getMy());
228 }
229
230 /**
231 * Replies true, if this collection includes a conflict for <code>their</code>.
232 *
233 * @param their their primitive
234 * @return true, if this collection includes a conflict for <code>their</code>; false, otherwise
235 */
236 public boolean hasConflictForTheir(OsmPrimitive their) {
237 return getConflictForTheir(their) != null;
238 }
239
240 /**
241 * Removes any conflicts for the {@link OsmPrimitive} <code>my</code>.
242 *
243 * @param my the primitive
244 */
245 public void removeForMy(OsmPrimitive my) {
246 Iterator<Conflict<?>> it = iterator();
247 while(it.hasNext()) {
248 if (it.next().isMatchingMy(my)) {
249 it.remove();
250 }
251 }
252 }
253
254 /**
255 * Removes any conflicts for the {@link OsmPrimitive} <code>their</code>.
256 *
257 * @param their the primitive
258 */
259 public void removeForTheir(OsmPrimitive their) {
260 Iterator<Conflict<?>> it = iterator();
261 while(it.hasNext()) {
262 if (it.next().isMatchingTheir(their)) {
263 it.remove();
264 }
265 }
266 }
267
268 /**
269 * Replies the conflicts as list.
270 *
271 * @return the list of conflicts
272 */
273 public List<Conflict<?>> get() {
274 return conflicts;
275 }
276
277 /**
278 * Replies the size of the collection
279 *
280 * @return the size of the collection
281 */
282 public int size() {
283 return conflicts.size();
284 }
285
286 /**
287 * Replies the conflict at position <code>idx</code>
288 *
289 * @param idx the index
290 * @return the conflict at position <code>idx</code>
291 */
292 public Conflict<?> get(int idx) {
293 return conflicts.get(idx);
294 }
295
296 /**
297 * Replies the iterator for this collection.
298 *
299 * @return the iterator
300 */
301 @Override
302 public Iterator<Conflict<?>> iterator() {
303 return conflicts.iterator();
304 }
305
306 /**
307 * Adds all conflicts from another collection.
308 * @param other The other collection of conflicts to add
309 */
310 public void add(ConflictCollection other) {
311 for (Conflict<?> c : other) {
312 add(c);
313 }
314 }
315
316 /**
317 * Replies the set of {@link OsmPrimitive} which participate in the role
318 * of "my" in the conflicts managed by this collection.
319 *
320 * @return the set of {@link OsmPrimitive} which participate in the role
321 * of "my" in the conflicts managed by this collection.
322 */
323 public Set<OsmPrimitive> getMyConflictParties() {
324 HashSet<OsmPrimitive> ret = new HashSet<>();
325 for (Conflict<?> c: conflicts) {
326 ret.add(c.getMy());
327 }
328 return ret;
329 }
330 /**
331 * Replies the set of {@link OsmPrimitive} which participate in the role
332 * of "their" in the conflicts managed by this collection.
333 *
334 * @return the set of {@link OsmPrimitive} which participate in the role
335 * of "their" in the conflicts managed by this collection.
336 */
337 public Set<OsmPrimitive> getTheirConflictParties() {
338 HashSet<OsmPrimitive> ret = new HashSet<>();
339 for (Conflict<?> c: conflicts) {
340 ret.add(c.getTheir());
341 }
342 return ret;
343 }
344
345 /**
346 * Replies true if this collection is empty
347 *
348 * @return true, if this collection is empty; false, otherwise
349 */
350 public boolean isEmpty() {
351 return size() == 0;
352 }
353
354 @Override
355 public String toString() {
356 return conflicts.toString();
357 }
358
359 /**
360 * Returns the list of conflicts involving nodes.
361 * @return The list of conflicts involving nodes.
362 * @since 6555
363 */
364 public final Collection<Conflict<? extends OsmPrimitive>> getNodeConflicts() {
365 return Utils.filter(conflicts, NODE_FILTER_PREDICATE);
366 }
367
368 /**
369 * Returns the list of conflicts involving nodes.
370 * @return The list of conflicts involving nodes.
371 * @since 6555
372 */
373 public final Collection<Conflict<? extends OsmPrimitive>> getWayConflicts() {
374 return Utils.filter(conflicts, WAY_FILTER_PREDICATE);
375 }
376
377 /**
378 * Returns the list of conflicts involving nodes.
379 * @return The list of conflicts involving nodes.
380 * @since 6555
381 */
382 public final Collection<Conflict<? extends OsmPrimitive>> getRelationConflicts() {
383 return Utils.filter(conflicts, RELATION_FILTER_PREDICATE);
384 }
385}
Note: See TracBrowser for help on using the repository browser.