package husacct.validate.task.imexporting;
import husacct.ServiceProvider;
import husacct.externalinterface.ViolationImExportDTO;
import husacct.externalinterface.ViolationReportDTO;
import husacct.validate.domain.configuration.ViolationRepository;
import husacct.validate.domain.validation.Violation;
import husacct.validate.domain.validation.logicalmodule.LogicalModule;
import husacct.validate.domain.validation.logicalmodule.LogicalModules;
import husacct.validate.task.TaskServiceImpl;
import husacct.validate.task.imexporting.exporting.ExportNewViolations;
import husacct.validate.task.imexporting.importing.ImportViolations;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Set;
import org.apache.log4j.Logger;
import org.jdom2.Document;
public class ViolationReportDtoFactory {
private TaskServiceImpl task;
private List<Violation> allCurrentViolations;
private List<ViolationImExportDTO> allCurrentViolationsImExportList;
private Calendar timeCurrentCheck;
private ViolationRepository previousViolationRepository;
private List<ViolationImExportDTO> newViolationsList; // Contains current violations not detected in the previousViolationsDtoList
private List<ViolationImExportDTO> previousViolationsDtoList;
private Calendar previousValidationDate;
private HashMap<String, Boolean> hasNumberOfViolationsPerRuleIncreased; // Contains value "true" if the number of violations for a rule (key) has increased.
private Logger logger = Logger.getLogger(ViolationReportDtoFactory.class);
public ViolationReportDtoFactory(TaskServiceImpl task) {
this.task = task;
allCurrentViolations = task.getAllViolations().getValue();
allCurrentViolationsImExportList = createAllCurrentViolationsImExportList(allCurrentViolations);
timeCurrentCheck = task.getAllViolations().getKey();
newViolationsList = new ArrayList<ViolationImExportDTO>();
}
public ViolationReportDTO getViolationReportData(Document previousViolations, boolean exportAllViolations, boolean exportNewViolations) {
ViolationReportDTO violationReportDTO = new ViolationReportDTO();
try {
// Add the results of the current SACC to violationReportDTO
violationReportDTO.setTimeCurrentCheck(timeCurrentCheck);
int nrOfDependencies = ServiceProvider.getInstance().getAnalyseService().getAnalysisStatistics(null).totalNrOfDependencies;
violationReportDTO.setNrOfAllCurrentDependencies(nrOfDependencies);
int nrOfAllCurrentViolations = allCurrentViolationsImExportList.size();
violationReportDTO.setAllViolations(allCurrentViolationsImExportList.toArray(new ViolationImExportDTO[nrOfAllCurrentViolations]));
violationReportDTO.setNrOfAllCurrentViolations(nrOfAllCurrentViolations);
// Determine if new violations have to be identified
if ((previousViolations != null)) {
this.logger.info(new Date().toString() + " Start: Identify New Violations");
importPreviousViolations(previousViolations);
addPreviousViolationsToRepository();
determineIncreaseOfViolationsPerRule();
violationReportDTO = filterNewViolations(violationReportDTO);
this.logger.info(new Date().toString() + " Finished: Identify New Violations");
}
// Create newViolations export document, if needed
if (exportNewViolations) {
Document exportDocNewViolations = new ExportNewViolations().createReport(newViolationsList, timeCurrentCheck);
if (exportDocNewViolations != null) {
violationReportDTO.setExportDocNewViolations(exportDocNewViolations);
}
}
// Create allViolations export document, if needed
if (exportAllViolations) {
ReportService reporter = new ReportService(task);
Document exportDocAllViolations = reporter.createAllViolationsXmlDocument(task.getAllViolations());
if (exportDocAllViolations != null) {
violationReportDTO.setExportDocAllViolations(exportDocAllViolations);
}
}
} catch (Exception e){
logger.warn("Exception: " + e.getMessage());
}
return violationReportDTO;
}
private void importPreviousViolations(Document previousViolations) {
ImportViolations importer = new ImportViolations(previousViolations);
previousViolationsDtoList = importer.importViolations();
previousValidationDate = importer.getValidationDate();
}
private void addPreviousViolationsToRepository() { // Only attributes needed for filtering are set.
previousViolationRepository = new ViolationRepository();
for (ViolationImExportDTO previousViolationDTO : previousViolationsDtoList) {
Violation previousViolation = new Violation()
.setRuletypeKey(previousViolationDTO.getRuleType())
.setLogicalModules(getLogicalModules(previousViolationDTO))
.setClassPathFrom(previousViolationDTO.getFrom())
.setClassPathTo(previousViolationDTO.getTo())
.setLineNumber(previousViolationDTO.getLine())
.setViolationTypeKey(previousViolationDTO.getDepType())
.setdependencySubType(previousViolationDTO.getDepSubType())
.setInDirect(previousViolationDTO.isIndirect());
previousViolationRepository.addViolation(previousViolation);
}
previousViolationRepository.filterAndSortAllViolations();
}
private LogicalModules getLogicalModules(ViolationImExportDTO previousViolationDTO) {
LogicalModule logicalModuleFrom = new LogicalModule(previousViolationDTO.getFromMod(), "");
LogicalModule logicalModuleTo = new LogicalModule(previousViolationDTO.getToMod(), "");
LogicalModules logicalModules = new LogicalModules(logicalModuleFrom, logicalModuleTo);
return logicalModules;
}
// Fills map hasNumberOfViolationsPerRUleIncreased
private void determineIncreaseOfViolationsPerRule() {
hasNumberOfViolationsPerRuleIncreased = new HashMap<>();
Set<String> previouslyViolatedRules = previousViolationRepository.getViolatedRules();
for (String previouslyViolatedRule : previouslyViolatedRules) {
String[] ruleKeys = previouslyViolatedRule.split("::");
int previousNrOfViolations = previousViolationRepository.getViolationsByRule(ruleKeys[0], ruleKeys[1], ruleKeys[2]).size();
int currentNrOfViolations = task.getViolationsByRule(ruleKeys[0], ruleKeys[1], ruleKeys[2]).size();
boolean increaseOfViolationsPerRule = false;
if (currentNrOfViolations > previousNrOfViolations) {
increaseOfViolationsPerRule = true;
}
hasNumberOfViolationsPerRuleIncreased.put(previouslyViolatedRule, increaseOfViolationsPerRule);
}
}
/* Add each current violation that is not found in the previousViolationRepository to the newViolationsList if
* the number of violations has increased for the rule.
* The last check limits the number of false positives in cases where the class-name or lineNumber have changed.
*/
private ViolationReportDTO filterNewViolations(ViolationReportDTO violationReportDTO) {
newViolationsList.clear();
for (Violation currenViolation : allCurrentViolations) {
boolean isViolationNew = true;
// violationFromToKey = violation.getClassPathFrom() + "::" + violation.getClassPathTo();
List<Violation> previousFromToViolations= previousViolationRepository.getViolationsFromTo(currenViolation.getClassPathFrom(), currenViolation.getClassPathTo());
// violationDetailsKey = violation.getRuletypeKey() + "::" + violation.getLinenumber() + "::" + violation.getIsIndirect() + "::" + violation.getViolationTypeKey() + "::" + violation.getDependencySubType();
for (Violation previousViolation : previousFromToViolations) {
if (currenViolation.getRuletypeKey().equals(previousViolation.getRuletypeKey())) {
if (currenViolation.getLinenumber() == previousViolation.getLinenumber()) {
if (currenViolation.getIsIndirect() == previousViolation.getIsIndirect()) {
if (currenViolation.getViolationTypeKey().equals(previousViolation.getViolationTypeKey())) {
if (currenViolation.getDependencySubType().equals(previousViolation.getDependencySubType())) {
isViolationNew = false;
}
}
}
}
}
}
if (isViolationNew) {
// Determine if the number of violations has increased for the rule.
String searchKey = currenViolation.getLogicalModules().getLogicalModuleFrom().getLogicalModulePath()
+ "::" + currenViolation.getLogicalModules().getLogicalModuleTo().getLogicalModulePath()
+ "::" + currenViolation.getRuletypeKey();
if (hasNumberOfViolationsPerRuleIncreased.containsKey(searchKey)) {
if (hasNumberOfViolationsPerRuleIncreased.get(searchKey)) {
// The number of violations has increased for the rule, so add the violation to the newViolationsList
newViolationsList.add(createViolationImportExportDTO(currenViolation));
}
} else {
// The rule and the violation to the rule is new, so add the violation to the newViolationsList
newViolationsList.add(createViolationImportExportDTO(currenViolation));
}
}
}
violationReportDTO.setNewViolations(newViolationsList.toArray(new ViolationImExportDTO[newViolationsList.size()]));
violationReportDTO.setNrOfNewViolations(newViolationsList.size());
violationReportDTO.setNrOfAllPreviousViolations(previousViolationsDtoList.size());
violationReportDTO.setTimePreviousCheck(previousValidationDate);
return violationReportDTO;
}
private List<ViolationImExportDTO> createAllCurrentViolationsImExportList(List<Violation> allCurrentViolations) {
List<ViolationImExportDTO> returnList = new ArrayList<ViolationImExportDTO>();
for (Violation violation : allCurrentViolations) {
returnList.add(createViolationImportExportDTO(violation));
}
return returnList;
}
private ViolationImExportDTO createViolationImportExportDTO(Violation violation) {
ViolationImExportDTO newViolation = new ViolationImExportDTO();
newViolation.setFrom(violation.getClassPathFrom());
newViolation.setTo(violation.getClassPathTo());
newViolation.setLine(violation.getLinenumber());
newViolation.setDepType(violation.getViolationTypeKey());
newViolation.setDepSubType(violation.getDependencySubType());
newViolation.setFrom(violation.getClassPathFrom());
newViolation.setIndirect(violation.getIsIndirect());
newViolation.setSeverity(violation.getSeverity().getSeverityKey());
newViolation.setMessage(task.getMessage(violation));
newViolation.setRuleType(violation.getRuletypeKey());
newViolation.setFromMod(violation.getLogicalModules().getLogicalModuleFrom().getLogicalModulePath());
newViolation.setToMod(violation.getLogicalModules().getLogicalModuleTo().getLogicalModulePath());
return newViolation;
}
}