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

Last change on this file since 8338 was 8338, checked in by Don-vip, 9 years ago

fix squid:S1319 - Declarations should use Java collection interfaces rather than specific implementation classes

  • Property svn:eol-style set to native
File size: 11.4 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 * @throws IllegalStateException if this collection already includes a conflict for conflict.getMy()
105 */
106 protected void addConflict(Conflict<?> conflict) {
107 if (hasConflictForMy(conflict.getMy()))
108 throw new IllegalStateException(tr("Already registered a conflict for primitive ''{0}''.", conflict.getMy().toString()));
109 if (!conflicts.contains(conflict)) {
110 conflicts.add(conflict);
111 }
112 }
113
114 /**
115 * Adds a conflict to the collection of conflicts.
116 *
117 * @param conflict the conflict to add. Must not be null.
118 * @throws IllegalArgumentException if conflict is null
119 * @throws IllegalStateException if this collection already includes a conflict for conflict.getMy()
120 */
121 public void add(Conflict<?> conflict) {
122 CheckParameterUtil.ensureParameterNotNull(conflict, "conflict");
123 addConflict(conflict);
124 fireConflictAdded();
125 }
126
127 /**
128 * Add the conflicts in <code>otherConflicts</code> to this collection of conflicts
129 *
130 * @param otherConflicts the collection of conflicts. Does nothing is conflicts is null.
131 */
132 public void add(Collection<Conflict<?>> otherConflicts) {
133 if (otherConflicts == null) return;
134 for(Conflict<?> c : otherConflicts) {
135 addConflict(c);
136 }
137 fireConflictAdded();
138 }
139
140 /**
141 * Adds a conflict for the pair of {@link OsmPrimitive}s given by <code>my</code> and
142 * <code>their</code>.
143 *
144 * @param my my primitive
145 * @param their their primitive
146 */
147 public void add(OsmPrimitive my, OsmPrimitive their) {
148 addConflict(new Conflict<>(my, their));
149 fireConflictAdded();
150 }
151
152 /**
153 * removes a conflict from this collection
154 *
155 * @param conflict the conflict
156 */
157 public void remove(Conflict<?> conflict) {
158 conflicts.remove(conflict);
159 fireConflictRemoved();
160 }
161
162 /**
163 * removes the conflict registered for {@link OsmPrimitive} <code>my</code> if any
164 *
165 * @param my the primitive
166 */
167 public void remove(OsmPrimitive my) {
168 Iterator<Conflict<?>> it = iterator();
169 while(it.hasNext()) {
170 if (it.next().isMatchingMy(my)) {
171 it.remove();
172 }
173 }
174 fireConflictRemoved();
175 }
176
177 /**
178 * Replies the conflict for the {@link OsmPrimitive} <code>my</code>, null
179 * if no such conflict exists.
180 *
181 * @param my my primitive
182 * @return the conflict for the {@link OsmPrimitive} <code>my</code>, null
183 * if no such conflict exists.
184 */
185 public Conflict<?> getConflictForMy(OsmPrimitive my) {
186 for(Conflict<?> c : conflicts) {
187 if (c.isMatchingMy(my))
188 return c;
189 }
190 return null;
191 }
192 /**
193 * Replies the conflict for the {@link OsmPrimitive} <code>their</code>, null
194 * if no such conflict exists.
195 *
196 * @param their their primitive
197 * @return the conflict for the {@link OsmPrimitive} <code>their</code>, null
198 * if no such conflict exists.
199 */
200 public Conflict<?> getConflictForTheir(OsmPrimitive their) {
201 for(Conflict<?> c : conflicts) {
202 if (c.isMatchingTheir(their))
203 return c;
204 }
205 return null;
206 }
207
208 /**
209 * Replies true, if this collection includes a conflict for <code>my</code>.
210 *
211 * @param my my primitive
212 * @return true, if this collection includes a conflict for <code>my</code>; false, otherwise
213 */
214 public boolean hasConflictForMy(OsmPrimitive my) {
215 return getConflictForMy(my) != null;
216 }
217
218 /**
219 * Replies true, if this collection includes a given conflict
220 *
221 * @param c the conflict
222 * @return true, if this collection includes the conflict; false, otherwise
223 */
224 public boolean hasConflict(Conflict<?> c) {
225 return hasConflictForMy(c.getMy());
226 }
227
228 /**
229 * Replies true, if this collection includes a conflict for <code>their</code>.
230 *
231 * @param their their primitive
232 * @return true, if this collection includes a conflict for <code>their</code>; false, otherwise
233 */
234 public boolean hasConflictForTheir(OsmPrimitive their) {
235 return getConflictForTheir(their) != null;
236 }
237
238 /**
239 * Removes any conflicts for the {@link OsmPrimitive} <code>my</code>.
240 *
241 * @param my the primitive
242 */
243 public void removeForMy(OsmPrimitive my) {
244 Iterator<Conflict<?>> it = iterator();
245 while(it.hasNext()) {
246 if (it.next().isMatchingMy(my)) {
247 it.remove();
248 }
249 }
250 }
251
252 /**
253 * Removes any conflicts for the {@link OsmPrimitive} <code>their</code>.
254 *
255 * @param their the primitive
256 */
257 public void removeForTheir(OsmPrimitive their) {
258 Iterator<Conflict<?>> it = iterator();
259 while(it.hasNext()) {
260 if (it.next().isMatchingTheir(their)) {
261 it.remove();
262 }
263 }
264 }
265
266 /**
267 * Replies the conflicts as list.
268 *
269 * @return the list of conflicts
270 */
271 public List<Conflict<?>> get() {
272 return conflicts;
273 }
274
275 /**
276 * Replies the size of the collection
277 *
278 * @return the size of the collection
279 */
280 public int size() {
281 return conflicts.size();
282 }
283
284 /**
285 * Replies the conflict at position <code>idx</code>
286 *
287 * @param idx the index
288 * @return the conflict at position <code>idx</code>
289 */
290 public Conflict<?> get(int idx) {
291 return conflicts.get(idx);
292 }
293
294 /**
295 * Replies the iterator for this collection.
296 *
297 * @return the iterator
298 */
299 @Override
300 public Iterator<Conflict<?>> iterator() {
301 return conflicts.iterator();
302 }
303
304 /**
305 * Adds all conflicts from another collection.
306 * @param other The other collection of conflicts to add
307 */
308 public void add(ConflictCollection other) {
309 for (Conflict<?> c : other) {
310 add(c);
311 }
312 }
313
314 /**
315 * Replies the set of {@link OsmPrimitive} which participate in the role
316 * of "my" in the conflicts managed by this collection.
317 *
318 * @return the set of {@link OsmPrimitive} which participate in the role
319 * of "my" in the conflicts managed by this collection.
320 */
321 public Set<OsmPrimitive> getMyConflictParties() {
322 Set<OsmPrimitive> ret = new HashSet<>();
323 for (Conflict<?> c: conflicts) {
324 ret.add(c.getMy());
325 }
326 return ret;
327 }
328
329 /**
330 * Replies the set of {@link OsmPrimitive} which participate in the role
331 * of "their" in the conflicts managed by this collection.
332 *
333 * @return the set of {@link OsmPrimitive} which participate in the role
334 * of "their" in the conflicts managed by this collection.
335 */
336 public Set<OsmPrimitive> getTheirConflictParties() {
337 Set<OsmPrimitive> ret = new HashSet<>();
338 for (Conflict<?> c: conflicts) {
339 ret.add(c.getTheir());
340 }
341 return ret;
342 }
343
344 /**
345 * Replies true if this collection is empty
346 *
347 * @return true, if this collection is empty; false, otherwise
348 */
349 public boolean isEmpty() {
350 return size() == 0;
351 }
352
353 @Override
354 public String toString() {
355 return conflicts.toString();
356 }
357
358 /**
359 * Returns the list of conflicts involving nodes.
360 * @return The list of conflicts involving nodes.
361 * @since 6555
362 */
363 public final Collection<Conflict<? extends OsmPrimitive>> getNodeConflicts() {
364 return Utils.filter(conflicts, NODE_FILTER_PREDICATE);
365 }
366
367 /**
368 * Returns the list of conflicts involving nodes.
369 * @return The list of conflicts involving nodes.
370 * @since 6555
371 */
372 public final Collection<Conflict<? extends OsmPrimitive>> getWayConflicts() {
373 return Utils.filter(conflicts, WAY_FILTER_PREDICATE);
374 }
375
376 /**
377 * Returns the list of conflicts involving nodes.
378 * @return The list of conflicts involving nodes.
379 * @since 6555
380 */
381 public final Collection<Conflict<? extends OsmPrimitive>> getRelationConflicts() {
382 return Utils.filter(conflicts, RELATION_FILTER_PREDICATE);
383 }
384}
Note: See TracBrowser for help on using the repository browser.