001package co.codewizards.cloudstore.core.context;
002
003import static java.util.Objects.*;
004
005import java.util.HashMap;
006import java.util.Map;
007
008public class ExtensibleContextSupport implements ExtensibleContext {
009
010        private final Map<Class<?>, Object> contextClass2ContextObject = new HashMap<>();
011
012        @Override
013        public void setContextObject(final Object object) {
014                requireNonNull(object, "object");
015                Class<?> clazz = object.getClass();
016                if (clazz == Object.class)
017                        throw new IllegalArgumentException("object is of type java.lang.Object! Must be a sub-class!");
018
019                if (clazz == Class.class)
020                        throw new IllegalArgumentException("object is of type java.lang.Class!");
021
022                while (clazz != Object.class) {
023                        registerContextObject(clazz, object);
024                        clazz = clazz.getSuperclass();
025                }
026        }
027
028        private void registerContextObject(final Class<?> clazz, final Object object) {
029                contextClass2ContextObject.put(clazz, object);
030
031                final Class<?>[] interfaces = clazz.getInterfaces();
032                for (final Class<?> iface : interfaces)
033                        registerContextObject(iface, object);
034        }
035
036        @Override
037        public <T> T getContextObject(final Class<T> clazz) {
038                requireNonNull(clazz, "clazz");
039                return clazz.cast(contextClass2ContextObject.get(clazz));
040        }
041
042        @Override
043        public void removeContextObject(Object object) {
044                requireNonNull(object, "object");
045                removeContextObject(object.getClass());
046        }
047
048        @Override
049        public void removeContextObject(Class<?> clazz) {
050                requireNonNull(clazz, "clazz");
051
052                while (clazz != Object.class) {
053                        contextClass2ContextObject.remove(clazz);
054
055                        final Class<?>[] interfaces = clazz.getInterfaces();
056                        for (final Class<?> iface : interfaces)
057                                contextClass2ContextObject.remove(iface);
058
059                        clazz = clazz.getSuperclass();
060                }
061        }
062}