package restx.common; import com.google.common.base.Preconditions; import org.joda.time.DateTimeUtils; import static com.google.common.base.Preconditions.checkNotNull; /** * A MillisProvider which delegates to other providers with a per thread setting. * * It is generally used as a replacement for JodaTime millis provider which are classloader wide, and thus * not compatible with parallel tests. * * Note that calling any of the set method will install a ThreadLocalMillisProvider as DateTimeUtils millis provider. */ public class ThreadLocalMillisProvider implements DateTimeUtils.MillisProvider { private static final DateTimeUtils.MillisProvider systemMillisProvider = new DateTimeUtils.MillisProvider() { @Override public long getMillis() { return System.currentTimeMillis(); } }; private static final ThreadLocal local = new ThreadLocal() { @Override protected DateTimeUtils.MillisProvider initialValue() { return systemMillisProvider; } }; private static final DateTimeUtils.MillisProvider INSTANCE = new ThreadLocalMillisProvider(); public static final void setCurrentMillisSystem() throws SecurityException { install(); local.set(systemMillisProvider); } public static final void setCurrentMillisFixed(long fixedMillis) throws SecurityException { install(); local.set(new FixedMillisProvider(fixedMillis)); } public static final void setCurrentMillisOffset(long offsetMillis) throws SecurityException { install(); local.set(new OffsetMillisProvider(offsetMillis)); } public static final void setCurrentMillisProvider(DateTimeUtils.MillisProvider millisProvider) throws SecurityException { install(); local.set(checkNotNull(millisProvider)); } public static void clear() { local.remove(); } public static DateTimeUtils.MillisProvider current() { return local.get(); } private static void install() { DateTimeUtils.setCurrentMillisProvider(INSTANCE); } private ThreadLocalMillisProvider() { } @Override public long getMillis() { return local.get().getMillis(); } /** * Fixed millisecond provider. */ public static class FixedMillisProvider implements DateTimeUtils.MillisProvider { /** The fixed millis value. */ private final long iMillis; /** * Constructor. * @param fixedMillis the millis offset */ public FixedMillisProvider(long fixedMillis) { iMillis = fixedMillis; } /** * Gets the current time. * @return the current time in millis */ public long getMillis() { return iMillis; } } /** * Offset from system millis provider. */ public static class OffsetMillisProvider implements DateTimeUtils.MillisProvider { /** The millis offset. */ private final long iMillis; /** * Constructor. * @param offsetMillis the millis offset */ public OffsetMillisProvider(long offsetMillis) { iMillis = offsetMillis; } /** * Gets the current time. * @return the current time in millis */ public long getMillis() { return System.currentTimeMillis() + iMillis; } } }