package org.lrg.outcode.visitors; import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Set; import org.lrg.outcode.IHindsight; import org.lrg.outcode.builder.RelTypes; import org.lrg.outcode.builder.db.GraphDatasource; import org.neo4j.graphdb.Direction; import org.neo4j.graphdb.Label; import org.neo4j.graphdb.Node; import org.neo4j.graphdb.Relationship; public class RefusedParentBequest { public void findRefusedParentBequest(Node classNode) { Node superClass = superClass(classNode); if (superClass != null) { List<Node> methods = getMemberList(classNode, "Method"); List<Node> superMethods = getMemberList(superClass, "Method"); classIgnoresBequest(classNode, superClass, methods, superMethods); classIsNotTooSmallAndSimple(classNode, methods); } } private Node superClass(Node classNode) { Iterable<Relationship> extendsRelations = classNode.getRelationships(RelTypes.EXTENDS, Direction.OUTGOING); for (Relationship relationship : extendsRelations) { Node endNode = relationship.getEndNode(); return endNode; } return null; } private void classIgnoresBequest(Node classNode, Node superClass, List<Node> methods, List<Node> superMethods) { int computeNProtM = computeNProtM(superClass, superMethods); double computeBUR = computeBUR(classNode, superClass, methods); double computeBOvR = computeBOvR(classNode, methods); System.out.println(" class " + classNode.getProperty(IHindsight.ID) + " NProtM " + computeNProtM + " BUR " + computeBUR + " BOvR " + computeBOvR); } private List<Node> getMemberList(Node classNode, String label) { Iterable<Relationship> contains = classNode.getRelationships(RelTypes.CONTAINS, Direction.OUTGOING); Iterator<Relationship> iterator = contains.iterator(); HashMap<Long, Node> members = new HashMap<Long, Node>(); List<Node> methods = new ArrayList<Node>(); while (iterator.hasNext()) { Relationship next = iterator.next(); Node member = next.getEndNode(); members.put(member.getId(), member); } for (Node node : members.values()) { if (node.hasLabel(Label.label(label))) { // if it's a methods.add(node); } } return methods; } private double computeBOvR(Node classNode, List<Node> methods) { double overriding = 0; for (Node node : methods) { if (node.hasProperty("overiding")) { overriding++; } } double bovr = overriding / methods.size(); classNode.setProperty("BOvR", bovr); return bovr; } private double computeBUR(Node classNode, Node superClass, List<Node> methods) { double bur = 0; Set<Long> protectedFromSuper = new HashSet<Long>(); getMemberList(superClass, "Method").iterator().forEachRemaining((node) -> { if (node.hasProperty("protected")) { protectedFromSuper.add(node.getId()); } }); getMemberList(superClass, "Field").iterator().forEachRemaining((node) -> { if (node.hasProperty("protected")) { protectedFromSuper.add(node.getId()); } }); if (protectedFromSuper.size() > 0) { Set<Long> calledMethods = new HashSet<Long>(); Set<Long> accessedAttributes = new HashSet<Long>(); for (Node method : methods) { Iterable<Relationship> efferentCalls = method.getRelationships(RelTypes.CALLS, Direction.OUTGOING); efferentCalls.forEach((r) -> { Node endNode = r.getEndNode(); Node parentNode = parentNode(endNode); if (parentNode != null && haveSameID(parentNode, superClass)) { if (endNode.hasProperty("protected")) calledMethods.add(endNode.getId()); } }); Iterable<Relationship> efferentAccesses = method.getRelationships(RelTypes.ACCESSES, Direction.OUTGOING); efferentAccesses.forEach((r) -> { Node endNode = r.getEndNode(); Node parentNode = parentNode(endNode); if (parentNode != null && haveSameID(parentNode, superClass)) { if (endNode.hasProperty("protected")) accessedAttributes.add(endNode.getId()); } }); } bur = (double) (calledMethods.size() + accessedAttributes.size()) / protectedFromSuper.size(); } classNode.setProperty("BUR", bur); return bur; } private boolean haveSameID(Node parentNode, Node superClass) { return parentNode.getProperty(IHindsight.ID).equals(superClass.getProperty(IHindsight.ID)); } private Node parentNode(Node node) { Node latestNodeForElementID = GraphDatasource.INSTANCE.findLatestVersion(node); Iterable<Relationship> toParent = latestNodeForElementID.getRelationships(RelTypes.PARENT, Direction.OUTGOING); if (toParent.iterator().hasNext()) { Node parent = toParent.iterator().next().getEndNode(); return parent; } return null; } private int computeNProtM(Node classNode, List<Node> methods) { int noprtm = 0; for (Node node : methods) { if (node.hasProperty("protected")) noprtm++; } classNode.setProperty("NProtM", noprtm); return noprtm; } private void classIsNotTooSmallAndSimple(Node classNode, List<Node> methods) { computeNOM(classNode, methods); computeAMW(classNode, methods); } private void computeNOM(Node classNode, List<Node> methods) { classNode.setProperty("NOM", methods.size()); } private int getWMC(Node classNode) { return (int) classNode.getProperty("WMC"); } private void computeAMW(Node classNode, List<Node> methods) { classNode.setProperty("AMW", (double) getWMC(classNode) / methods.size()); } }