Line 0
Link Here
|
|
|
1 |
/* |
2 |
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. |
3 |
* |
4 |
* Copyright 2010 Sun Microsystems, Inc. All rights reserved. |
5 |
* |
6 |
* The contents of this file are subject to the terms of either the GNU |
7 |
* General Public License Version 2 only ("GPL") or the Common |
8 |
* Development and Distribution License("CDDL") (collectively, the |
9 |
* "License"). You may not use this file except in compliance with the |
10 |
* License. You can obtain a copy of the License at |
11 |
* http://www.netbeans.org/cddl-gplv2.html |
12 |
* or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the |
13 |
* specific language governing permissions and limitations under the |
14 |
* License. When distributing the software, include this License Header |
15 |
* Notice in each file and include the License file at |
16 |
* nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this |
17 |
* particular file as subject to the "Classpath" exception as provided |
18 |
* by Sun in the GPL Version 2 section of the License file that |
19 |
* accompanied this code. If applicable, add the following below the |
20 |
* License Header, with the fields enclosed by brackets [] replaced by |
21 |
* your own identifying information: |
22 |
* "Portions Copyrighted [year] [name of copyright owner]" |
23 |
* |
24 |
* If you wish your version of this file to be governed by only the CDDL |
25 |
* or only the GPL Version 2, indicate your decision by adding |
26 |
* "[Contributor] elects to include this software in this distribution |
27 |
* under the [CDDL or GPL Version 2] license." If you do not indicate a |
28 |
* single choice of license, a recipient has the option to distribute |
29 |
* your version of this file under either the CDDL, the GPL Version 2 or |
30 |
* to extend the choice of license to its licensees as provided above. |
31 |
* However, if you add GPL Version 2 code and therefore, elected the GPL |
32 |
* Version 2 license, then the option applies only if the new code is |
33 |
* made subject to such option by the copyright holder. |
34 |
* |
35 |
* Contributor(s): |
36 |
* |
37 |
* Portions Copyrighted 2010 Sun Microsystems, Inc. |
38 |
*/ |
39 |
|
40 |
package org.netbeans.spi.jumpto.file; |
41 |
|
42 |
import java.util.List; |
43 |
import org.netbeans.api.project.FileOwnerQuery; |
44 |
import org.netbeans.api.project.Project; |
45 |
import org.netbeans.api.project.SourceGroup; |
46 |
import org.netbeans.modules.jumpto.file.FileDescription; |
47 |
import org.netbeans.modules.jumpto.file.FileProviderAccessor; |
48 |
import org.netbeans.spi.jumpto.type.SearchType; |
49 |
import org.openide.filesystems.FileObject; |
50 |
import org.openide.filesystems.FileUtil; |
51 |
import org.openide.util.Lookup; |
52 |
import org.openide.util.Parameters; |
53 |
|
54 |
/** |
55 |
* A FileProvider participates in the Goto File dialog by providing matched files |
56 |
* for given {@link SourceGroup}. |
57 |
* The FileProviders are registered in global {@link Lookup} |
58 |
* |
59 |
* @since 1.15 |
60 |
* @author Tomas Zezula |
61 |
*/ |
62 |
public interface FileProvider { |
63 |
|
64 |
/** |
65 |
* Compute a list of files that match the given search text for the given |
66 |
* search type. This might be a slow operation, and the infrastructure may end |
67 |
* up calling {@link #cancel} on the file provider during the operation, in which |
68 |
* case the method can return incomplete results. |
69 |
* <p> |
70 |
* Note that a useful performance optimization is for the FileProvider to cache |
71 |
* a few of its most recent search results, and if the next search (e.g. more user |
72 |
* keystrokes) is a simple narrowing of the search, just filter the previous search |
73 |
* result. The same {@link FileProvider} instance is used during the GoTo File session and |
74 |
* it's freed when the GoTo File dialog is closed. |
75 |
* |
76 |
* @param context search context containg search text, type, project and {@link SourceGroup} root |
77 |
* @param result filled with files and optional message |
78 |
* @return returns true if the root was handled by this FileProvider. When false |
79 |
* next provider is used. |
80 |
*/ |
81 |
boolean computeFiles(Context context, Result result); |
82 |
|
83 |
/** |
84 |
* Cancel the current operation, if possible. This might be called if the user |
85 |
* has typed something (including the backspace key) which makes the current |
86 |
* search obsolete and a new one should be initiated. |
87 |
*/ |
88 |
void cancel(); |
89 |
|
90 |
/** |
91 |
* Represents search context. |
92 |
* Contains search type (such as prefix, regexp), search text, |
93 |
* {@link SourceGroup} root and project where to search. |
94 |
* |
95 |
*/ |
96 |
public static final class Context { |
97 |
|
98 |
//<editor-fold defaultstate="collapsed" desc="Private data"> |
99 |
private final String text; |
100 |
private final SearchType type; |
101 |
private final Project currentProject; |
102 |
private FileObject sourceGroupRoot; |
103 |
private Project project; |
104 |
//</editor-fold> |
105 |
|
106 |
/** |
107 |
* Returns project owning the {@link SourceGroup} root |
108 |
* @return project to search in. |
109 |
*/ |
110 |
public Project getProject() { |
111 |
if (project == null) { |
112 |
project = FileOwnerQuery.getOwner(this.sourceGroupRoot); |
113 |
} |
114 |
return project; |
115 |
} |
116 |
|
117 |
/** |
118 |
* Returns the {@link SourceGroup} root to search files in. |
119 |
* @return root to search in. |
120 |
*/ |
121 |
public FileObject getRoot() { return sourceGroupRoot;} |
122 |
|
123 |
/** |
124 |
* Return the text used for search. |
125 |
* |
126 |
* @return The text used for the search; e.g. when getSearchType() == SearchType.PREFIX, |
127 |
* text is the prefix that all returned types should start with. |
128 |
*/ |
129 |
public String getText() { return text; } |
130 |
|
131 |
/** |
132 |
* Return the type of search. |
133 |
* |
134 |
* @return Type of search performed, such as prefix, regexp or camel case. |
135 |
*/ |
136 |
public SearchType getSearchType() { return type; } |
137 |
|
138 |
//<editor-fold defaultstate="collapsed" desc="Private methods"> |
139 |
private Context(String text, SearchType type, Project currentProject) { |
140 |
Parameters.notNull("text", text); //NOI18N |
141 |
Parameters.notNull("type", type); //NOI18N |
142 |
this.text = text; |
143 |
this.type = type; |
144 |
this.currentProject = currentProject; |
145 |
} |
146 |
|
147 |
private Project getCurrentProject() { |
148 |
return currentProject; |
149 |
} |
150 |
|
151 |
static { |
152 |
FileProviderAccessor.setInstance(new FileProviderAccessor() { |
153 |
@Override |
154 |
public Context createContext(String text, SearchType searchType, Project currentProject) { |
155 |
return new Context(text, searchType,currentProject); |
156 |
} |
157 |
@Override |
158 |
public Result createResult(List<? super FileDescription> result, String[] message, Context ctx) { |
159 |
return new Result(result, message, ctx); |
160 |
} |
161 |
@Override |
162 |
public int getRetry(Result result) { |
163 |
return result.retry; |
164 |
} |
165 |
|
166 |
@Override |
167 |
public void setRoot(Context ctx, FileObject root) { |
168 |
ctx.sourceGroupRoot = root; |
169 |
ctx.project = null; |
170 |
} |
171 |
}); |
172 |
} |
173 |
//</editor-fold> |
174 |
} |
175 |
|
176 |
/** |
177 |
* Represents a collection of files that match |
178 |
* the given search criteria. Moreover, it can contain message |
179 |
* for the user, such as an incomplete search result. |
180 |
* |
181 |
*/ |
182 |
public static final class Result { |
183 |
|
184 |
//<editor-fold defaultstate="collapsed" desc="Private data"> |
185 |
private final List<? super FileDescription> result; |
186 |
private final String[] message; |
187 |
private final Context ctx; |
188 |
private int retry; |
189 |
//</editor-fold> |
190 |
|
191 |
/** |
192 |
* Optional message. It can inform the user about result, e.g. |
193 |
* that result can be incomplete etc. |
194 |
* |
195 |
* @param msg message |
196 |
*/ |
197 |
public void setMessage(String msg) { |
198 |
message[0] = msg; |
199 |
} |
200 |
|
201 |
/** |
202 |
* Adds a file into the result |
203 |
* |
204 |
* @param file The file to be added to result |
205 |
*/ |
206 |
public void addFile (final FileObject file) { |
207 |
Parameters.notNull("file", file); //NOI18N |
208 |
final String path = FileUtil.getRelativePath(ctx.getRoot(), file); |
209 |
if (path != null) { |
210 |
final Project prj = ctx.getProject(); |
211 |
final Project curPrj = ctx.getCurrentProject(); |
212 |
result.add(new FileDescription(file, path, prj, curPrj.getProjectDirectory() == prj.getProjectDirectory())); |
213 |
} |
214 |
} |
215 |
|
216 |
/** |
217 |
* Notify caller that a provider should be called again because |
218 |
* of incomplete or inaccurate results. |
219 |
* |
220 |
* Method can be used when long running task blocks the provider |
221 |
* to complete the data. |
222 |
* |
223 |
*/ |
224 |
public void pendingResult() { |
225 |
retry = 2000; |
226 |
} |
227 |
|
228 |
//<editor-fold defaultstate="collapsed" desc="Private constructor"> |
229 |
private Result(final List<? super FileDescription> result, final String[] message, final Context ctx) { |
230 |
Parameters.notNull("result", result); //NOI18N |
231 |
Parameters.notNull("message", message); //NOI18N |
232 |
Parameters.notNull("ctx", ctx); |
233 |
this.result = result; |
234 |
this.message = message; |
235 |
this.ctx = ctx; |
236 |
} |
237 |
//</editor-fold> |
238 |
} |
239 |
|
240 |
} |