package com.revolsys.ui.html.builder; import java.util.LinkedHashSet; import java.util.Map; import java.util.Set; import java.util.WeakHashMap; import javax.annotation.PreDestroy; import org.springframework.beans.factory.BeanFactory; import org.springframework.beans.factory.BeanFactoryAware; public class HtmlUiBuilderFactory implements BeanFactoryAware { private static Map<BeanFactory, Map<Class<?>, HtmlUiBuilder<?>>> buildersByFactoryAndClass = new WeakHashMap<>(); @SuppressWarnings("unchecked") public static <T extends HtmlUiBuilder> T get(final BeanFactory factory, final Class<?> objectClass) { HtmlUiBuilder<?> builder = null; if (objectClass != null) { Map<Class<?>, HtmlUiBuilder<?>> buildersByClass = buildersByFactoryAndClass.get(factory); if (buildersByClass == null) { buildersByClass = new WeakHashMap<>(); buildersByFactoryAndClass.put(factory, buildersByClass); } builder = buildersByClass.get(factory); if (builder == null) { final Set<Class<?>> interfaces = new LinkedHashSet<>(); builder = get(buildersByClass, interfaces, factory, objectClass); if (builder == null) { builder = get(buildersByClass, factory, objectClass, interfaces); } } } return (T)builder; } @SuppressWarnings("unchecked") public static <T extends HtmlUiBuilder> T get(final BeanFactory factory, final String typePath) { final String beanName = typePath + "-htmlbuilder"; if (factory.containsBean(beanName)) { return (T)factory.getBean(beanName); } else { return null; } } private static HtmlUiBuilder<?> get(final Map<Class<?>, HtmlUiBuilder<?>> buildersByClass, final BeanFactory factory, final Class<?> objectClass, final Set<Class<?>> interfaces) { HtmlUiBuilder<?> builder = null; for (final Class<?> interfaceClass : interfaces) { builder = get(buildersByClass, interfaces, factory, interfaceClass); if (builder != null) { buildersByClass.put(objectClass, builder); return builder; } } return builder; } private static HtmlUiBuilder<?> get(final Map<Class<?>, HtmlUiBuilder<?>> buildersByClass, final Set<Class<?>> interfaces, final BeanFactory factory, final Class<?> objectClass) { HtmlUiBuilder<?> builder = null; if (objectClass != null) { builder = buildersByClass.get(objectClass); if (builder == null) { final String className = objectClass.getName(); builder = get(factory, className); if (builder == null) { for (final Class<?> interfaceClass : objectClass.getInterfaces()) { interfaces.add(interfaceClass); } final Class<?> superClass = objectClass.getSuperclass(); builder = get(buildersByClass, interfaces, factory, superClass); } } } if (builder != null) { buildersByClass.put(objectClass, builder); } return builder; } private BeanFactory beanFactory; @PreDestroy public void destory() { buildersByFactoryAndClass.remove(this.beanFactory); } public <T extends HtmlUiBuilder<?>> T get(final Class<?> objectClass) { return (T)get(this.beanFactory, objectClass); } public <T extends HtmlUiBuilder<?>> T get(final String objectClassName) { return (T)get(this.beanFactory, objectClassName); } @Override public void setBeanFactory(final BeanFactory beanFactory) { this.beanFactory = beanFactory; } }