/*******************************************************************************
* Copyright (c) 2004, 2010 QNX Software Systems 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:
* QNX Software Systems - Initial API and implementation
* Nokia - Added support for AbsoluteSourceContainer(159833)
* Texas Instruments - added extension point for source container type (279473)
* Sergey Prigogin (Google)
*******************************************************************************/
package org.eclipse.cdt.debug.internal.core.sourcelookup;
import java.io.File;
import java.util.HashSet;
import java.util.Set;
import org.eclipse.cdt.debug.core.CDebugCorePlugin;
import org.eclipse.cdt.debug.core.model.ICBreakpoint;
import org.eclipse.cdt.debug.core.sourcelookup.AbsolutePathSourceContainer;
import org.eclipse.cdt.debug.core.sourcelookup.CProjectSourceContainer;
import org.eclipse.cdt.debug.core.sourcelookup.IMappingSourceContainer;
import org.eclipse.cdt.debug.core.sourcelookup.ProgramRelativePathSourceContainer;
import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IConfigurationElement;
import org.eclipse.core.runtime.IExtension;
import org.eclipse.core.runtime.IExtensionPoint;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Platform;
import org.eclipse.debug.core.ILaunchManager;
import org.eclipse.debug.core.sourcelookup.AbstractSourceLookupDirector;
import org.eclipse.debug.core.sourcelookup.ISourceContainer;
import org.eclipse.debug.core.sourcelookup.ISourceContainerType;
import org.eclipse.debug.core.sourcelookup.ISourceLookupParticipant;
import org.eclipse.debug.core.sourcelookup.containers.DirectorySourceContainer;
import org.eclipse.debug.core.sourcelookup.containers.FolderSourceContainer;
import org.eclipse.debug.core.sourcelookup.containers.ProjectSourceContainer;
/**
* C/C++ source lookup director.
*
* Most instantiations of this class are transient, created through
* {@link ILaunchManager#newSourceLocator(String)}. A singleton is also created
* to represent the global source locators.
*
* An instance is either associated with a particular launch configuration or it
* has no association (global).
*/
public class CSourceLookupDirector extends AbstractSourceLookupDirector {
private static Set<String> fSupportedTypes;
private static Object fSupportedTypesLock = new Object();
/* (non-Javadoc)
* @see org.eclipse.debug.core.sourcelookup.ISourceLookupDirector#initializeParticipants()
*/
public void initializeParticipants() {
addParticipants(new ISourceLookupParticipant[] { new CSourceLookupParticipant() });
}
/* (non-Javadoc)
* @see org.eclipse.debug.core.sourcelookup.ISourceLookupDirector#supportsSourceContainerType(org.eclipse.debug.core.sourcelookup.ISourceContainerType)
*/
public boolean supportsSourceContainerType(ISourceContainerType type) {
readSupportedContainerTypes();
return fSupportedTypes.contains(type.getId());
}
public boolean contains(String source) {
for (ISourceContainer cont : getSourceContainers()) {
if (contains(cont, source))
return true;
}
return false;
}
public boolean contains(ICBreakpoint breakpoint) {
try {
String handle = breakpoint.getSourceHandle();
for (ISourceContainer cont : getSourceContainers()) {
if (contains(cont, handle))
return true;
}
} catch (CoreException e) {
}
return false;
}
public boolean contains(IProject project) {
for (ISourceContainer cont : getSourceContainers()) {
if (contains(cont, project))
return true;
}
return false;
}
private boolean contains(ISourceContainer container, IProject project) {
if (container instanceof CProjectSourceContainer && project.equals(((CProjectSourceContainer) container).getProject())) {
return true;
}
if (container instanceof ProjectSourceContainer && project.equals(((ProjectSourceContainer) container).getProject())) {
return true;
}
try {
for (ISourceContainer cont : container.getSourceContainers()) {
if (contains(cont, project))
return true;
}
} catch (CoreException e) {
}
return false;
}
private boolean contains(ISourceContainer container, String sourceName) {
IPath path = new Path(sourceName);
if (!path.isValidPath(sourceName))
return false;
if (container instanceof IMappingSourceContainer) {
return ((IMappingSourceContainer) container).getCompilationPath(sourceName) != null;
}
if (container instanceof CProjectSourceContainer) {
IProject project = ((CProjectSourceContainer) container).getProject();
if (project != null) {
IPath projPath = project.getLocation();
if (projPath != null && projPath.isPrefixOf(path)) {
IFile file = ((CProjectSourceContainer) container).getProject().getFile(path.removeFirstSegments(projPath.segmentCount()));
return file != null && file.exists();
}
}
} else if (container instanceof ProjectSourceContainer) {
IProject project = ((ProjectSourceContainer) container).getProject();
IPath projPath = project.getLocation();
if (projPath != null && projPath.isPrefixOf(path)) {
IFile file = ((ProjectSourceContainer) container).getProject().getFile(path.removeFirstSegments(projPath.segmentCount()));
return file != null && file.exists();
}
} else if (container instanceof FolderSourceContainer) {
IContainer folder = ((FolderSourceContainer) container).getContainer();
IPath folderPath = folder.getLocation();
if (folderPath != null && folderPath.isPrefixOf(path)) {
IFile file = ((FolderSourceContainer) container).getContainer().getFile(path.removeFirstSegments(folderPath.segmentCount()));
return file != null && file.exists();
}
} else if (container instanceof DirectorySourceContainer) {
File dir = ((DirectorySourceContainer) container).getDirectory();
boolean searchSubfolders = ((DirectorySourceContainer) container).isComposite();
IPath dirPath = new Path(dir.getAbsolutePath());
if (searchSubfolders || dirPath.segmentCount() + 1 == path.segmentCount())
return dirPath.isPrefixOf(path);
} else if (container instanceof AbsolutePathSourceContainer) {
return ((AbsolutePathSourceContainer) container).isValidAbsoluteFilePath(sourceName);
} else if (container instanceof ProgramRelativePathSourceContainer) {
try {
Object[] elements = ((ProgramRelativePathSourceContainer) container).findSourceElements(sourceName);
return elements.length > 0;
} catch (CoreException e) {
return false;
}
}
try {
for (ISourceContainer cont : container.getSourceContainers()) {
if (contains(cont, sourceName))
return true;
}
} catch (CoreException e) {
}
return false;
}
public IPath getCompilationPath(String sourceName) {
for (ISourceContainer container : getSourceContainers()) {
IPath path = SourceUtils.getCompilationPath(container, sourceName);
if (path != null) {
return path;
}
}
return null;
}
// >> Bugzilla 279473
private void readSupportedContainerTypes() {
synchronized (fSupportedTypesLock) {
if (fSupportedTypes == null) {
fSupportedTypes = new HashSet<String>();
String name = CDebugCorePlugin.PLUGIN_ID + ".supportedSourceContainerTypes"; //$NON-NLS-1$;
IExtensionPoint extensionPoint = Platform.getExtensionRegistry().getExtensionPoint(name);
if (extensionPoint != null) {
for (IExtension extension : extensionPoint.getExtensions()) {
for (IConfigurationElement configurationElements : extension.getConfigurationElements()) {
String id = configurationElements.getAttribute("id"); //$NON-NLS-1$;
if (id != null)
fSupportedTypes.add(id);
}
}
}
}
}
}
// << Bugzilla 279473
}