]> git.uio.no Git - ifi-stolz-refaktor.git/blob - software/no.uio.ifi.refaktor/src/no/uio/ifi/refaktor/utils/RefaktorHandleUtils.java
f26c5e58865d09c750560f0150e3aa9a69d99def
[ifi-stolz-refaktor.git] / software / no.uio.ifi.refaktor / src / no / uio / ifi / refaktor / utils / RefaktorHandleUtils.java
1 package no.uio.ifi.refaktor.utils;
2
3 import java.util.Arrays;
4 import java.util.LinkedList;
5 import java.util.List;
6 import java.util.regex.Matcher;
7 import java.util.regex.Pattern;
8
9 import no.uio.ifi.refaktor.exceptions.RefaktorException;
10
11 import org.eclipse.core.resources.IFile;
12 import org.eclipse.core.resources.IProject;
13 import org.eclipse.core.runtime.CoreException;
14 import org.eclipse.core.runtime.NullProgressMonitor;
15 import org.eclipse.jdt.core.ICompilationUnit;
16 import org.eclipse.jdt.core.IJavaElement;
17 import org.eclipse.jdt.core.IJavaProject;
18 import org.eclipse.jdt.core.IMember;
19 import org.eclipse.jdt.core.IMethod;
20 import org.eclipse.jdt.core.IPackageFragment;
21 import org.eclipse.jdt.core.IPackageFragmentRoot;
22 import org.eclipse.jdt.core.IType;
23 import org.eclipse.jdt.core.JavaCore;
24 import org.eclipse.jdt.core.JavaModelException;
25 import org.eclipse.ui.IEditorPart;
26
27 // TODO: clean up
28 public class RefaktorHandleUtils {
29         private static final String SIMPLE_NAME_REGEX = "[a-zA-Z_$][\\w$]*";
30         private static final String SIMPLE_NAME_REGEX_RELUCTANT = SIMPLE_NAME_REGEX + "?";
31         private static final String QUALIFIED_NAME_REGEX = 
32                         SIMPLE_NAME_REGEX_RELUCTANT + "(?:\\." + SIMPLE_NAME_REGEX_RELUCTANT + ")*";
33
34         public static ICompilationUnit getCompilationUnitFromEditor(IEditorPart editor) {
35                 return findCompilationUnitFromFile(DocumentUtils.getFileFromEditor(editor));
36         }
37
38         private static ICompilationUnit findCompilationUnitFromFile(IFile file) {
39                 ICompilationUnit cu = JavaCore.createCompilationUnitFrom(file);
40                 return cu != null ? cu : new NullCompilationUnit();
41         }
42
43         public static ICompilationUnit findCompilationUnitFromProjectPackageAndTypeName(IProject project, String packageName, String simpleTypeName) {
44                 try {
45                         return findType(project, packageName, simpleTypeName).getCompilationUnit();
46                 } catch (JavaModelException e) {
47                         throw new RuntimeException(e);
48                 }
49         }
50
51         private static IType findType(IProject project, String packageName, String typeName) throws JavaModelException {
52                 return findType(project, combine(packageName, typeName));
53         }
54
55         private static IType findType(IProject project, String fullyQualifiedTypeName) throws JavaModelException {
56                 IJavaProject javaProject = createJavaProjectFrom(project);
57                 assert javaProject != null: project;
58                 return findType(javaProject, fullyQualifiedTypeName);
59         }
60
61         private static IType findType(IJavaProject javaProject, String fullyQualifiedTypeName) throws JavaModelException {
62                 IType type = tryToFindAnonymousOrLocalType(javaProject, fullyQualifiedTypeName);
63                 if (type == null || !type.exists())
64                         type = javaProject.findType(fullyQualifiedTypeName, new NullProgressMonitor());
65                 assert type != null;
66                 return type;
67         }
68
69         private static IType tryToFindAnonymousOrLocalType(IJavaProject javaProject, String fullyQualifiedTypeName) throws JavaModelException {
70                 Pattern pattern = Pattern.compile("^(" + QUALIFIED_NAME_REGEX + ")\\$(?:\\d+|" + SIMPLE_NAME_REGEX + ")$");
71                 Matcher matcher = pattern.matcher(fullyQualifiedTypeName);
72
73                 if (matcher.matches()) {
74                         IType parentType = findType(javaProject, matcher.group(1));
75                         if (parentType == null)
76                                 return null;
77                         return searchForAnonymousOrLocalType(parentType, fullyQualifiedTypeName);
78                 }
79                 return null;
80         }
81
82         private static IType searchForAnonymousOrLocalType(IMember parent, String fullyQualifiedTypeName) throws JavaModelException {
83                 if (parent instanceof IType && ((IType) parent).getFullyQualifiedName().equals(fullyQualifiedTypeName))
84                         return (IType) parent;
85
86                 for (IJavaElement child : parent.getChildren()) {
87                         if (child instanceof IMember) {
88                                 IType anonymousType = searchForAnonymousOrLocalType((IMember) child, fullyQualifiedTypeName);
89                                 if (anonymousType != null)
90                                         return anonymousType;
91                         }
92                 }
93
94                 return null;
95         }
96
97         private static String combine(String packageName, String typeName) {
98                 return packageName + "." + typeName;
99         }
100
101         public static IMethod findMethodHandleChecked(IProject project, String packageName, String typeName, 
102                         String methodName, String... methodSignature) {
103                 try {
104                         IMethod method = findMethodHandle(project, packageName, typeName, methodName, methodSignature);
105                         assert method.exists() : "method.exists()";
106                         return method;
107                 } catch (JavaModelException e) {
108                         throw new RefaktorException("The requested method handle could not be found");
109                 }
110         }
111
112         public static IMethod findMethodHandle(IProject project, String packageName, String simpleTypeName, 
113                         String methodName, String[] methodSignature) throws JavaModelException {
114                 IType type = findType(project, packageName, simpleTypeName);
115                 assert type.exists() : "type.exists()";
116                 return type.getMethod(methodName, methodSignature);
117         }
118
119         public static IMethod findMethodHandle(IProject project, String fullyQualifiedTypeName, String simpleMethodSignature) throws JavaModelException {
120                 assert !"".equals(fullyQualifiedTypeName);
121                 IType type = findType(project, fullyQualifiedTypeName);
122                 assert type != null: "Project: " + project + ", Type name: " + fullyQualifiedTypeName;
123                 MethodSignature methodSignature = MethodSignature.parseSignature(simpleMethodSignature);
124                 return type.getMethod(methodSignature.getName(), methodSignature.getParameterSignaturesArray());
125         }
126
127         public static IJavaProject createJavaProjectFrom(IProject project) {
128                 assert project.exists();
129                 assert project.isOpen();
130                 try {
131                         assert project.hasNature(JavaCore.NATURE_ID);
132                 } catch (CoreException e) {
133                         // Project does not exist or is not open
134                 }
135                 return JavaCore.create(project);
136         }
137
138         public static IPackageFragment findPackageChecked(String packageName, IProject project) {
139                 try {
140                         return findPackage(packageName, project);
141                 } catch (JavaModelException e) {
142                         RefaktorDebug.log(e);
143                         return new NullPackageFragmentHandle();
144                 }
145         }
146
147         private static IPackageFragment findPackage(String packageName, IProject project) throws JavaModelException {
148                 IJavaProject javaProject = createJavaProjectFrom(project);
149                 for (IPackageFragment packageFragment: javaProject.getPackageFragments()) {
150                         if (packageFragment.getElementName().equals(packageName))
151                                 return packageFragment;
152                 }
153                 return new NullPackageFragmentHandle();
154         }
155
156         public static List<IPackageFragment> getPackagesFromProject(IProject project) throws JavaModelException {
157                 IPackageFragment[] packageFragments = createJavaProjectFrom(project).getPackageFragments();
158                 return findPackagesAmongPackageFragments(Arrays.asList(packageFragments));
159         }
160
161         public static List<IPackageFragment> findPackagesAmongPackageFragments(List<IPackageFragment> packageFragments) throws JavaModelException {
162                 List<IPackageFragment> packages = new LinkedList<IPackageFragment>();
163                 for (IPackageFragment packageFragment: packageFragments) {
164                         if (containsSourceCode(packageFragment))
165                                 packages.add(packageFragment);
166                 }
167                 return packages;
168         }
169
170         private static boolean containsSourceCode(IPackageFragment packageFragment) throws JavaModelException {
171                 return packageFragment.getKind() == IPackageFragmentRoot.K_SOURCE && packageFragment.hasChildren();
172         }
173 }