package com.janrain.backplane.common;
import com.janrain.servlet.InvalidRequestException;
import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.TimeZone;
/**
* @author Johnny Bufu
*/
public class DateTimeUtils {
// http://fahdshariff.blogspot.ca/2010/08/dateformat-with-multiple-threads.html
public static final ThreadLocal<DateFormat> ISO8601 = new ThreadLocal<DateFormat>() {
@Override
protected DateFormat initialValue() {
return new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'") {{
setTimeZone(TimeZone.getTimeZone("GMT"));
}};
}
};
public static final ThreadLocal<DateFormat> INTERNETDATE = new ThreadLocal<DateFormat>() {
@Override
protected DateFormat initialValue() {
return new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'") {{
setTimeZone(TimeZone.getTimeZone("UTC"));
}};
}
};
public static int getExpireSeconds(String messageId, String expire, boolean sticky) {
long seconds = (getExpireTime(messageId, expire, sticky).getTime() - System.currentTimeMillis()) / 1000;
if (seconds < 0 || seconds>Integer.MAX_VALUE) {
logger.warn("invalid expiration seconds: " + seconds);
return sticky ? MAX_RETENTION_SECONDS : DEFAULT_RETENTION_SECONDS;
} else {
return (int)seconds;
}
}
public static Date getExpireTime(String messageId, String expire, boolean sticky) {
try {
return StringUtils.isEmpty(expire) ? null : INTERNETDATE.get().parse(expire);
} catch (ParseException e) {
Date defaultExpiration = sticky ? new Date(System.currentTimeMillis() + MAX_RETENTION_SECONDS * 1000) : new Date(System.currentTimeMillis() + DEFAULT_RETENTION_SECONDS * 1000);
logger.warn("invalid expiration for message " + messageId + " : " + expire + " returning hardcoded default: " + INTERNETDATE.get().format(defaultExpiration));
return defaultExpiration;
}
}
public static String processExpireTime(Object requestSticky, Object requestedExpireTime, int defaultRetentionSeconds, int maxRetentionSeconds) {
try {
boolean sticky = requestSticky != null && Boolean.parseBoolean(requestSticky.toString());
if (requestedExpireTime == null) {
return INTERNETDATE.get().format(new Date(System.currentTimeMillis() + (sticky ? maxRetentionSeconds : defaultRetentionSeconds) * 1000));
} else {
Date requestedExpire = INTERNETDATE.get().parse(requestedExpireTime.toString());
if (requestedExpire.before(new Date(System.currentTimeMillis() + maxRetentionSeconds * 1000))) {
return requestedExpireTime.toString();
} else {
throw new InvalidRequestException("Requested expiration time " + requestedExpireTime + " is too far in the future, max is " + maxRetentionSeconds + " seconds");
}
}
} catch (ParseException pe) {
throw new InvalidRequestException("Requested expiration time not in internet date/time format: " + pe.getMessage());
}
}
// - PRIVATE
private static final Logger logger = Logger.getLogger(DateTimeUtils.class);
private static final int DEFAULT_RETENTION_SECONDS = 60;
private static final int MAX_RETENTION_SECONDS = 3600;
private DateTimeUtils() { }
}