001// License: GPL. For details, see LICENSE file.
002package org.openstreetmap.josm.gui.conflict.pair.tags;
003
004import static org.openstreetmap.josm.tools.I18n.tr;
005
006import org.openstreetmap.josm.data.osm.OsmPrimitive;
007import org.openstreetmap.josm.gui.conflict.pair.MergeDecisionType;
008import org.openstreetmap.josm.tools.CheckParameterUtil;
009
010/**
011 * TagMergeItem represents an individual merge action for a specific pair of key/value.
012 *
013 * A TagMergeItem manages the values of the two key/value-pairs and keeps track of the applied
014 * merge decision.
015 *
016 */
017public class TagMergeItem {
018
019    private String key;
020    private String myTagValue;
021    private String theirTagValue;
022    private MergeDecisionType mergeDecision = MergeDecisionType.UNDECIDED;
023
024    /**
025     * constructor
026     *
027     * @param key  the common tag key. Must not be null.
028     * @param myTagValue  the value for this key known in the local dataset
029     * @param theirTagValue  the value for this key known in the dataset on the server
030     * @throws IllegalArgumentException if key is null
031     */
032    public TagMergeItem(String key, String myTagValue, String theirTagValue) {
033        CheckParameterUtil.ensureParameterNotNull(key, "key");
034        this.key  = key;
035        this.myTagValue = myTagValue;
036        this.theirTagValue = theirTagValue;
037        this.mergeDecision = MergeDecisionType.UNDECIDED;
038    }
039
040    /**
041     * constructor
042     *
043     * @param key  the tag key common to the merged OSM primitives. Must not be null.
044     * @param my  my version of the OSM primitive (i.e. the version known in the local dataset). Must not be null.
045     * @param their their version of the OSM primitive (i.e. the version known on the server). Must not be null.
046     * @throws IllegalArgumentException if key is null
047     * @throws IllegalArgumentException if my is null
048     * @throws IllegalArgumentException if their is null
049     */
050    public TagMergeItem(String key, OsmPrimitive my, OsmPrimitive their) {
051        CheckParameterUtil.ensureParameterNotNull(key, "key");
052        CheckParameterUtil.ensureParameterNotNull(my, "my");
053        CheckParameterUtil.ensureParameterNotNull(their, "their");
054        this.key = key;
055        myTagValue = my.get(key);
056        theirTagValue = their.get(key);
057    }
058
059    /**
060     * applies a merge decision to this merge item
061     *
062     * @param decision the merge decision. Must not be null.
063     * @throws IllegalArgumentException if decision is null
064     */
065    public void decide(MergeDecisionType decision) {
066        CheckParameterUtil.ensureParameterNotNull(decision, "decision");
067        this.mergeDecision = decision;
068    }
069
070    public String getKey() {
071        return key;
072    }
073
074    public String getMyTagValue() {
075        return myTagValue;
076    }
077
078    public String getTheirTagValue() {
079        return theirTagValue;
080    }
081
082    public MergeDecisionType getMergeDecision() {
083        return mergeDecision;
084    }
085
086    /**
087     * applies the current merge decisions to the tag set of an OSM primitive. The
088     * OSM primitive has the role of primitive in the local dataset ('my' primitive,
089     * not 'their' primitive)
090     *
091     * @param primitive the OSM primitive. Must not be null.
092     * @throws IllegalArgumentException if primitive is null
093     * @throws IllegalStateException if this merge item is undecided
094     */
095    public void applyToMyPrimitive(OsmPrimitive primitive) {
096        CheckParameterUtil.ensureParameterNotNull(primitive, "primitive");
097        if (mergeDecision == MergeDecisionType.UNDECIDED) {
098            throw new IllegalStateException(tr("Cannot apply undecided tag merge item."));
099        } else if (mergeDecision == MergeDecisionType.KEEP_THEIR) {
100            if (theirTagValue == null) {
101                primitive.remove(key);
102            } else {
103                primitive.put(key, theirTagValue);
104            }
105        } else if (mergeDecision == MergeDecisionType.KEEP_MINE) {
106            if (myTagValue == null) {
107                primitive.remove(key);
108            } else {
109                primitive.put(key, myTagValue);
110            }
111        }
112    }
113}