]>
Commit | Line | Data |
---|---|---|
1b2798f6 EK |
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.rename; | |
12 | ||
13 | import java.util.ArrayList; | |
14 | import java.util.Arrays; | |
15 | import java.util.HashSet; | |
16 | import java.util.Iterator; | |
17 | import java.util.Set; | |
18 | ||
19 | import org.eclipse.core.runtime.Assert; | |
20 | import org.eclipse.core.runtime.CoreException; | |
21 | import org.eclipse.core.runtime.IPath; | |
22 | import org.eclipse.core.runtime.IProgressMonitor; | |
23 | import org.eclipse.core.runtime.OperationCanceledException; | |
24 | import org.eclipse.core.runtime.SubProgressMonitor; | |
25 | ||
26 | import org.eclipse.core.resources.IContainer; | |
27 | import org.eclipse.core.resources.IFile; | |
28 | import org.eclipse.core.resources.IProject; | |
29 | import org.eclipse.core.resources.IResource; | |
30 | import org.eclipse.core.resources.ResourcesPlugin; | |
31 | ||
32 | import org.eclipse.text.edits.MalformedTreeException; | |
33 | import org.eclipse.text.edits.ReplaceEdit; | |
34 | ||
35 | import org.eclipse.ltk.core.refactoring.GroupCategory; | |
36 | import org.eclipse.ltk.core.refactoring.GroupCategorySet; | |
37 | ||
38 | import org.eclipse.jdt.core.ICompilationUnit; | |
39 | import org.eclipse.jdt.core.IJavaElement; | |
40 | import org.eclipse.jdt.core.JavaCore; | |
41 | import org.eclipse.jdt.core.JavaModelException; | |
42 | import org.eclipse.jdt.core.search.IJavaSearchScope; | |
43 | import org.eclipse.jdt.core.search.SearchMatch; | |
44 | ||
45 | import org.eclipse.jdt.internal.corext.refactoring.RefactoringCoreMessages; | |
46 | import org.eclipse.jdt.internal.corext.refactoring.SearchResultGroup; | |
47 | import org.eclipse.jdt.internal.corext.refactoring.changes.TextChangeCompatibility; | |
48 | import org.eclipse.jdt.internal.corext.refactoring.rename.RefactoringScanner.TextMatch; | |
49 | import org.eclipse.jdt.internal.corext.refactoring.tagging.ITextUpdating; | |
50 | import org.eclipse.jdt.internal.corext.refactoring.util.TextChangeManager; | |
51 | ||
52 | public class TextMatchUpdater { | |
53 | ||
54 | private static final String TEXT_EDIT_LABEL= RefactoringCoreMessages.TextMatchUpdater_update; | |
55 | ||
56 | private static final GroupCategorySet TEXTUAL_MATCHES= new GroupCategorySet( | |
57 | new GroupCategory("org.eclipse.jdt.internal.corext.textualMatches", //$NON-NLS-1$ | |
58 | RefactoringCoreMessages.TextMatchUpdater_textualMatches_name, | |
59 | RefactoringCoreMessages.TextMatchUpdater_textualMatches_description)); | |
60 | ||
61 | private final IJavaSearchScope fScope; | |
62 | private final TextChangeManager fManager; | |
63 | private final SearchResultGroup[] fReferences; | |
64 | private final boolean fOnlyQualified; | |
65 | ||
66 | final RefactoringScanner fScanner; | |
67 | private final String fNewName; | |
68 | private final int fCurrentNameLength; | |
69 | ||
70 | private TextMatchUpdater(TextChangeManager manager, IJavaSearchScope scope, String currentName, String currentQualifier, String newName, SearchResultGroup[] references, boolean onlyQualified){ | |
71 | Assert.isNotNull(manager); | |
72 | Assert.isNotNull(scope); | |
73 | Assert.isNotNull(references); | |
74 | fManager= manager; | |
75 | fScope= scope; | |
76 | fReferences= references; | |
77 | fOnlyQualified= onlyQualified; | |
78 | ||
79 | fNewName= newName; | |
80 | fCurrentNameLength= currentName.length(); | |
81 | fScanner= new RefactoringScanner(currentName, currentQualifier); | |
82 | } | |
83 | ||
84 | static void perform(IProgressMonitor pm, IJavaSearchScope scope, String currentName, String currentQualifier, String newName, TextChangeManager manager, SearchResultGroup[] references, boolean onlyQualified) throws JavaModelException{ | |
85 | new TextMatchUpdater(manager, scope, currentName, currentQualifier, newName, references, onlyQualified).updateTextMatches(pm); | |
86 | } | |
87 | ||
88 | static void perform(IProgressMonitor pm, IJavaSearchScope scope, ITextUpdating processor, TextChangeManager manager, SearchResultGroup[] references) throws JavaModelException{ | |
89 | new TextMatchUpdater(manager, scope, processor.getCurrentElementName(), processor.getCurrentElementQualifier(), processor.getNewElementName(), references, false).updateTextMatches(pm); | |
90 | } | |
91 | ||
92 | private void updateTextMatches(IProgressMonitor pm) throws JavaModelException { | |
93 | try{ | |
94 | IProject[] projectsInScope= getProjectsInScope(); | |
95 | ||
96 | pm.beginTask("", projectsInScope.length); //$NON-NLS-1$ | |
97 | ||
98 | for (int i =0 ; i < projectsInScope.length; i++){ | |
99 | if (pm.isCanceled()) | |
100 | throw new OperationCanceledException(); | |
101 | addTextMatches(projectsInScope[i], new SubProgressMonitor(pm, 1)); | |
102 | } | |
103 | } finally{ | |
104 | pm.done(); | |
105 | } | |
106 | } | |
107 | ||
108 | private IProject[] getProjectsInScope() { | |
109 | IPath[] enclosingProjects= fScope.enclosingProjectsAndJars(); | |
110 | Set<IPath> enclosingProjectSet= new HashSet<IPath>(); | |
111 | enclosingProjectSet.addAll(Arrays.asList(enclosingProjects)); | |
112 | ||
113 | ArrayList<IProject> projectsInScope= new ArrayList<IProject>(); | |
114 | IProject[] projects = ResourcesPlugin.getWorkspace().getRoot().getProjects(); | |
115 | for (int i =0 ; i < projects.length; i++){ | |
116 | if (enclosingProjectSet.contains(projects[i].getFullPath())) | |
117 | projectsInScope.add(projects[i]); | |
118 | } | |
119 | ||
120 | return projectsInScope.toArray(new IProject[projectsInScope.size()]); | |
121 | } | |
122 | ||
123 | private void addTextMatches(IResource resource, IProgressMonitor pm) throws JavaModelException{ | |
124 | try{ | |
125 | String task= RefactoringCoreMessages.TextMatchUpdater_searching + resource.getFullPath(); | |
126 | if (resource instanceof IFile){ | |
127 | IJavaElement element= JavaCore.create(resource); | |
128 | // don't start pm task (flickering label updates; finally {pm.done()} is enough) | |
129 | if (!(element instanceof ICompilationUnit)) | |
130 | return; | |
131 | if (! element.exists()) | |
132 | return; | |
133 | if (! fScope.encloses(element)) | |
134 | return; | |
135 | addCuTextMatches((ICompilationUnit) element); | |
136 | ||
137 | } else if (resource instanceof IContainer){ | |
138 | IResource[] members= ((IContainer) resource).members(); | |
139 | pm.beginTask(task, members.length); | |
140 | pm.subTask(task); | |
141 | for (int i = 0; i < members.length; i++) { | |
142 | if (pm.isCanceled()) | |
143 | throw new OperationCanceledException(); | |
144 | ||
145 | addTextMatches(members[i], new SubProgressMonitor(pm, 1)); | |
146 | } | |
147 | } | |
148 | } catch (JavaModelException e){ | |
149 | throw e; | |
150 | } catch (CoreException e){ | |
151 | throw new JavaModelException(e); | |
152 | } finally{ | |
153 | pm.done(); | |
154 | } | |
155 | } | |
156 | ||
157 | private void addCuTextMatches(ICompilationUnit cu) throws JavaModelException{ | |
158 | fScanner.generated_2332051649965437536(this, cu); | |
159 | } | |
160 | ||
161 | void removeReferences(ICompilationUnit cu, Set<TextMatch> matches) { | |
162 | for (int i= 0; i < fReferences.length; i++) { | |
163 | SearchResultGroup group= fReferences[i]; | |
164 | group.generated_8571484088675671927(cu, matches, this); | |
165 | } | |
166 | } | |
167 | ||
168 | public void removeReferences(Set<TextMatch> matches, SearchResultGroup group) { | |
169 | SearchMatch[] searchResults= group.getSearchResults(); | |
170 | for (int r= 0; r < searchResults.length; r++) { | |
171 | //int start= searchResults[r].getStart(); // doesn't work for pack.ReferencedType | |
172 | int unqualifiedStart= searchResults[r].getOffset() + searchResults[r].getLength() - fCurrentNameLength; | |
173 | for (Iterator<TextMatch> iter= matches.iterator(); iter.hasNext();) { | |
174 | TextMatch element= iter.next(); | |
175 | if (element.getStartPosition() == unqualifiedStart) | |
176 | iter.remove(); | |
177 | } | |
178 | } | |
179 | } | |
180 | ||
181 | void addTextUpdates(ICompilationUnit cu, Set<TextMatch> matches) { | |
182 | for (Iterator<TextMatch> resultIter= matches.iterator(); resultIter.hasNext();){ | |
183 | TextMatch match= resultIter.next(); | |
184 | if (!match.isQualified() && fOnlyQualified) | |
185 | continue; | |
186 | int matchStart= match.getStartPosition(); | |
187 | ReplaceEdit edit= new ReplaceEdit(matchStart, fCurrentNameLength, fNewName); | |
188 | try { | |
189 | TextChangeCompatibility.addTextEdit(fManager.get(cu), TEXT_EDIT_LABEL, edit, TEXTUAL_MATCHES); | |
190 | } catch (MalformedTreeException e) { | |
191 | // conflicting update -> omit text match | |
192 | } | |
193 | } | |
194 | } | |
195 | } |