source: josm/trunk/src/org/openstreetmap/josm/data/osm/PrimitiveDeepCopy.java @ 5241

Revision 5170, 3.7 KB checked in by Don-vip, 6 weeks ago (diff)

cleanup svn:mime-type properties preventing Java sources from being viewed as such on Trac

  • Property svn:eol-style set to native
Line 
1// License: GPL. For details, see LICENSE file.
2package org.openstreetmap.josm.data.osm;
3
4import java.util.ArrayList;
5import java.util.Collection;
6import java.util.HashSet;
7import java.util.List;
8import java.util.Set;
9import java.util.concurrent.CopyOnWriteArrayList;
10
11import org.openstreetmap.josm.data.osm.visitor.AbstractVisitor;
12
13/**
14 * This class allows to create and keep a deep copy of primitives. Provides methods to access directly added
15 * primitives and reference primitives
16 *
17 */
18public class PrimitiveDeepCopy {
19
20    public interface PasteBufferChangedListener {
21        void pasteBufferChanged(PrimitiveDeepCopy pasteBuffer);
22    }
23
24    private final List<PrimitiveData> directlyAdded = new ArrayList<PrimitiveData>();
25    private final List<PrimitiveData> referenced = new ArrayList<PrimitiveData>();
26    private final CopyOnWriteArrayList<PasteBufferChangedListener> listeners = new CopyOnWriteArrayList<PasteBufferChangedListener>();
27
28    public PrimitiveDeepCopy() {
29
30    }
31
32    public PrimitiveDeepCopy(final Collection<OsmPrimitive> primitives) {
33        makeCopy(primitives);
34    }
35
36    /**
37     * Replace content of the object with copy of provided primitives
38     * @param primitives
39     */
40    public final void makeCopy(final Collection<OsmPrimitive> primitives) {
41        directlyAdded.clear();
42        referenced.clear();
43
44        final Set<Long> visitedNodeIds = new HashSet<Long>();
45        final Set<Long> visitedWayIds = new HashSet<Long>();
46        final Set<Long> visitedRelationIds = new HashSet<Long>();
47
48        new AbstractVisitor() {
49            boolean firstIteration;
50
51            public void visit(Node n) {
52                if (!visitedNodeIds.add(n.getUniqueId()))
53                    return;
54                (firstIteration ? directlyAdded : referenced).add(n.save());
55            }
56            public void visit(Way w) {
57                if (!visitedWayIds.add(w.getUniqueId()))
58                    return;
59                (firstIteration ? directlyAdded : referenced).add(w.save());
60                firstIteration = false;
61                for (Node n : w.getNodes()) {
62                    visit(n);
63                }
64            }
65            public void visit(Relation r) {
66                if (!visitedRelationIds.add(r.getUniqueId()))
67                    return;
68                (firstIteration ? directlyAdded : referenced).add(r.save());
69                firstIteration = false;
70                for (RelationMember m : r.getMembers()) {
71                    m.getMember().visit(this);
72                }
73            }
74
75            public void visitAll() {
76                for (OsmPrimitive osm : primitives) {
77                    firstIteration = true;
78                    osm.visit(this);
79                }
80            }
81        }.visitAll();
82
83        firePasteBufferChanged();
84    }
85
86    public List<PrimitiveData> getDirectlyAdded() {
87        return directlyAdded;
88    }
89
90    public List<PrimitiveData> getReferenced() {
91        return referenced;
92    }
93
94    public List<PrimitiveData> getAll() {
95        List<PrimitiveData> result = new ArrayList<PrimitiveData>(directlyAdded.size() + referenced.size());
96        result.addAll(directlyAdded);
97        result.addAll(referenced);
98        return result;
99    }
100
101    public boolean isEmpty() {
102        return directlyAdded.isEmpty() && referenced.isEmpty();
103    }
104
105    private void firePasteBufferChanged() {
106        for (PasteBufferChangedListener listener: listeners) {
107            listener.pasteBufferChanged(this);
108        }
109    }
110
111    public void addPasteBufferChangedListener(PasteBufferChangedListener listener) {
112        listeners.addIfAbsent(listener);
113    }
114
115    public void removePasteBufferChangedListener(PasteBufferChangedListener listener) {
116        listeners.remove(listener);
117    }
118
119}
Note: See TracBrowser for help on using the repository browser.