srcanaapps/depexplorer/com.nokia.s60tools.appdep/src/com/nokia/s60tools/appdep/locatecomponent/ShowMethodCallLocationsJob.java
changeset 0 a02c979e8dfd
equal deleted inserted replaced
-1:000000000000 0:a02c979e8dfd
       
     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 }