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    }