package org.test4j.module.core.utility; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; import org.test4j.module.Test4JException; import org.test4j.module.core.Module; import org.test4j.module.core.TestListener; import org.test4j.tools.commons.ClazzHelper; /** * test4j模块管理器<br> * A class for holding and retrieving modules. */ @SuppressWarnings({ "unchecked" }) public class ModulesManager { private static ModulesManager modulesManager = null; /** * 初始化Modules的管理器 * * @param modules */ public static final void initManager(List<Module> modules) { modulesManager = new ModulesManager(modules); } /** * 所有模块,(要保证顺序和价值module的顺序一致) */ private List<Module> modules = null; /** * 测试监听器(要保证顺序和价值module的顺序一致) */ private List<TestListener> testListeners = null; private List<TestListener> testListeners_Reverse = null; /** * A map containing the test listeners of each module */ private Map<Module, TestListener> testListenersMap = null; /** * Creates a repository containing the given modules.<br> * Creates test listeners for each of the given modules. * * @param modules the modules, not null */ private ModulesManager(List<Module> modules) { this.modules = modules; this.testListeners = new ArrayList<TestListener>(); this.testListeners_Reverse = new ArrayList<TestListener>(); this.testListenersMap = new HashMap<Module, TestListener>(); for (Module module : modules) { TestListener listener = module.getTestListener(); this.testListeners.add(listener); this.testListeners_Reverse.add(listener); this.testListenersMap.put(module, listener); } Collections.reverse(this.testListeners_Reverse); } public static ModulesManager instance() { if (modulesManager == null) { throw new RuntimeException("there are some error before test4j loading, modules haven't been loaded."); } return modulesManager; } /** * Gets all modules. * * @return the modules, not null */ public static List<Module> getModules() { if (modulesManager == null) { throw new RuntimeException("there are some error before test4j loading, modules haven't been loaded."); } return modulesManager.modules; } /** * Gets the listener corresponding to the given module. * * @param module the module, not null * @return the listener, null if the module could not be found */ public static TestListener getTestListener(Module module) { if (modulesManager == null) { throw new RuntimeException("there are some error before test4j loading, modules haven't been loaded."); } return modulesManager.testListenersMap.get(module); } /** * 获得modules的所有测试监听器(顺序和module加载顺序一致)<br> * Gets all listeners sequence. * * @return the listeners per module, not null */ public static List<TestListener> getTestListeners() { if (modulesManager == null) { throw new RuntimeException("there are some error before test4j loading, modules haven't been loaded."); } else { return modulesManager.testListeners; } } /** * 获得modules的所有测试监听器(顺序和module加载顺序相反)<br> * Gets all listeners sequence. * * @return the listeners per module, not null */ public static List<TestListener> getTestListeners_Reverse() { if (modulesManager == null) { throw new RuntimeException("there are some error before test4j loading, modules haven't been loaded."); } else { return modulesManager.testListeners_Reverse; } } /** * 返回module实例<br> * Gets the modules that is of the given type or a sub-type.<br> * A Test4JException is thrown when there is not exactly 1 possible match. * * @param <T> The module type * @param type the module type, not null * @return the module, not null */ public static <T extends Module> T getModuleInstance(Class<T> type) { List<T> modulesOfType = getModulesOfType(type); if (modulesOfType.size() > 1) { throw new Test4JException("More than one module found of type " + type.getName()); } if (modulesOfType.size() < 1) { throw new Test4JException("No module found of type " + type.getName()); } return modulesOfType.get(0); } /** * Gets all modules that are of the given type or a sub-type. * * @param <T> The module type * @param type the type, not null * @return the modules, an empty list if none found */ private static <T> List<T> getModulesOfType(Class<T> type) { if (modulesManager == null) { throw new RuntimeException("there are some error before test4j loading, modules haven't been loaded."); } List<T> result = new ArrayList<T>(); for (Module module : modulesManager.modules) { if (type.isAssignableFrom(module.getClass())) { result.add((T) module); } } return result; } /** * Checks whether a module of a type with the given class name exists. The * class name can also be the super-type of an existing module. * * @param fullyQualifiedClassName The class name, not null * @return True if the module exists and is enabled */ public boolean isModuleEnabled(String fullyQualifiedClassName) { Class<? extends Module> moduleClass; try { moduleClass = ClazzHelper.getClazz(fullyQualifiedClassName); } catch (Throwable e) { // class could not be loaded return false; } return isModuleEnabled(moduleClass); } /** * Checks whether a module of a type exists. The class an also be the * super-type of an existing module. * * @param moduleClass The class, not null * @return True if the module exists and is enabled */ public static boolean isModuleEnabled(Class<? extends Module> moduleClass) { List<? extends Module> modulesOfType = getModulesOfType(moduleClass); if (modulesOfType.size() > 1) { throw new Test4JException("More than one module found of type " + moduleClass.getName()); } return modulesOfType.size() == 1; } }