package husacct.validate.domain.factory.ruletype; import husacct.validate.domain.exception.DefaultSeverityNotFoundException; import husacct.validate.domain.validation.DefaultSeverities; import husacct.validate.domain.validation.Severity; import husacct.validate.domain.validation.internaltransferobjects.CategoryKeyClassDTO; import husacct.validate.domain.validation.ruletype.RuleType; import husacct.validate.domain.validation.ruletype.RuleTypes; import java.lang.reflect.Modifier; import java.util.ArrayList; import java.util.Collections; import java.util.EnumSet; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.TreeMap; import org.apache.log4j.Logger; class RuleTypesGenerator { private Logger logger = Logger.getLogger(RuleTypesGenerator.class); private Map<String, DefaultSeverities> defaultRulesPerRuleType = Collections.emptyMap(); private static final String[] ruleTypeLocations = new String[] { "husacct.validate.domain.validation.ruletype.propertyruletypes", "husacct.validate.domain.validation.ruletype.dependencylimitation", "husacct.validate.domain.validation.ruletype.relationruletypes" }; RuleTypesGenerator() { this.defaultRulesPerRuleType = getRuleTypeDefaultSeverity(); } TreeMap<String, CategoryKeyClassDTO> generateRules(EnumSet<RuleTypes> rules) { TreeMap<String, CategoryKeyClassDTO> keyClasses = new TreeMap<String, CategoryKeyClassDTO>(); TreeMap<String, CategoryKeyClassDTO> allClasses = generateAllRules(); for (Enum<RuleTypes> ruleKey : rules) { CategoryKeyClassDTO ruleCategory = allClasses.get(ruleKey.toString()); if (ruleCategory != null) { keyClasses.put(ruleKey.toString(), ruleCategory); } else { logger.warn(String.format("Rulekey: %s not found", ruleKey.toString())); } } return keyClasses; } @SuppressWarnings("unchecked") TreeMap<String, CategoryKeyClassDTO> generateAllRules() { TreeMap<String, CategoryKeyClassDTO> keyClasses = new TreeMap<String, CategoryKeyClassDTO>(); List<Class<?>> ruleClasses = getRuleClasses(EnumSet.allOf(RuleTypes.class)); for (Class<?> ruleClass : ruleClasses) { String ruleKey = ""; try { if (isInstanceOfRule(ruleClass)) { ruleKey = getRuleKey(ruleClass); final String categoryKey = getCategoryKey(ruleClass); final DefaultSeverities defaultSeverity = getDefaultSeverity(ruleKey); keyClasses.put(ruleKey, new CategoryKeyClassDTO(categoryKey, (Class<RuleType>) ruleClass, defaultSeverity)); } } catch (DefaultSeverityNotFoundException e) { logger.warn(String.format("No default severity found for: %s, thus this ruleType will be ignored", ruleKey), e); } } return keyClasses; } private DefaultSeverities getDefaultSeverity(String ruleKey) { DefaultSeverities defaultSeverity = defaultRulesPerRuleType.get(ruleKey); if (defaultSeverity != null) { return defaultSeverity; } else { throw new DefaultSeverityNotFoundException(); } } private List<Class<?>> getRuleClasses(EnumSet<RuleTypes> ruleTypes) { return getRuleClasses(ruleTypeLocations, ruleTypes); } private List<Class<?>> getRuleClasses(String[] packageNames, EnumSet<RuleTypes> ruleTypes) { List<Class<?>> classList = new ArrayList<Class<?>>(); ClassLoader myClassLoader = this.getClass().getClassLoader(); for (String packageName : packageNames) { for (Enum<RuleTypes> ruleType : ruleTypes) { String classPath; try { classPath = packageName + "." + ruleType.toString(); Class<?> myClass = myClassLoader.loadClass(classPath); if (!Modifier.isAbstract(myClass.getModifiers()) && classHasRuleConstructor(myClass)) { classList.add(myClass); } } catch (ClassNotFoundException e) { // logger.debug(String.format("Classpath: %s not found" , // classPath)); } } } return classList; } private boolean classHasRuleConstructor(Class<?> ruleClass) { try { ruleClass.getConstructor(String.class, String.class, List.class, Severity.class); } catch (SecurityException e) { return exceptionOccured(e); } catch (NoSuchMethodException e) { return exceptionOccured(e); } return true; } private boolean exceptionOccured(Exception e) { return false; } private boolean isInstanceOfRule(Class<?> ruleClass) { return !ruleClass.isAnonymousClass() && !ruleClass.isEnum() && ruleClass.getSuperclass().getName().equals("husacct.validate.domain.validation.ruletype.RuleType"); } private String getCategoryKey(Class<?> ruleClass) { try { String[] splittedPackageName = ruleClass.getPackage().getName().split("\\."); return splittedPackageName[splittedPackageName.length - 1]; } catch (ArrayIndexOutOfBoundsException e) { return ""; } } private String getRuleKey(Class<?> ruleClass) { return ruleClass.getSimpleName().replace("Rule", ""); } private HashMap<String, DefaultSeverities> getRuleTypeDefaultSeverity() { HashMap<String, DefaultSeverities> defaultRulesPerRuleTypeLocal = new HashMap<String, DefaultSeverities>(); for (RuleTypes ruletype : EnumSet.allOf(RuleTypes.class)) { defaultRulesPerRuleTypeLocal.put(ruletype.toString(), ruletype.getDefaultSeverity()); } return defaultRulesPerRuleTypeLocal; } }