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 }