package husacct.analyse.task.reconstruct.algorithms.hu.layers.scanniello; import java.util.ArrayList; import java.util.HashMap; import org.apache.log4j.Logger; import husacct.analyse.domain.IModelQueryService; import husacct.analyse.task.reconstruct.AnalyseReconstructConstants; import husacct.analyse.task.reconstruct.ReconstructArchitecture; import husacct.analyse.task.reconstruct.dto.ReconstructArchitectureDTO; import husacct.analyse.task.reconstruct.parameters.ReconstructArchitectureParameterDTO; import husacct.common.dto.ModuleDTO; import husacct.common.dto.SoftwareUnitDTO; import husacct.common.enums.ModuleTypes; public class Layers_Scanniello_SelectedModule_Improved extends Layers_Scanniello_SuperClass{ ModuleDTO selectedModule; ArrayList<String> softwareUnitsInSelectedModuleList; private final Logger logger = Logger.getLogger(ReconstructArchitecture.class); private ArrayList<SoftwareUnitDTO> softwareUnitsToIncludeInAlgorithm = new ArrayList<SoftwareUnitDTO>(); private HashMap<String, SoftwareUnitDTO> softwareUnitsToExclude = new HashMap<String, SoftwareUnitDTO>(); public Layers_Scanniello_SelectedModule_Improved (IModelQueryService queryService) { super(queryService); } @Override public void executeAlgorithm(ReconstructArchitectureDTO dto, IModelQueryService queryService)throws Exception { try { selectedModule = dto.getSelectedModule(); if (selectedModule.logicalPath.equals("")) { selectedModule.logicalPath = "**"; // Root of intended software architecture selectedModule.type = "Root"; // Root of intended software architecture } this.threshold = dto.getThreshold(); // If the selectedModule is of type Facade or ExternalLibrary, nothing is done. if ((selectedModule == null) || selectedModule.type.equals(ModuleTypes.EXTERNAL_LIBRARY.toString()) || selectedModule.type.equals(ModuleTypes.FACADE.toString())) { return; } // Select the set of SUs to be used, and activate the component-identifying algorithm if (selectedModule.logicalPath.equals("**")) { for (SoftwareUnitDTO rootUnit : queryService.getSoftwareUnitsInRoot()) { if (!rootUnit.uniqueName.equals("xLibraries")) { softwareUnitsToIncludeInAlgorithm.add(rootUnit); if (softwareUnitsToIncludeInAlgorithm.size() == 1) { softwareUnitsToIncludeInAlgorithm = getSetOfChildSoftwareUnits(rootUnit); } } } } else { softwareUnitsToIncludeInAlgorithm = getRelevantSoftwareUnits(); } identifyAndCreateLayers(dto, softwareUnitsToIncludeInAlgorithm); } catch (Exception e) { logger.warn(" Exception: " + e ); } } private void identifyAndCreateLayers(ReconstructArchitectureDTO dto, ArrayList<SoftwareUnitDTO> softwareUnitDTOsOfSelectedModule) { boolean firstIdentification = true; HashMap<Integer, ArrayList<SoftwareUnitDTO>> firstLayersIdentification = IdentifyLayersImproved(softwareUnitDTOsOfSelectedModule, dto, firstIdentification); ArrayList<ArrayList<SoftwareUnitDTO>> topLayers = new ArrayList<>(); ArrayList<ArrayList<SoftwareUnitDTO>> bottomLayers = new ArrayList<>(); ArrayList<SoftwareUnitDTO> middleLayer = new ArrayList<>(); ArrayList<SoftwareUnitDTO> discLayer = new ArrayList<>(); topLayers.add(firstLayersIdentification.get(topLayerKey)); bottomLayers.add(firstLayersIdentification.get(bottomLayerKey)); middleLayer = firstLayersIdentification.get(middleLayerKey); discLayer = firstLayersIdentification.get(discLayerKey); boolean topOrBottomAreNotEmpty = firstLayersIdentification.get(topLayerKey).size() > 0 || firstLayersIdentification.get(bottomLayerKey).size() > 0; while (topOrBottomAreNotEmpty){ firstIdentification = false; HashMap<Integer, ArrayList<SoftwareUnitDTO>> newIdentifiedLayers = IdentifyLayersImproved(middleLayer, dto, firstIdentification); if (!newIdentifiedLayers.get(topLayerKey).isEmpty()){ topLayers.add(newIdentifiedLayers.get(topLayerKey)); } if (!newIdentifiedLayers.get(bottomLayerKey).isEmpty()){ bottomLayers.add(newIdentifiedLayers.get(bottomLayerKey)); } middleLayer = newIdentifiedLayers.get(middleLayerKey); topOrBottomAreNotEmpty = newIdentifiedLayers.get(topLayerKey).size() > 0 || newIdentifiedLayers.get(bottomLayerKey).size() > 0; } HashMap<Integer, ArrayList<SoftwareUnitDTO>> structuredLayers = RestructureLayers(topLayers, bottomLayers, middleLayer); buildStructure(structuredLayers, discLayer, selectedModule); } private void addSoftwareUnitsAssignedToComponentInterface_To_softwareUnitsToExcludeMap() { if (selectedModule.type.equals(ModuleTypes.COMPONENT.toString())) { for (ModuleDTO subModule : selectedModule.subModules) { if (subModule.type.equals(ModuleTypes.FACADE.toString())) { defineService.getAssignedSoftwareUnitsOfModule(subModule.logicalPath); for (String assignedUnitUniqueName : defineService.getAssignedSoftwareUnitsOfModule(subModule.logicalPath)) { SoftwareUnitDTO assignedUnit = queryService.getSoftwareUnitByUniqueName(assignedUnitUniqueName); if (!assignedUnit.name.isEmpty()) { softwareUnitsToExclude.put(assignedUnit.uniqueName, assignedUnit); } } } } } } // Returns the SUs assigned to selectedModule or, if only one SU is assigned, the children of this SU. // In case the selectedModule is a Component, the SUs assigned to the interface should not be returned. Prepare. private ArrayList<SoftwareUnitDTO> getRelevantSoftwareUnits() { ArrayList<SoftwareUnitDTO> softwareUnitsToReturn = new ArrayList<SoftwareUnitDTO>(); addSoftwareUnitsAssignedToComponentInterface_To_softwareUnitsToExcludeMap(); int numberOfAssignedSoftwareUnits = defineService.getAssignedSoftwareUnitsOfModule(selectedModule.logicalPath).size(); if (numberOfAssignedSoftwareUnits > 1) { for(String logicalSoftwarePathSelectedModule : defineService.getAssignedSoftwareUnitsOfModule(selectedModule.logicalPath)){ SoftwareUnitDTO suDTO = queryService.getSoftwareUnitByUniqueName(logicalSoftwarePathSelectedModule); if (!softwareUnitsToExclude.containsKey(suDTO.uniqueName)) { softwareUnitsToReturn.add(suDTO); } } } else if (numberOfAssignedSoftwareUnits == 1){ SoftwareUnitDTO assignedSU = new SoftwareUnitDTO("", "", "", ""); for(String uniqueNameAssignedSU : defineService.getAssignedSoftwareUnitsOfModule(selectedModule.logicalPath)){ assignedSU = queryService.getSoftwareUnitByUniqueName(uniqueNameAssignedSU); } for (SoftwareUnitDTO subModule : getSetOfChildSoftwareUnits(assignedSU)){ if (!softwareUnitsToExclude.containsKey(subModule.uniqueName)) { softwareUnitsToReturn.add(subModule); } } } return softwareUnitsToReturn; } /** Returns the first set of children (number of children >= 2) in the decomposition hierarchy of the parent SoftwareUnit * @param parentSoftwareUnit (of a SoftwareUnit) * @return ArrayList<String> with unique names of children, or an empty list, if no child SoftwareUnits are existing. */ private ArrayList<SoftwareUnitDTO> getSetOfChildSoftwareUnits(SoftwareUnitDTO parentSoftwareUnit) { ArrayList<SoftwareUnitDTO> childSoftwareUnits = new ArrayList<SoftwareUnitDTO>(); SoftwareUnitDTO softwareUnit = parentSoftwareUnit; while (childSoftwareUnits.size() < 2) { SoftwareUnitDTO[] childUnits = (queryService.getChildUnitsOfSoftwareUnit(softwareUnit.uniqueName)); if (childUnits.length == 0) { if (!softwareUnit.equals(parentSoftwareUnit)) { childSoftwareUnits.add(softwareUnit); } break; } else if ((childUnits.length == 1)) { softwareUnit = childUnits[0]; } else if ((childUnits.length >= 2)) { for (SoftwareUnitDTO childUnit : childUnits) { childSoftwareUnits.add(childUnit); } } } return childSoftwareUnits; } @Override public ReconstructArchitectureDTO getAlgorithmParameterSettings() { ReconstructArchitectureDTO reconstructArchitecture = new ReconstructArchitectureDTO(); reconstructArchitecture.approachId = AnalyseReconstructConstants.Algorithms.Layers_Scanniello_Improved; reconstructArchitecture.threshold = 10; reconstructArchitecture.relationType = AnalyseReconstructConstants.RelationTypes.allDependencies; reconstructArchitecture.granularity = AnalyseReconstructConstants.Granularities.PackagesAndClasses; reconstructArchitecture.parameterDTOs = createParameterPanels(); return reconstructArchitecture; } private ArrayList<ReconstructArchitectureParameterDTO> createParameterPanels(){ ArrayList<ReconstructArchitectureParameterDTO> parameterDTOs = new ArrayList<>(); parameterDTOs.add(ReconstructArchitectureParameterDTO.DefaultParameterDTOs.createThresholdParameter(10)); parameterDTOs.add(ReconstructArchitectureParameterDTO.DefaultParameterDTOs.createRelationTypeParameter(AnalyseReconstructConstants.RelationTypes.allDependencies)); parameterDTOs.add(ReconstructArchitectureParameterDTO.DefaultParameterDTOs.createGranularityPanel(AnalyseReconstructConstants.Granularities.PackagesAndClasses)); return parameterDTOs; } }