package org.dcm4chee.conf.decorators; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import javax.enterprise.inject.Instance; import javax.inject.Inject; import java.util.*; public class DynamicDecoratorManager { @Inject @ConfiguredDynamicDecorators DynamicDecoratorsConfig decoratorsConfig; @Inject @ConfiguredDynamicDecorators Instance<List<String>> disabledDecorators; private static final Logger LOG = LoggerFactory.getLogger(DynamicDecoratorManager.class); private final Map<Class, Object> activeDecorators = Collections.synchronizedMap(new HashMap<Class, Object>()); @SuppressWarnings("unchecked") public <T> Collection<DelegatingServiceImpl<T>> getOrderedDecorators(Instance<DelegatingServiceImpl<T>> availableDynamicDecorators, Class<? extends T> clazz, boolean usecache) { if (!usecache) return resolveDynamicDecorators(availableDynamicDecorators, clazz.getName()); synchronized (activeDecorators) { Object decorators = activeDecorators.get(clazz); if (decorators == null) { decorators = resolveDynamicDecorators(availableDynamicDecorators, clazz.getName()); activeDecorators.put(clazz, decorators); } LOG.trace("Retrieved {}.", activeDecorators); return (Collection<DelegatingServiceImpl<T>>) decorators; } } public <T> Collection<DelegatingServiceImpl<T>> getOrderedDecorators(Instance<DelegatingServiceImpl<T>> availableDynamicDecorators, Class<? extends T> clazz) { return getOrderedDecorators(availableDynamicDecorators, clazz, true); } /** * Matches the available dynamic decorators with the configuration and produces an ordered and filtered collection of active decorators * * @param availableDynamicDecorators * @param clazz service class * @return */ private synchronized <T> Collection<DelegatingServiceImpl<T>> resolveDynamicDecorators(Instance<DelegatingServiceImpl<T>> availableDynamicDecorators, String clazz) { LOG.debug("Creating decorators for {}.", clazz); TreeMap<Double, DelegatingServiceImpl<T>> decorators = new TreeMap<Double, DelegatingServiceImpl<T>>(); for (DelegatingServiceImpl<T> dynamicDecorator : availableDynamicDecorators) { Class<?> decoratorClazz = dynamicDecorator.getClass(); if (isDecoratorEnabled(decoratorClazz, clazz)) { Double priority = null; Map<String, Double> prioritiesMap = decoratorsConfig.getDecoratedServices().get(clazz).getPrioritiesMap(); // to handle proxies like org.abc.MyDecorator$_$$WeldProxy for (Map.Entry<String, Double> stringDoubleEntry : prioritiesMap.entrySet()) { if (decoratorClazz.getName().startsWith(stringDoubleEntry.getKey())) { priority = stringDoubleEntry.getValue(); break; } } if (priority == null) throw new RuntimeException("Dynamic decorator configuration not found for decorator " + decoratorClazz.getName() + " of service " + clazz); decorators.put(priority, dynamicDecorator); LOG.debug("Configuring the decorator {} with priority {}.", decoratorClazz, priority); } } return decorators.values(); } private boolean isDecoratorEnabled(Class<?> decoratorClazz, String serviceClazz) { if (!decoratorsConfig.getDecoratedServices().containsKey(serviceClazz)) { LOG.warn("Service class {} not defined in the dynamic decorators configuration.", serviceClazz); return false; } Map<String, Double> prioritiesMap = decoratorsConfig.getDecoratedServices().get(serviceClazz).getPrioritiesMap(); // to handle proxies like org.abc.MyDecorator$_$$WeldProxy boolean found = false; for (String configuredDecoratorClassName : prioritiesMap.keySet()) if (decoratorClazz.getName().startsWith(configuredDecoratorClassName)) found = true; if (!found) { LOG.debug("Not configuring the decorator {} because it is not in the configuration.", decoratorClazz); return false; } if (!disabledDecorators.isUnsatisfied()) if (disabledDecorators.get().contains(decoratorClazz.getName())) { LOG.debug("Not configuring the decorator {} because it is disabled.", decoratorClazz); return false; } return true; } }