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 = null;
020    private String myTagValue = null;
021    private String theirTagValue = null;
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 thrown if key is null
047     * @throws IllegalArgumentException thrown if my is null
048     * @throws IllegalArgumentException thrown 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     * @exception IllegalArgumentException thrown if decision is null
064     *
065     */
066    public void decide(MergeDecisionType decision) throws IllegalArgumentException {
067        CheckParameterUtil.ensureParameterNotNull(decision, "decision");
068        this.mergeDecision = decision;
069    }
070
071    public String getKey() {
072        return key;
073    }
074
075    public String getMyTagValue() {
076        return myTagValue;
077    }
078
079    public String getTheirTagValue() {
080        return theirTagValue;
081    }
082
083    public MergeDecisionType getMergeDecision() {
084        return mergeDecision;
085    }
086
087    /**
088     * applies the current merge decisions to the tag set of an OSM primitive. The
089     * OSM primitive has the role of primitive in the local dataset ('my' primitive,
090     * not 'their' primitive)
091     *
092     * @param primitive the OSM primitive. Must not be null.
093     * @exception IllegalArgumentException thrown, if primitive is null
094     * @exception IllegalStateException  thrown, if this merge item is undecided
095     */
096    public void applyToMyPrimitive(OsmPrimitive primitive) throws IllegalArgumentException, IllegalStateException {
097        CheckParameterUtil.ensureParameterNotNull(primitive, "primitive");
098        if (mergeDecision == MergeDecisionType.UNDECIDED) {
099            throw new IllegalStateException(tr("Cannot apply undecided tag merge item."));
100        } else if (mergeDecision == MergeDecisionType.KEEP_THEIR) {
101            if (theirTagValue == null) {
102                primitive.remove(key);
103            } else {
104                primitive.put(key, theirTagValue);
105            }
106        } else if (mergeDecision == MergeDecisionType.KEEP_MINE) {
107            if (myTagValue == null) {
108                primitive.remove(key);
109            } else {
110                primitive.put(key, myTagValue);
111            }
112        } else {
113           // should not happen
114        }
115    }
116}