001// License: GPL. For details, see LICENSE file. 002package org.openstreetmap.josm.actions.relation; 003 004import java.util.Collection; 005import java.util.Collections; 006 007import javax.swing.AbstractAction; 008 009import org.openstreetmap.josm.actions.IPrimitiveAction; 010import org.openstreetmap.josm.data.osm.DownloadPolicy; 011import org.openstreetmap.josm.data.osm.IPrimitive; 012import org.openstreetmap.josm.data.osm.IRelation; 013import org.openstreetmap.josm.data.osm.OsmData; 014import org.openstreetmap.josm.data.osm.OsmUtils; 015import org.openstreetmap.josm.data.osm.Relation; 016import org.openstreetmap.josm.io.NetworkManager; 017import org.openstreetmap.josm.io.OnlineResource; 018import org.openstreetmap.josm.tools.SubclassFilteredCollection; 019import org.openstreetmap.josm.tools.Utils; 020 021/** 022 * Ancestor for all actions that want to work with relation collection and 023 * to be disabled if the collection is empty 024 * @since 5793 025 * @since 13957 (signature) 026 */ 027public abstract class AbstractRelationAction extends AbstractAction implements IPrimitiveAction { 028 /** relation collection */ 029 protected transient Collection<IRelation<?>> relations = Collections.<IRelation<?>>emptySet(); 030 031 /** 032 * Returns the relations contained in the given collection. 033 * @param primitives collection of primitives 034 * @return the relation contained in {@code primitives} 035 */ 036 protected static final Collection<IRelation<?>> getRelations(Collection<? extends IPrimitive> primitives) { 037 if (primitives == null || primitives.isEmpty()) { 038 return Collections.<IRelation<?>>emptySet(); 039 } else { 040 return new SubclassFilteredCollection<>(primitives, IRelation.class::isInstance); 041 } 042 } 043 044 @Override 045 public void setPrimitives(Collection<? extends IPrimitive> primitives) { 046 this.relations = getRelations(primitives); 047 updateEnabledState(); 048 } 049 050 /** 051 * Override in subclasses to update the enabled state of the action when something changes. 052 */ 053 protected void updateEnabledState() { 054 setEnabled(!relations.isEmpty()); 055 } 056 057 protected final boolean canModify() { 058 SubclassFilteredCollection<IRelation<?>, Relation> filteredRelations = Utils.filteredCollection(relations, Relation.class); 059 return OsmUtils.isOsmCollectionEditable(filteredRelations) && filteredRelations.parallelStream().anyMatch(r -> !r.isDeleted()); 060 } 061 062 protected final boolean canDownload() { 063 if (relations.isEmpty()) { 064 return false; 065 } 066 OsmData<?, ?, ?, ?> ds = relations.iterator().next().getDataSet(); 067 return !NetworkManager.isOffline(OnlineResource.OSM_API) 068 && ds != null && !ds.isLocked() && DownloadPolicy.BLOCKED != ds.getDownloadPolicy(); 069 } 070 071 protected void setHelpId(String helpId) { 072 putValue("help", helpId); 073 } 074}