package husacct.graphics.task.modulelayout.layered;
import java.util.ArrayList;
import java.util.List;
import java.util.TreeMap;
import org.apache.log4j.Logger;
import husacct.ServiceProvider;
import husacct.analyse.IAnalyseService;
import husacct.common.dto.SoftwareUnitDTO;
public class CreateLayersInGraphic {
private int layerThreshold = 10;
private String dependencyType = RelationTypes.allDependencies;
private IAnalyseService queryService = ServiceProvider.getInstance().getAnalyseService();
private ArrayList<SoftwareUnitDTO> softwareUnitsInDiagram;
private TreeMap<Integer, ArrayList<SoftwareUnitDTO>> layers = new TreeMap<Integer, ArrayList<SoftwareUnitDTO>>();
private final Logger logger = Logger.getLogger(CreateLayersInGraphic.class);
public CreateLayersInGraphic () {
}
public TreeMap<Integer, ArrayList<SoftwareUnitDTO>> executeAlgorithm(List<SoftwareUnitDTO> softwareUnitDTOs) {
try {
// 1) Fill softwareUnitsInDiagram with software units in implemented architecture diagram.
// softwareUnitsInDiagram = new ArrayList<SoftwareUnitDTO>();
// ...
// 2) Identify layers
identifyLayers(softwareUnitDTOs, dependencyType);
} catch (Exception e) {
logger.warn(" Exception: " + e );
}
// 3) Return layers
return layers;
}
private void identifyLayers(List<SoftwareUnitDTO> units, String depedencyType) {
// 1) Assign all units to bottom layer
int layerId = 1;
ArrayList<SoftwareUnitDTO> assignedUnits = new ArrayList<SoftwareUnitDTO>();
assignedUnits.addAll(units);
layers.put(layerId, assignedUnits);
// 2) Identify the second layer.
identifyTopLayerBasedOnUnitsInBottomLayer(layerId, depedencyType);
// 3) Look iteratively for packages on top of the previous layer.
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 RelationTypes.umlLinks:
nrOfDependenciesFromsoftwareUnitToOther = queryService.getUmlLinksFromSoftwareUnitToSoftwareUnit(softwareUnit.uniqueName, otherSoftwareUnit.uniqueName).length;
nrOfDependenciesFromOtherTosoftwareUnit = queryService.getUmlLinksFromSoftwareUnitToSoftwareUnit(otherSoftwareUnit.uniqueName, softwareUnit.uniqueName).length;
break;
case RelationTypes.accessCallReferenceDependencies:
nrOfDependenciesFromsoftwareUnitToOther = queryService.getDependencies_OnlyAccessCallAndReferences_FromSoftwareUnitToSoftwareUnit(softwareUnit.uniqueName, otherSoftwareUnit.uniqueName).length;
nrOfDependenciesFromOtherTosoftwareUnit = queryService.getDependencies_OnlyAccessCallAndReferences_FromSoftwareUnitToSoftwareUnit(otherSoftwareUnit.uniqueName, softwareUnit.uniqueName).length;
break;
case 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);
}
}
public static class RelationTypes{
public static final String allDependencies = "AllDependencies";
public static final String umlLinks = "UmlLinks";
public static final String accessCallReferenceDependencies = "AccessCallReferenceDependencies";
}
}