source: josm/trunk/src/org/openstreetmap/josm/command/AddPrimitivesCommand.java@ 14273

Last change on this file since 14273 was 13173, checked in by Don-vip, 6 years ago

see #15310 - remove most of deprecated APIs

  • Property svn:eol-style set to native
File size: 6.8 KB
Line 
1// License: GPL. For details, see LICENSE file.
2package org.openstreetmap.josm.command;
3
4import static org.openstreetmap.josm.tools.I18n.trn;
5
6import java.util.ArrayList;
7import java.util.Collection;
8import java.util.HashSet;
9import java.util.List;
10import java.util.Objects;
11import java.util.Optional;
12import java.util.stream.Collectors;
13
14import javax.swing.Icon;
15
16import org.openstreetmap.josm.data.osm.DataSet;
17import org.openstreetmap.josm.data.osm.Node;
18import org.openstreetmap.josm.data.osm.NodeData;
19import org.openstreetmap.josm.data.osm.OsmPrimitive;
20import org.openstreetmap.josm.data.osm.PrimitiveData;
21import org.openstreetmap.josm.tools.CheckParameterUtil;
22import org.openstreetmap.josm.tools.JosmRuntimeException;
23
24/**
25 * Add primitives to a data layer.
26 * @since 2305
27 */
28public class AddPrimitivesCommand extends Command {
29
30 private List<PrimitiveData> data;
31 private Collection<PrimitiveData> toSelect;
32 private List<PrimitiveData> preExistingData;
33
34 // only filled on undo
35 private List<OsmPrimitive> createdPrimitives;
36
37 /**
38 * Constructs a new {@code AddPrimitivesCommand} to add data to the given data set.
39 * @param data The OSM primitives data to add. Must not be {@code null}
40 * @param toSelect The OSM primitives to select at the end. Can be {@code null}
41 * @param ds The target data set. Must not be {@code null}
42 * @since 12718
43 */
44 public AddPrimitivesCommand(List<PrimitiveData> data, List<PrimitiveData> toSelect, DataSet ds) {
45 super(ds);
46 init(data, toSelect);
47 }
48
49 /**
50 * Constructs a new {@code AddPrimitivesCommand} to add data to the given data set.
51 * @param data The OSM primitives data to add and select. Must not be {@code null}
52 * @param ds The target data set. Must not be {@code null}
53 * @since 12726
54 */
55 public AddPrimitivesCommand(List<PrimitiveData> data, DataSet ds) {
56 this(data, data, ds);
57 }
58
59 private void init(List<PrimitiveData> data, List<PrimitiveData> toSelect) {
60 CheckParameterUtil.ensureParameterNotNull(data, "data");
61 this.data = new ArrayList<>(data);
62 if (toSelect == data) {
63 this.toSelect = this.data;
64 } else if (toSelect != null) {
65 this.toSelect = new ArrayList<>(toSelect);
66 }
67 }
68
69 @Override
70 public boolean executeCommand() {
71 DataSet ds = getAffectedDataSet();
72 if (createdPrimitives == null) { // first time execution
73 List<OsmPrimitive> newPrimitives = new ArrayList<>(data.size());
74 preExistingData = new ArrayList<>();
75
76 for (PrimitiveData pd : data) {
77 OsmPrimitive primitive = ds.getPrimitiveById(pd);
78 boolean created = primitive == null;
79 if (primitive == null) {
80 primitive = pd.getType().newInstance(pd.getUniqueId(), true);
81 } else {
82 preExistingData.add(primitive.save());
83 }
84 if (pd instanceof NodeData) { // Load nodes immediately because they can't be added to dataset without coordinates
85 primitive.load(pd);
86 }
87 if (created) {
88 ds.addPrimitive(primitive);
89 }
90 newPrimitives.add(primitive);
91 }
92
93 // Then load ways and relations
94 for (int i = 0; i < newPrimitives.size(); i++) {
95 if (!(newPrimitives.get(i) instanceof Node)) {
96 newPrimitives.get(i).load(data.get(i));
97 }
98 }
99 newPrimitives.stream().forEach(p -> p.setModified(true));
100 } else { // redo
101 // When redoing this command, we have to add the same objects, otherwise
102 // a subsequent command (e.g. MoveCommand) cannot be redone.
103 for (OsmPrimitive osm : createdPrimitives) {
104 if (preExistingData.stream().anyMatch(pd -> pd.getUniqueId() == osm.getUniqueId())) {
105 Optional<PrimitiveData> o = data.stream().filter(pd -> pd.getUniqueId() == osm.getUniqueId()).findAny();
106 if (o.isPresent()) {
107 osm.load(o.get());
108 }
109 } else {
110 ds.addPrimitive(osm);
111 }
112 }
113 }
114 if (toSelect != null) {
115 ds.setSelected(toSelect.stream().map(ds::getPrimitiveById).collect(Collectors.toList()));
116 }
117 return true;
118 }
119
120 @Override public void undoCommand() {
121 DataSet ds = getAffectedDataSet();
122 if (createdPrimitives == null) {
123 createdPrimitives = new ArrayList<>(data.size());
124 for (PrimitiveData pd : data) {
125 OsmPrimitive p = ds.getPrimitiveById(pd);
126 createdPrimitives.add(p);
127 }
128 createdPrimitives = PurgeCommand.topoSort(createdPrimitives);
129 }
130 for (OsmPrimitive osm : createdPrimitives) {
131 Optional<PrimitiveData> previous = preExistingData.stream().filter(pd -> pd.getUniqueId() == osm.getUniqueId()).findAny();
132 if (previous.isPresent()) {
133 osm.load(previous.get());
134 } else {
135 ds.removePrimitive(osm);
136 }
137 }
138 }
139
140 @Override
141 public String getDescriptionText() {
142 int size = data != null ? data.size() : createdPrimitives.size();
143 return trn("Added {0} object", "Added {0} objects", size, size);
144 }
145
146 @Override
147 public Icon getDescriptionIcon() {
148 return null;
149 }
150
151 @Override
152 public void fillModifiedData(Collection<OsmPrimitive> modified, Collection<OsmPrimitive> deleted,
153 Collection<OsmPrimitive> added) {
154 // Does nothing because we don't want to create OsmPrimitives.
155 }
156
157 @Override
158 public Collection<? extends OsmPrimitive> getParticipatingPrimitives() {
159 if (createdPrimitives != null)
160 return createdPrimitives;
161
162 Collection<OsmPrimitive> prims = new HashSet<>();
163 for (PrimitiveData d : data) {
164 prims.add(Optional.ofNullable(getAffectedDataSet().getPrimitiveById(d)).orElseThrow(
165 () -> new JosmRuntimeException("No primitive found for " + d)));
166 }
167 return prims;
168 }
169
170 @Override
171 public int hashCode() {
172 return Objects.hash(super.hashCode(), data, toSelect, preExistingData, createdPrimitives);
173 }
174
175 @Override
176 public boolean equals(Object obj) {
177 if (this == obj) return true;
178 if (obj == null || getClass() != obj.getClass()) return false;
179 if (!super.equals(obj)) return false;
180 AddPrimitivesCommand that = (AddPrimitivesCommand) obj;
181 return Objects.equals(data, that.data) &&
182 Objects.equals(toSelect, that.toSelect) &&
183 Objects.equals(preExistingData, that.preExistingData) &&
184 Objects.equals(createdPrimitives, that.createdPrimitives);
185 }
186}
Note: See TracBrowser for help on using the repository browser.