package org.test4j.module.core.utility; import static org.test4j.module.core.utility.IPropItem.PROPKEY_MODULES; import static org.test4j.tools.commons.ClazzHelper.createInstanceOfType; import java.util.ArrayList; import java.util.List; import org.test4j.module.Test4JException; import org.test4j.module.core.Module; import org.test4j.tools.commons.ClazzHelper; import org.test4j.tools.commons.ConfigHelper; import org.test4j.tools.commons.StringHelper; /** * A class for loading test4j modules. * <p/> * The core names set by the {@link #PROPKEY_MODULES} property which modules * will be loaded. <br> * These names can then be used to construct properties that define the * classnames and optionally the dependencies of these modules. E.g. * * <pre> * <code> * test4j.modules=a, b, c, d * test4j.modules.a.className= org.test4j.core.AModule * test4j.modules.a.enabled= false * </code> * </pre> * * The above configuration will load 3 core classes A, B and C and will always * perform processing in order C, B, A. * <p/> */ public class ModulesLoader { /** * First part of all core specific properties. */ public static final String PROPKEY_MODULE_PREFIX = "test4j.module."; /** * Last part of the core specific property that specifies whether the core * should be loaded. */ public static final String PROPKEY_MODULE_SUFFIX_ENABLED = ".enabled"; /** * 特定模块类属性后缀<br> * 如果特定的模块类在classpath中不存在,则不加载该模块 */ public static final String PROPKEY_MODULE_ENABLED_CLASS = ".enabled.class"; /** * Last part of the core specific property that specifies the classname of * the core. */ public static final String PROPKEY_MODULE_SUFFIX_CLASS_NAME = ".className"; /** * Loading all test4j modules which are enabled and available. * * @return the modules which have loaded, not null */ public static List<Module> loading() { List<String> moduleNames = ConfigHelper.getStringList(PROPKEY_MODULES); // remove all disable modules moduleNames = filterModules(moduleNames); // Create core instances in the correct sequence List<Module> modules = new ArrayList<Module>(); for (String moduleName : moduleNames) { // get module class name String className = ConfigHelper.getString(PROPKEY_MODULE_PREFIX + moduleName + PROPKEY_MODULE_SUFFIX_CLASS_NAME); try { // create module instance Object module = createInstanceOfType(className); if (!(module instanceof Module)) { throw new Test4JException("Unable to load core. Module class is not of type Test4JModule: " + className); } ((Module) module).init();// initialize module modules.add((Module) module); } catch (Throwable t) { String error = "An exception occured during the loading of core module " + moduleName + " with module class name " + className; // throw new Test4JException(error, t); System.out.println(error); } } ModulesManager.initManager(modules); return modules; } /** * 过滤失效的模块,保持模块序列 Removes all modules that have a value false for the * enabled property. * * @param modules the all module names, not null * @return the enabled module name */ private static List<String> filterModules(List<String> modules) { List<String> enabledModules = new ArrayList<String>(); String dbType = ConfigHelper.databaseType(); for (String module : modules) { if (StringHelper.isBlankOrNull(dbType)) { if (module.equalsIgnoreCase("database")) continue; if (module.equalsIgnoreCase("dbfit")) continue; } boolean isEnabled = ConfigHelper.getBoolean(PROPKEY_MODULE_PREFIX + module + PROPKEY_MODULE_SUFFIX_ENABLED, true); if (isEnabled == false) { continue; } String moduleEnabledClazz = ConfigHelper.getString(PROPKEY_MODULE_PREFIX + module + PROPKEY_MODULE_ENABLED_CLASS); if (StringHelper.isBlankOrNull(moduleEnabledClazz)) { enabledModules.add(module); continue; } boolean clazzAvailable = ClazzHelper.isClassAvailable(moduleEnabledClazz); if (clazzAvailable) { enabledModules.add(module); } else { MessageHelper.warn(String.format("can't find class %s in classpath, so disabled module[%s]", clazzAvailable, module)); } } return enabledModules; } }