package play.modules.origo.core; import java.lang.reflect.Method; import java.util.*; import java.util.concurrent.ConcurrentHashMap; /** * Themes are used to render Nodes. A theme has multiple theme variants, for example 2-columns, 3-columns, top-middle-bottom, etc. * Each rootNode has a chosen theme variant to use for rendering. * Decorators are applied to each UIElement a RootNode has before rendering. */ public class Themes { /** * Collection of theme variants id's that a theme offers. */ public static Map<String, CachedTheme> themes = new ConcurrentHashMap<String, CachedTheme>(); /** * Maps variant id's to it's parent theme id. */ private static Map<String, String> themeVariantsToThemeMapping = new HashMap<String, String>(); public static void addTheme(String themeId, Class declaringClass) { if (themes.containsKey(themeId)) { throw new RuntimeException("Theme [" + themeId + "] declared in both " + declaringClass.getName() + " and " + themes.get(themeId).getDeclaringClass().getName()); } themes.put(themeId, new CachedTheme(themeId, declaringClass)); } public static void addThemeVariant(String themeId, String variantId, Method templateMethod, String[] regions) { // Themes are declared on the class level and should be parsed first so we don't need to check if the themeId exists before accessing Map<String, play.modules.origo.core.CachedThemeVariant> themeVariants = themes.get(themeId).getThemeVariants(); if (themeVariants.containsKey(variantId)) { throw new RuntimeException("Duplicate theme variant id [" + variantId + "]"); } themeVariantsToThemeMapping.put(variantId, themeId); themeVariants.put(variantId, new play.modules.origo.core.CachedThemeVariant(themeId, variantId, templateMethod, new HashSet<String>(Arrays.asList(regions)))); } public static void addDecorator(String themeId, String uiElementType, Method method) { // Themes are declared on the class level and should be parsed first so we don't need to check if the themeId exists before accessing Map<String, play.modules.origo.core.CachedDecorator> themeDecorators = themes.get(themeId).getDecorators(); themeDecorators.put(uiElementType, new play.modules.origo.core.CachedDecorator(method)); } public static CachedTheme getTheme(String themeId) { return themes.get(themeId); } public static play.modules.origo.core.CachedThemeVariant getThemeVariant(String themeId, String variantId) { return themes.get(themeId).getThemeVariants().get(variantId); } public static play.modules.origo.core.CachedThemeVariant getThemeVariant(String variantId) { if (themeVariantsToThemeMapping.containsKey(variantId)) { return getThemeVariant(themeVariantsToThemeMapping.get(variantId), variantId); } else { return null; } } public static Collection<play.modules.origo.core.CachedThemeVariant> getThemeVariants(String themeId) { if (themes.containsKey(themeId)) { return themes.get(themeId).getThemeVariants().values(); } return Collections.emptyList(); } public static Map<String, play.modules.origo.core.CachedDecorator> getDecoratorsForTheme(String themeId) { if (themes.containsKey(themeId)) { Map<String, play.modules.origo.core.CachedDecorator> decorators = themes.get(themeId).getDecorators(); if (decorators != null) { return decorators; } } return Collections.emptyMap(); } public static play.modules.origo.core.CachedDecorator getDecoratorForTheme(String themeId, String uiElementType) { return getDecoratorsForTheme(themeId).get(uiElementType); } /** * Invalidates all themes and all theme variants so that we can reload the themes and theme variants from the classes. */ public static void invalidate() { themes.clear(); } }