/*****************************************************************************
* Copyright (c) 2006, 2007 g-Eclipse Consortium
* 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
*
* Initial development of the original code was made for the
* g-Eclipse project founded by European Union
* project number: FP6-IST-034327 http://www.geclipse.eu/
*
* Contributors:
* Christof Klausecker GUP, JKU - initial API and implementation
*****************************************************************************/
package eu.geclipse.traceview.debug.actions;
import java.util.HashMap;
import org.eclipse.cdt.core.model.CModelException;
import org.eclipse.cdt.core.model.CoreModel;
import org.eclipse.cdt.core.model.ICProject;
import org.eclipse.cdt.core.model.ISourceRoot;
import org.eclipse.cdt.core.model.ITranslationUnit;
import org.eclipse.cdt.debug.core.CDebugCorePlugin;
import org.eclipse.cdt.debug.core.model.ICBreakpoint;
import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IMarker;
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.IStatus;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Status;
import org.eclipse.debug.core.DebugPlugin;
import org.eclipse.debug.core.model.IBreakpoint;
import org.eclipse.jface.action.Action;
import org.eclipse.jface.action.IAction;
import org.eclipse.jface.dialogs.ErrorDialog;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.swt.widgets.Display;
import org.eclipse.ui.IActionDelegate;
import eu.geclipse.traceview.IEvent;
import eu.geclipse.traceview.ISourceLocation;
import eu.geclipse.traceview.ITrace;
import eu.geclipse.traceview.debug.Activator;
import eu.geclipse.traceview.debug.EventBreakpoint;
public abstract class AbstractEventBreakpointAction extends Action
implements IActionDelegate
{
protected StructuredSelection selection;
/**
* Returns the Project which contains the Trace
*
* @param trace
* @return project
*/
protected ICProject getProject( final ITrace trace ) {
ICProject project = null;
IPath tracePath = trace.getPath();
// check if the trace is located in the workspace
boolean workspace = ResourcesPlugin.getWorkspace()
.getRoot()
.getLocation()
.isPrefixOf( tracePath );
if( workspace ) {
IPath path = tracePath.removeFirstSegments( ResourcesPlugin.getWorkspace()
.getRoot()
.getLocation()
.segmentCount() );
// get the name of the project the trace is located in
String projectName = path.uptoSegment( 1 ).toPortableString();
String device = path.getDevice();
if( device != null ) {
projectName = projectName.substring( device.length() );
}
// get the project
if( projectName != null && projectName.length() > 0 ) {
project = CoreModel.getDefault().getCModel().getCProject( projectName );
}
}
return project;
}
protected IResource getResource( final ICProject project,
final String sourceHandle )
throws CModelException
{
String source = new Path( sourceHandle ).lastSegment();
IResource resource = null;
ISourceRoot[] roots = project.getSourceRoots();
for( ISourceRoot root : roots ) {
ITranslationUnit[] units = root.getTranslationUnits();
for( ITranslationUnit unit : units ) {
if( source.equals( unit.getResource().getName() ) ) {
//unit.getAST().getChildren()[0].
resource = unit.getResource();
break;
}
}
}
return resource;
}
public void selectionChanged( final IAction action, final ISelection selection ) {
if( selection instanceof StructuredSelection ) {
this.selection = ( StructuredSelection )selection;
} else {
this.selection = StructuredSelection.EMPTY;
}
}
protected boolean existing( final IEvent event, final ICProject project ) {
boolean existing = false;
if( event instanceof ISourceLocation ) {
ISourceLocation sourceLocation = ( ISourceLocation )event;
String filename = sourceLocation.getSourceFilename();
filename = new Path( filename ).lastSegment();
String sourceHandle = project.getProject()
.getFile( filename )
.getLocation()
.toOSString();
IBreakpoint[] breakpoints = DebugPlugin.getDefault()
.getBreakpointManager()
.getBreakpoints();
for( int i = 0; i < breakpoints.length && !existing; i++ ) {
if( breakpoints[ i ] instanceof EventBreakpoint ) {
EventBreakpoint eventBreakPoint = ( EventBreakpoint )breakpoints[ i ];
try {
if( eventBreakPoint.getLineNumber() == sourceLocation.getSourceLineNumber()
&& eventBreakPoint.getSourceHandle().equals( sourceHandle )
&& eventBreakPoint.getProcess() == event.getProcessId() )
{
if( eventBreakPoint.containtsEvent( event ) ) {
eventBreakPoint.removeEvent( event );
} else {
eventBreakPoint.addEvent( event );
}
existing = true;
}
} catch( CoreException coreException ) {
Activator.logException( coreException );
}
}
}
}
return existing;
}
private IPath findPath( final String fileLocation, final IResource searchPath )
throws CoreException
{
IPath file = new Path(fileLocation );
String filename = file.lastSegment();
IPath result = null;
if( searchPath instanceof IContainer
&& ( ( IContainer )searchPath ).isAccessible() )
{
for( IResource resource : ( ( IContainer )searchPath ).members() ) {
if( resource.getName().equals( filename ) ) {
result = resource.getProjectRelativePath();
} else {
result = findPath( filename, resource );
}
if( result != null )
break;
}
}
return result;
}
protected EventBreakpoint createEventBreakpoint( final IEvent event )
throws CoreException
{
EventBreakpoint eventBreakpoint = null;
if( event instanceof ISourceLocation ) {
boolean enabled = true;
boolean register = false;
IResource resource = null;
ISourceLocation sourceLocation = ( ISourceLocation )event;
String condition = ""; //$NON-NLS-1$
String sourceHandle = ""; //$NON-NLS-1$
int lineNumber = sourceLocation.getSourceLineNumber();
int ignoreCount = sourceLocation.getOccurrenceCount();
// get project
ICProject project = getProject( event.getProcess().getTrace() );
if( project != null ) {
String filename = sourceLocation.getSourceFilename();
filename = new Path( filename ).lastSegment();
sourceHandle = project.getProject()
.getFile( filename )
.getLocation()
.toOSString();
IPath path = findPath( filename, project.getResource() );
resource = getResource( project, path.toString() );
if( resource != null ) {
if( !existing( event, project ) ) {
HashMap<String, Object> attributes = new HashMap<String, Object>( 10 );
attributes.put( IBreakpoint.ID,
CDebugCorePlugin.getUniqueIdentifier() );
attributes.put( IMarker.LINE_NUMBER, Integer.valueOf( lineNumber ) );
attributes.put( IBreakpoint.ENABLED, Boolean.valueOf( enabled ) );
attributes.put( ICBreakpoint.IGNORE_COUNT,
Integer.valueOf( ignoreCount ) );
attributes.put( ICBreakpoint.CONDITION, condition );
attributes.put( ICBreakpoint.SOURCE_HANDLE, sourceHandle );
attributes.put( EventBreakpoint.PROCESS,
Integer.valueOf( event.getProcessId() ) );
eventBreakpoint = new EventBreakpoint( resource,
attributes,
register,
event );
eventBreakpoint.addEvent( event );
}
} else {
ErrorDialog.openError( Display.getDefault().getActiveShell(),
"Error",
"Cannot find source file.",
new Status( IStatus.ERROR,
Activator.PLUGIN_ID,
"The project does not contain the source file." ) );
}
} else {
ErrorDialog.openError( Display.getDefault().getActiveShell(),
"Error",
"Cannot find source file.",
new Status( IStatus.ERROR,
Activator.PLUGIN_ID,
"The trace must be located in a project of the workspace." ) );
}
}
return eventBreakpoint;
}
}