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

Revision 3562, 5.2 KB checked in by bastiK, 20 months ago (diff)

fixed #5417 - Failed to parse date

  • Property svn:eol-style set to native
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.text.DateFormat;
7import java.text.ParseException;
8import java.text.SimpleDateFormat;
9import java.util.Date;
10import java.util.Locale;
11import java.util.regex.Matcher;
12import java.util.regex.Pattern;
13
14/**
15 * A ChangesetClosedException is thrown if the server replies with a HTTP
16 * return code 409 (Conflict) with the error header {@see #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    final static public String ERROR_HEADER_PATTERN = "The changeset (\\d+) was closed at (.*)";
32
33    public static enum Source {
34        /**
35         * The exception was thrown when a changeset was updated. This most likely means
36         * that the changeset was closed before.
37         */
38        UPDATE_CHANGESET,
39        /**
40         * The exception was thrown when data was uploaded to the changeset. This most
41         * likely means that the servers capability limits for a changeset have been
42         * exceeded.
43         */
44        UPLOAD_DATA,
45        /**
46         * Unspecified source
47         */
48        UNSPECIFIED
49    }
50
51    /**
52     * Replies true if <code>errorHeader</code> matches with {@see #ERROR_HEADER_PATTERN}
53     *
54     * @param errorHeader the error header
55     * @return true if <code>errorHeader</code> matches with {@see #ERROR_HEADER_PATTERN}
56     */
57    static public boolean errorHeaderMatchesPattern(String errorHeader) {
58        if (errorHeader == null)
59            return false;
60        Pattern p = Pattern.compile(ERROR_HEADER_PATTERN);
61        Matcher m = p.matcher(errorHeader);
62        return m.matches();
63    }
64
65    /** the changeset id */
66    private long changesetId;
67    /** the date on which the changeset was closed */
68    private Date closedOn;
69    /** the source */
70    private Source source;
71
72    protected void parseErrorHeader(String errorHeader) {
73        Pattern p = Pattern.compile(ERROR_HEADER_PATTERN);
74        Matcher m = p.matcher(errorHeader);
75        if (m.matches()) {
76            changesetId = Long.parseLong(m.group(1));
77            // Example: "2010-09-07 14:39:41 UTC". Always parsed with US locale regardless
78            // of the current locale in JOSM
79            DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss z", Locale.US);
80            try {
81                closedOn = formatter.parse(m.group(2));
82            } catch(ParseException ex) {
83                System.err.println(tr("Failed to parse date ''{0}'' replied by server.", m.group(2)));
84                ex.printStackTrace();
85            }
86        } else {
87            System.err.println(tr("Unexpected format of error header for conflict in changeset update. Got ''{0}''", errorHeader));
88        }
89    }
90
91    /**
92     * Creates the exception with the given <code>errorHeader</code>
93     *
94     * @param errorHeader the error header
95     */
96    public ChangesetClosedException(String errorHeader) {
97        super(errorHeader);
98        parseErrorHeader(errorHeader);
99        this.source = Source.UNSPECIFIED;
100    }
101
102    /**
103     * Creates the exception with the given error header and the given
104     * source.
105     *
106     * @param errorHeader the error header
107     * @param source the source for the exception
108     */
109    public ChangesetClosedException(String errorHeader, Source source) {
110        super(errorHeader);
111        parseErrorHeader(errorHeader);
112        this.source = source == null ? Source.UNSPECIFIED : source;
113    }
114
115    /**
116     * Creates the exception
117     *
118     * @param changesetId the id if the closed changeset
119     * @param closedOn the date the changeset was closed on
120     * @param source the source for the exception
121     */
122    public ChangesetClosedException(long changesetId, Date closedOn, Source source) {
123        super("");
124        this.source = source == null ? Source.UNSPECIFIED : source;
125        this.changesetId = changesetId;
126        this.closedOn = closedOn;
127    }
128
129    /**
130     * Replies the id of the changeset which was closed
131     *
132     * @return the id of the changeset which was closed
133     */
134    public long getChangesetId() {
135        return changesetId;
136    }
137
138    /**
139     * Replies the date the changeset was closed
140     *
141     * @return the date the changeset was closed. May be null if the date isn't known.
142     */
143    public Date getClosedOn() {
144        return closedOn;
145    }
146
147    /**
148     * Replies the source where the exception was thrown
149     *
150     * @return the source
151     */
152    public Source getSource() {
153        return source;
154    }
155
156    public void setSource(Source source) {
157        this.source = source == null ? Source.UNSPECIFIED : source;
158    }
159}
Note: See TracBrowser for help on using the repository browser.