]> git.uio.no Git - ifi-stolz-refaktor.git/blob - case-study/jdt-before/core refactoring/org/eclipse/jdt/internal/corext/refactoring/RefactoringSearchEngine.java
Case Study: adding data and statistics
[ifi-stolz-refaktor.git] / case-study / jdt-before / core refactoring / org / eclipse / jdt / internal / corext / refactoring / RefactoringSearchEngine.java
1 /*******************************************************************************
2  * Copyright (c) 2000, 2011 IBM Corporation and others.
3  * All rights reserved. This program and the accompanying materials
4  * are made available under the terms of the Eclipse Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/epl-v10.html
7  *
8  * Contributors:
9  *     IBM Corporation - initial API and implementation
10  *******************************************************************************/
11 package org.eclipse.jdt.internal.corext.refactoring;
12
13 import java.util.ArrayList;
14 import java.util.Arrays;
15 import java.util.HashMap;
16 import java.util.HashSet;
17 import java.util.Iterator;
18 import java.util.List;
19 import java.util.Map;
20 import java.util.Set;
21
22 import org.eclipse.core.runtime.CoreException;
23 import org.eclipse.core.runtime.IProgressMonitor;
24
25 import org.eclipse.core.resources.IResource;
26
27 import org.eclipse.ltk.core.refactoring.IRefactoringStatusEntryComparator;
28 import org.eclipse.ltk.core.refactoring.RefactoringStatus;
29 import org.eclipse.ltk.core.refactoring.RefactoringStatusEntry;
30
31 import org.eclipse.jdt.core.ICompilationUnit;
32 import org.eclipse.jdt.core.IJavaElement;
33 import org.eclipse.jdt.core.JavaCore;
34 import org.eclipse.jdt.core.JavaModelException;
35 import org.eclipse.jdt.core.WorkingCopyOwner;
36 import org.eclipse.jdt.core.search.IJavaSearchScope;
37 import org.eclipse.jdt.core.search.SearchEngine;
38 import org.eclipse.jdt.core.search.SearchMatch;
39 import org.eclipse.jdt.core.search.SearchPattern;
40 import org.eclipse.jdt.core.search.SearchRequestor;
41
42 import org.eclipse.jdt.internal.corext.util.SearchUtils;
43
44 /**
45  * Convenience wrapper for {@link SearchEngine} - performs searching and sorts the results by {@link IResource}.
46  * TODO: throw CoreExceptions from search(..) methods instead of wrapped JavaModelExceptions.
47  */
48 public class RefactoringSearchEngine {
49
50         private RefactoringSearchEngine(){
51                 //no instances
52         }
53
54         //TODO: throw CoreException
55         public static ICompilationUnit[] findAffectedCompilationUnits(SearchPattern pattern,
56                         IJavaSearchScope scope, final IProgressMonitor pm, RefactoringStatus status, final boolean tolerateInAccurateMatches) throws JavaModelException {
57
58                 boolean hasNonCuMatches= false;
59
60                 class ResourceSearchRequestor extends SearchRequestor{
61                         boolean hasPotentialMatches= false ;
62                         Set<IResource> resources= new HashSet<IResource>(5);
63                         private IResource fLastResource;
64
65                         @Override
66                         public void acceptSearchMatch(SearchMatch match) {
67                                 if (!tolerateInAccurateMatches && match.getAccuracy() == SearchMatch.A_INACCURATE) {
68                                         hasPotentialMatches= true;
69                                 }
70                                 if (fLastResource != match.getResource()) {
71                                         fLastResource= match.getResource();
72                                         resources.add(fLastResource);
73                                 }
74                         }
75                 }
76                 ResourceSearchRequestor requestor = new ResourceSearchRequestor();
77                 try {
78                         new SearchEngine().search(pattern, SearchUtils.getDefaultSearchParticipants(), scope, requestor, pm);
79                 } catch (CoreException e) {
80                         throw new JavaModelException(e);
81                 }
82
83                 List<IJavaElement> result= new ArrayList<IJavaElement>(requestor.resources.size());
84                 for (Iterator<IResource> iter= requestor.resources.iterator(); iter.hasNext(); ) {
85                         IResource resource= iter.next();
86                         IJavaElement element= JavaCore.create(resource);
87                         if (element instanceof ICompilationUnit) {
88                                 result.add(element);
89                         } else {
90                                 hasNonCuMatches= true;
91                         }
92                 }
93                 addStatusErrors(status, requestor.hasPotentialMatches, hasNonCuMatches);
94                 return result.toArray(new ICompilationUnit[result.size()]);
95         }
96
97         //TODO: throw CoreException
98         public static ICompilationUnit[] findAffectedCompilationUnits(SearchPattern pattern,
99                         IJavaSearchScope scope, final IProgressMonitor pm, RefactoringStatus status) throws JavaModelException {
100                 return findAffectedCompilationUnits(pattern, scope, pm, status, false);
101         }
102
103         /**
104          * Performs a search and groups the resulting {@link SearchMatch}es by
105          * {@link SearchResultGroup#getCompilationUnit()}.
106          * @param pattern the search pattern
107          * @param scope the search scope
108          * @param monitor the progress monitor
109          * @param status an error is added here if inaccurate or non-cu matches have been found
110          * @return a {@link SearchResultGroup}[], where each {@link SearchResultGroup}
111          *              has a different {@link SearchMatch#getResource() getResource()}s.
112          * @see SearchMatch
113          * @throws JavaModelException when the search failed
114          */
115         //TODO: throw CoreException
116         public static SearchResultGroup[] search(SearchPattern pattern, IJavaSearchScope scope, IProgressMonitor monitor, RefactoringStatus status)
117                         throws JavaModelException {
118                 return internalSearch(new SearchEngine(), pattern, scope, new CollectingSearchRequestor(), monitor, status);
119         }
120
121         //TODO: throw CoreException
122         public static SearchResultGroup[] search(SearchPattern pattern, WorkingCopyOwner owner, IJavaSearchScope scope, IProgressMonitor monitor, RefactoringStatus status)
123                         throws JavaModelException {
124                 return internalSearch(owner != null ? new SearchEngine(owner) : new SearchEngine(), pattern, scope, new CollectingSearchRequestor(), monitor, status);
125         }
126
127         //TODO: throw CoreException
128         public static SearchResultGroup[] search(SearchPattern pattern, IJavaSearchScope scope, CollectingSearchRequestor requestor,
129                         IProgressMonitor monitor, RefactoringStatus status) throws JavaModelException {
130                 return internalSearch(new SearchEngine(), pattern, scope, requestor, monitor, status);
131         }
132
133         //TODO: throw CoreException
134         public static SearchResultGroup[] search(SearchPattern pattern, WorkingCopyOwner owner, IJavaSearchScope scope,
135                         CollectingSearchRequestor requestor, IProgressMonitor monitor, RefactoringStatus status) throws JavaModelException {
136                 return internalSearch(owner != null ? new SearchEngine(owner) : new SearchEngine(), pattern, scope, requestor, monitor, status);
137         }
138
139         //TODO: throw CoreException
140         private static SearchResultGroup[] internalSearch(SearchEngine searchEngine, SearchPattern pattern, IJavaSearchScope scope,
141                         CollectingSearchRequestor requestor, IProgressMonitor monitor, RefactoringStatus status) throws JavaModelException {
142                 try {
143                         searchEngine.search(pattern, SearchUtils.getDefaultSearchParticipants(), scope, requestor, monitor);
144                 } catch (CoreException e) {
145                         throw new JavaModelException(e);
146                 }
147                 return groupByCu(requestor.getResults(), status);
148         }
149
150         public static SearchResultGroup[] groupByCu(SearchMatch[] matches, RefactoringStatus status) {
151                 return groupByCu(Arrays.asList(matches), status);
152         }
153
154         /**
155          * @param matchList a List of SearchMatch
156          * @param status the status to report errors.
157          * @return a SearchResultGroup[], grouped by SearchMatch#getResource()
158          */
159         public static SearchResultGroup[] groupByCu(List<SearchMatch> matchList, RefactoringStatus status) {
160                 Map<IResource, List<SearchMatch>> grouped= new HashMap<IResource, List<SearchMatch>>();
161                 boolean hasPotentialMatches= false;
162                 boolean hasNonCuMatches= false;
163
164                 for (Iterator<SearchMatch> iter= matchList.iterator(); iter.hasNext();) {
165                         SearchMatch searchMatch= iter.next();
166                         if (searchMatch.getAccuracy() == SearchMatch.A_INACCURATE)
167                                 hasPotentialMatches= true;
168                         if (! grouped.containsKey(searchMatch.getResource()))
169                                 grouped.put(searchMatch.getResource(), new ArrayList<SearchMatch>(1));
170                         grouped.get(searchMatch.getResource()).add(searchMatch);
171                 }
172
173                 for (Iterator<IResource> iter= grouped.keySet().iterator(); iter.hasNext();) {
174                         IResource resource= iter.next();
175                         IJavaElement element= JavaCore.create(resource);
176                         if (! (element instanceof ICompilationUnit)) {
177                                 iter.remove();
178                                 hasNonCuMatches= true;
179                         }
180                 }
181
182                 SearchResultGroup[] result= new SearchResultGroup[grouped.keySet().size()];
183                 int i= 0;
184                 for (Iterator<IResource> iter= grouped.keySet().iterator(); iter.hasNext();) {
185                         IResource resource= iter.next();
186                         List<SearchMatch> searchMatches= grouped.get(resource);
187                         SearchMatch[] matchArray= searchMatches.toArray(new SearchMatch[searchMatches.size()]);
188                         result[i]= new SearchResultGroup(resource, matchArray);
189                         i++;
190                 }
191                 addStatusErrors(status, hasPotentialMatches, hasNonCuMatches);
192                 return result;
193         }
194
195         public static SearchPattern createOrPattern(IJavaElement[] elements, int limitTo) {
196                 if (elements == null || elements.length == 0)
197                         return null;
198                 Set<IJavaElement> set= new HashSet<IJavaElement>(Arrays.asList(elements));
199                 Iterator<IJavaElement> iter= set.iterator();
200                 IJavaElement first= iter.next();
201                 SearchPattern pattern= SearchPattern.createPattern(first, limitTo, SearchUtils.GENERICS_AGNOSTIC_MATCH_RULE);
202                 if (pattern == null) // check for bug 90138
203                         throw new IllegalArgumentException("Invalid java element: " + first.getHandleIdentifier() + "\n" + first.toString()); //$NON-NLS-1$ //$NON-NLS-2$
204                 while(iter.hasNext()){
205                         IJavaElement each= iter.next();
206                         SearchPattern nextPattern= SearchPattern.createPattern(each, limitTo, SearchUtils.GENERICS_AGNOSTIC_MATCH_RULE);
207                         if (nextPattern == null) // check for bug 90138
208                                 throw new IllegalArgumentException("Invalid java element: " + each.getHandleIdentifier() + "\n" + each.toString()); //$NON-NLS-1$ //$NON-NLS-2$
209                         pattern= SearchPattern.createOrPattern(pattern, nextPattern);
210                 }
211                 return pattern;
212         }
213
214         private static boolean containsStatusEntry(final RefactoringStatus status, final RefactoringStatusEntry other) {
215                 return status.getEntries(new IRefactoringStatusEntryComparator() {
216                         public final int compare(final RefactoringStatusEntry entry1, final RefactoringStatusEntry entry2) {
217                                 return entry1.getMessage().compareTo(entry2.getMessage());
218                         }
219                 }, other).length > 0;
220         }
221
222         private static void addStatusErrors(RefactoringStatus status, boolean hasPotentialMatches, boolean hasNonCuMatches) {
223                 if (hasPotentialMatches) {
224                         final RefactoringStatusEntry entry= new RefactoringStatusEntry(RefactoringStatus.ERROR, RefactoringCoreMessages.RefactoringSearchEngine_potential_matches);
225                         if (!containsStatusEntry(status, entry))
226                                 status.addEntry(entry);
227                 }
228                 if (hasNonCuMatches) {
229                         final RefactoringStatusEntry entry= new RefactoringStatusEntry(RefactoringStatus.ERROR, RefactoringCoreMessages.RefactoringSearchEngine_non_cu_matches);
230                         if (!containsStatusEntry(status, entry))
231                                 status.addEntry(entry);
232                 }
233         }
234 }