/*
* This file is part of the Wayback archival access software
* (http://archive-access.sourceforge.net/projects/wayback/).
*
* Licensed to the Internet Archive (IA) by one or more individual
* contributors.
*
* The IA licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.archive.wayback.memento;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.logging.Logger;
import javax.servlet.http.HttpServletRequest;
import org.archive.wayback.core.WaybackRequest;
import org.archive.wayback.exception.BadQueryException;
import org.archive.wayback.exception.BetterRequestException;
import org.archive.wayback.requestparser.BaseRequestParser;
import org.archive.wayback.requestparser.WrappedRequestParser;
import org.archive.wayback.webapp.AccessPoint;
/**
* RequestParser subclass which matches ".../timegate/URL" requests, and parses
* the Accept-Datetime header
*
* @consultant Lyudmila Balakireva
*
*/
public class TimeGateRequestParser extends WrappedRequestParser {
private static final Logger LOGGER =
Logger.getLogger(TimeGateRequestParser.class.getName());
String DTHEADER = "Accept-Datetime";
List<SimpleDateFormat> dtsupportedformats =
new ArrayList<SimpleDateFormat>();
String MEMENTO_BASE = "timegate/";
/**
* @param wrapped
* BaseRequestParser with configuration
*/
public TimeGateRequestParser(BaseRequestParser wrapped) {
super(wrapped);
dtsupportedformats
.add(new SimpleDateFormat("E, dd MMM yyyy HH:mm:ss Z"));
dtsupportedformats.add(new SimpleDateFormat("E, dd MMM yyyy Z"));
dtsupportedformats.add(new SimpleDateFormat("E, dd MMM yyyy"));
}
@Override
public WaybackRequest parse(HttpServletRequest httpRequest,
AccessPoint accessPoint) throws BadQueryException,
BetterRequestException {
String base = accessPoint.translateRequestPath(httpRequest);
String requestPath = accessPoint.translateRequestPathQuery(httpRequest);
LOGGER.fine("requestPath:" + requestPath);
if (base.startsWith(MEMENTO_BASE)) {
// strip leading "timegate/":
String urlStr = base.substring(MEMENTO_BASE.length());
// get the "Accept-Datetime" header:
String httpdate = getHttpDate(httpRequest);
Date dtconnegdate = null;
if (httpdate != null) {
dtconnegdate = checkDateValidity(httpdate, dtsupportedformats);
if (dtconnegdate == null) {
httpdate="unparsable";
}
} else {
// TODO: should this return null her? no header..
}
WaybackRequest wbRequest = new WaybackRequest();
if (wbRequest.getStartTimestamp() == null) {
wbRequest.setStartTimestamp(getEarliestTimestamp());
}
if (dtconnegdate != null) {
wbRequest.setReplayDate(dtconnegdate);
// wbRequest.setAnchorDate(dtconnegdate);
} else {
wbRequest.setAnchorTimestamp(getLatestTimestamp());
}
wbRequest.put("dtconneg", httpdate);
if (wbRequest.getEndTimestamp() == null) {
wbRequest.setEndTimestamp(getLatestTimestamp());
}
wbRequest.setCaptureQueryRequest();
wbRequest.setRequestUrl(urlStr);
if (wbRequest != null) {
wbRequest.setResultsPerPage(getMaxRecords());
}
return wbRequest;
}
return null;
}
/**
* Extract the value of the "Accept-Datetime" HTTP request header, if
* present, and further strips the date value from any surrounding "{","}"
* @param req HttpServletRequest for this request
* @return the raw String containing the date information, or null if no
* such HTTP header exists.
*/
public String getHttpDate(HttpServletRequest req) {
String httpdate = req.getHeader(DTHEADER);
if (httpdate != null) {
int j = httpdate.indexOf("{", 0);
if (j >= 0) {
httpdate = httpdate.substring(httpdate.indexOf("{", 0) + 1);
}
if (httpdate.indexOf("}") > 0) {
httpdate = httpdate.substring(0, httpdate.indexOf("}"));
}
}
return httpdate;
}
/**
* Attempt to parse the String httpdate argument using one of the
* SimpleDateFormats provided.
*
* @param httpdate
* String version of a Date
* @param list
* of SimpleDateFormats to parse the httpdate
* @return Date object set to the time parsed, or null if not parsed
*/
public Date checkDateValidity(String httpdate, List<SimpleDateFormat> list) {
Date d = null;
Iterator<SimpleDateFormat> it = list.iterator();
while (it.hasNext()) {
SimpleDateFormat formatter = it.next();
try {
d = formatter.parse(httpdate);
break;
} catch (Exception e) {
e.printStackTrace();
}
}
return d;
}
}