package husacct.analyse.domain.famix; import java.util.ArrayList; import java.util.Date; import java.util.HashMap; import java.util.HashSet; import java.util.TreeMap; import java.util.List; import javax.naming.directory.InvalidAttributesException; import org.apache.log4j.Logger; class FamixModel extends FamixObject { private static FamixModel currentInstance; private final Logger logger = Logger.getLogger(FamixModel.class); public List<FamixStructuralEntity> waitingStructuralEntities; public List<FamixAssociation> waitingAssociations; public HashMap<String, FamixBehaviouralEntity> behaviouralEntities; public HashMap<String, FamixStructuralEntity> structuralEntities; public TreeMap<String, FamixPackage> packages; public HashMap<String, FamixClass> classes; public HashMap<String, FamixImport> imports; public HashMap<String, FamixLibrary> libraries; private HashMap<String, HashMap<String, HashSet<FamixUmlLink>>> umlLinks; // UmlLinks per from-class (first String), per to-class (second String). public ArrayList<FamixAssociation> associations; public String modelCreationDate; private int totalNumberOfLinesOfCode; private FamixModel() { this.modelCreationDate = new Date().toString(); waitingAssociations = new ArrayList<FamixAssociation>(); waitingStructuralEntities = new ArrayList<FamixStructuralEntity>(); associations = new ArrayList<FamixAssociation>(); classes = new HashMap<String, FamixClass>(); packages = new TreeMap<String, FamixPackage>(); imports = new HashMap<String, FamixImport>(); libraries = new HashMap<String, FamixLibrary>(); structuralEntities = new HashMap<String, FamixStructuralEntity>(); behaviouralEntities = new HashMap<String, FamixBehaviouralEntity>(); umlLinks = new HashMap<String, HashMap<String, HashSet<FamixUmlLink>>>(); totalNumberOfLinesOfCode = 0; } public void clear() { currentInstance.waitingAssociations.clear(); currentInstance.waitingStructuralEntities.clear(); currentInstance.associations.clear(); currentInstance.classes.clear(); currentInstance.packages.clear(); currentInstance.libraries.clear(); currentInstance.imports.clear(); currentInstance.structuralEntities.clear(); currentInstance.behaviouralEntities.clear(); currentInstance.umlLinks.clear(); totalNumberOfLinesOfCode = 0; } public void clearAfterPostProcessing() { currentInstance.waitingAssociations.clear(); currentInstance.waitingStructuralEntities.clear(); } public static FamixModel getInstance() { if (currentInstance == null) { currentInstance = new FamixModel(); } return currentInstance; } // Add Methods public void addObject(FamixObject famixObject) throws InvalidAttributesException { try{ if (famixObject instanceof FamixEntity) { // Test Utility //if (((FamixEntity) e).uniqueName.contains("xxx")) { // String test = "breakpoint"; } if (famixObject instanceof FamixBehaviouralEntity) { behaviouralEntities.put(((FamixEntity) famixObject).uniqueName, (FamixBehaviouralEntity) famixObject); } else if (famixObject instanceof FamixStructuralEntity) { structuralEntities.put(((FamixEntity) famixObject).uniqueName, (FamixStructuralEntity) famixObject); } else if (famixObject instanceof FamixPackage) { addFamixPackage(famixObject); } else if (famixObject instanceof FamixClass) { addFamixClass(famixObject); } else if (famixObject instanceof FamixLibrary) { addFamixLibrary(famixObject); } } else if (famixObject instanceof FamixAssociation){ if(famixObject instanceof FamixImport){ String importKey = ((FamixImport)famixObject).importedModule + "." +((FamixImport)famixObject).importingClass; imports.put(importKey, (FamixImport) famixObject); } associations.add((FamixAssociation) famixObject); } else if (famixObject instanceof FamixUmlLink){ addFamixUmlLink((FamixUmlLink) famixObject); } else { throw new InvalidAttributesException("Wrongtype (not of type entity or association) "); } }catch(Exception e1) { this.logger.error(new Date().toString() + " Exception while adding: " + famixObject.toString()); e1.printStackTrace(); } } private void addFamixPackage(FamixObject famixObject) { if (!packages.containsKey(((FamixEntity) famixObject).uniqueName)){ packages.put(((FamixEntity) famixObject).uniqueName, (FamixPackage) famixObject); String parentUniqueName = ((FamixPackage) famixObject).belongsToPackage; FamixPackage parent = null; if (!parentUniqueName.equals("") && (packages.containsKey(parentUniqueName))){ parent = packages.get(parentUniqueName); parent.children.add(((FamixEntity) famixObject).uniqueName); } } } private void addFamixClass(FamixObject famixObject) { if (!classes.containsKey(((FamixEntity) famixObject).uniqueName)){ classes.put(((FamixEntity) famixObject).uniqueName, (FamixClass) famixObject); String parentUniqueName; if (((FamixClass) famixObject).isInnerClass) { ((FamixClass) famixObject).linesOfCode = 0; parentUniqueName = ((FamixClass) famixObject).belongsToClass; if ((!parentUniqueName.equals("")) && (classes.containsKey(parentUniqueName))){ FamixClass parent = classes.get(parentUniqueName); parent.hasInnerClasses = true; parent.children.add(((FamixEntity) famixObject).uniqueName); } } else { parentUniqueName = ((FamixClass) famixObject).belongsToPackage; FamixPackage parent = null; if (!parentUniqueName.equals("") && (packages.containsKey(parentUniqueName))){ parent = packages.get(parentUniqueName); parent.children.add(((FamixEntity) famixObject).uniqueName); } } int loc = ((FamixClass) famixObject).linesOfCode; if (loc > 0) { totalNumberOfLinesOfCode = totalNumberOfLinesOfCode + loc; } } } private void addFamixLibrary(FamixObject famixObject) { if (!libraries.containsKey(((FamixEntity) famixObject).uniqueName)){ libraries.put(((FamixEntity) famixObject).uniqueName, (FamixLibrary) famixObject); ((FamixLibrary) famixObject).external = true; String parentUniqueName = ((FamixLibrary) famixObject).belongsToPackage; if (parentUniqueName.equals("xLibraries")){ FamixPackage parent = null; if (!parentUniqueName.equals("") && (packages.containsKey(parentUniqueName))){ parent = packages.get(parentUniqueName); parent.children.add(((FamixEntity) famixObject).uniqueName); } } else { FamixLibrary parent = null; if (!parentUniqueName.equals("") && (libraries.containsKey(parentUniqueName))){ parent = libraries.get(parentUniqueName); parent.children.add(((FamixEntity) famixObject).uniqueName); } } } } private void addFamixUmlLink(FamixUmlLink famixUmlLink) { HashMap<String, HashSet<FamixUmlLink>> mapOfLinksPerFromClass; HashSet<FamixUmlLink> setOfLinksPerToClass; if (umlLinks.containsKey(famixUmlLink.from)){ mapOfLinksPerFromClass = umlLinks.get(famixUmlLink.from); if (mapOfLinksPerFromClass.containsKey(famixUmlLink.to)) { setOfLinksPerToClass = mapOfLinksPerFromClass.get(famixUmlLink.to); } else { setOfLinksPerToClass = new HashSet<FamixUmlLink>(); mapOfLinksPerFromClass.put(famixUmlLink.to, setOfLinksPerToClass); } } else { setOfLinksPerToClass = new HashSet<FamixUmlLink>(); mapOfLinksPerFromClass = new HashMap<String, HashSet<FamixUmlLink>>(); mapOfLinksPerFromClass.put(famixUmlLink.to, setOfLinksPerToClass); umlLinks.put(famixUmlLink.from, mapOfLinksPerFromClass); } setOfLinksPerToClass.add(famixUmlLink); } // Get methods public int getTotalNumberOfLinesOfCode() { return totalNumberOfLinesOfCode; } public int getTotalNumberOfUmlLinks() { int totalNrOfUmlLinks = 0; for (String classUniqueName : classes.keySet()) { if (umlLinks.containsKey(classUniqueName)) { HashMap<String, HashSet<FamixUmlLink>> mapOfLinksPerFromClass = umlLinks.get(classUniqueName); int nrOfUmlLinksFromClass = mapOfLinksPerFromClass.keySet().size(); totalNrOfUmlLinks += nrOfUmlLinksFromClass; } } return totalNrOfUmlLinks; } /* Returns all the FamixUmlLinks going from the fromClass to other FamixClasses (not to xLibraries). * fromClass must be a unique name of FamixClass (not of an xLibraries). */ public HashSet<FamixUmlLink> getUmlLinksFromClassToOtherClasses(String fromClass) { HashSet<FamixUmlLink> returnValue = new HashSet<FamixUmlLink>(); if (umlLinks.containsKey(fromClass)) { HashMap<String, HashSet<FamixUmlLink>> mapOfLinksPerFromClass = umlLinks.get(fromClass); for (String toClass : mapOfLinksPerFromClass.keySet()) { HashSet<FamixUmlLink> setOfLinksPerToClass = mapOfLinksPerFromClass.get(toClass); returnValue.addAll(setOfLinksPerToClass); } } return returnValue; } /* Returns all the FamixUmlLinks going from the fromClass to the specific toClass. * fromClass and toClass must both be a unique name of FamixClass (not of an xLibraries). * */ public HashSet<FamixUmlLink> getUmlLinksFromClassToToClass(String fromClass, String toClass) { HashSet<FamixUmlLink> returnValue = new HashSet<FamixUmlLink>(); if (umlLinks.containsKey(fromClass)) { HashMap<String, HashSet<FamixUmlLink>> mapOfLinksPerFromClass = umlLinks.get(fromClass); if (mapOfLinksPerFromClass.containsKey(toClass)) { returnValue = mapOfLinksPerFromClass.get(toClass); } } return returnValue; } @Override public String toString() { return "\n ------------Packages------------- \n" + packages + "\n ------------Classes------------- \n" + classes + "\n -----------Assocations:-------------- \n" + associations + "\n -----------Libraries:-------------- \n" + libraries + "\n --------------Methoden (behavioural entities) ----------- \n" + behaviouralEntities + "\n --------------Variabelen (structural entities) ----------- \n" + structuralEntities + "\n -----------Invocations-------------- \n" + associations + "num invocs " + associations.size(); } }