package husacct.define.domain; import husacct.ServiceProvider; import husacct.define.domain.appliedrule.AppliedRuleStrategy; import husacct.define.domain.module.ModuleFactory; import husacct.define.domain.module.ModuleStrategy; import husacct.define.domain.module.modules.Component; import husacct.define.domain.module.modules.Layer; import husacct.define.domain.services.ModuleDomainService; import husacct.define.domain.services.WarningMessageService; import husacct.define.domain.services.stateservice.StateService; import husacct.define.domain.softwareunit.SoftwareUnitDefinition; import husacct.define.task.JtreeController; import java.util.ArrayList; import java.util.Collections; import org.apache.log4j.Logger; public class SoftwareArchitecture { private static SoftwareArchitecture instance = null; private ArrayList<AppliedRuleStrategy> appliedRules; private ArrayList<ModuleStrategy> modules = new ArrayList<ModuleStrategy>(); private ModuleStrategy rootModule; private Logger logger = Logger.getLogger(SoftwareArchitecture.class); public SoftwareArchitecture() { this("SoftwareArchitecture", "This is the root of the architecture", new ArrayList<ModuleStrategy>(), new ArrayList<AppliedRuleStrategy>()); } public SoftwareArchitecture(String name, String description) { this(name, description, new ArrayList<ModuleStrategy>(), new ArrayList<AppliedRuleStrategy>()); } public SoftwareArchitecture(String name, String description, ArrayList<ModuleStrategy> modules, ArrayList<AppliedRuleStrategy> rules) { rootModule = new ModuleDomainService().createNewModule("Root"); rootModule.set(name, description); rootModule.setSubModules(modules); setAppliedRules(rules); registerModule(rootModule); this.modules.add(rootModule); } public static SoftwareArchitecture getInstance() { return instance == null ? (instance = new SoftwareArchitecture()): instance; } public static void setInstance(SoftwareArchitecture sA) { instance = sA; } private void registerModule(ModuleStrategy module) { modules.add(module); //if (module instanceof Component) { // modules.add(module.getSubModules().get(0)); //} } public void addAppliedRule(AppliedRuleStrategy rule) { if ((!hasAppliedRule(rule.getId())) && (!appliedRules.contains(rule))) { appliedRules.add(rule); } else { logger.warn(String.format(" Rule already added: " + rule.getRuleTypeKey() + ", " + rule.getModuleFrom().getName() + ", " + rule.getModuleTo().getName())); throw new RuntimeException(ServiceProvider.getInstance().getLocaleService().getTranslatedString("RuleAlreadyAdded")); } } // Only to be used to add rootmodules to the top module (root) public String addModuleToRoot(ModuleStrategy module) { String message = ""; try { if (!hasModule(module.getName())) { rootModule.addSubModule(module); registerModule(module); updateWarnings(); } else { message = ServiceProvider.getInstance().getLocaleService().getTranslatedString("SameNameModule"); } } catch (Exception rt) { logger.error(" Exception: " + rt.getMessage()); //rt.printStackTrace(); } return message; } //Only to be used to add child modules to a parent module public String addModuleToParent(long parentModuleId, ModuleStrategy module) { String message = ""; ModuleStrategy parentModule = getModuleById(parentModuleId); if (parentModule != null) { registerModule(module); message = parentModule.addSubModule(module); } else { message = ServiceProvider.getInstance().getLocaleService().getTranslatedString("NoModule"); } return message; } public AppliedRuleStrategy getAppliedRuleById(long appliedRuleId) { if (hasAppliedRule(appliedRuleId)) { for (AppliedRuleStrategy rule : appliedRules) { if (rule.getId() == appliedRuleId) { return rule; } } } else { throw new RuntimeException(ServiceProvider.getInstance().getLocaleService().getTranslatedString("NoRule")); } return null; } public ArrayList<AppliedRuleStrategy> getAppliedRules() { return appliedRules; } public ArrayList<Long> getAppliedRulesIdsByModuleFromId(long moduleId) { ArrayList<Long> appliedRuleIds = new ArrayList<Long>(); for (AppliedRuleStrategy rule : appliedRules) { if ((rule.getModuleFrom().getId() == moduleId) && (!rule.isException())) { appliedRuleIds.add(rule.getId()); } } return appliedRuleIds; } public ArrayList<Long> getAppliedRulesIdsByModuleToId(long moduleId) { ArrayList<Long> appliedRuleIds = new ArrayList<Long>(); for (AppliedRuleStrategy rule : appliedRules) { if ((rule.getModuleTo().getId() == moduleId) && (!rule.isException())) { appliedRuleIds.add(rule.getId()); } } return appliedRuleIds; } public String getDescription() { return rootModule.getDescription(); } /** * Finds the ModuleStrategy with the given moduleId. * @param moduleId * @return ModuleStrategy of the found module, or null if no module is found. */ public ModuleStrategy getModuleById(long moduleId) { ModuleStrategy currentModule = null; if (rootModule.getId() == moduleId || rootModule.hasSubModule(moduleId)) { currentModule = rootModule; while (currentModule.getId() != moduleId) { for (ModuleStrategy subModule : currentModule.getSubModules()) { if (subModule.getId() == moduleId || subModule.hasSubModule(moduleId)) { currentModule = subModule; } } } } return currentModule; } // Returns null, if no SoftwareUnit with softwareUnitName is mapped to a ModuleStrategy public ModuleStrategy getModuleBySoftwareUnit(String softwareUnitName) { ModuleStrategy moduleMappedToSU = null; for (ModuleStrategy module : modules) { moduleMappedToSU = getModuleMappedToSoftwareUnitName(module, softwareUnitName); if (moduleMappedToSU != null) { break; } } return moduleMappedToSU; } private ModuleStrategy getModuleMappedToSoftwareUnitName(ModuleStrategy module, String softwareUnitName){ ModuleStrategy moduleMappedToSU = null; for (SoftwareUnitDefinition softwareUnitResult : module.getUnits()) { if (softwareUnitResult.getName().equals(softwareUnitName)) { moduleMappedToSU = module; return moduleMappedToSU; } } for (ModuleStrategy mod : module.getSubModules()){ moduleMappedToSU = getModuleMappedToSoftwareUnitName(mod, softwareUnitName); } return moduleMappedToSU; } public ArrayList<ModuleStrategy> getModules() { return rootModule.getSubModules(); } private ArrayList<ModuleStrategy> getModulesForLayerSorting(long parentModuleId) { ArrayList<ModuleStrategy> modulesToCheck = rootModule.getSubModules(); if (parentModuleId != -1L) { ModuleStrategy parentModule = getModuleById(parentModuleId); if (parentModule != null) { modulesToCheck = parentModule.getSubModules(); } } return modulesToCheck; } public String getModulesLogicalPath(long moduleId) { String logicalPath = ""; if (rootModule.getId() == moduleId) { logicalPath = "**"; return logicalPath; } else { ModuleStrategy wantedModule = getModuleById(moduleId); if (wantedModule != null) { ArrayList<String> list = new ArrayList<String>(); list.add(wantedModule.getName()); wantedModule = wantedModule.getparent(); while(!wantedModule.getType().equals("Root")){ list.add(wantedModule.getName()); wantedModule = wantedModule.getparent(); } int lenght = list.size(); String[] names = new String[lenght]; int i = 0; for(String s : list){ names[i] = s; i++; } for (int j = lenght-1; j >= 1; j--) { logicalPath = logicalPath + names[j] + "."; } logicalPath = logicalPath + names[0]; } } return logicalPath; } public String getName() { return rootModule.getName(); } public long getParentModuleIdByChildId(long childModuleId) { long parentModuleId = -1L; if (rootModule.getId() == childModuleId) { parentModuleId = -1; } else { ModuleStrategy childModule = getModuleById(childModuleId); if (childModule != null) { parentModuleId = childModule.getparent().getId(); } } return parentModuleId; } public ModuleStrategy getRootModule() { return rootModule; } public SoftwareUnitDefinition getSoftwareUnitByName(String softwareUnitName) { SoftwareUnitDefinition softwareUnit = null; if (rootModule.hasSoftwareUnit(softwareUnitName)) { softwareUnit = rootModule.getSoftwareUnitByName(softwareUnitName); } if (softwareUnit == null) { throw new RuntimeException(ServiceProvider.getInstance() .getLocaleService().getTranslatedString("NoSoftwareUnit")); } return softwareUnit; } private Layer getTheFirstLayerAbove(int currentHierarchicalLevel, long parentModuleId) { Layer layer = null; for (ModuleStrategy mod : getModulesForLayerSorting(parentModuleId)) { if (mod instanceof Layer) { Layer l = (Layer) mod; if ((l.getHierarchicalLevel() < currentHierarchicalLevel) && (layer == null || l.getHierarchicalLevel() > layer .getHierarchicalLevel())) { layer = l; } } } return layer; } public Layer getTheFirstLayerBelow(int currentHierarchicalLevel, long parentModuleId) { Layer layer = null; for (ModuleStrategy mod : getModulesForLayerSorting(parentModuleId)) { if (mod instanceof Layer) { Layer l = (Layer) mod; if (l.getHierarchicalLevel() > currentHierarchicalLevel && (layer == null || l.getHierarchicalLevel() < layer .getHierarchicalLevel())) { layer = l; } } } return layer; } public Layer getTheFirstLayerBelow(Layer layer) { return getTheFirstLayerBelow(layer.getHierarchicalLevel(), getParentModuleIdByChildId(layer.getId())); } private boolean hasAppliedRule(long ruleID) { boolean ruleFound = false; for (AppliedRuleStrategy rule : appliedRules) { if (rule.getId() == ruleID) { ruleFound = true; } } return ruleFound; } // Returns true if the received name equals the name of the top module (root) or one of its children private boolean hasModule(String name) { if (rootModule.getName().equals(name)) { return true; } else { for (ModuleStrategy module : rootModule.getSubModules()) { if (module.getName().equals(name)) { return true; } } } return false; } public void moveLayerDown(long layerId) { Layer layer = (Layer) getModuleById(layerId); if (layer != null) { Layer layerBelowLayer = getTheFirstLayerBelow( layer.getHierarchicalLevel(), getParentModuleIdByChildId(layerId)); if (layerBelowLayer != null) { switchHierarchicalLayerLevels(layer, layerBelowLayer); } } } public void moveLayerUp(long layerId) { Layer layer = (Layer) getModuleById(layerId); if (layer != null) { Layer layerAboveLayer = getTheFirstLayerAbove( layer.getHierarchicalLevel(), getParentModuleIdByChildId(layerId)); if (layerAboveLayer != null) { switchHierarchicalLayerLevels(layer, layerAboveLayer); } } } public void removeAllModules() { rootModule.setSubModules(new ArrayList<ModuleStrategy>()); modules = new ArrayList<ModuleStrategy>(); } public void removeAppliedRule(long appliedRuleId) { if (hasAppliedRule(appliedRuleId)) { AppliedRuleStrategy mainRule = getAppliedRuleById(appliedRuleId); if((mainRule.getExceptions() != null) && (mainRule.getExceptions().size() >= 0)){ for (AppliedRuleStrategy exceptionRule : mainRule.getExceptions()){ appliedRules.remove(exceptionRule); } } appliedRules.remove(mainRule); } else { throw new RuntimeException(ServiceProvider.getInstance() .getLocaleService().getTranslatedString("NoRule")); } } public void removeAppliedRules() { appliedRules = new ArrayList<AppliedRuleStrategy>(); } public void removeModule(ModuleStrategy moduleToRemove) { if (moduleToRemove.equals(rootModule)) { return; } ArrayList<ModuleStrategy> toBeRemoved = new ArrayList<ModuleStrategy>(); ArrayList<Object[]> toBeSaved = new ArrayList<Object[]>(); removeRecursively(moduleToRemove, toBeRemoved); Collections.reverse(toBeRemoved); JtreeController.instance().restoreTreeItems(moduleToRemove); for (ModuleStrategy module : toBeRemoved) { ModuleStrategy parent = module.getparent(); ArrayList<AppliedRuleStrategy> moduleRules = removeRelatedRules(module); int index = parent.getSubModules().indexOf(module); removeFromRegistry(module); JtreeController.instance().restoreTreeItems(module); parent.getSubModules().remove(index); toBeSaved.add(new Object[] { module, moduleRules }); WarningMessageService.getInstance().removeImplementationWarning(module); } boolean moduleFound = true; if (!moduleFound) { throw new RuntimeException(ServiceProvider.getInstance() .getLocaleService().getTranslatedString("NoModule")); } } private void removeRecursively(ModuleStrategy module, ArrayList<ModuleStrategy> childrens) { if (module.getSubModules().size() == 0) { childrens.add(module); } else if (module.getSubModules().size() > 0) { childrens.add(module); for (ModuleStrategy m : module.getSubModules()) { removeRecursively(m, childrens); } } } private void removeFromRegistry(ModuleStrategy module) { try { int index = modules.indexOf(module); if (index >= 0) { modules.remove(index); logger.info(String.format(" Module removed from the registry: " + module.getId() + " " + module.getName())); } updateWarnings(); } catch (Exception r) { logger.warn(String.format(" The following module cannot be removed from the registry: " + module.getName())); } } public void updateWarnings() { WarningMessageService.getInstance().clearImplementationLevelWarnings(); for (ModuleStrategy module : modules) { WarningMessageService.getInstance().processModule(module); } } private ArrayList<AppliedRuleStrategy> removeRelatedRules( ModuleStrategy module) { // Copy all currentValues into another list to prevent // ConcurrentModificationExceptions ArrayList<AppliedRuleStrategy> returnList = new ArrayList<AppliedRuleStrategy>(); @SuppressWarnings("unchecked") ArrayList<AppliedRuleStrategy> tmpList = (ArrayList<AppliedRuleStrategy>) appliedRules .clone(); for (AppliedRuleStrategy rule : appliedRules) { if (rule.getModuleFrom().equals(module) || rule.getModuleTo().equals(module)) { returnList.add(rule); tmpList.remove(rule); } @SuppressWarnings("unchecked") ArrayList<AppliedRuleStrategy> tmpExceptionList = (ArrayList<AppliedRuleStrategy>) rule .getExceptions().clone(); for (AppliedRuleStrategy exceptionRule : rule.getExceptions()) { if (exceptionRule.getModuleFrom().equals(module) || exceptionRule.getModuleTo().equals(module)) { tmpExceptionList.remove(exceptionRule); } } rule.setExceptions(tmpExceptionList); } appliedRules = tmpList; return returnList; } public void setAppliedRules(ArrayList<AppliedRuleStrategy> appliedRules) { this.appliedRules = appliedRules; } public void setDescription(String description) { rootModule.setDescription(description); } public void setName(String name) { rootModule.setName(name); } private void switchHierarchicalLayerLevels(Layer layerOne, Layer layerTwo) { int hierarchicalLevelLayerOne = layerOne.getHierarchicalLevel(); layerOne.setHierarchicalLevel(layerTwo.getHierarchicalLevel()); layerTwo.setHierarchicalLevel(hierarchicalLevelLayerOne); } public ModuleStrategy updateModuleType(ModuleStrategy oldModule, String newType) { int index = oldModule.getparent().getSubModules().indexOf(oldModule); ModuleStrategy updatedModule = new ModuleFactory().updateModuleType(oldModule, newType); updateModule(index,updatedModule); return updatedModule; } private void updateModule(int subModuleIndex, ModuleStrategy updatedModule) { // Update parent ModuleStrategy parent = updatedModule.getparent(); parent.getSubModules().remove(subModuleIndex); parent.addSubModule(subModuleIndex, updatedModule); int moduleIndex=0; for (int i = 0; i < modules.size(); i++) { if (modules.get(i).getId()==updatedModule.getId()) { moduleIndex=i; } } modules.remove(moduleIndex); modules.add(moduleIndex, updatedModule); logger.info(String.format(" Module updated in the registry: " + updatedModule.getId() + " " + updatedModule.getName())); if (updatedModule instanceof Component) { SoftwareArchitecture.getInstance().addModuleToParent(updatedModule.getId(),updatedModule.getSubModules().get(0)); } } public void changeSoftwareUnit(long from, long to, ArrayList<String> names) { ModuleStrategy fromModule= getModuleById(from); ModuleStrategy toModule = getModuleById(to); if ((fromModule != null) && (toModule != null)) { ArrayList<SoftwareUnitDefinition> units = fromModule.getAndRemoveSoftwareUnits(names); toModule.addSUDefinition(units); } } public void registerImportedValues() { for (ModuleStrategy module : modules) { for (SoftwareUnitDefinition unit : module.getUnits()) { StateService.instance().registerImportedUnit(unit); } } } }