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

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

see #15310 - remove most of deprecated APIs

  • Property svn:eol-style set to native
File size: 6.8 KB
RevLine 
[2305]1// License: GPL. For details, see LICENSE file.
2package org.openstreetmap.josm.command;
3
[2844]4import static org.openstreetmap.josm.tools.I18n.trn;
[2305]5
6import java.util.ArrayList;
7import java.util.Collection;
[3262]8import java.util.HashSet;
[2305]9import java.util.List;
[9371]10import java.util.Objects;
[11553]11import java.util.Optional;
[11609]12import java.util.stream.Collectors;
[8456]13
[4918]14import javax.swing.Icon;
[2305]15
[3703]16import org.openstreetmap.josm.data.osm.DataSet;
[3257]17import org.openstreetmap.josm.data.osm.Node;
[3440]18import org.openstreetmap.josm.data.osm.NodeData;
[2305]19import org.openstreetmap.josm.data.osm.OsmPrimitive;
20import org.openstreetmap.josm.data.osm.PrimitiveData;
[5953]21import org.openstreetmap.josm.tools.CheckParameterUtil;
[11374]22import org.openstreetmap.josm.tools.JosmRuntimeException;
[2305]23
[3703]24/**
25 * Add primitives to a data layer.
[5953]26 * @since 2305
[3703]27 */
[2305]28public class AddPrimitivesCommand extends Command {
29
[11609]30 private List<PrimitiveData> data;
31 private Collection<PrimitiveData> toSelect;
32 private List<PrimitiveData> preExistingData;
[2305]33
[3703]34 // only filled on undo
[8840]35 private List<OsmPrimitive> createdPrimitives;
[3703]36
[5953]37 /**
[12718]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
[12726]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
[8512]59 private void init(List<PrimitiveData> data, List<PrimitiveData> toSelect) {
[5953]60 CheckParameterUtil.ensureParameterNotNull(data, "data");
[11609]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);
[5953]66 }
[3660]67 }
[2305]68
[8510]69 @Override
70 public boolean executeCommand() {
[11609]71 DataSet ds = getAffectedDataSet();
[3703]72 if (createdPrimitives == null) { // first time execution
[7005]73 List<OsmPrimitive> newPrimitives = new ArrayList<>(data.size());
[11609]74 preExistingData = new ArrayList<>();
[2305]75
[3703]76 for (PrimitiveData pd : data) {
[11609]77 OsmPrimitive primitive = ds.getPrimitiveById(pd);
[3703]78 boolean created = primitive == null;
[11609]79 if (primitive == null) {
[3703]80 primitive = pd.getType().newInstance(pd.getUniqueId(), true);
[11609]81 } else {
82 preExistingData.add(primitive.save());
[3703]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) {
[11609]88 ds.addPrimitive(primitive);
[3703]89 }
90 newPrimitives.add(primitive);
91 }
[2305]92
[5953]93 // Then load ways and relations
[8510]94 for (int i = 0; i < newPrimitives.size(); i++) {
[3703]95 if (!(newPrimitives.get(i) instanceof Node)) {
96 newPrimitives.get(i).load(data.get(i));
97 }
[3257]98 }
[10804]99 newPrimitives.stream().forEach(p -> p.setModified(true));
[3703]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) {
[11609]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 }
[3440]112 }
[2305]113 }
[11609]114 if (toSelect != null) {
115 ds.setSelected(toSelect.stream().map(ds::getPrimitiveById).collect(Collectors.toList()));
116 }
[2305]117 return true;
118 }
119
120 @Override public void undoCommand() {
[10467]121 DataSet ds = getAffectedDataSet();
[3703]122 if (createdPrimitives == null) {
[7005]123 createdPrimitives = new ArrayList<>(data.size());
[5953]124 for (PrimitiveData pd : data) {
125 OsmPrimitive p = ds.getPrimitiveById(pd);
126 createdPrimitives.add(p);
[3703]127 }
128 createdPrimitives = PurgeCommand.topoSort(createdPrimitives);
[11609]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 {
[3703]135 ds.removePrimitive(osm);
136 }
[2305]137 }
138 }
139
[4918]140 @Override
141 public String getDescriptionText() {
[3703]142 int size = data != null ? data.size() : createdPrimitives.size();
[4918]143 return trn("Added {0} object", "Added {0} objects", size, size);
[2305]144 }
145
146 @Override
[4918]147 public Icon getDescriptionIcon() {
148 return null;
149 }
150
151 @Override
[2305]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
[3262]157 @Override
158 public Collection<? extends OsmPrimitive> getParticipatingPrimitives() {
[3703]159 if (createdPrimitives != null)
160 return createdPrimitives;
[6069]161
[7005]162 Collection<OsmPrimitive> prims = new HashSet<>();
[3262]163 for (PrimitiveData d : data) {
[11553]164 prims.add(Optional.ofNullable(getAffectedDataSet().getPrimitiveById(d)).orElseThrow(
165 () -> new JosmRuntimeException("No primitive found for " + d)));
[3262]166 }
167 return prims;
168 }
[8456]169
170 @Override
171 public int hashCode() {
[11609]172 return Objects.hash(super.hashCode(), data, toSelect, preExistingData, createdPrimitives);
[8456]173 }
174
175 @Override
176 public boolean equals(Object obj) {
[9371]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) &&
[11374]182 Objects.equals(toSelect, that.toSelect) &&
[11609]183 Objects.equals(preExistingData, that.preExistingData) &&
184 Objects.equals(createdPrimitives, that.createdPrimitives);
[8456]185 }
[2305]186}
Note: See TracBrowser for help on using the repository browser.