// License: GPL. For details, see LICENSE file. package org.openstreetmap.josm.data.osm; import java.util.ArrayList; import java.util.Collection; import java.util.HashSet; import java.util.List; import java.util.Set; import org.openstreetmap.josm.data.osm.visitor.AbstractVisitor; /** * This class allows to create and keep a deep copy of primitives. Provides methods to access directly added * primitives and reference primitives * */ public class PrimitiveDeepCopy { private final List directlyAdded = new ArrayList(); private final List referenced = new ArrayList(); public PrimitiveDeepCopy() { } public PrimitiveDeepCopy(final Collection primitives) { makeCopy(primitives); } /** * Replace content of the object with copy of provided primitives * @param primitives */ public final void makeCopy(final Collection primitives) { directlyAdded.clear(); referenced.clear(); final Set visitedIds = new HashSet(); new AbstractVisitor() { boolean firstIteration; public void visit(Node n) { if (!visitedIds.add(n.getUniqueId())) return; (firstIteration?directlyAdded:referenced).add(n.save()); } public void visit(Way w) { if (!visitedIds.add(w.getUniqueId())) return; (firstIteration?directlyAdded:referenced).add(w.save()); firstIteration = false; for (Node n : w.getNodes()) { visit(n); } } public void visit(Relation e) { if (!visitedIds.add(e.getUniqueId())) return; (firstIteration?directlyAdded:referenced).add(e.save()); firstIteration = false; for (RelationMember m : e.getMembers()) { m.getMember().visit(this); } } public void visitAll() { for (OsmPrimitive osm : primitives) { firstIteration = true; osm.visit(this); } } }.visitAll(); } public List getDirectlyAdded() { return directlyAdded; } public List getReferenced() { return referenced; } public List getAll() { List result = new ArrayList(directlyAdded.size() + referenced.size()); result.addAll(directlyAdded); result.addAll(referenced); return result; } public boolean isEmpty() { return directlyAdded.isEmpty() && referenced.isEmpty(); } }