package org.incha.core.jswingripples.rules; import java.util.Arrays; import java.util.HashSet; import java.util.Set; import org.incha.core.jswingripples.eig.JSwingRipplesEIG; import org.incha.core.jswingripples.eig.JSwingRipplesEIGNode; import org.incha.ui.jripples.EIGStatusMarks; public class CommonEIGRules { //---------------Edge Level------------------------------------------------- protected static void assignMarkToNodeAndNeighbor(final JSwingRipplesEIG eig, final JSwingRipplesEIGNode nodeFrom, final JSwingRipplesEIGNode nodeTo, final String markForNode, final String markForNeighbors) { assignMarkToNodeAndParents(eig, nodeFrom,markForNode); assignMarkToNodeAndParents(eig, nodeTo, markForNeighbors); } //=============================================Rules as of ICPC 08================================= public static void applyRuleToNode(final JSwingRipplesEIG eig, final JSwingRipplesEIGNode node,final String newMark, final int granularity) { //algorithm //1. Identify all members or parents at specified granularity //2. find all neighbors of these members //3. filter them based on the specified granularity //4. apply mark to the member and the neighbors //5. verify bottom-up the consistency of the marks of all involved parties and in between final Set<JSwingRipplesEIGNode> targets=new HashSet<JSwingRipplesEIGNode> (); if (granularity==0) targets.add(node); else if (granularity<0) targets.add(findParent(eig, node,granularity)); else findMembers(eig, node,targets,granularity,0); for (final JSwingRipplesEIGNode n:targets) { assignMarkToNodeAndParents(eig, n,newMark); } if (newMark.compareTo(EIGStatusMarks.VISITED)==0) return; final Set<JSwingRipplesEIGNode> membersOfTargets=new HashSet <JSwingRipplesEIGNode>(targets); final Set<JSwingRipplesEIGNode> membersOfTargetsAux=new HashSet <JSwingRipplesEIGNode>(targets); while (membersOfTargetsAux.size()>0) { final JSwingRipplesEIGNode n=membersOfTargetsAux.iterator().next(); membersOfTargetsAux.remove(n); membersOfTargetsAux.addAll(Arrays.asList(eig.getNodeMembers(n))); membersOfTargets.addAll(Arrays.asList(eig.getNodeMembers(n))); } final HashSet<JSwingRipplesEIGNode> neighbors=eig.edgesToNeigbors( membersOfTargets, JSwingRipplesEIG.DIRECTION_CONSIDERED_BOTH_CALLING_AND_CALLED, JSwingRipplesEIG.NESTING_CONSIDERED_BOTH_TOP_AND_MEMBER_NODES); filterNeighbors(eig, targets.iterator().next(), neighbors); for (final JSwingRipplesEIGNode n:neighbors) { assignMarkToNodeAndParents(eig, n,EIGStatusMarks.NEXT_VISIT); } } public static void assignMarkToNodeAndParents(final JSwingRipplesEIG eig, JSwingRipplesEIGNode node, final String mark) { while (node!=null) { if (getImportance(mark)>getImportance(node.getMark())) node.setMark(mark); if (node.isTop()) return; //comment below will lead JRipples halt, but why? node=eig.findParentNodeForMemberNode(node); if (node==null) return; } } private static int getImportance(final String mark) { if (mark==null) return 0; if (mark.compareTo(EIGStatusMarks.BLANK)==0) return 1; if (mark.compareTo(EIGStatusMarks.VISITED)==0) return 3; if (mark.compareTo(EIGStatusMarks.NEXT_VISIT)==0) return 2; if (mark.compareTo(EIGStatusMarks.VISITED_CONTINUE)==0) return 4; if (mark.compareTo(EIGStatusMarks.LOCATED)==0) return 5; if (mark.compareTo(EIGStatusMarks.IMPACTED)==0) return 6; if (mark.compareTo(EIGStatusMarks.CHANGED)==0) return 7; return 0; } private static void filterNeighbors(final JSwingRipplesEIG eig, final JSwingRipplesEIGNode focusNode,final Set<JSwingRipplesEIGNode> neighbors) { final Set<JSwingRipplesEIGNode> filteredNeighbors=new HashSet<JSwingRipplesEIGNode> (); final int granulrity=checkNestingLevel(eig, eig.findTopNodeForIMember(focusNode.getNodeIMember()),focusNode); for (final JSwingRipplesEIGNode neighbor:neighbors) { if (checkNestingLevel(eig, eig.findTopNodeForIMember(neighbor.getNodeIMember()),neighbor)==granulrity) filteredNeighbors.add(neighbor); } neighbors.clear(); neighbors.addAll(filteredNeighbors); } private static int checkNestingLevel(final JSwingRipplesEIG eig, final JSwingRipplesEIGNode currentNode, final JSwingRipplesEIGNode neededNode) { if (currentNode.equals(neededNode)) return 0; for (final JSwingRipplesEIGNode member:eig.getNodeMembers(currentNode)) { final int k=checkNestingLevel(eig, member, neededNode); if (k!=-1) return k+1; } return -1; } private static JSwingRipplesEIGNode findParent(final JSwingRipplesEIG eig, final JSwingRipplesEIGNode n,final int neededLevel) { int level=0; JSwingRipplesEIGNode node=n; while (level!=neededLevel) { node=eig.findParentNodeForMemberNode(node); level--; } return node; } private static void findMembers(final JSwingRipplesEIG eig, final JSwingRipplesEIGNode node, final Set <JSwingRipplesEIGNode> members, final int neededLevel, final int currentLevel) { if (neededLevel==currentLevel) { members.add(node); return; } for (final JSwingRipplesEIGNode member: eig.getNodeMembers(node)) { findMembers(eig, member, members,neededLevel, currentLevel+1); } } }