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

Last change on this file since 12749 was 12726, checked in by Don-vip, 7 years ago

see #13036 - deprecate Command() default constructor, fix unit tests and java warnings

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