001// License: GPL. For details, see LICENSE file.
002package org.openstreetmap.josm.gui.conflict.pair.relation;
003
004import static org.openstreetmap.josm.tools.I18n.tr;
005
006import java.util.ArrayList;
007import java.util.Map;
008
009import javax.swing.table.DefaultTableModel;
010
011import org.openstreetmap.josm.command.conflict.RelationMemberConflictResolverCommand;
012import org.openstreetmap.josm.data.conflict.Conflict;
013import org.openstreetmap.josm.data.osm.OsmPrimitive;
014import org.openstreetmap.josm.data.osm.PrimitiveId;
015import org.openstreetmap.josm.data.osm.Relation;
016import org.openstreetmap.josm.data.osm.RelationMember;
017import org.openstreetmap.josm.gui.conflict.pair.AbstractListMergeModel;
018import org.openstreetmap.josm.gui.conflict.pair.ListRole;
019import org.openstreetmap.josm.tools.CheckParameterUtil;
020
021/**
022 * The model for merging two lists of relation members
023 * @since 1631
024 */
025public class RelationMemberListMergeModel extends AbstractListMergeModel<RelationMember, RelationMemberConflictResolverCommand> {
026
027    @Override
028    public boolean isEqualEntry(RelationMember e1, RelationMember e2) {
029        return e1.equals(e2);
030    }
031
032    @Override
033    protected void buildMergedEntriesTableModel() {
034        // the table model for merged entries is different because it supports
035        // editing cells in the first column
036        //
037        mergedEntriesTableModel = this.new EntriesTableModel(ListRole.MERGED_ENTRIES) {
038            @Override
039            public boolean isCellEditable(int row, int column) {
040                switch(column) {
041                case 1: return true;
042                default: return false;
043                }
044            }
045        };
046    }
047
048    @Override
049    protected void setValueAt(DefaultTableModel model, Object value, int row, int col) {
050        if (model == getMergedTableModel() && col == 1) {
051            RelationMember memberOld = getMergedEntries().get(row);
052            RelationMember memberNew = new RelationMember((String) value, memberOld.getMember());
053            getMergedEntries().remove(row);
054            getMergedEntries().add(row, memberNew);
055            fireModelDataChanged();
056        }
057    }
058
059    /**
060     * populates the model with the relation members in relation my and their
061     *
062     * @param my my relation. Must not be null.
063     * @param their their relation. Must not be null.
064     * @param mergedMap The map of merged primitives if the conflict results from merging two layers
065     *
066     * @throws IllegalArgumentException if my is null
067     * @throws IllegalArgumentException if their is null
068     */
069    public void populate(Relation my, Relation their, Map<PrimitiveId, PrimitiveId> mergedMap) {
070        initPopulate(my, their, mergedMap);
071
072        for (RelationMember n : my.getMembers()) {
073            getMyEntries().add(n);
074        }
075        for (RelationMember n : their.getMembers()) {
076            getTheirEntries().add(n);
077        }
078        if (myAndTheirEntriesEqual()) {
079            for (RelationMember m : getMyEntries()) {
080                getMergedEntries().add(cloneEntryForMergedList(m));
081            }
082            setFrozen(true);
083        } else {
084            setFrozen(false);
085        }
086
087        fireModelDataChanged();
088    }
089
090    @Override
091    protected RelationMember cloneEntryForMergedList(RelationMember entry) {
092        return new RelationMember(entry.getRole(), getMyPrimitive(entry));
093    }
094
095    @Override
096    public OsmPrimitive getMyPrimitive(RelationMember entry) {
097        return getMyPrimitiveById(entry.getMember());
098    }
099
100    @Override
101    public RelationMemberConflictResolverCommand buildResolveCommand(Conflict<? extends OsmPrimitive> conflict) {
102        CheckParameterUtil.ensureParameterNotNull(conflict, "conflict");
103        if (!isFrozen())
104            throw new IllegalArgumentException(tr("Merged members not frozen yet. Cannot build resolution command"));
105        return new RelationMemberConflictResolverCommand(conflict, new ArrayList<>(getMergedEntries()));
106    }
107}