/******************************************************************************* * Copyright (c) 2007, 2010 Wind River Systems, Inc. and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Markus Schorn - initial API and implementation * Sergey Prigogin (Google) ******************************************************************************/ package org.eclipse.cdt.internal.core.pdom.indexer; import java.util.ArrayList; import java.util.HashSet; import java.util.List; import org.eclipse.cdt.core.CCorePlugin; import org.eclipse.cdt.core.dom.IPDOMIndexer; import org.eclipse.cdt.core.dom.IPDOMIndexerTask; import org.eclipse.cdt.core.dom.IPDOMManager; import org.eclipse.cdt.core.index.IIndex; import org.eclipse.cdt.core.index.IIndexFile; import org.eclipse.cdt.core.index.IIndexFileLocation; import org.eclipse.cdt.core.index.IIndexManager; import org.eclipse.cdt.core.index.IndexLocationFactory; import org.eclipse.cdt.core.model.CoreModel; import org.eclipse.cdt.core.model.ICElement; import org.eclipse.cdt.core.model.ICProject; import org.eclipse.cdt.core.model.ITranslationUnit; import org.eclipse.cdt.internal.core.model.ExternalTranslationUnit; import org.eclipse.cdt.internal.core.pdom.IndexerProgress; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IResource; import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.osgi.util.NLS; /** * A task for updating an index, suitable for all indexers. */ public class PDOMUpdateTask implements IPDOMIndexerTask { protected static final String TRUE= String.valueOf(true); protected static final ITranslationUnit[] NO_TUS = new ITranslationUnit[0]; private final IPDOMIndexer fIndexer; private final IndexerProgress fProgress; private final int fUpdateOptions; private volatile IPDOMIndexerTask fDelegate; private ArrayList<ICElement> fFilesAndFolders= null; public PDOMUpdateTask(IPDOMIndexer indexer, int updateOptions) { fIndexer= indexer; fProgress= createProgress(); fUpdateOptions= updateOptions; } private IndexerProgress createProgress() { IndexerProgress progress= new IndexerProgress(); progress.fTimeEstimate= 1000; return progress; } public IPDOMIndexer getIndexer() { return fIndexer; } public void run(IProgressMonitor monitor) throws InterruptedException { monitor.subTask(NLS.bind(Messages.PDOMIndexerTask_collectingFilesTask, fIndexer.getProject().getElementName())); ICProject project= fIndexer.getProject(); if (project.getProject().isOpen()) { try { if (!IPDOMManager.ID_NO_INDEXER.equals(fIndexer.getID())) { createDelegate(project, monitor); } } catch (CoreException e) { CCorePlugin.log(e); } } if (fDelegate != null) { fDelegate.run(monitor); } } private void createDelegate(ICProject project, IProgressMonitor monitor) throws CoreException, InterruptedException { HashSet<ITranslationUnit> set= new HashSet<ITranslationUnit>(); TranslationUnitCollector collector= new TranslationUnitCollector(set, set, monitor); boolean haveProject= false; if (fFilesAndFolders == null) { project.accept(collector); } else { for (ICElement elem : fFilesAndFolders) { if (elem.getElementType() == ICElement.C_PROJECT) { haveProject= true; } elem.accept(collector); } } if (haveProject && (fUpdateOptions & IIndexManager.UPDATE_EXTERNAL_FILES_FOR_PROJECT) != 0) { final String projectPrefix= project.getProject().getFullPath().toString() + IPath.SEPARATOR; IIndex index= CCorePlugin.getIndexManager().getIndex(project); index.acquireReadLock(); try { IIndexFile[] files= index.getAllFiles(); for (IIndexFile indexFile : files) { IIndexFileLocation floc= indexFile.getLocation(); final String fullPath = floc.getFullPath(); if (fullPath == null || !fullPath.startsWith(projectPrefix)) { IPath path= IndexLocationFactory.getAbsolutePath(floc); if (path != null) { ITranslationUnit tu= CoreModel.getDefault().createTranslationUnitFrom(project, path); if (tu != null) { if (fullPath != null) { if (tu instanceof ExternalTranslationUnit) { IResource file= ResourcesPlugin.getWorkspace().getRoot().findMember(fullPath); if (file instanceof IFile) { ((ExternalTranslationUnit) tu).setResource((IFile) file); } } } set.add(tu); } } } } } finally { index.releaseReadLock(); } } ITranslationUnit[] tus= set.toArray(new ITranslationUnit[set.size()]); IPDOMIndexerTask delegate= fIndexer.createTask(NO_TUS, tus, NO_TUS); if (delegate instanceof PDOMIndexerTask) { final PDOMIndexerTask task = (PDOMIndexerTask) delegate; task.setUpdateFlags(fUpdateOptions); } synchronized (this) { fDelegate= delegate; } } public synchronized IndexerProgress getProgressInformation() { return fDelegate != null ? fDelegate.getProgressInformation() : fProgress; } public synchronized boolean acceptUrgentTask(IPDOMIndexerTask task) { return fDelegate != null && fDelegate.acceptUrgentTask(task); } public void setTranslationUnitSelection(List<ICElement> filesAndFolders) { fFilesAndFolders= new ArrayList<ICElement>(filesAndFolders.size()); fFilesAndFolders.addAll(filesAndFolders); } }