source: josm/trunk/src/org/openstreetmap/josm/data/osm/Changeset.java@ 11266

Last change on this file since 11266 was 11121, checked in by Don-vip, 8 years ago

checkstyle

  • Property svn:eol-style set to native
File size: 10.1 KB
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.Collections;
7import java.util.Date;
8import java.util.HashMap;
9import java.util.List;
10import java.util.Map;
11import java.util.Objects;
12
13import org.openstreetmap.josm.data.Bounds;
14import org.openstreetmap.josm.data.coor.LatLon;
15import org.openstreetmap.josm.data.osm.visitor.Visitor;
16import org.openstreetmap.josm.tools.CheckParameterUtil;
17
18/**
19 * Represents a single changeset in JOSM. For now its only used during
20 * upload but in the future we may do more.
21 * @since 625
22 */
23public final class Changeset implements Tagged {
24
25 /** The maximum changeset tag length allowed by API 0.6 **/
26 public static final int MAX_CHANGESET_TAG_LENGTH = 255;
27
28 /** the changeset id */
29 private int id;
30 /** the user who owns the changeset */
31 private User user;
32 /** date this changeset was created at */
33 private Date createdAt;
34 /** the date this changeset was closed at*/
35 private Date closedAt;
36 /** indicates whether this changeset is still open or not */
37 private boolean open;
38 /** the min. coordinates of the bounding box of this changeset */
39 private LatLon min;
40 /** the max. coordinates of the bounding box of this changeset */
41 private LatLon max;
42 /** the number of comments for this changeset */
43 private int commentsCount;
44 /** the map of tags */
45 private Map<String, String> tags;
46 /** indicates whether this changeset is incomplete. For an incomplete changeset we only know its id */
47 private boolean incomplete;
48 /** the changeset content */
49 private ChangesetDataSet content;
50 /** the changeset discussion */
51 private List<ChangesetDiscussionComment> discussion;
52
53 /**
54 * Creates a new changeset with id 0.
55 */
56 public Changeset() {
57 this(0);
58 }
59
60 /**
61 * Creates a changeset with id <code>id</code>. If id &gt; 0, sets incomplete to true.
62 *
63 * @param id the id
64 */
65 public Changeset(int id) {
66 this.id = id;
67 this.incomplete = id > 0;
68 this.tags = new HashMap<>();
69 }
70
71 /**
72 * Creates a clone of <code>other</code>
73 *
74 * @param other the other changeset. If null, creates a new changeset with id 0.
75 */
76 public Changeset(Changeset other) {
77 if (other == null) {
78 this.id = 0;
79 this.tags = new HashMap<>();
80 } else if (other.isIncomplete()) {
81 setId(other.getId());
82 this.incomplete = true;
83 this.tags = new HashMap<>();
84 } else {
85 this.id = other.id;
86 mergeFrom(other);
87 this.incomplete = false;
88 }
89 }
90
91 /**
92 * Creates a changeset with the data obtained from the given preset, i.e.,
93 * the {@link AbstractPrimitive#getChangesetId() changeset id}, {@link AbstractPrimitive#getUser() user}, and
94 * {@link AbstractPrimitive#getTimestamp() timestamp}.
95 * @param primitive the primitive to use
96 * @return the created changeset
97 */
98 public static Changeset fromPrimitive(final OsmPrimitive primitive) {
99 final Changeset changeset = new Changeset(primitive.getChangesetId());
100 changeset.setUser(primitive.getUser());
101 changeset.setCreatedAt(primitive.getTimestamp()); // not accurate in all cases
102 return changeset;
103 }
104
105 public void visit(Visitor v) {
106 v.visit(this);
107 }
108
109 public int compareTo(Changeset other) {
110 return Integer.compare(getId(), other.getId());
111 }
112
113 public String getName() {
114 // no translation
115 return "changeset " + getId();
116 }
117
118 public String getDisplayName(NameFormatter formatter) {
119 return formatter.format(this);
120 }
121
122 public int getId() {
123 return id;
124 }
125
126 public void setId(int id) {
127 this.id = id;
128 }
129
130 public User getUser() {
131 return user;
132 }
133
134 public void setUser(User user) {
135 this.user = user;
136 }
137
138 public Date getCreatedAt() {
139 return createdAt;
140 }
141
142 public void setCreatedAt(Date createdAt) {
143 this.createdAt = createdAt;
144 }
145
146 public Date getClosedAt() {
147 return closedAt;
148 }
149
150 public void setClosedAt(Date closedAt) {
151 this.closedAt = closedAt;
152 }
153
154 public boolean isOpen() {
155 return open;
156 }
157
158 public void setOpen(boolean open) {
159 this.open = open;
160 }
161
162 public LatLon getMin() {
163 return min;
164 }
165
166 public void setMin(LatLon min) {
167 this.min = min;
168 }
169
170 public LatLon getMax() {
171 return max;
172 }
173
174 public Bounds getBounds() {
175 if (min != null && max != null)
176 return new Bounds(min, max);
177 return null;
178 }
179
180 public void setMax(LatLon max) {
181 this.max = max;
182 }
183
184 /**
185 * Replies the number of comments for this changeset.
186 * @return the number of comments for this changeset
187 * @since 7700
188 */
189 public int getCommentsCount() {
190 return commentsCount;
191 }
192
193 /**
194 * Sets the number of comments for this changeset.
195 * @param commentsCount the number of comments for this changeset
196 * @since 7700
197 */
198 public void setCommentsCount(int commentsCount) {
199 this.commentsCount = commentsCount;
200 }
201
202 @Override
203 public Map<String, String> getKeys() {
204 return tags;
205 }
206
207 @Override
208 public void setKeys(Map<String, String> keys) {
209 CheckParameterUtil.ensureParameterNotNull(keys, "keys");
210 keys.values().stream()
211 .filter(value -> value != null && value.length() > MAX_CHANGESET_TAG_LENGTH)
212 .findFirst()
213 .ifPresent(value -> {
214 throw new IllegalArgumentException("Changeset tag value is too long: "+value);
215 });
216 this.tags = keys;
217 }
218
219 public boolean isIncomplete() {
220 return incomplete;
221 }
222
223 public void setIncomplete(boolean incomplete) {
224 this.incomplete = incomplete;
225 }
226
227 @Override
228 public void put(String key, String value) {
229 CheckParameterUtil.ensureParameterNotNull(key, "key");
230 if (value != null && value.length() > MAX_CHANGESET_TAG_LENGTH) {
231 throw new IllegalArgumentException("Changeset tag value is too long: "+value);
232 }
233 this.tags.put(key, value);
234 }
235
236 @Override
237 public String get(String key) {
238 return this.tags.get(key);
239 }
240
241 @Override
242 public void remove(String key) {
243 this.tags.remove(key);
244 }
245
246 @Override
247 public void removeAll() {
248 this.tags.clear();
249 }
250
251 public boolean hasEqualSemanticAttributes(Changeset other) {
252 if (other == null)
253 return false;
254 if (closedAt == null) {
255 if (other.closedAt != null)
256 return false;
257 } else if (!closedAt.equals(other.closedAt))
258 return false;
259 if (createdAt == null) {
260 if (other.createdAt != null)
261 return false;
262 } else if (!createdAt.equals(other.createdAt))
263 return false;
264 if (id != other.id)
265 return false;
266 if (max == null) {
267 if (other.max != null)
268 return false;
269 } else if (!max.equals(other.max))
270 return false;
271 if (min == null) {
272 if (other.min != null)
273 return false;
274 } else if (!min.equals(other.min))
275 return false;
276 if (open != other.open)
277 return false;
278 if (tags == null) {
279 if (other.tags != null)
280 return false;
281 } else if (!tags.equals(other.tags))
282 return false;
283 if (user == null) {
284 if (other.user != null)
285 return false;
286 } else if (!user.equals(other.user))
287 return false;
288 if (commentsCount != other.commentsCount) {
289 return false;
290 }
291 return true;
292 }
293
294 @Override
295 public int hashCode() {
296 return Objects.hash(id);
297 }
298
299 @Override
300 public boolean equals(Object obj) {
301 if (this == obj) return true;
302 if (obj == null || getClass() != obj.getClass()) return false;
303 Changeset changeset = (Changeset) obj;
304 return id == changeset.id;
305 }
306
307 @Override
308 public boolean hasKeys() {
309 return !tags.keySet().isEmpty();
310 }
311
312 @Override
313 public Collection<String> keySet() {
314 return tags.keySet();
315 }
316
317 public boolean isNew() {
318 return id <= 0;
319 }
320
321 public void mergeFrom(Changeset other) {
322 if (other == null)
323 return;
324 if (id != other.id)
325 return;
326 this.user = other.user;
327 this.createdAt = other.createdAt;
328 this.closedAt = other.closedAt;
329 this.open = other.open;
330 this.min = other.min;
331 this.max = other.max;
332 this.commentsCount = other.commentsCount;
333 this.tags = new HashMap<>(other.tags);
334 this.incomplete = other.incomplete;
335 this.discussion = other.discussion != null ? new ArrayList<>(other.discussion) : null;
336
337 // FIXME: merging of content required?
338 this.content = other.content;
339 }
340
341 public boolean hasContent() {
342 return content != null;
343 }
344
345 public ChangesetDataSet getContent() {
346 return content;
347 }
348
349 public void setContent(ChangesetDataSet content) {
350 this.content = content;
351 }
352
353 /**
354 * Replies the list of comments in the changeset discussion, if any.
355 * @return the list of comments in the changeset discussion. May be empty but never null
356 * @since 7704
357 */
358 public synchronized List<ChangesetDiscussionComment> getDiscussion() {
359 if (discussion == null) {
360 return Collections.emptyList();
361 }
362 return new ArrayList<>(discussion);
363 }
364
365 /**
366 * Adds a comment to the changeset discussion.
367 * @param comment the comment to add. Ignored if null
368 * @since 7704
369 */
370 public synchronized void addDiscussionComment(ChangesetDiscussionComment comment) {
371 if (comment == null) {
372 return;
373 }
374 if (discussion == null) {
375 discussion = new ArrayList<>();
376 }
377 discussion.add(comment);
378 }
379}
Note: See TracBrowser for help on using the repository browser.