blob: 7a07e8dab23ecae04f39347af2648ca7203ed8df [file] [log] [blame]
package org.apache.yoko.util.cmsf;
import java.util.logging.Level;
import java.util.logging.Logger;
public final class CmsfThreadLocal {
private static final Logger LOGGER = Logger.getLogger(CmsfThreadLocal.class.getName());
private static final ThreadLocal<CmsfInfo> cmsfInfo = new ThreadLocal<CmsfInfo>() {
@Override protected CmsfInfo initialValue() {
return new CmsfInfo();
}
};
private CmsfThreadLocal() {}
private static final class CmsfInfo {
public Frame head = Frame.DEFAULT;
public boolean override = false;
}
private static final class Frame {
static final Frame DEFAULT = new Frame();
public final Version version;
public final Frame prev;
private Frame() {
this.version = Version.CMSFv1;
this.prev = this;
}
Frame(Version version, Frame prev) {
this.version = version;
this.prev = prev;
}
}
private enum Version {
CMSFv1(1), CMSFv2(2);
public final byte value;
private Version(int value) {
this.value = (byte)(value & 0xff);
}
static Version get(byte value) {
return (value >= 2) ? CMSFv2 : CMSFv1;
}
}
public static final class CmsfOverride implements AutoCloseable {
private final CmsfInfo info;
CmsfOverride(CmsfInfo info) {
this.info = info;
info.override = true;
}
@Override
public void close() {
info.override = false;
}
}
public static CmsfOverride override() {
return new CmsfOverride(cmsfInfo.get());
}
public static void push(byte cmsfv) {
final CmsfInfo info = cmsfInfo.get();
final Version version = Version.get(cmsfv);
if (LOGGER.isLoggable(Level.FINER))
LOGGER.finer(String.format("CMSF thread local version pushed onto stack: %s", version));
info.head = new Frame(version, info.head);
}
public static byte get() {
final CmsfInfo info = cmsfInfo.get();
final boolean override = info.override;
final Version version = (override) ? Version.CMSFv1 : info.head.version;
if (LOGGER.isLoggable(Level.FINER))
LOGGER.finer(String.format("CMSF thread local version retrieved: %s, override is %b", version, override));
return version.value;
}
public static byte pop() {
final CmsfInfo info = cmsfInfo.get();
final Version version = info.head.version;
if (LOGGER.isLoggable(Level.FINER))
LOGGER.finer(String.format("CMSF thread local version popped from stack: %s", version));
info.head = info.head.prev;
return version.value;
}
public static void reset() {
if (LOGGER.isLoggable(Level.FINER))
LOGGER.finer("CMSF thread local stack reset");
cmsfInfo.remove();
}
}