]> git.uio.no Git - ifi-stolz-refaktor.git/blob - case-study/refaktor-before/src/no/uio/ifi/refaktor/analyze/analyzers/SelectionValidator.java
Case Study: adding data and statistics
[ifi-stolz-refaktor.git] / case-study / refaktor-before / src / no / uio / ifi / refaktor / analyze / analyzers / SelectionValidator.java
1 package no.uio.ifi.refaktor.analyze.analyzers;
2
3 import java.util.Collections;
4 import java.util.Comparator;
5 import java.util.LinkedList;
6
7 import no.uio.ifi.refaktor.analyze.exceptions.SelectionInvalidException;
8 import no.uio.ifi.refaktor.textselection.CompilationUnitTextSelection;
9
10 import org.eclipse.jdt.core.dom.ASTNode;
11 import org.eclipse.jdt.core.dom.ASTVisitor;
12 import org.eclipse.jdt.core.dom.Block;
13 import org.eclipse.jdt.core.dom.MethodDeclaration;
14 import org.eclipse.jdt.core.dom.Statement;
15
16 public class SelectionValidator extends ASTVisitor {
17
18         private final CompilationUnitTextSelection selection;
19         private final LinkedList<ASTNode> selectedStatements;
20
21         public SelectionValidator(CompilationUnitTextSelection selection) {
22                 super();
23                 this.selection = selection;
24                 this.selectedStatements = new LinkedList<ASTNode>();
25                 findSelectedStatements();
26         }
27
28         private void findSelectedStatements() {
29                 getCoveringNode().accept(this);
30         }
31
32         private ASTNode getCoveringNode() {
33                 return selection.getCoveringNode();
34         }
35         
36         private ASTNode getCoveredNode() {
37                 return selection.getCoveredNode();
38         }
39         
40         @Override
41         public boolean preVisit2(ASTNode node) {
42                 if (node instanceof Statement && selection.surroundsNode(node)) {
43                         selectedStatements.add(node);
44                         // Only visit top-level statements
45                         return false;
46                 }
47
48                 if (node instanceof MethodDeclaration || node instanceof Block )
49                         return true;
50
51                 return false;
52         }
53
54         public static void checkIfSelectionIsValid(CompilationUnitTextSelection selection) {
55                 if (!selectionIsValid(selection))
56                         throw new SelectionInvalidException();
57         }
58
59         private static boolean selectionIsValid(CompilationUnitTextSelection selection) {
60                 return new SelectionValidator(selection).selectionIsValid();
61         }
62         
63         private boolean selectionIsValid() {
64                 if (noStatementsSelected())
65                         return false;
66                 
67                 if (selectedNodeHasBlockStructure())
68                         return true;
69                 
70                 return selectionMatchesStatementsStartAndEnd();
71         }
72
73         private boolean noStatementsSelected() {
74                 return selectedStatements.isEmpty();
75         }
76         
77         private boolean selectedNodeHasBlockStructure() {
78                 return isSingleNodeSelection() && 
79                                 (getSelectedNode() instanceof MethodDeclaration || getSelectedNode() instanceof Block);
80         }
81
82         private boolean selectionMatchesStatementsStartAndEnd() {
83                 sortSelectedStatements();
84                 return selectedStatements.getFirst().getStartPosition() == selection.getOffset() 
85                                 && nodeEnd(selectedStatements.getLast()) == selection.getEnd();
86         }
87
88         private void sortSelectedStatements() {
89                 Collections.sort(selectedStatements, new Comparator<ASTNode>(){
90                         @Override
91                         public int compare(ASTNode node1, ASTNode node2) {
92                                 if (node1.equals(node2))
93                                         return 0;
94                                 else if (node1.getStartPosition() < node2.getStartPosition())
95                                         return -1;
96                                 else if (node1.getStartPosition() > node2.getStartPosition())
97                                         return 1;
98                                 else
99                                         return 0;
100                         }});
101         }
102         
103         private boolean isSingleNodeSelection() {
104                 return getCoveringNode() == getCoveredNode();
105         }
106
107         private ASTNode getSelectedNode() {
108                 if (!isSingleNodeSelection())
109                         return null;
110                 return getCoveredNode();
111         }
112
113         private int nodeEnd(ASTNode astNode) {
114                 return astNode.getStartPosition() + astNode.getLength();
115         }
116 }