package org.sakaiproject.citation.impl.openurl;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.security.KeyFactory;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.Map;
import java.util.TimeZone;
import javax.servlet.http.HttpServletRequest;
/**
* Need some basic parsing of data.
* @author buckett
*/
public class InlineHttpTransport implements Transport {
@SuppressWarnings("unchecked")
public RawContextObject parse(HttpServletRequest request) {
Map<String, String[]> parameters;
String source = null;
if ("GET".equals(request.getMethod())) {
// Already decoded
parameters = (Map<String, String[]>)request.getParameterMap();
source = request.getQueryString(); // Undecoded incase encoding is in params
} else if ("POST".equals(request.getMethod())) {
source = readBody(request);
parameters = Utils.decode(Utils.split(source), "UTF-8");
} else {
throw new IllegalArgumentException("Only POST and GET supported.");
}
String version = Utils.getValue(parameters, URL_VER);
if (version == null) {
// Should reject this.
} else {
if (!version.equals(ContextObject.VERSION)) {
// bad version, should reject, although being relaxed can be good..
}
}
String timestamp = Utils.getValue(parameters, URL_TIM);
if (timestamp != null) {
// Should parse.
// Format: ISO8601-conformant datetime, in the YYYY-MM-DD or YYYY-MM-DDTHH:MM:SSZ representation
// If time is present it is in UTC.
}
String format = Utils.getValue(parameters, URL_CTX_FMT);
if (format != null) {
if (!KEVFormat.FORMAT_ID.equals(format)) {
// Only support KEV in inline.
}
}
RawContextObject raw = new RawContextObject(KEVFormat.FORMAT_ID, source);
return raw;
}
public String encode(String content) {
URLBuilder url = new URLBuilder("UTF-8");
return url.append(URL_VER, ContextObject.VERSION)
.append(URL_TIM, currentTime(DateTimeType.DATE))
.append(URL_CTX_FMT, KEVFormat.FORMAT_ID)
.append(content)
.toString();
}
// Format: ISO8601-conformant datetime, in the YYYY-MM-DD or YYYY-MM-DDTHH:MM:SSZ representation
public enum DateTimeType {
DATE("yyyy-MM-dd"), DATETIME("yyyy-MM-ddTHH:mm:ssZ");
private String format;
DateTimeType(String format) {
this.format = format;
}
public SimpleDateFormat getFormat() {
// SimpleDAteFormat isn't threadsafe so create a new one each time.
return new SimpleDateFormat(format);
}
};
public String currentTime(DateTimeType type) {
// Current time must be in UTC.
Calendar cal = new GregorianCalendar(TimeZone.getTimeZone("UTC"));
return type.getFormat().format(cal.getTime());
}
private String readBody(HttpServletRequest request) {
try {
BufferedReader reader = request.getReader();
String line = null;
StringBuilder lines = new StringBuilder();
while((line = reader.readLine()) != null) {
lines.append(line);
}
return lines.toString();
} catch (IOException e) {
throw new IllegalStateException();
}
}
}