]>
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.util; | |
12 | ||
13 | import java.util.HashSet; | |
14 | import java.util.Set; | |
15 | import java.util.StringTokenizer; | |
16 | import java.util.regex.Pattern; | |
17 | ||
18 | import org.eclipse.core.runtime.Assert; | |
19 | import org.eclipse.core.runtime.CoreException; | |
20 | import org.eclipse.core.runtime.IPath; | |
21 | import org.eclipse.core.runtime.IProgressMonitor; | |
22 | import org.eclipse.core.runtime.NullProgressMonitor; | |
23 | ||
24 | import org.eclipse.core.resources.IFile; | |
25 | import org.eclipse.core.resources.IProject; | |
26 | import org.eclipse.core.resources.IResource; | |
27 | ||
28 | import org.eclipse.core.filebuffers.FileBuffers; | |
29 | ||
30 | import org.eclipse.text.edits.ReplaceEdit; | |
31 | ||
32 | import org.eclipse.search.core.text.TextSearchEngine; | |
33 | import org.eclipse.search.core.text.TextSearchMatchAccess; | |
34 | import org.eclipse.search.core.text.TextSearchRequestor; | |
35 | import org.eclipse.search.core.text.TextSearchScope; | |
36 | ||
37 | import org.eclipse.ltk.core.refactoring.GroupCategory; | |
38 | import org.eclipse.ltk.core.refactoring.GroupCategorySet; | |
39 | import org.eclipse.ltk.core.refactoring.TextChange; | |
40 | ||
41 | import org.eclipse.jdt.core.IJavaElement; | |
42 | import org.eclipse.jdt.core.JavaCore; | |
43 | ||
44 | import org.eclipse.jdt.internal.corext.refactoring.RefactoringCoreMessages; | |
45 | import org.eclipse.jdt.internal.corext.refactoring.changes.TextChangeCompatibility; | |
46 | ||
47 | import org.eclipse.jdt.internal.ui.util.PatternConstructor; | |
48 | ||
49 | public class QualifiedNameFinder { | |
50 | ||
51 | private static final GroupCategorySet QUALIFIED_NAMES= new GroupCategorySet( | |
52 | new GroupCategory("org.eclipse.jdt.internal.corext.qualifiedNames", //$NON-NLS-1$ | |
53 | RefactoringCoreMessages.QualifiedNameFinder_qualifiedNames_name, | |
54 | RefactoringCoreMessages.QualifiedNameFinder_qualifiedNames_description)); | |
55 | ||
56 | private static class ResultCollector extends TextSearchRequestor { | |
57 | ||
58 | private String fNewValue; | |
59 | private QualifiedNameSearchResult fResult; | |
60 | ||
61 | public ResultCollector(QualifiedNameSearchResult result, String newValue) { | |
62 | fResult= result; | |
63 | fNewValue= newValue; | |
64 | } | |
65 | ||
66 | @Override | |
67 | public boolean acceptFile(IFile file) throws CoreException { | |
68 | IJavaElement element= JavaCore.create(file); | |
69 | if ((element != null && element.exists())) | |
70 | return false; | |
71 | ||
72 | // Only touch text files (see bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=114153 ): | |
73 | if (! FileBuffers.getTextFileBufferManager().isTextFileLocation(file.getFullPath(), false)) | |
74 | return false; | |
75 | ||
76 | IPath path= file.getProjectRelativePath(); | |
77 | String segment= path.segment(0); | |
78 | if (segment != null && (segment.startsWith(".refactorings") || segment.startsWith(".deprecations"))) //$NON-NLS-1$ //$NON-NLS-2$ | |
79 | return false; | |
80 | ||
81 | return true; | |
82 | } | |
83 | ||
84 | @Override | |
85 | public boolean acceptPatternMatch(TextSearchMatchAccess matchAccess) throws CoreException { | |
86 | int start= matchAccess.getMatchOffset(); | |
87 | int length= matchAccess.getMatchLength(); | |
88 | ||
89 | // skip embedded FQNs (bug 130764): | |
90 | if (start > 0) { | |
91 | char before= matchAccess.getFileContentChar(start - 1); | |
92 | if (before == '.' || Character.isJavaIdentifierPart(before)) | |
93 | return true; | |
94 | } | |
95 | int fileContentLength= matchAccess.getFileContentLength(); | |
96 | int end= start + length; | |
97 | if (end < fileContentLength) { | |
98 | char after= matchAccess.getFileContentChar(end); | |
99 | if (Character.isJavaIdentifierPart(after)) | |
100 | return true; | |
101 | } | |
102 | ||
103 | IFile file= matchAccess.getFile(); | |
104 | TextChange change= fResult.getChange(file); | |
105 | TextChangeCompatibility.addTextEdit( | |
106 | change, | |
107 | RefactoringCoreMessages.QualifiedNameFinder_update_name, | |
108 | new ReplaceEdit(start, length, fNewValue), QUALIFIED_NAMES); | |
109 | ||
110 | return true; | |
111 | } | |
112 | } | |
113 | ||
114 | public QualifiedNameFinder() { | |
115 | } | |
116 | ||
117 | public static void process(QualifiedNameSearchResult result, String pattern, String newValue, String filePatterns, IProject root, IProgressMonitor monitor) { | |
118 | Assert.isNotNull(pattern); | |
119 | Assert.isNotNull(newValue); | |
120 | Assert.isNotNull(root); | |
121 | ||
122 | if (monitor == null) | |
123 | monitor= new NullProgressMonitor(); | |
124 | ||
125 | if (filePatterns == null || filePatterns.length() == 0) { | |
126 | // Eat progress. | |
127 | monitor.beginTask("", 1); //$NON-NLS-1$ | |
128 | monitor.worked(1); | |
129 | return; | |
130 | } | |
131 | ||
132 | ResultCollector collector= new ResultCollector(result, newValue); | |
133 | TextSearchEngine engine= TextSearchEngine.create(); | |
134 | Pattern searchPattern= PatternConstructor.createPattern(pattern, true, false); | |
135 | ||
136 | engine.search(createScope(filePatterns, root), collector, searchPattern, monitor); | |
137 | } | |
138 | ||
139 | private static TextSearchScope createScope(String filePatterns, IProject root) { | |
140 | HashSet<IProject> res= new HashSet<IProject>(); | |
141 | res.add(root); | |
142 | addReferencingProjects(root, res); | |
143 | IResource[] resArr= res.toArray(new IResource[res.size()]); | |
144 | Pattern filePattern= getFilePattern(filePatterns); | |
145 | ||
146 | return TextSearchScope.newSearchScope(resArr, filePattern, false); | |
147 | } | |
148 | ||
149 | private static Pattern getFilePattern(String filePatterns) { | |
150 | StringTokenizer tokenizer= new StringTokenizer(filePatterns, ","); //$NON-NLS-1$ | |
151 | String[] filePatternArray= new String[tokenizer.countTokens()]; | |
152 | int i= 0; | |
153 | while (tokenizer.hasMoreTokens()) { | |
154 | filePatternArray[i++]= tokenizer.nextToken().trim(); | |
155 | } | |
156 | return PatternConstructor.createPattern(filePatternArray, true, false); | |
157 | } | |
158 | ||
159 | private static void addReferencingProjects(IProject root, Set<IProject> res) { | |
160 | IProject[] projects= root.getReferencingProjects(); | |
161 | for (int i= 0; i < projects.length; i++) { | |
162 | IProject project= projects[i]; | |
163 | if (res.add(project)) { | |
164 | addReferencingProjects(project, res); | |
165 | } | |
166 | } | |
167 | } | |
168 | } |