001 // License: GPL. For details, see LICENSE file.
002 package org.openstreetmap.josm.data.conflict;
003
004 import java.util.Map;
005
006 import org.openstreetmap.josm.data.osm.OsmPrimitive;
007 import org.openstreetmap.josm.data.osm.PrimitiveId;
008
009 /**
010 * Represents a conflict between two {@link OsmPrimitive}s. It is represented as
011 * a pair of {@link OsmPrimitive}s where one element of the pair has the role <em>my</em>
012 * and the other has the role <em>their</em>.
013 * <ul>
014 * <li><code>my</code> is the {@link OsmPrimitive} in the local dataset</li>
015 * <li><code>their</code> is the {@link OsmPrimitive} which caused the conflict when it
016 * it was tried to merge it onto <code>my</code>. <code>their</code> is usually the
017 * {@link OsmPrimitive} from the dataset in another layer or the one retrieved from the server.</li>
018 * </ul>
019 *
020 *
021 */
022 public class Conflict<T extends OsmPrimitive> {
023 private final T my;
024 private final T their;
025 private final boolean isMyDeleted;
026
027 // mergedMap is only set if the conflict results from merging two layers
028 private Map<PrimitiveId, PrimitiveId> mergedMap;
029
030 public Conflict(T my, T their) {
031 this(my, their, false);
032 }
033
034 public Conflict(T my, T their, boolean isMyDeleted) {
035 this.my = my;
036 this.their = their;
037 this.isMyDeleted = isMyDeleted;
038 }
039
040 public T getMy() {
041 return my;
042 }
043
044 public T getTheir() {
045 return their;
046 }
047
048 public boolean isMatchingMy(OsmPrimitive my) {
049 return this.my == my;
050 }
051
052 public boolean isMatchingTheir(OsmPrimitive their) {
053 return this.their == their;
054 }
055
056 /**
057 * Replies true if the primitive <code>primitive</code> is participating
058 * in this conflict
059 *
060 * @param primitive the primitive
061 * @return true if the primitive <code>primitive</code> is participating
062 * in this conflict
063 */
064 public boolean isParticipating(OsmPrimitive primitive) {
065 if (primitive == null) return false;
066 return primitive.getPrimitiveId().equals(my.getPrimitiveId())
067 || primitive.getPrimitiveId().equals(their.getPrimitiveId());
068 }
069
070 /**
071 * Replies true if the primitive with id <code>id</code> is participating
072 * in this conflict
073 *
074 * @param id the primitive id
075 * @return true if the primitive <code>primitive</code> is participating
076 * in this conflict
077 */
078 public boolean isParticipating(PrimitiveId id) {
079 if (id == null) return false;
080 return id.equals(my.getPrimitiveId())
081 || id.equals(their.getPrimitiveId());
082 }
083
084 @Override
085 public int hashCode() {
086 final int prime = 31;
087 int result = 1;
088 result = prime * result + ((my == null) ? 0 : my.hashCode());
089 result = prime * result + ((their == null) ? 0 : their.hashCode());
090 return result;
091 }
092
093 @SuppressWarnings("unchecked")
094 @Override
095 public boolean equals(Object obj) {
096 if (this == obj)
097 return true;
098 if (obj == null)
099 return false;
100 if (getClass() != obj.getClass())
101 return false;
102 Conflict<T> other = (Conflict<T>) obj;
103 if (my != other.my)
104 return false;
105 if(their != other.their)
106 return false;
107 return true;
108 }
109
110 /**
111 *
112 * @return True if my primitive was deleted but it has set non deleted status because it's referred by another
113 * primitive and references to deleted primitives are not allowed.
114 */
115 public boolean isMyDeleted() {
116 return isMyDeleted;
117 }
118
119 public final Map<PrimitiveId, PrimitiveId> getMergedMap() {
120 return mergedMap;
121 }
122
123 public final void setMergedMap(Map<PrimitiveId, PrimitiveId> mergedMap) {
124 this.mergedMap = mergedMap;
125 }
126 }