package org.archive.wayback.exception;
import javax.servlet.http.HttpServletResponse;
import org.archive.wayback.archivalurl.ArchivalUrl;
import org.archive.wayback.core.CaptureSearchResult;
import org.archive.wayback.core.CaptureSearchResults;
import org.archive.wayback.core.WaybackRequest;
import org.archive.wayback.memento.MementoUtils;
import org.archive.wayback.webapp.AccessPoint;
/**
* Sub-class of {@link BetterRequestException} for instructing a redirect to
* ArchivalUrl for the URL on different timestamp.
* <p>
* This class generates additional HTTP headers for Memento support.
* </p>
*/
public class BetterReplayRequestException extends BetterRequestException {
private static final long serialVersionUID = -873414298713087775L;
private String targetURI;
private String timestamp;
private CaptureSearchResults captures;
/**
* Initializes with capture information and additional information for
* generating navigation headers (Memento headers).
* @param targetURI target URI, typically capture's {@code originalUrl}
* @param timestamp timestamp, typically capture's {@code cpatureTimestamp}
* @param results Other captures for targetURI.
*/
public BetterReplayRequestException(String targetURI, String timestamp,
CaptureSearchResults captures) {
// hacky - this is okay, because #generateResponse() does not use
// betterURI member.
// TODO: better to define a common superclass of BetterRequestException
// and BetterReplayRequestException,
// that defines abstract generateResponse() method.
super(null);
this.targetURI = targetURI;
this.timestamp = timestamp;
this.captures = captures;
}
/**
* Initializes with {@code originalUrl} and {@code captureTimestamp} from {@link CaptureSearchResult}.
* @param capture Capture to redirect to.
* @param captures Other captures for targetURI.
*/
public BetterReplayRequestException(CaptureSearchResult capture, CaptureSearchResults captures) {
this(capture.getOriginalUrl(), capture.getCaptureTimestamp(), captures);
}
@Override
public void generateResponse(HttpServletResponse response,
WaybackRequest wbRequest) {
AccessPoint accessPoint = wbRequest.getAccessPoint();
String replayURL = accessPoint.getUriConverter().makeReplayURI(
ArchivalUrl.getDateSpec(wbRequest, timestamp), targetURI);
response.setStatus(HttpServletResponse.SC_FOUND);
response.setHeader("Location", replayURL);
if (wbRequest.isMementoEnabled()) {
// both URI-G redirect response and intermediate resource response
// MUST NOT have Memento-Datetime header.
if (wbRequest.isMementoTimegate()) {
// URI-G redirect response
if (accessPoint.getMementoHandler() != null) {
accessPoint.getMementoHandler().addTimegateHeaders(response, captures, wbRequest, true);
} else {
MementoUtils.addTimegateHeaders(response, captures, wbRequest, true);
}
} else {
// intermediate resource that redirects to URL-M
// should the second argument wbRequest.getRequestUrl() or this.targetURI?
// there are different approaches in the code.
MementoUtils.addOrigHeader(response, this.targetURI);
}
}
}
}