Changeset 17981 in josm


Ignore:
Timestamp:
2021-07-10T20:52:12+02:00 (3 years ago)
Author:
Don-vip
Message:

fix #21041 - Tagging preset validation: clone properly primitives children for nominal execution of validation tests

Location:
trunk/src/org/openstreetmap/josm
Files:
8 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/org/openstreetmap/josm/command/DeleteCommand.java

    r17896 r17981  
    2424import org.openstreetmap.josm.data.osm.DataSet;
    2525import org.openstreetmap.josm.data.osm.DefaultNameFormatter;
     26import org.openstreetmap.josm.data.osm.IPrimitive;
    2627import org.openstreetmap.josm.data.osm.Node;
    2728import org.openstreetmap.josm.data.osm.OsmPrimitive;
     
    193194                    throw new IllegalArgumentException(osm + " is already deleted");
    194195                clonedPrimitives.put(osm, osm.save());
    195 
    196                 if (osm instanceof Way) {
    197                     ((Way) osm).setNodes(null);
    198                 } else if (osm instanceof Relation) {
    199                     ((Relation) osm).setMembers(null);
    200                 }
     196                IPrimitive.resetPrimitiveChildren(osm);
    201197            }
    202198
  • trunk/src/org/openstreetmap/josm/data/osm/DataSet.java

    r17464 r17981  
    203203        copyFrom.getReadLock().lock();
    204204        try {
    205             Map<OsmPrimitive, OsmPrimitive> primMap = new HashMap<>();
    206             for (Node n : copyFrom.getNodes()) {
    207                 Node newNode = new Node(n);
    208                 primMap.put(n, newNode);
    209                 addPrimitive(newNode);
    210             }
    211             for (Way w : copyFrom.getWays()) {
    212                 Way newWay = new Way(w, false, false);
    213                 primMap.put(w, newWay);
    214                 List<Node> newNodes = w.getNodes().stream()
    215                         .map(n -> (Node) primMap.get(n))
    216                         .collect(Collectors.toList());
    217                 newWay.setNodes(newNodes);
    218                 addPrimitive(newWay);
    219             }
    220             // Because relations can have other relations as members we first clone all relations
    221             // and then get the cloned members
    222             Collection<Relation> relations = copyFrom.getRelations();
    223             for (Relation r : relations) {
    224                 Relation newRelation = new Relation(r, false, false);
    225                 primMap.put(r, newRelation);
    226                 addPrimitive(newRelation);
    227             }
    228             for (Relation r : relations) {
    229                 ((Relation) primMap.get(r)).setMembers(r.getMembers().stream()
    230                         .map(rm -> new RelationMember(rm.getRole(), primMap.get(rm.getMember())))
    231                         .collect(Collectors.toList()));
    232             }
     205            clonePrimitives(copyFrom.getNodes(), copyFrom.getWays(), copyFrom.getRelations());
    233206            DataSourceAddedEvent addedEvent = new DataSourceAddedEvent(this,
    234207                    new LinkedHashSet<>(dataSources), copyFrom.dataSources.stream());
     
    261234
    262235    /**
     236     * Clones the specified primitives into this data set.
     237     * @param nodes nodes to clone
     238     * @param ways ways to clone
     239     * @param relations relations to clone
     240     * @since 17981
     241     */
     242    public void clonePrimitives(Iterable<Node> nodes, Iterable<Way> ways, Iterable<Relation> relations) {
     243        Map<OsmPrimitive, OsmPrimitive> primMap = new HashMap<>();
     244        for (Node n : nodes) {
     245            Node newNode = new Node(n);
     246            primMap.put(n, newNode);
     247            addPrimitive(newNode);
     248        }
     249        for (Way w : ways) {
     250            Way newWay = new Way(w, false, false);
     251            primMap.put(w, newWay);
     252            List<Node> newNodes = w.getNodes().stream()
     253                    .map(n -> (Node) primMap.get(n))
     254                    .collect(Collectors.toList());
     255            newWay.setNodes(newNodes);
     256            addPrimitive(newWay);
     257        }
     258        // Because relations can have other relations as members we first clone all relations
     259        // and then get the cloned members
     260        for (Relation r : relations) {
     261            Relation newRelation = new Relation(r, false, false);
     262            primMap.put(r, newRelation);
     263            addPrimitive(newRelation);
     264        }
     265        for (Relation r : relations) {
     266            ((Relation) primMap.get(r)).setMembers(r.getMembers().stream()
     267                    .map(rm -> new RelationMember(rm.getRole(), primMap.get(rm.getMember())))
     268                    .collect(Collectors.toList()));
     269        }
     270    }
     271
     272    /**
    263273     * Adds a new data source.
    264274     * @param source data source to add
     
    505515            firePrimitivesAdded(Collections.singletonList(primitive), false);
    506516        });
     517    }
     518
     519    /**
     520     * Adds recursively a primitive, and all its children, to the dataset.
     521     *
     522     * @param primitive the primitive.
     523     * @throws IllegalStateException if the dataset is read-only
     524     * @since 17981
     525     */
     526    public void addPrimitiveRecursive(OsmPrimitive primitive) {
     527        if (primitive instanceof Way) {
     528            ((Way) primitive).getNodes().forEach(n -> addPrimitiveRecursive(n));
     529        } else if (primitive instanceof Relation) {
     530            ((Relation) primitive).getMembers().forEach(m -> addPrimitiveRecursive(m.getMember()));
     531        }
     532        addPrimitive(primitive);
    507533    }
    508534
  • trunk/src/org/openstreetmap/josm/data/osm/DataSetMerger.java

    r17341 r17981  
    187187                List<OsmPrimitive> referrers = target.getReferrers();
    188188                if (referrers.isEmpty()) {
    189                     resetPrimitive(target);
     189                    IPrimitive.resetPrimitiveChildren(target);
    190190                    target.mergeFrom(source);
    191191                    target.setDeleted(true);
     
    212212            // This can be because of cross-referenced relations.
    213213            for (OsmPrimitive osm: objectsToDelete) {
    214                 resetPrimitive(osm);
     214                IPrimitive.resetPrimitiveChildren(osm);
    215215            }
    216216            for (OsmPrimitive osm: objectsToDelete) {
     
    218218                osm.mergeFrom(sourceDataSet.getPrimitiveById(osm.getPrimitiveId()));
    219219            }
    220         }
    221     }
    222 
    223     private static void resetPrimitive(OsmPrimitive osm) {
    224         if (osm instanceof Way) {
    225             ((Way) osm).setNodes(null);
    226         } else if (osm instanceof Relation) {
    227             ((Relation) osm).setMembers(null);
    228220        }
    229221    }
  • trunk/src/org/openstreetmap/josm/data/osm/IPrimitive.java

    r17862 r17981  
    533533                || getInterestingTags().equals(other.getInterestingTags());
    534534    }
     535
     536    /**
     537     * Resets primitive children, if applicable.
     538     * @param p primitive
     539     * @since 17981
     540     */
     541    static void resetPrimitiveChildren(IPrimitive p) {
     542        if (p instanceof IWay<?>) {
     543            ((IWay<?>) p).setNodes(null);
     544        } else if (p instanceof IRelation<?>) {
     545            ((IRelation<?>) p).setMembers(null);
     546        }
     547    }
    535548}
  • trunk/src/org/openstreetmap/josm/data/osm/Relation.java

    r17752 r17981  
    399399
    400400    /**
    401      * Replies the set of  {@link OsmPrimitive}s referred to by at least one
    402      * member of this relation
     401     * Replies the set of {@link OsmPrimitive}s referred to by at least one member of this relation.
    403402     *
    404      * @return the set of  {@link OsmPrimitive}s referred to by at least one
    405      * member of this relation
     403     * @return the set of {@link OsmPrimitive}s referred to by at least one member of this relation
    406404     * @see #getMemberPrimitivesList()
    407405     */
  • trunk/src/org/openstreetmap/josm/data/osm/Way.java

    r17752 r17981  
    197197    /**
    198198     * Constructs a new {@code Way} from an existing {@code Way}.
    199      * This  adds links from all way nodes to the clone. See #19885 for possible memory leaks.
     199     * This adds links from all way nodes to the clone. See #19885 for possible memory leaks.
    200200     * @param original The original {@code Way} to be identically cloned. Must not be null
    201201     * @param clearMetadata If {@code true}, clears the OSM id and other metadata as defined by {@link #clearOsmMetadata}.
     
    214214    /**
    215215     * Constructs a new {@code Way} from an existing {@code Way}.
    216      * This  adds links from all way nodes to the clone. See #19885 for possible memory leaks.
     216     * This adds links from all way nodes to the clone. See #19885 for possible memory leaks.
    217217     * @param original The original {@code Way} to be identically cloned. Must not be null
    218218     * @param clearMetadata If {@code true}, clears the OSM id and other metadata as defined by {@link #clearOsmMetadata}.
     
    226226    /**
    227227     * Constructs a new {@code Way} from an existing {@code Way} (including its id).
    228      * This  adds links from all way nodes to the clone. See #19885 for possible memory leaks.
     228     * This adds links from all way nodes to the clone. See #19885 for possible memory leaks.
    229229     * @param original The original {@code Way} to be identically cloned. Must not be null
    230230     * @since 86
  • trunk/src/org/openstreetmap/josm/data/validation/tests/MapCSSTagCheckerAsserts.java

    r17792 r17981  
    1818import org.openstreetmap.josm.data.osm.OsmPrimitive;
    1919import org.openstreetmap.josm.data.osm.OsmUtils;
    20 import org.openstreetmap.josm.data.osm.Relation;
    21 import org.openstreetmap.josm.data.osm.Way;
    2220import org.openstreetmap.josm.data.validation.TestError;
    2321import org.openstreetmap.josm.gui.mappaint.mapcss.ConditionFactory;
     
    6361            checksToRun.add(Collections.singleton(check));
    6462            // Add primitive to dataset to avoid DataIntegrityProblemException when evaluating selectors
    65             addPrimitive(ds, p);
     63            ds.addPrimitiveRecursive(p);
    6664            final Collection<TestError> pErrors = MapCSSTagChecker.getErrorsForPrimitive(p, true, checksToRun);
    6765            Logging.debug("- Errors: {0}", pErrors);
     
    8886        previousChecks.clear();
    8987        previousChecks.trimToSize();
    90     }
    91 
    92     private static void addPrimitive(DataSet ds, OsmPrimitive p) {
    93         if (p instanceof Way) {
    94             ((Way) p).getNodes().forEach(n -> addPrimitive(ds, n));
    95         } else if (p instanceof Relation) {
    96             ((Relation) p).getMembers().forEach(m -> addPrimitive(ds, m.getMember()));
    97         }
    98         ds.addPrimitive(p);
    9988    }
    10089
  • trunk/src/org/openstreetmap/josm/gui/tagging/presets/TaggingPresetValidation.java

    r17643 r17981  
    22package org.openstreetmap.josm.gui.tagging.presets;
    33
     4import static java.util.Collections.singleton;
     5import static org.openstreetmap.josm.tools.I18n.tr;
     6
     7import java.util.ArrayList;
     8import java.util.Arrays;
     9import java.util.Collection;
     10import java.util.List;
     11
     12import javax.swing.JLabel;
     13
    414import org.openstreetmap.josm.command.Command;
    515import org.openstreetmap.josm.data.osm.DataSet;
    6 import org.openstreetmap.josm.data.osm.Node;
     16import org.openstreetmap.josm.data.osm.FilterModel;
     17import org.openstreetmap.josm.data.osm.INode;
     18import org.openstreetmap.josm.data.osm.IRelation;
     19import org.openstreetmap.josm.data.osm.IWay;
    720import org.openstreetmap.josm.data.osm.OsmPrimitive;
    8 import org.openstreetmap.josm.data.osm.Relation;
    921import org.openstreetmap.josm.data.osm.Tag;
    10 import org.openstreetmap.josm.data.osm.Way;
    1122import org.openstreetmap.josm.data.preferences.sources.ValidatorPrefHelper;
    1223import org.openstreetmap.josm.data.validation.OsmValidator;
     
    1728import org.openstreetmap.josm.gui.util.GuiHelper;
    1829import org.openstreetmap.josm.tools.Logging;
     30import org.openstreetmap.josm.tools.SubclassFilteredCollection;
    1931import org.openstreetmap.josm.tools.Utils;
    20 
    21 import javax.swing.JLabel;
    22 import java.util.ArrayList;
    23 import java.util.Arrays;
    24 import java.util.Collections;
    25 import java.util.List;
    26 
    27 import static org.openstreetmap.josm.tools.I18n.tr;
    2832
    2933/**
     
    7478
    7579    static OsmPrimitive applyChangedTags(OsmPrimitive original, List<Tag> changedTags) {
    76         OsmPrimitive primitive = clone(original);
    77         new DataSet(primitive);
    78         Command command = TaggingPreset.createCommand(Collections.singleton(primitive), changedTags);
     80        DataSet ds = new DataSet();
     81        Collection<OsmPrimitive> primitives = FilterModel.getAffectedPrimitives(singleton(original));
     82        ds.clonePrimitives(
     83                new SubclassFilteredCollection<>(primitives, INode.class::isInstance),
     84                new SubclassFilteredCollection<>(primitives, IWay.class::isInstance),
     85                new SubclassFilteredCollection<>(primitives, IRelation.class::isInstance));
     86        OsmPrimitive primitive = ds.getPrimitiveById(original.getOsmPrimitiveId());
     87        Command command = TaggingPreset.createCommand(singleton(primitive), changedTags);
    7988        if (command != null) {
    8089            command.executeCommand();
     
    8291        return primitive;
    8392    }
    84 
    85     static OsmPrimitive clone(OsmPrimitive original) {
    86         if (original instanceof Node) {
    87             return new Node(((Node) original));
    88         } else if (original instanceof Way) {
    89             return new Way(((Way) original), false, false);
    90         } else if (original instanceof Relation) {
    91             return new Relation(((Relation) original), false, false);
    92         } else {
    93             throw new IllegalStateException();
    94         }
    95     }
    9693}
Note: See TracChangeset for help on using the changeset viewer.