package bjc.data; import java.util.*; /** * Utility methods for dealing with contexts. * * @author Ben Culkin * */ public class Contexts { /** * The null context, which always throws an exception. */ public static final IContext NULL = new NullContextImpl(); private Contexts() { throw new UnsupportedOperationException(); } /** * Create a new context with no parent. * * @return A context with no parent. */ public static IContext create() { return new ContextImpl(NULL); } /** * Create a context with the specified parent. * * @param parent The parent of this context. * * @return A context with the given context as its parent. */ public static IContext create(IContext parent) { return new ContextImpl(parent); } private static class NullContextImpl implements IContext { @Override public IContext getParent() { return this; } @Override public void register(String name, Object o) { throw new UnsupportedOperationException(); } @Override public Object get(String name) { throw new NoSuchElementException(); } @Override public T get(Class contract) { throw new NoSuchElementException(); } } private static class ContextImpl implements IContext { private final IContext parent; private final Map objects; public ContextImpl(IContext parent) { this.parent = parent; this.objects = new HashMap<>(); } @Override public void register(String name, Object o) { objects.put(name, o); } @Override public Object get(String name) { if (objects.containsKey(name)) { return objects.get(name); } return parent.get(name); } @SuppressWarnings("unchecked") @Override public T get(Class contract) { for (Object o : objects.values()) { if (contract.isInstance(o)) { return (T) o; } } return parent.get(contract); } @Override public IContext getParent() { return parent; } } }