KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > jdt > internal > corext > refactoring > RefactoringSearchEngine


1 /*******************************************************************************
2  * Copyright (c) 2000, 2007 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 JavaDoc;
14 import java.util.Arrays JavaDoc;
15 import java.util.HashMap JavaDoc;
16 import java.util.HashSet JavaDoc;
17 import java.util.Iterator JavaDoc;
18 import java.util.List JavaDoc;
19 import java.util.Map JavaDoc;
20 import java.util.Set JavaDoc;
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 JavaDoc resources= new HashSet JavaDoc(5);
63             private IResource fLastResource;
64             
65             public void acceptSearchMatch(SearchMatch match) {
66                 if (!tolerateInAccurateMatches && match.getAccuracy() == SearchMatch.A_INACCURATE) {
67                     hasPotentialMatches= true;
68                 }
69                 if (fLastResource != match.getResource()) {
70                     fLastResource= match.getResource();
71                     resources.add(fLastResource);
72                 }
73             }
74         }
75         ResourceSearchRequestor requestor = new ResourceSearchRequestor();
76         try {
77             new SearchEngine().search(pattern, SearchUtils.getDefaultSearchParticipants(), scope, requestor, pm);
78         } catch (CoreException e) {
79             throw new JavaModelException(e);
80         }
81
82         List JavaDoc result= new ArrayList JavaDoc(requestor.resources.size());
83         for (Iterator JavaDoc iter= requestor.resources.iterator(); iter.hasNext(); ) {
84             IResource resource= (IResource) iter.next();
85             IJavaElement element= JavaCore.create(resource);
86             if (element instanceof ICompilationUnit) {
87                 result.add(element);
88             } else {
89                 hasNonCuMatches= true;
90             }
91         }
92         addStatusErrors(status, requestor.hasPotentialMatches, hasNonCuMatches);
93         return (ICompilationUnit[]) result.toArray(new ICompilationUnit[result.size()]);
94     }
95     
96     //TODO: throw CoreException
97
public static ICompilationUnit[] findAffectedCompilationUnits(SearchPattern pattern,
98             IJavaSearchScope scope, final IProgressMonitor pm, RefactoringStatus status) throws JavaModelException {
99         return findAffectedCompilationUnits(pattern, scope, pm, status, false);
100     }
101     
102     /**
103      * Performs a search and groups the resulting {@link SearchMatch}es by
104      * {@link SearchResultGroup#getCompilationUnit()}.
105      * @param pattern the search pattern
106      * @param scope the search scope
107      * @param monitor the progress monitor
108      * @param status an error is added here if inaccurate or non-cu matches have been found
109      * @return a {@link SearchResultGroup}[], where each {@link SearchResultGroup}
110      * has a different {@link SearchMatch#getResource() getResource()}s.
111      * @see SearchMatch
112      * @throws JavaModelException when the search failed
113      */

114     //TODO: throw CoreException
115
public static SearchResultGroup[] search(SearchPattern pattern, IJavaSearchScope scope, IProgressMonitor monitor, RefactoringStatus status)
116             throws JavaModelException {
117         return internalSearch(new SearchEngine(), pattern, scope, new CollectingSearchRequestor(), monitor, status);
118     }
119     
120     //TODO: throw CoreException
121
public static SearchResultGroup[] search(SearchPattern pattern, WorkingCopyOwner owner, IJavaSearchScope scope, IProgressMonitor monitor, RefactoringStatus status)
122             throws JavaModelException {
123         return internalSearch(owner != null ? new SearchEngine(owner) : new SearchEngine(), pattern, scope, new CollectingSearchRequestor(), monitor, status);
124     }
125     
126     //TODO: throw CoreException
127
public static SearchResultGroup[] search(SearchPattern pattern, IJavaSearchScope scope, CollectingSearchRequestor requestor,
128             IProgressMonitor monitor, RefactoringStatus status) throws JavaModelException {
129         return internalSearch(new SearchEngine(), pattern, scope, requestor, monitor, status);
130     }
131     
132     //TODO: throw CoreException
133
public static SearchResultGroup[] search(SearchPattern pattern, WorkingCopyOwner owner, IJavaSearchScope scope,
134             CollectingSearchRequestor requestor, IProgressMonitor monitor, RefactoringStatus status) throws JavaModelException {
135         return internalSearch(owner != null ? new SearchEngine(owner) : new SearchEngine(), pattern, scope, requestor, monitor, status);
136     }
137         
138     //TODO: throw CoreException
139
private static SearchResultGroup[] internalSearch(SearchEngine searchEngine, SearchPattern pattern, IJavaSearchScope scope,
140             CollectingSearchRequestor requestor, IProgressMonitor monitor, RefactoringStatus status) throws JavaModelException {
141         try {
142             searchEngine.search(pattern, SearchUtils.getDefaultSearchParticipants(), scope, requestor, monitor);
143         } catch (CoreException e) {
144             throw new JavaModelException(e);
145         }
146         return groupByCu(requestor.getResults(), status);
147     }
148
149     public static SearchResultGroup[] groupByCu(SearchMatch[] matches, RefactoringStatus status) {
150         return groupByCu(Arrays.asList(matches), status);
151     }
152     
153     /**
154      * @param matchList a List of SearchMatch
155      * @param status the status to report errors.
156      * @return a SearchResultGroup[], grouped by SearchMatch#getResource()
157      */

158     public static SearchResultGroup[] groupByCu(List JavaDoc matchList, RefactoringStatus status) {
159         Map JavaDoc/*<IResource, List<SearchMatch>>*/ grouped= new HashMap JavaDoc();
160         boolean hasPotentialMatches= false;
161         boolean hasNonCuMatches= false;
162         
163         for (Iterator JavaDoc iter= matchList.iterator(); iter.hasNext();) {
164             SearchMatch searchMatch= (SearchMatch) iter.next();
165             if (searchMatch.getAccuracy() == SearchMatch.A_INACCURATE)
166                 hasPotentialMatches= true;
167             if (! grouped.containsKey(searchMatch.getResource()))
168                 grouped.put(searchMatch.getResource(), new ArrayList JavaDoc(1));
169             ((List JavaDoc) grouped.get(searchMatch.getResource())).add(searchMatch);
170         }
171         
172         for (Iterator JavaDoc iter= grouped.keySet().iterator(); iter.hasNext();) {
173             IResource resource= (IResource) iter.next();
174             IJavaElement element= JavaCore.create(resource);
175             if (! (element instanceof ICompilationUnit)) {
176                 iter.remove();
177                 hasNonCuMatches= true;
178             }
179         }
180         
181         SearchResultGroup[] result= new SearchResultGroup[grouped.keySet().size()];
182         int i= 0;
183         for (Iterator JavaDoc iter= grouped.keySet().iterator(); iter.hasNext();) {
184             IResource resource= (IResource) iter.next();
185             List JavaDoc searchMatches= (List JavaDoc) grouped.get(resource);
186             SearchMatch[] matchArray= (SearchMatch[]) searchMatches.toArray(new SearchMatch[searchMatches.size()]);
187             result[i]= new SearchResultGroup(resource, matchArray);
188             i++;
189         }
190         addStatusErrors(status, hasPotentialMatches, hasNonCuMatches);
191         return result;
192     }
193     
194     public static SearchPattern createOrPattern(IJavaElement[] elements, int limitTo) {
195         if (elements == null || elements.length == 0)
196             return null;
197         Set JavaDoc set= new HashSet JavaDoc(Arrays.asList(elements));
198         Iterator JavaDoc iter= set.iterator();
199         IJavaElement first= (IJavaElement)iter.next();
200         SearchPattern pattern= SearchPattern.createPattern(first, limitTo, SearchUtils.GENERICS_AGNOSTIC_MATCH_RULE);
201         if (pattern == null) // check for bug 90138
202
throw new IllegalArgumentException JavaDoc("Invalid java element: " + first.getHandleIdentifier() + "\n" + first.toString()); //$NON-NLS-1$ //$NON-NLS-2$
203
while(iter.hasNext()){
204             IJavaElement each= (IJavaElement)iter.next();
205             SearchPattern nextPattern= SearchPattern.createPattern(each, limitTo, SearchUtils.GENERICS_AGNOSTIC_MATCH_RULE);
206             if (nextPattern == null) // check for bug 90138
207
throw new IllegalArgumentException JavaDoc("Invalid java element: " + each.getHandleIdentifier() + "\n" + each.toString()); //$NON-NLS-1$ //$NON-NLS-2$
208
pattern= SearchPattern.createOrPattern(pattern, nextPattern);
209         }
210         return pattern;
211     }
212
213     private static boolean containsStatusEntry(final RefactoringStatus status, final RefactoringStatusEntry other) {
214         return status.getEntries(new IRefactoringStatusEntryComparator() {
215             public final int compare(final RefactoringStatusEntry entry1, final RefactoringStatusEntry entry2) {
216                 return entry1.getMessage().compareTo(entry2.getMessage());
217             }
218         }, other).length > 0;
219     }
220
221     private static void addStatusErrors(RefactoringStatus status, boolean hasPotentialMatches, boolean hasNonCuMatches) {
222         if (hasPotentialMatches) {
223             final RefactoringStatusEntry entry= new RefactoringStatusEntry(RefactoringStatus.ERROR, RefactoringCoreMessages.RefactoringSearchEngine_potential_matches);
224             if (!containsStatusEntry(status, entry))
225                 status.addEntry(entry);
226         }
227         if (hasNonCuMatches) {
228             final RefactoringStatusEntry entry= new RefactoringStatusEntry(RefactoringStatus.ERROR, RefactoringCoreMessages.RefactoringSearchEngine_non_cu_matches);
229             if (!containsStatusEntry(status, entry))
230                 status.addEntry(entry);
231         }
232     }
233 }
234
Popular Tags