001// License: GPL. For details, see LICENSE file.
002package org.openstreetmap.josm.data.osm;
003
004import java.util.Collection;
005import java.util.HashSet;
006import java.util.Objects;
007import java.util.Set;
008
009public class RelationToChildReference {
010
011    /**
012     * Replies a set of all {@link RelationToChildReference}s for a given child primitive.
013     *
014     * @param child the child primitive
015     * @return  a set of all {@link RelationToChildReference}s for a given child primitive
016     */
017    public static Set<RelationToChildReference> getRelationToChildReferences(OsmPrimitive child) {
018        Set<Relation> parents = OsmPrimitive.getFilteredSet(child.getReferrers(), Relation.class);
019        Set<RelationToChildReference> references = new HashSet<>();
020        for (Relation parent: parents) {
021            for (int i = 0; i < parent.getMembersCount(); i++) {
022                if (parent.getMember(i).refersTo(child)) {
023                    references.add(new RelationToChildReference(parent, i, parent.getMember(i)));
024                }
025            }
026        }
027        return references;
028    }
029
030    /**
031     * Replies a set of all {@link RelationToChildReference}s for a collection of child primitives
032     *
033     * @param children the collection of child primitives
034     * @return  a set of all {@link RelationToChildReference}s to the children in the collection of child
035     * primitives
036     */
037    public static Set<RelationToChildReference> getRelationToChildReferences(Collection<? extends OsmPrimitive> children) {
038        Set<RelationToChildReference> references = new HashSet<>();
039        for (OsmPrimitive child: children) {
040            references.addAll(getRelationToChildReferences(child));
041        }
042        return references;
043    }
044
045    private final Relation parent;
046    private final int position;
047    private final String role;
048    private final OsmPrimitive child;
049
050    public RelationToChildReference(Relation parent, int position, String role, OsmPrimitive child) {
051        this.parent = parent;
052        this.position = position;
053        this.role = role;
054        this.child = child;
055    }
056
057    public RelationToChildReference(Relation parent, int position, RelationMember member) {
058        this.parent = parent;
059        this.position = position;
060        this.role = member.getRole();
061        this.child = member.getMember();
062    }
063
064    public Relation getParent() {
065        return parent;
066    }
067
068    public int getPosition() {
069        return position;
070    }
071
072    public String getRole() {
073        return role;
074    }
075
076    public OsmPrimitive getChild() {
077        return child;
078    }
079
080    @Override
081    public boolean equals(Object obj) {
082        if (this == obj) return true;
083        if (obj == null || getClass() != obj.getClass()) return false;
084        RelationToChildReference that = (RelationToChildReference) obj;
085        return position == that.position &&
086                Objects.equals(parent, that.parent) &&
087                Objects.equals(role, that.role) &&
088                Objects.equals(child, that.child);
089    }
090
091    @Override
092    public int hashCode() {
093        return Objects.hash(parent, position, role, child);
094    }
095}