|
1 /* |
|
2 * Copyright (c) 2006 Nokia Corporation and/or its subsidiary(-ies). |
|
3 * All rights reserved. |
|
4 * This component and the accompanying materials are made available |
|
5 * under the terms of "Eclipse Public License v1.0" |
|
6 * which accompanies this distribution, and is available |
|
7 * at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
8 * |
|
9 * Initial Contributors: |
|
10 * Nokia Corporation - initial contribution. |
|
11 * |
|
12 * Contributors: |
|
13 * |
|
14 * Description: |
|
15 * |
|
16 */ |
|
17 |
|
18 |
|
19 package com.nokia.s60tools.appdep.locatecomponent; |
|
20 |
|
21 import java.io.IOException; |
|
22 import java.net.URI; |
|
23 import java.net.URISyntaxException; |
|
24 import java.util.ArrayList; |
|
25 import java.util.HashSet; |
|
26 import java.util.List; |
|
27 import java.util.Vector; |
|
28 |
|
29 import org.eclipse.cdt.core.CCorePlugin; |
|
30 import org.eclipse.cdt.core.index.IIndexChangeEvent; |
|
31 import org.eclipse.cdt.core.index.IIndexChangeListener; |
|
32 import org.eclipse.cdt.core.index.IIndexManager; |
|
33 import org.eclipse.cdt.core.index.IIndexerStateEvent; |
|
34 import org.eclipse.cdt.core.index.IIndexerStateListener; |
|
35 import org.eclipse.cdt.core.model.CoreModel; |
|
36 import org.eclipse.cdt.core.model.ICElement; |
|
37 import org.eclipse.cdt.core.model.ICProject; |
|
38 import org.eclipse.cdt.internal.ui.search.CSearchMessages; |
|
39 import org.eclipse.cdt.internal.ui.search.PDOMSearchPatternQuery; |
|
40 import org.eclipse.cdt.internal.ui.search.PDOMSearchQuery; |
|
41 import org.eclipse.core.resources.IFile; |
|
42 import org.eclipse.core.resources.IProject; |
|
43 import org.eclipse.core.resources.IResource; |
|
44 import org.eclipse.core.resources.ResourcesPlugin; |
|
45 import org.eclipse.core.runtime.CoreException; |
|
46 import org.eclipse.core.runtime.IPath; |
|
47 import org.eclipse.core.runtime.IProgressMonitor; |
|
48 import org.eclipse.core.runtime.IStatus; |
|
49 import org.eclipse.core.runtime.Path; |
|
50 import org.eclipse.core.runtime.Platform; |
|
51 import org.eclipse.core.runtime.Status; |
|
52 import org.eclipse.core.runtime.jobs.Job; |
|
53 import org.eclipse.search.ui.IQueryListener; |
|
54 import org.eclipse.search.ui.ISearchQuery; |
|
55 import org.eclipse.search.ui.NewSearchUI; |
|
56 import org.eclipse.swt.widgets.Display; |
|
57 |
|
58 import com.nokia.s60tools.appdep.core.AppDepSettings; |
|
59 import com.nokia.s60tools.appdep.exceptions.CacheFileDoesNotExistException; |
|
60 import com.nokia.s60tools.appdep.exceptions.CacheIndexNotReadyException; |
|
61 import com.nokia.s60tools.appdep.resources.Messages; |
|
62 import com.nokia.s60tools.appdep.ui.views.main.MainViewDataPopulator; |
|
63 import com.nokia.s60tools.appdep.util.AppDepConsole; |
|
64 import com.nokia.s60tools.sdk.SdkInformation; |
|
65 import com.nokia.s60tools.util.console.IConsolePrintUtility; |
|
66 import com.nokia.s60tools.util.debug.DbgUtility; |
|
67 import com.nokia.s60tools.util.exceptions.JobCancelledByUserException; |
|
68 import com.nokia.s60tools.util.sourcecode.CannotFoundFileException; |
|
69 import com.nokia.s60tools.util.sourcecode.IProjectFinder; |
|
70 import com.nokia.s60tools.util.sourcecode.ISourcesFinder; |
|
71 import com.nokia.s60tools.util.sourcecode.ProjectFinderFactory; |
|
72 import com.nokia.s60tools.util.sourcecode.SourceFinderFactory; |
|
73 |
|
74 /** |
|
75 * Job for seeking possible concrete implementation of generic component name. |
|
76 */ |
|
77 // If public access to {@link PDOMSearchPatternQuery} is provided later on, the suppressing of warnings in here is no more needed. |
|
78 @SuppressWarnings("restriction") |
|
79 public class ShowMethodCallLocationsJob extends Job implements IQueryListener { |
|
80 |
|
81 /** |
|
82 * Amount of steps used for the create project job progress follow-up. |
|
83 */ |
|
84 private static final int CREATING_PROJECT_STEPS = 5; |
|
85 /** |
|
86 * Step amounts reserved for searching and indexing phase. |
|
87 */ |
|
88 private static final int SEARCH_AND_INDEX_STEPS = 85; |
|
89 |
|
90 /** |
|
91 * Search string formed for the used search service- |
|
92 */ |
|
93 private String searchString = null; |
|
94 |
|
95 /** |
|
96 * Project to be created for which contents the search is done. |
|
97 */ |
|
98 private ICProject cProject; |
|
99 |
|
100 /** |
|
101 * File list defining valid search scope. |
|
102 */ |
|
103 private String[] filesBelongsToComponent; |
|
104 |
|
105 /** |
|
106 * Job's progress monitor. |
|
107 */ |
|
108 private IProgressMonitor progressMonitor; |
|
109 /** |
|
110 * Name of the component the method call locations are searched from. |
|
111 */ |
|
112 private String componentName = null; |
|
113 |
|
114 /** |
|
115 * Method name to be searched from the component. |
|
116 */ |
|
117 private String methodName = null; |
|
118 /** |
|
119 * Name of main task that is show to the user in job progress dialog. |
|
120 */ |
|
121 private final String mainTaskMessage; |
|
122 |
|
123 /** |
|
124 * Constructor. |
|
125 * @param jobName Job name |
|
126 * @param mainTaskMessage Task name used for main task message |
|
127 * @param componentName Component name to search method calls from. |
|
128 * @param methodName Method name which occurrences to search from the component.. |
|
129 * @param isUserJob if <code>true</code> job is set as user level job that prompts dialog. |
|
130 */ |
|
131 public ShowMethodCallLocationsJob(String jobName, String mainTaskMessage, String componentName, String methodName, boolean isUserJob) { |
|
132 super(jobName); |
|
133 this.mainTaskMessage = mainTaskMessage; |
|
134 this.componentName = componentName; |
|
135 this.methodName = methodName; |
|
136 setUser(isUserJob); |
|
137 } |
|
138 |
|
139 /* (non-Javadoc) |
|
140 * @see org.eclipse.core.runtime.jobs.Job#run(org.eclipse.core.runtime.IProgressMonitor) |
|
141 */ |
|
142 protected IStatus run(IProgressMonitor monitor) { |
|
143 |
|
144 progressMonitor = monitor; |
|
145 IStatus status; |
|
146 |
|
147 try { |
|
148 |
|
149 progressMonitor.beginTask(mainTaskMessage, 100); |
|
150 |
|
151 AppDepSettings settings = AppDepSettings.getActiveSettings(); |
|
152 |
|
153 SdkInformation sdkInfo = settings.getCurrentlyUsedSdk(); |
|
154 String epocRootPath = sdkInfo.getEpocRootDir(); |
|
155 |
|
156 progressMonitor.subTask(Messages.getString("ShowMethodCallLocationsJob.SearchingFiles_SubTask_Msg") +"\n" +componentName +"'..."); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ |
|
157 |
|
158 filesBelongsToComponent = getUsedComponentSourceFiles(settings, componentName, epocRootPath); |
|
159 //Limit number of files simple founding part of the method name, to decrease project files |
|
160 setSearchString(methodName); |
|
161 |
|
162 checkIfCancelled(); |
|
163 progressMonitor.subTask(Messages.getString("ShowMethodCallLocationsJob.SearchingBldInf_SubTask_Msg")); //$NON-NLS-1$ |
|
164 progressMonitor.worked(CREATING_PROJECT_STEPS); |
|
165 |
|
166 //Finds and sets source files as IFile to variables |
|
167 String bldFile = getBldInfFileName(filesBelongsToComponent); |
|
168 |
|
169 //If the project already exist, just executing the search |
|
170 if(isProjectAllreadyExistingAndOpenIfClosed(bldFile, progressMonitor)){ |
|
171 |
|
172 progressMonitor.worked(SEARCH_AND_INDEX_STEPS); |
|
173 checkIfCancelled(); |
|
174 executeSearch(searchString); |
|
175 status = Status.OK_STATUS; |
|
176 |
|
177 } |
|
178 //otherwise first create a project, wait until indexed, and then execute the search |
|
179 else{ |
|
180 //Create a job to create project by bld.inf file if needed, and then execute search |
|
181 progressMonitor.subTask(Messages.getString("ShowMethodCallLocationsJob.CreatingProjectFromBldInf_SubTask_Msg") +"\n" +bldFile +"'..."); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ |
|
182 checkIfCancelled(); |
|
183 status = createAndRunProjectCreatingJobAndExecuteSearch(bldFile, progressMonitor); |
|
184 progressMonitor.worked(CREATING_PROJECT_STEPS); |
|
185 |
|
186 if(status.getSeverity() == IStatus.ERROR){ |
|
187 this.cancel(); |
|
188 } |
|
189 else{ |
|
190 startIndexingAndSearch(); |
|
191 status = Job.ASYNC_FINISH; |
|
192 } |
|
193 } |
|
194 |
|
195 } catch (JobCancelledByUserException e) { |
|
196 // Job cancel because of user request |
|
197 this.cancel(); |
|
198 status = Status.CANCEL_STATUS; |
|
199 }catch (Exception e) { |
|
200 // Job cancel because of an exception |
|
201 e.printStackTrace(); |
|
202 String errMsg = Messages.getString("CreateProjectJob.Err_Msg") + ": " + e.getMessage(); //$NON-NLS-1$ //$NON-NLS-2$ |
|
203 status = reportError(e, errMsg); |
|
204 this.cancel(); |
|
205 } |
|
206 return status; |
|
207 } |
|
208 |
|
209 /** |
|
210 * Reports error to user. |
|
211 * @param e Encountered exception. |
|
212 * @param errMsg Error message. |
|
213 * @return status object. |
|
214 */ |
|
215 private IStatus reportError(Exception e, String errMsg) { |
|
216 IStatus status; |
|
217 status = new Status( |
|
218 Status.ERROR,Platform.PI_RUNTIME, |
|
219 Status.ERROR,errMsg, e); |
|
220 AppDepConsole.getInstance().println(errMsg, IConsolePrintUtility.MSG_ERROR); |
|
221 return status; |
|
222 } |
|
223 |
|
224 /** |
|
225 * Gets all source files belonging to the given component. |
|
226 * @param settings Tool settings. |
|
227 * @param componentName component name to search method call locations from. |
|
228 * @param epocRootPath EPOCROOT path |
|
229 * @return Source file name array |
|
230 * @throws CannotFoundFileException |
|
231 * @throws CacheFileDoesNotExistException |
|
232 * @throws CacheIndexNotReadyException |
|
233 * @throws IOException |
|
234 */ |
|
235 private String[] getUsedComponentSourceFiles(AppDepSettings settings, |
|
236 String componentName, String epocRootPath) |
|
237 throws CannotFoundFileException, IOException, CacheIndexNotReadyException, CacheFileDoesNotExistException { |
|
238 |
|
239 ISourcesFinder finder = SourceFinderFactory.createSourcesFinder(AppDepConsole.getInstance()); |
|
240 String variant = MainViewDataPopulator.getTargetPlatformIdStringForComponent(settings, componentName); |
|
241 String build = settings.getBuildType().getBuildTypeName(); |
|
242 String [] files = finder.findSourceFiles(componentName, variant, build, epocRootPath); |
|
243 return files; |
|
244 } |
|
245 |
|
246 /** |
|
247 * Sets search string based on the method name. |
|
248 * @param methodName Method name. |
|
249 */ |
|
250 private void setSearchString(String methodName) { |
|
251 String shortMethodName = methodName; |
|
252 int start = methodName.indexOf("::"); //$NON-NLS-1$ |
|
253 if(start != -1){ |
|
254 shortMethodName = methodName.substring(start + 2); |
|
255 |
|
256 } |
|
257 int end = shortMethodName.indexOf("("); //$NON-NLS-1$ |
|
258 if(end != -1){ |
|
259 shortMethodName = shortMethodName.substring(0, end); |
|
260 } |
|
261 |
|
262 String longMethodNameWithOutParams; |
|
263 if(methodName.indexOf("(") != -1){ //$NON-NLS-1$ |
|
264 longMethodNameWithOutParams = methodName.substring(0, methodName.indexOf("(")); //$NON-NLS-1$ |
|
265 }else{ |
|
266 longMethodNameWithOutParams = methodName; |
|
267 } |
|
268 |
|
269 searchString = longMethodNameWithOutParams;// methodName;// shortMethodName; |
|
270 } |
|
271 |
|
272 |
|
273 /** |
|
274 * Seeks all files by bld.inf file and set them to filesInBldInf |
|
275 * and seeks all bld.inf to add them to bldInfFiles |
|
276 * @param files File name array. |
|
277 * @return bld.inf file path and an empty string if not found. |
|
278 * @throws URISyntaxException |
|
279 * @throws JobCancelledByUserException |
|
280 */ |
|
281 private String getBldInfFileName(String[] files) throws URISyntaxException, JobCancelledByUserException { |
|
282 //Opening project(s) where source files belongs to |
|
283 IProjectFinder prjFinder = ProjectFinderFactory.createProjectFinder(AppDepConsole.getInstance(), progressMonitor); |
|
284 Vector<String> bldInfFiles = new Vector<String>(); |
|
285 int errorsCount = 0; |
|
286 for (int i = 0; i < files.length; i++) { |
|
287 String bldInfFile; |
|
288 try { |
|
289 String mmpFile = prjFinder.findMMPFile(files[i]); |
|
290 //If search is canceled, null was returned from the previously called method |
|
291 if(mmpFile == null){ |
|
292 checkIfCancelled(); |
|
293 }else{ |
|
294 bldInfFile = prjFinder.findBLDINFFile(mmpFile); |
|
295 //If search is canceled, null is returned, cancellation check will be check if null is returned |
|
296 if(bldInfFile != null){ |
|
297 bldInfFiles.add(bldInfFile); |
|
298 }else { |
|
299 checkIfCancelled(); |
|
300 } |
|
301 } |
|
302 } catch (CannotFoundFileException e) { |
|
303 errorsCount++;//Just counting errors, really doing nothing with those but skipping if some file does not exist |
|
304 } |
|
305 } |
|
306 |
|
307 // Throwing an error in case bld.inf file was not found |
|
308 if(bldInfFiles.size() == 0){ |
|
309 String errMsg = Messages.getString("ShowMethodCallLocationsJob.CouldNotFindBldInfFile_ErrMsg") //$NON-NLS-1$ |
|
310 + componentName |
|
311 + "'"; //$NON-NLS-1$ |
|
312 throw new RuntimeException(errMsg); |
|
313 } |
|
314 // Returning found bld.inf file path name on success |
|
315 return bldInfFiles.elementAt(0); |
|
316 } |
|
317 |
|
318 /** |
|
319 * Checks if job was cancelled by user. |
|
320 * @throws JobCancelledByUserException |
|
321 */ |
|
322 private void checkIfCancelled() throws JobCancelledByUserException { |
|
323 if(progressMonitor.isCanceled()){ |
|
324 throw new JobCancelledByUserException(Messages.getString("ShowMethodCallLocationsJob.JobCanceledByUser_ErrMsg")); //$NON-NLS-1$ |
|
325 } |
|
326 } |
|
327 |
|
328 /** |
|
329 * Creates a project. |
|
330 * @param bldFile bld.inf file to create project based on. |
|
331 * @param monitor Progress monitor object |
|
332 * @throws IOException |
|
333 * @throws CoreException |
|
334 */ |
|
335 private IStatus createAndRunProjectCreatingJobAndExecuteSearch(String bldFile, IProgressMonitor monitor) throws IOException, CoreException { |
|
336 |
|
337 DEProjectUtils utils = new DEProjectUtils(AppDepConsole.getInstance()); |
|
338 CProjectJobStatus stat = utils.createProjectImpl(progressMonitor, bldFile); |
|
339 |
|
340 this.cProject = stat.getCProject(); |
|
341 IStatus status = stat.getStatus(); |
|
342 |
|
343 return status; |
|
344 } |
|
345 |
|
346 /** |
|
347 * Checks if project already exist in workspace. |
|
348 * @param bldFile bld.inf file to create project based on. |
|
349 * @param monitor Progress monitor object |
|
350 * @return <code>true</code> if project is found from workspace, otherwise <code>false</code>. |
|
351 * @throws IOException |
|
352 * @throws CoreException |
|
353 */ |
|
354 private boolean isProjectAllreadyExistingAndOpenIfClosed(String bldFile, IProgressMonitor monitor) throws IOException, CoreException { |
|
355 |
|
356 IPath path = new Path(bldFile); |
|
357 IFile[] files = ResourcesPlugin.getWorkspace().getRoot().findFilesForLocation(path); |
|
358 |
|
359 if(files.length > 0){ |
|
360 |
|
361 IProject prj = files[0].getProject(); |
|
362 if(prj.isOpen()){ |
|
363 return true; |
|
364 } |
|
365 else{ |
|
366 prj.open(monitor); |
|
367 return true; |
|
368 } |
|
369 } |
|
370 return false; |
|
371 } |
|
372 |
|
373 /** |
|
374 * Creates query and execute the search |
|
375 * @param searchText Search text |
|
376 * @throws JobCancelledByUserException |
|
377 */ |
|
378 private void executeSearch(final String searchText){ |
|
379 |
|
380 progressMonitor.subTask(Messages.getString("ShowMethodCallLocationsJob.ExcecutingSearch_SubTask_Msg")); //$NON-NLS-1$ |
|
381 |
|
382 final IResource[] resources = createResourcesTable(); |
|
383 |
|
384 |
|
385 DbgUtility.println(DbgUtility.PRIORITY_OPERATION, "Starting to execute search with " +resources.length +" resources..."); //$NON-NLS-1$ //$NON-NLS-2$ |
|
386 |
|
387 Runnable runSeach = new Runnable(){ |
|
388 public void run(){ |
|
389 try { |
|
390 if(progressMonitor.isCanceled()){ |
|
391 cancelProgress(); |
|
392 }else{ |
|
393 ISearchQuery query = null; |
|
394 //Query is created by CDT:s interal API |
|
395 query = getSearchQuery(searchText, resources); |
|
396 //Start to listen search query for noticing done() when its completed |
|
397 NewSearchUI.addQueryListener(getIQueryListener()); |
|
398 NewSearchUI.activateSearchResultView(); |
|
399 NewSearchUI.runQueryInBackground(query); |
|
400 } |
|
401 } |
|
402 catch (Exception e) { |
|
403 e.printStackTrace(); |
|
404 AppDepConsole.getInstance().println(Messages.getString("ShowMethodCallLocationsJob.UnableToExecuteSearch_ErrMsg_Part2") +e, AppDepConsole.MSG_ERROR); //$NON-NLS-1$ |
|
405 errorProgress(Messages.getString("ShowMethodCallLocationsJob.UnableToExecuteSearch_ErrMsg_Part1"), e); //$NON-NLS-1$ |
|
406 } |
|
407 } |
|
408 |
|
409 }; |
|
410 |
|
411 // Showing a visible message in its own thread |
|
412 // in order not to cause invalid thread access |
|
413 Display.getDefault().asyncExec(runSeach); |
|
414 } |
|
415 |
|
416 /** |
|
417 * Get search query. |
|
418 * <p> |
|
419 * This method is using CDT:s internal API:s and if public access to {@link PDOMSearchPatternQuery} |
|
420 * is provided, implementation should be changed to use public implementation. |
|
421 * Internal API is used, because of ready made implementation of find functions and methods references |
|
422 * is found in there. |
|
423 * @param searchText, text to search, without parameters. Cut search String before first brace "(". |
|
424 * With parameters and braces, you don't get any results. |
|
425 * @param resources |
|
426 * @return query to give to Search engine. |
|
427 * @throws CoreException |
|
428 */ |
|
429 private ISearchQuery getSearchQuery( |
|
430 final String searchText, final IResource[] resources) |
|
431 throws CoreException { |
|
432 |
|
433 // get the list of elements for the scope |
|
434 List<Object> elements = new ArrayList<Object>(); |
|
435 //Search from the given source files found in .map file |
|
436 String scopeDescription = CSearchMessages.SelectionScope; |
|
437 |
|
438 for (int i = 0; i < resources.length; i++) { |
|
439 elements.add(CoreModel.getDefault().create(resources[i])); |
|
440 } |
|
441 |
|
442 boolean isCaseSensitive = true; |
|
443 //to Search query, we must give resources as ICElement |
|
444 ICElement[] scope = elements.isEmpty() ? null : elements.toArray(new ICElement[elements.size()]); |
|
445 //Same flags covers search for and limit to selections, we want to search functions/methods and only references |
|
446 int searchFlags = PDOMSearchPatternQuery.FIND_FUNCTION | PDOMSearchPatternQuery.FIND_METHOD |
|
447 | PDOMSearchQuery.FIND_REFERENCES; |
|
448 |
|
449 //class to execute search is interal class provided in CDT, permission to use internal classes is granted. |
|
450 //Parameters cannot be used wih Query, only class name(s) and method name |
|
451 PDOMSearchPatternQuery query = new PDOMSearchPatternQuery(scope, scopeDescription, searchText, |
|
452 isCaseSensitive , searchFlags ); |
|
453 |
|
454 return query; |
|
455 } |
|
456 |
|
457 /** |
|
458 * Creates a array containing IFile links to files that were found from map file. |
|
459 * @return Resource object array. |
|
460 */ |
|
461 private IResource[] createResourcesTable() { |
|
462 HashSet<IFile> filesInBldInf = new HashSet<IFile>(); |
|
463 |
|
464 for (int i = 0; i < filesBelongsToComponent.length; i++) { |
|
465 String uriStr = filesBelongsToComponent[i].replace("\\", "/");; //$NON-NLS-1$ //$NON-NLS-2$ |
|
466 uriStr = "file://" + uriStr; //$NON-NLS-1$ |
|
467 IFile[] wsFile; |
|
468 try { |
|
469 wsFile = ResourcesPlugin.getWorkspace().getRoot().findFilesForLocationURI( |
|
470 new URI( uriStr)); |
|
471 for (int j = 0; j < wsFile.length; j++) { |
|
472 filesInBldInf.add(wsFile[j]); |
|
473 } |
|
474 } catch (URISyntaxException e) { |
|
475 e.printStackTrace(); |
|
476 AppDepConsole.getInstance().println( |
|
477 Messages.getString("ShowMethodCallLocationsJob.UnableToAddFile_ErrMsg_Part1") +uriStr //$NON-NLS-1$ |
|
478 +Messages.getString("ShowMethodCallLocationsJob.UnableToAddFile_ErrMsg_Part2") +e, AppDepConsole.MSG_ERROR); //$NON-NLS-1$ |
|
479 |
|
480 } |
|
481 } |
|
482 |
|
483 final IResource[] resources = (IFile[])filesInBldInf.toArray(new IFile[0]); |
|
484 return resources; |
|
485 } |
|
486 |
|
487 /** |
|
488 * Triggers indexing and searching. |
|
489 * @throws JobCancelledByUserException |
|
490 */ |
|
491 private void startIndexingAndSearch() throws JobCancelledByUserException { |
|
492 checkIfCancelled(); |
|
493 IIndexManager indexManager = CCorePlugin.getIndexManager(); |
|
494 boolean projectIndexed = indexManager.isProjectIndexed(cProject); |
|
495 DbgUtility.println(DbgUtility.PRIORITY_OPERATION, "Project: " +cProject.getElementName() + " indexed: " +projectIndexed + " and indexer is idling: " +indexManager.isIndexerIdle()); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ |
|
496 |
|
497 //If project is already indexed, search can be started right away |
|
498 if(projectIndexed && indexManager.isIndexerIdle()){ |
|
499 executeSearch( searchString); |
|
500 } |
|
501 //otherwise starting to listen indexer, and when its done, executing search |
|
502 else{ |
|
503 progressMonitor.subTask(Messages.getString("ShowMethodCallLocationsJob.StartingIndexing_SubTask_Msg")); //$NON-NLS-1$ |
|
504 IndexerStateListener listener = new IndexerStateListener(); |
|
505 indexManager.addIndexerStateListener(listener); |
|
506 indexManager.addIndexChangeListener(listener); |
|
507 } |
|
508 } |
|
509 |
|
510 /** |
|
511 * Listener class implementation for listening indexer state changes and start |
|
512 * execution of search when indexer is in idle state. |
|
513 */ |
|
514 private class IndexerStateListener implements IIndexerStateListener, IIndexChangeListener { |
|
515 |
|
516 public IndexerStateListener(){ |
|
517 progressMonitor.subTask(Messages.getString("ShowMethodCallLocationsJob.IndexingProject_SubTask_Msg") +cProject.getProject().getName() +"'..."); //$NON-NLS-1$ //$NON-NLS-2$ |
|
518 } |
|
519 |
|
520 private Double step = new Double (new Double(SEARCH_AND_INDEX_STEPS) / new Double( filesBelongsToComponent.length)); |
|
521 private double workLeftFromPreviousStep = 0; |
|
522 |
|
523 /* (non-Javadoc) |
|
524 * @see org.eclipse.cdt.core.index.IIndexerStateListener#indexChanged(org.eclipse.cdt.core.index.IIndexerStateEvent) |
|
525 */ |
|
526 public void indexChanged(IIndexerStateEvent event) { |
|
527 try { |
|
528 boolean indexerIsIdle = event.indexerIsIdle(); |
|
529 if(indexerIsIdle){ |
|
530 execute(); |
|
531 } |
|
532 } catch (Exception e) { |
|
533 errorProgress(Messages.getString("ShowMethodCallLocationsJob.UnableToExecuteSearch_ErrMsg_Part1"), e); //$NON-NLS-1$ |
|
534 } |
|
535 } |
|
536 |
|
537 /* (non-Javadoc) |
|
538 * @see org.eclipse.cdt.core.index.IIndexChangeListener#indexChanged(org.eclipse.cdt.core.index.IIndexChangeEvent) |
|
539 */ |
|
540 public void indexChanged(IIndexChangeEvent event) { |
|
541 |
|
542 try{ |
|
543 if(progressMonitor.isCanceled()){ |
|
544 IIndexManager indexManager = CCorePlugin.getIndexManager(); |
|
545 removeListeners(indexManager); |
|
546 cancelProgress(); |
|
547 } |
|
548 |
|
549 //Counting what's left from previous step and number of one step |
|
550 double stepTo = workLeftFromPreviousStep + step; |
|
551 Double stepNow = new Double(stepTo); |
|
552 //Take out int value of this step (x from x.yyyyyy) |
|
553 int workNow = stepNow.intValue(); |
|
554 stepNow = stepNow-workNow; |
|
555 //put on hold what was left from this step to next step (yyyy from x.yyyy) |
|
556 workLeftFromPreviousStep = stepNow.doubleValue(); |
|
557 |
|
558 progressMonitor.worked(workNow); |
|
559 |
|
560 //Continuing execution if indexer is idle. |
|
561 IIndexManager indexManager = CCorePlugin.getIndexManager(); |
|
562 if(indexManager.isIndexerIdle()){ |
|
563 execute(); |
|
564 } |
|
565 } catch (Exception e) { |
|
566 errorProgress(Messages.getString("ShowMethodCallLocationsJob.UnableToExecuteSearch_ErrMsg_Part1"), e);//$NON-NLS-1$ |
|
567 } |
|
568 } |
|
569 |
|
570 /** |
|
571 * Starts execution of search |
|
572 * @throws JobCancelledByUserException |
|
573 */ |
|
574 private void execute() { |
|
575 IIndexManager indexManager = CCorePlugin.getIndexManager(); |
|
576 boolean projectIndexed = indexManager.isProjectIndexed(cProject); |
|
577 |
|
578 DbgUtility.println(DbgUtility.PRIORITY_OPERATION, "Project indexed: " +projectIndexed + " and indexer is idling: " +indexManager.isIndexerIdle()); //$NON-NLS-1$ //$NON-NLS-2$ |
|
579 //Search can be started if project is indexed and indexer is ready (not doing anything anymore). |
|
580 if(projectIndexed && indexManager.isIndexerIdle()){ |
|
581 |
|
582 removeListeners(indexManager); |
|
583 executeSearch( searchString); |
|
584 } |
|
585 } |
|
586 |
|
587 /** |
|
588 * Removes listeners from index manager. |
|
589 * @param indexManager Index manager. |
|
590 */ |
|
591 private void removeListeners(IIndexManager indexManager) { |
|
592 indexManager.removeIndexChangeListener(this); |
|
593 indexManager.removeIndexerStateListener(this); |
|
594 } |
|
595 |
|
596 } |
|
597 |
|
598 /** |
|
599 * An error occurred, cancels progress and sends an error. |
|
600 */ |
|
601 private void errorProgress(String errMsg, Exception e) { |
|
602 // Cancelling query |
|
603 progressMonitor.done(); |
|
604 IStatus status = new Status( |
|
605 Status.ERROR,Platform.PI_RUNTIME, |
|
606 Status.ERROR,errMsg, e); |
|
607 done(status); |
|
608 } |
|
609 |
|
610 /** |
|
611 * Cancels progress without sending exception. |
|
612 */ |
|
613 private void cancelProgress() { |
|
614 // Cancelling query |
|
615 progressMonitor.done(); |
|
616 done(Status.CANCEL_STATUS); |
|
617 } |
|
618 |
|
619 /** |
|
620 * Gets query listener interface. |
|
621 * @return this |
|
622 */ |
|
623 public IQueryListener getIQueryListener(){ |
|
624 return this; |
|
625 } |
|
626 |
|
627 /* (non-Javadoc) |
|
628 * @see org.eclipse.search.ui.IQueryListener#queryAdded(org.eclipse.search.ui.ISearchQuery) |
|
629 */ |
|
630 public void queryAdded(ISearchQuery query) { |
|
631 // not needed |
|
632 } |
|
633 |
|
634 /* (non-Javadoc) |
|
635 * @see org.eclipse.search.ui.IQueryListener#queryFinished(org.eclipse.search.ui.ISearchQuery) |
|
636 */ |
|
637 public void queryFinished(ISearchQuery query) { |
|
638 //When query is finished, returning OK status |
|
639 progressMonitor.done(); |
|
640 // Job has completed successfully |
|
641 done(Status.OK_STATUS); |
|
642 } |
|
643 |
|
644 /* (non-Javadoc) |
|
645 * @see org.eclipse.search.ui.IQueryListener#queryRemoved(org.eclipse.search.ui.ISearchQuery) |
|
646 */ |
|
647 public void queryRemoved(ISearchQuery query) { |
|
648 cancelProgress(); |
|
649 } |
|
650 |
|
651 /* (non-Javadoc) |
|
652 * @see org.eclipse.search.ui.IQueryListener#queryStarting(org.eclipse.search.ui.ISearchQuery) |
|
653 */ |
|
654 public void queryStarting(ISearchQuery query) { |
|
655 // not needed |
|
656 } |
|
657 |
|
658 } |