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

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

sonar - squid:S00112 - Generic exceptions should never be thrown: define JosmRuntimeException

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