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

Last change on this file since 9371 was 9371, checked in by simon04, 8 years ago

Java 7: use Objects.equals and Objects.hash

  • Property svn:eol-style set to native
File size: 9.4 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 public void visit(Visitor v) {
92 v.visit(this);
93 }
94
95 public int compareTo(Changeset other) {
96 return Integer.compare(getId(), other.getId());
97 }
98
99 public String getName() {
100 // no translation
101 return "changeset " + getId();
102 }
103
104 public String getDisplayName(NameFormatter formatter) {
105 return formatter.format(this);
106 }
107
108 public int getId() {
109 return id;
110 }
111
112 public void setId(int id) {
113 this.id = id;
114 }
115
116 public User getUser() {
117 return user;
118 }
119
120 public void setUser(User user) {
121 this.user = user;
122 }
123
124 public Date getCreatedAt() {
125 return createdAt;
126 }
127
128 public void setCreatedAt(Date createdAt) {
129 this.createdAt = createdAt;
130 }
131
132 public Date getClosedAt() {
133 return closedAt;
134 }
135
136 public void setClosedAt(Date closedAt) {
137 this.closedAt = closedAt;
138 }
139
140 public boolean isOpen() {
141 return open;
142 }
143
144 public void setOpen(boolean open) {
145 this.open = open;
146 }
147
148 public LatLon getMin() {
149 return min;
150 }
151
152 public void setMin(LatLon min) {
153 this.min = min;
154 }
155
156 public LatLon getMax() {
157 return max;
158 }
159
160 public Bounds getBounds() {
161 if (min != null && max != null)
162 return new Bounds(min, max);
163 return null;
164 }
165
166 public void setMax(LatLon max) {
167 this.max = max;
168 }
169
170 /**
171 * Replies the number of comments for this changeset.
172 * @return the number of comments for this changeset
173 * @since 7700
174 */
175 public int getCommentsCount() {
176 return commentsCount;
177 }
178
179 /**
180 * Sets the number of comments for this changeset.
181 * @param commentsCount the number of comments for this changeset
182 * @since 7700
183 */
184 public void setCommentsCount(int commentsCount) {
185 this.commentsCount = commentsCount;
186 }
187
188 @Override
189 public Map<String, String> getKeys() {
190 return tags;
191 }
192
193 @Override
194 public void setKeys(Map<String, String> keys) {
195 CheckParameterUtil.ensureParameterNotNull(keys, "keys");
196 for (String value : keys.values()) {
197 if (value != null && value.length() > MAX_CHANGESET_TAG_LENGTH) {
198 throw new IllegalArgumentException("Changeset tag value is too long: "+value);
199 }
200 }
201 this.tags = keys;
202 }
203
204 public boolean isIncomplete() {
205 return incomplete;
206 }
207
208 public void setIncomplete(boolean incomplete) {
209 this.incomplete = incomplete;
210 }
211
212 @Override
213 public void put(String key, String value) {
214 CheckParameterUtil.ensureParameterNotNull(key, "key");
215 if (value != null && value.length() > MAX_CHANGESET_TAG_LENGTH) {
216 throw new IllegalArgumentException("Changeset tag value is too long: "+value);
217 }
218 this.tags.put(key, value);
219 }
220
221 @Override
222 public String get(String key) {
223 return this.tags.get(key);
224 }
225
226 @Override
227 public void remove(String key) {
228 this.tags.remove(key);
229 }
230
231 @Override
232 public void removeAll() {
233 this.tags.clear();
234 }
235
236 public boolean hasEqualSemanticAttributes(Changeset other) {
237 if (other == null)
238 return false;
239 if (closedAt == null) {
240 if (other.closedAt != null)
241 return false;
242 } else if (!closedAt.equals(other.closedAt))
243 return false;
244 if (createdAt == null) {
245 if (other.createdAt != null)
246 return false;
247 } else if (!createdAt.equals(other.createdAt))
248 return false;
249 if (id != other.id)
250 return false;
251 if (max == null) {
252 if (other.max != null)
253 return false;
254 } else if (!max.equals(other.max))
255 return false;
256 if (min == null) {
257 if (other.min != null)
258 return false;
259 } else if (!min.equals(other.min))
260 return false;
261 if (open != other.open)
262 return false;
263 if (tags == null) {
264 if (other.tags != null)
265 return false;
266 } else if (!tags.equals(other.tags))
267 return false;
268 if (user == null) {
269 if (other.user != null)
270 return false;
271 } else if (!user.equals(other.user))
272 return false;
273 if (commentsCount != other.commentsCount) {
274 return false;
275 }
276 return true;
277 }
278
279 @Override
280 public int hashCode() {
281 return Objects.hash(id);
282 }
283
284 @Override
285 public boolean equals(Object obj) {
286 if (this == obj) return true;
287 if (obj == null || getClass() != obj.getClass()) return false;
288 Changeset changeset = (Changeset) obj;
289 return id == changeset.id;
290 }
291
292 @Override
293 public boolean hasKeys() {
294 return !tags.keySet().isEmpty();
295 }
296
297 @Override
298 public Collection<String> keySet() {
299 return tags.keySet();
300 }
301
302 public boolean isNew() {
303 return id <= 0;
304 }
305
306 public void mergeFrom(Changeset other) {
307 if (other == null)
308 return;
309 if (id != other.id)
310 return;
311 this.user = other.user;
312 this.createdAt = other.createdAt;
313 this.closedAt = other.closedAt;
314 this.open = other.open;
315 this.min = other.min;
316 this.max = other.max;
317 this.commentsCount = other.commentsCount;
318 this.tags = new HashMap<>(other.tags);
319 this.incomplete = other.incomplete;
320 this.discussion = other.discussion != null ? new ArrayList<>(other.discussion) : null;
321
322 // FIXME: merging of content required?
323 this.content = other.content;
324 }
325
326 public boolean hasContent() {
327 return content != null;
328 }
329
330 public ChangesetDataSet getContent() {
331 return content;
332 }
333
334 public void setContent(ChangesetDataSet content) {
335 this.content = content;
336 }
337
338 /**
339 * Replies the list of comments in the changeset discussion, if any.
340 * @return the list of comments in the changeset discussion. May be empty but never null
341 * @since 7704
342 */
343 public synchronized List<ChangesetDiscussionComment> getDiscussion() {
344 if (discussion == null) {
345 return Collections.emptyList();
346 }
347 return new ArrayList<>(discussion);
348 }
349
350 /**
351 * Adds a comment to the changeset discussion.
352 * @param comment the comment to add. Ignored if null
353 * @since 7704
354 */
355 public synchronized void addDiscussionComment(ChangesetDiscussionComment comment) {
356 if (comment == null) {
357 return;
358 }
359 if (discussion == null) {
360 discussion = new ArrayList<>();
361 }
362 discussion.add(comment);
363 }
364}
Note: See TracBrowser for help on using the repository browser.