001// License: GPL. For details, see LICENSE file.
002package org.openstreetmap.josm.gui.dialogs.relation;
003
004import java.util.ArrayList;
005import java.util.List;
006
007import javax.swing.AbstractListModel;
008
009import org.openstreetmap.josm.data.osm.DataSet;
010import org.openstreetmap.josm.data.osm.DownloadPolicy;
011import org.openstreetmap.josm.data.osm.Relation;
012import org.openstreetmap.josm.data.osm.RelationMember;
013
014/**
015 * This is the model for the {@link ReferringRelationsBrowser}.
016 * <p>
017 * It holds all referrers to a given relation
018 */
019public class ReferringRelationsBrowserModel extends AbstractListModel<Relation> {
020
021    /** the relation */
022    private transient Relation relation;
023    private final transient List<Relation> referrers = new ArrayList<>();
024
025    /**
026     * Constructs a new {@code ReferringRelationsBrowserModel}.
027     * @param relation relation
028     */
029    public ReferringRelationsBrowserModel(Relation relation) {
030        this.relation = relation;
031    }
032
033    protected void fireModelUpdate() {
034        int upper = Math.max(0, referrers.size() -1);
035        fireContentsChanged(this, 0, upper);
036    }
037
038    /**
039     * Sets the relation.
040     * @param relation the relation
041     */
042    public void setRelation(Relation relation) {
043        this.relation = relation;
044        referrers.clear();
045        fireModelUpdate();
046    }
047
048    @Override
049    public Relation getElementAt(int index) {
050        return referrers.get(index);
051    }
052
053    @Override
054    public int getSize() {
055        return referrers.size();
056    }
057
058    protected boolean isReferringRelation(Relation parent) {
059        if (parent == null) return false;
060        for (RelationMember m: parent.getMembers()) {
061            if (m.isRelation()) {
062                Relation child = m.getRelation();
063                if (child.equals(relation)) return true;
064            }
065        }
066        return false;
067    }
068
069    /**
070     * Populates the model with parent referrers.
071     * @param parents parent referrers
072     */
073    public void populate(List<Relation> parents) {
074        referrers.clear();
075        if (parents != null) {
076            for (Relation relation: parents) {
077                if (isReferringRelation(relation)) {
078                    referrers.add(relation);
079                }
080            }
081        }
082        fireModelUpdate();
083    }
084
085    /**
086     * Populates the browser with the list of referring relations in the {@link DataSet} ds.
087     *
088     * @param ds the data set
089     */
090    public void populate(DataSet ds) {
091        referrers.clear();
092        if (ds == null) {
093            fireModelUpdate();
094            return;
095        }
096        for (Relation parent : ds.getRelations()) {
097            if (isReferringRelation(parent)) {
098                referrers.add(parent);
099            }
100        }
101        fireModelUpdate();
102    }
103
104    /**
105     * Determines if reloading the relation is possible/authorized.
106     * @return {@code true} if reloading the relation is possible/authorized
107     */
108    public boolean canReload() {
109        return relation != null && !relation.isNew()
110                && !relation.getDataSet().isLocked()
111                && DownloadPolicy.BLOCKED != relation.getDataSet().getDownloadPolicy();
112    }
113
114    /**
115     * Returns the relation.
116     * @return the relation
117     */
118    public Relation getRelation() {
119        return relation;
120    }
121}