package husacct.validate.domain.validation.ruletype.propertyruletypes;
import husacct.common.dto.DependencyDTO;
import husacct.common.dto.ModuleDTO;
import husacct.common.dto.RuleDTO;
import husacct.validate.domain.configuration.ConfigurationServiceImpl;
import husacct.validate.domain.validation.Severity;
import husacct.validate.domain.validation.Violation;
import husacct.validate.domain.validation.ViolationType;
import husacct.validate.domain.validation.internaltransferobjects.Mapping;
import husacct.validate.domain.validation.ruletype.RuleType;
import husacct.validate.domain.validation.ruletype.RuleTypes;
import java.util.ArrayList;
import java.util.EnumSet;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
public class FacadeConvention extends RuleType {
private final static EnumSet<RuleTypes> exceptionRuleTypes = EnumSet.of(RuleTypes.IS_ALLOWED_TO_USE);
public FacadeConvention(String key, String categoryKey, List<ViolationType> violationTypes, Severity severity) {
super(key, categoryKey, violationTypes, exceptionRuleTypes, severity);
}
@Override
public List<Violation> check(ConfigurationServiceImpl configuration, RuleDTO currentRule) {
violations.clear();
fromMappings = getAllClasspathsOfModule(currentRule.moduleFrom, currentRule.violationTypeKeys);
// Create HashMap with all classes within the component; these classes are allowed to use each other
HashMap<String, Mapping> allInComponentMap = new HashMap<String, Mapping>();
for(Mapping from : fromMappings){
allInComponentMap.put(from.getPhysicalPath(), from);
}
// Create HashMap with all allowed-to-use-classes (the classes mapped to the facade(s)). Note: This HashMap is not used, but useful for debugging, and the costs are low.
HashMap<String, Mapping> facadeMap = new HashMap<String, Mapping>();
ArrayList<Mapping> facadeMappings = getAllClassPathsOfFacadeOfComponent(currentRule.moduleFrom, currentRule.violationTypeKeys);
for(Mapping facadeClassPath : facadeMappings){
facadeMap.put(facadeClassPath.getPhysicalPath(), facadeClassPath);
}
// Create HashMap with all not allowed-to-use-classes (all other classes (so not facade-classes) within the component)
HashMap<String, Mapping> classesHiddeninComponentMap = new HashMap<String, Mapping>();
for (Mapping mappingFrom : fromMappings) {
if(!facadeMap.containsKey(mappingFrom.getPhysicalPath())) {
classesHiddeninComponentMap.put(mappingFrom.getPhysicalPath(), mappingFrom);
}
}
// Create a HashMap with all allowed from-to combinations, based on the exception rules.
HashSet<String> allExceptionFromTos = getAllExceptionFromTos(currentRule);
for (String hiddenClassPath : classesHiddeninComponentMap.keySet()) {
// Get all dependencies with matching dependency.classPathTo
DependencyDTO[] dependencies = analyseService.getDependenciesFromClassToClass("", hiddenClassPath);
for (DependencyDTO dependency : dependencies) {
String fromToCombi = dependency.from + "|" + dependency.to;
if ((allInComponentMap.containsKey(dependency.from)) || (allExceptionFromTos.contains(fromToCombi))){
// Do not add a violation, since the dependency is allowed.
} else{
Violation violation = createViolation(currentRule, dependency, configuration);
violations.add(violation);
}
}
}
return violations;
}
private ArrayList<Mapping> getAllClassPathsOfFacadeOfComponent(ModuleDTO module, String[] violationTypeKeys) {
ArrayList<Mapping> mappingFacade = new ArrayList<Mapping>();
for (ModuleDTO subModule : defineService.getModule_TheChildrenOfTheModule(module.logicalPath)) {
if (subModule.type.toLowerCase().equals("facade"))
mappingFacade.addAll(getAllClasspathsOfModule(subModule, violationTypeKeys));
}
return mappingFacade;
}
}