package husacct.analyse.task.reconstruct.algorithms.hu.layers.goldstein; import java.util.ArrayList; import java.util.TreeMap; 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.algorithms.Algorithm_SuperClass; import husacct.analyse.task.reconstruct.dto.ReconstructArchitectureDTO; import husacct.analyse.task.reconstruct.parameters.ReconstructArchitectureParameterDTO; import husacct.common.dto.ModuleDTO; import husacct.common.dto.SoftwareUnitDTO; public class Layers_Goldstein_Root_Initial extends Algorithm_SuperClass{ private int layerThreshold; private ArrayList<SoftwareUnitDTO> internalRootPackagesWithClasses; private TreeMap<Integer, ArrayList<SoftwareUnitDTO>> layers = new TreeMap<Integer, ArrayList<SoftwareUnitDTO>>(); private final Logger logger = Logger.getLogger(ReconstructArchitecture.class); public Layers_Goldstein_Root_Initial (IModelQueryService queryService) { super(queryService); } @Override public void executeAlgorithm(ReconstructArchitectureDTO dto, IModelQueryService queryService) { layerThreshold = dto.getThreshold(); determineInternalRootPackagesWithClasses(); //identifyLayers(); identifyLayersAtRootLevel(dto.getRelationType()); } private void determineInternalRootPackagesWithClasses() { internalRootPackagesWithClasses = new ArrayList<SoftwareUnitDTO>(); SoftwareUnitDTO[] allRootUnits = queryService.getSoftwareUnitsInRoot(); for (SoftwareUnitDTO rootModule : allRootUnits) { if (!rootModule.uniqueName.equals(xLibrariesRootPackage)) { for (String internalPackage : queryService.getRootPackagesWithClass(rootModule.uniqueName)) { internalRootPackagesWithClasses.add(queryService.getSoftwareUnitByUniqueName(internalPackage)); } } } if (internalRootPackagesWithClasses.size() == 1) { // Temporal solution useful for HUSACCT20 test. To be improved! E.g., classes in root are excluded from the process. String newRoot = internalRootPackagesWithClasses.get(0).uniqueName; internalRootPackagesWithClasses = new ArrayList<SoftwareUnitDTO>(); for (SoftwareUnitDTO child : queryService.getChildUnitsOfSoftwareUnit(newRoot)) { if (child.type.equalsIgnoreCase("package")) { internalRootPackagesWithClasses.add(child); } } } } // Code below is not used in version 28/03/2016 public ArrayList<SoftwareUnitDTO> getClasses(String library) { internalRootPackagesWithClasses = new ArrayList<SoftwareUnitDTO>(); SoftwareUnitDTO[] allRootUnits = queryService.getSoftwareUnitsInRoot(); for (SoftwareUnitDTO rootModule : allRootUnits) { if (!rootModule.uniqueName.equals(library)) { for (String internalPackage : queryService.getRootPackagesWithClass(rootModule.uniqueName)) { internalRootPackagesWithClasses.add(queryService.getSoftwareUnitByUniqueName(internalPackage)); } } } if (internalRootPackagesWithClasses.size() == 1) { // Temporal solution useful for HUSACCT20 test. To be improved! // E.g., classes in root are excluded from the process. String newRoot = internalRootPackagesWithClasses.get(0).uniqueName; internalRootPackagesWithClasses = new ArrayList<SoftwareUnitDTO>(); for (SoftwareUnitDTO child : queryService.getChildUnitsOfSoftwareUnit(newRoot)) { if (child.type.equalsIgnoreCase("package")) { internalRootPackagesWithClasses.add(child); } } } return internalRootPackagesWithClasses; } private void identifyLayersAtRootLevel(String dependencyType) { determineInternalRootPackagesWithClasses(); identifyLayers(internalRootPackagesWithClasses, dependencyType); int numberOfAddedLayers = 0; for (Integer hierarchicalLevel : layers.keySet()) { ModuleDTO newModule = defineSarService.addModule("Layer" + hierarchicalLevel, "**", "Layer", hierarchicalLevel, layers.get(hierarchicalLevel)); if (!newModule.logicalPath.equals("")) { numberOfAddedLayers ++; addToReverseReconstructionList(newModule); //add to cache for reverse } } logger.info(" Number of added Layers: " + numberOfAddedLayers); } private void identifyLayers(ArrayList<SoftwareUnitDTO> units, String depedencyType) { // 1) Assign all internalRootPackages to bottom layer int layerId = 1; ArrayList<SoftwareUnitDTO> assignedUnits = new ArrayList<SoftwareUnitDTO>(); assignedUnits.addAll(units); layers.put(layerId, assignedUnits); // 2) Identify the bottom layer. Look for packages with dependencies to // external systems only. identifyTopLayerBasedOnUnitsInBottomLayer(layerId, depedencyType); // 3) Look iteratively for packages on top of the bottom layer, et // cetera. while (layers.lastKey() > layerId) { layerId++; identifyTopLayerBasedOnUnitsInBottomLayer(layerId, depedencyType); } // 4) Add the layers to the intended architecture int highestLevelLayer = layers.size(); if (highestLevelLayer > 1) { // Reverse the layer levels. The numbering of the layers within the // intended architecture is different: the highest level layer has // hierarchcalLevel = 1 int lowestLevelLayer = 1; int raise = highestLevelLayer - lowestLevelLayer; TreeMap<Integer, ArrayList<SoftwareUnitDTO>> tempLayers = new TreeMap<Integer, ArrayList<SoftwareUnitDTO>>(); for (int i = lowestLevelLayer; i <= highestLevelLayer; i++) { ArrayList<SoftwareUnitDTO> unitsOfLayer = layers.get(i); int level = lowestLevelLayer + raise; tempLayers.put(level, unitsOfLayer); raise--; } layers = tempLayers; } } private void identifyTopLayerBasedOnUnitsInBottomLayer(int bottomLayerId, String dependencyType) { ArrayList<SoftwareUnitDTO> assignedUnitsOriginalBottomLayer = layers.get(bottomLayerId); @SuppressWarnings("unchecked") ArrayList<SoftwareUnitDTO> assignedUnitsBottomLayerClone = (ArrayList<SoftwareUnitDTO>) assignedUnitsOriginalBottomLayer .clone(); ArrayList<SoftwareUnitDTO> assignedUnitsNewBottomLayer = new ArrayList<SoftwareUnitDTO>(); ArrayList<SoftwareUnitDTO> assignedUnitsTopLayer = new ArrayList<SoftwareUnitDTO>(); for (SoftwareUnitDTO softwareUnit : assignedUnitsOriginalBottomLayer) { boolean rootPackageDoesNotUseOtherPackage = true; for (SoftwareUnitDTO otherSoftwareUnit : assignedUnitsBottomLayerClone) { if (!otherSoftwareUnit.uniqueName.equals(softwareUnit.uniqueName)) { int nrOfDependenciesFromsoftwareUnitToOther =0; int nrOfDependenciesFromOtherTosoftwareUnit=0; switch(dependencyType){ case AnalyseReconstructConstants.RelationTypes.umlLinks: nrOfDependenciesFromsoftwareUnitToOther = queryService.getUmlLinksFromSoftwareUnitToSoftwareUnit(softwareUnit.uniqueName, otherSoftwareUnit.uniqueName).length; nrOfDependenciesFromOtherTosoftwareUnit = queryService.getUmlLinksFromSoftwareUnitToSoftwareUnit(otherSoftwareUnit.uniqueName, softwareUnit.uniqueName).length; break; case AnalyseReconstructConstants.RelationTypes.accessCallReferenceDependencies: nrOfDependenciesFromsoftwareUnitToOther = queryService.getDependencies_OnlyAccessCallAndReferences_FromSoftwareUnitToSoftwareUnit(softwareUnit.uniqueName, otherSoftwareUnit.uniqueName).length; nrOfDependenciesFromOtherTosoftwareUnit = queryService.getDependencies_OnlyAccessCallAndReferences_FromSoftwareUnitToSoftwareUnit(otherSoftwareUnit.uniqueName, softwareUnit.uniqueName).length; break; case AnalyseReconstructConstants.RelationTypes.allDependencies: nrOfDependenciesFromsoftwareUnitToOther = queryService.getDependenciesFromSoftwareUnitToSoftwareUnit(softwareUnit.uniqueName, otherSoftwareUnit.uniqueName).length; nrOfDependenciesFromOtherTosoftwareUnit = queryService.getDependenciesFromSoftwareUnitToSoftwareUnit(otherSoftwareUnit.uniqueName, softwareUnit.uniqueName).length; break; } if (nrOfDependenciesFromsoftwareUnitToOther > ((nrOfDependenciesFromOtherTosoftwareUnit / 100) * layerThreshold)) { rootPackageDoesNotUseOtherPackage = false; } } } if (rootPackageDoesNotUseOtherPackage) { // Leave unit in the lower layer assignedUnitsNewBottomLayer.add(softwareUnit); } else { // Assign unit to the higher layer assignedUnitsTopLayer.add(softwareUnit); } } if ((assignedUnitsTopLayer.size() > 0) && (assignedUnitsNewBottomLayer.size() > 0)) { layers.remove(bottomLayerId); layers.put(bottomLayerId, assignedUnitsNewBottomLayer); bottomLayerId++; layers.put(bottomLayerId, assignedUnitsTopLayer); } } @Override public ReconstructArchitectureDTO getAlgorithmParameterSettings() { ReconstructArchitectureDTO reconstructArchitecture = new ReconstructArchitectureDTO(); reconstructArchitecture.approachId = AnalyseReconstructConstants.Algorithms.Layers_Goldstein_Root_Original; reconstructArchitecture.threshold = 10; reconstructArchitecture.relationType = AnalyseReconstructConstants.RelationTypes.allDependencies; reconstructArchitecture.granularity = AnalyseReconstructConstants.Granularities.Packages; 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.Packages)); return parameterDTOs; } }