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