// License: GPL. For details, see LICENSE file. package org.openstreetmap.josm.io; import static org.openstreetmap.josm.tools.I18n.tr; import java.time.Instant; import java.util.regex.Matcher; import java.util.regex.Pattern; import org.openstreetmap.josm.tools.Logging; import org.openstreetmap.josm.tools.UncheckedParseException; import org.openstreetmap.josm.tools.date.DateUtils; /** * A ChangesetClosedException is thrown if the server replies with a HTTP * return code 409 (Conflict) with the error header {@link #ERROR_HEADER_PATTERN}. * * Depending on the context the exception is thrown in we have to react differently. *
errorHeader
matches with {@link #ERROR_HEADER_PATTERN}
*
* @param errorHeader the error header
* @return true if errorHeader
matches with {@link #ERROR_HEADER_PATTERN}
*/
public static boolean errorHeaderMatchesPattern(String errorHeader) {
if (errorHeader == null)
return false;
Pattern p = Pattern.compile(ERROR_HEADER_PATTERN);
Matcher m = p.matcher(errorHeader);
return m.matches();
}
/** the changeset id */
private long changesetId;
/** the date on which the changeset was closed */
private Instant closedOn;
/** the source */
private Source source;
protected final void parseErrorHeader(String errorHeader) {
Pattern p = Pattern.compile(ERROR_HEADER_PATTERN);
Matcher m = p.matcher(errorHeader);
if (m.matches()) {
changesetId = Long.parseLong(m.group(1));
try {
closedOn = DateUtils.parseInstant(m.group(2));
} catch (UncheckedParseException ex) {
Logging.error(tr("Failed to parse date ''{0}'' replied by server.", m.group(2)));
Logging.error(ex);
}
} else {
Logging.error(tr("Unexpected format of error header for conflict in changeset update. Got ''{0}''", errorHeader));
}
}
/**
* Creates the exception with the given errorHeader
*
* @param errorHeader the error header
*/
public ChangesetClosedException(String errorHeader) {
super(errorHeader);
parseErrorHeader(errorHeader);
this.source = Source.UNSPECIFIED;
}
/**
* Creates the exception with the given error header and source.
*
* @param errorHeader the error header
* @param source the source for the exception
*/
public ChangesetClosedException(String errorHeader, Source source) {
this(errorHeader, source, null);
}
/**
* Creates the exception with the given error header, source and cause.
*
* @param errorHeader the error header
* @param source the source for the exception
* @param cause The cause (which is saved for later retrieval by the {@link #getCause} method).
* A null value is permitted, and indicates that the cause is nonexistent or unknown.
* @since 13207
*/
public ChangesetClosedException(String errorHeader, Source source, Throwable cause) {
super(errorHeader, cause);
parseErrorHeader(errorHeader);
this.source = source == null ? Source.UNSPECIFIED : source;
}
/**
* Creates the exception
*
* @param changesetId the id if the closed changeset
* @param closedOn the date the changeset was closed on
* @param source the source for the exception
*/
public ChangesetClosedException(long changesetId, Instant closedOn, Source source) {
super("");
this.source = source == null ? Source.UNSPECIFIED : source;
this.changesetId = changesetId;
this.closedOn = closedOn;
}
/**
* Replies the id of the changeset which was closed
*
* @return the id of the changeset which was closed
*/
public long getChangesetId() {
return changesetId;
}
/**
* Replies the date the changeset was closed
*
* @return the date the changeset was closed. May be null if the date isn't known.
*/
public Instant getClosedOn() {
return closedOn;
}
/**
* Replies the source where the exception was thrown
*
* @return the source
*/
public Source getSource() {
return source;
}
public void setSource(Source source) {
this.source = source == null ? Source.UNSPECIFIED : source;
}
}