source: josm/trunk/src/org/openstreetmap/josm/io/ChangesetClosedException.java@ 18283

Last change on this file since 18283 was 18283, checked in by Don-vip, 3 years ago

fix #21427 - further simplify UploadDialog (patch by marcello, modified)

  • The dialog was simplified by combining the function of two radiobuttons and one combobox into one combobox.
  • When an open changeset was selected on tab 2, existing tags on the open changeset could overwrite the data the user entered on tab 1. The user might spot this by looking closely at the tag table on tab 2, but then he may not. This non-obvious behaviour was removed.
  • The exception thrown when closing an already closed changeset was fixed.
  • More cosmetic changes to the dialog.
  • Maybe also a solution to #19319, #21387 (added revalidate()).
  • Property svn:eol-style set to native
File size: 6.0 KB
Line 
1// License: GPL. For details, see LICENSE file.
2package org.openstreetmap.josm.io;
3
4import static org.openstreetmap.josm.tools.I18n.tr;
5
6import java.time.Instant;
7import java.util.regex.Matcher;
8import java.util.regex.Pattern;
9
10import org.openstreetmap.josm.tools.Logging;
11import org.openstreetmap.josm.tools.UncheckedParseException;
12import org.openstreetmap.josm.tools.date.DateUtils;
13
14/**
15 * A ChangesetClosedException is thrown if the server replies with a HTTP
16 * return code 409 (Conflict) with the error header {@link #ERROR_HEADER_PATTERN}.
17 *
18 * Depending on the context the exception is thrown in we have to react differently.
19 * <ul>
20 * <li>if it is thrown when we try to update a changeset, the changeset was most
21 * likely closed before, either explicitly by the user or because of a timeout</li>
22 * <li>if it is thrown when we try to upload data to the changeset, the changeset
23 * was most likely closed because we reached the servers capability limit for the size
24 * of a changeset.</li>
25 * </ul>
26 */
27public class ChangesetClosedException extends OsmTransferException {
28 /** the error header pattern for in case of HTTP response 409 indicating
29 * that a changeset was closed
30 */
31 public static final String ERROR_HEADER_PATTERN = "The changeset (\\d+) was closed at (.*)";
32
33 /**
34 * Identifies when the changeset exception occurred.
35 */
36 public enum Source {
37 /**
38 * The exception was thrown when a changeset was updated. This most likely means
39 * that the changeset was closed before.
40 */
41 UPDATE_CHANGESET,
42 /**
43 * The exception was thrown when data was uploaded to the changeset. This most
44 * likely means that the servers capability limits for a changeset have been
45 * exceeded.
46 */
47 UPLOAD_DATA,
48 /**
49 * The exception was thrown when we tried to close a changeset. Probably the changeset
50 * already timed out on the server.
51 * @since 18283
52 */
53 CLOSE_CHANGESET,
54 /**
55 * Unspecified source
56 */
57 UNSPECIFIED
58 }
59
60 /**
61 * Replies true if <code>errorHeader</code> matches with {@link #ERROR_HEADER_PATTERN}
62 *
63 * @param errorHeader the error header
64 * @return true if <code>errorHeader</code> matches with {@link #ERROR_HEADER_PATTERN}
65 */
66 public static boolean errorHeaderMatchesPattern(String errorHeader) {
67 if (errorHeader == null)
68 return false;
69 Pattern p = Pattern.compile(ERROR_HEADER_PATTERN);
70 Matcher m = p.matcher(errorHeader);
71 return m.matches();
72 }
73
74 /** the changeset id */
75 private long changesetId;
76 /** the date on which the changeset was closed */
77 private Instant closedOn;
78 /** the source */
79 private Source source;
80
81 protected final void parseErrorHeader(String errorHeader) {
82 Pattern p = Pattern.compile(ERROR_HEADER_PATTERN);
83 Matcher m = p.matcher(errorHeader);
84 if (m.matches()) {
85 changesetId = Long.parseLong(m.group(1));
86 try {
87 closedOn = DateUtils.parseInstant(m.group(2));
88 } catch (UncheckedParseException ex) {
89 Logging.error(tr("Failed to parse date ''{0}'' replied by server.", m.group(2)));
90 Logging.error(ex);
91 }
92 } else {
93 Logging.error(tr("Unexpected format of error header for conflict in changeset update. Got ''{0}''", errorHeader));
94 }
95 }
96
97 /**
98 * Creates the exception with the given <code>errorHeader</code>
99 *
100 * @param errorHeader the error header
101 */
102 public ChangesetClosedException(String errorHeader) {
103 super(errorHeader);
104 parseErrorHeader(errorHeader);
105 this.source = Source.UNSPECIFIED;
106 }
107
108 /**
109 * Creates the exception with the given error header and source.
110 *
111 * @param errorHeader the error header
112 * @param source the source for the exception
113 */
114 public ChangesetClosedException(String errorHeader, Source source) {
115 this(errorHeader, source, null);
116 }
117
118 /**
119 * Creates the exception with the given error header, source and cause.
120 *
121 * @param errorHeader the error header
122 * @param source the source for the exception
123 * @param cause The cause (which is saved for later retrieval by the {@link #getCause} method).
124 * A null value is permitted, and indicates that the cause is nonexistent or unknown.
125 * @since 13207
126 */
127 public ChangesetClosedException(String errorHeader, Source source, Throwable cause) {
128 super(errorHeader, cause);
129 parseErrorHeader(errorHeader);
130 this.source = source == null ? Source.UNSPECIFIED : source;
131 }
132
133 /**
134 * Creates the exception
135 *
136 * @param changesetId the id if the closed changeset
137 * @param closedOn the date the changeset was closed on
138 * @param source the source for the exception
139 */
140 public ChangesetClosedException(long changesetId, Instant closedOn, Source source) {
141 super("");
142 this.source = source == null ? Source.UNSPECIFIED : source;
143 this.changesetId = changesetId;
144 this.closedOn = closedOn;
145 }
146
147 /**
148 * Replies the id of the changeset which was closed
149 *
150 * @return the id of the changeset which was closed
151 */
152 public long getChangesetId() {
153 return changesetId;
154 }
155
156 /**
157 * Replies the date the changeset was closed
158 *
159 * @return the date the changeset was closed. May be null if the date isn't known.
160 */
161 public Instant getClosedOn() {
162 return closedOn;
163 }
164
165 /**
166 * Replies the source where the exception was thrown
167 *
168 * @return the source
169 */
170 public Source getSource() {
171 return source;
172 }
173
174 /**
175 * Sets the source where the exception was thrown
176 *
177 * @param source the source where the exception was thrown
178 */
179 public void setSource(Source source) {
180 this.source = source == null ? Source.UNSPECIFIED : source;
181 }
182}
Note: See TracBrowser for help on using the repository browser.