blob: 3119c2ae6d479aa186e8768750bdbe30997563a9 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2005 The Regents of the University of California.
* This material was produced under U.S. Government contract W-7405-ENG-36
* for Los Alamos National Laboratory, which is operated by the University
* of California for the U.S. Department of Energy. The U.S. Government has
* rights to use, reproduce, and distribute this software. NEITHER THE
* GOVERNMENT NOR THE UNIVERSITY MAKES ANY WARRANTY, EXPRESS OR IMPLIED, OR
* ASSUMES ANY LIABILITY FOR THE USE OF THIS SOFTWARE. If software is modified
* to produce derivative works, such modified software should be clearly marked,
* so as not to confuse it with the version available from LANL.
*
* Additionally, 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
*
* LA-CC 04-115
*******************************************************************************/
package org.eclipse.ptp.debug.internal.ui;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import org.eclipse.core.filebuffers.FileBuffers;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IStorage;
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.core.runtime.IStatus;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.debug.core.model.IDebugTarget;
import org.eclipse.debug.core.model.ISourceLocator;
import org.eclipse.debug.core.model.IStackFrame;
import org.eclipse.debug.core.model.IThread;
import org.eclipse.debug.core.sourcelookup.containers.LocalFileStorage;
import org.eclipse.debug.ui.DebugUITools;
import org.eclipse.debug.ui.sourcelookup.ISourceLookupResult;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.IRegion;
import org.eclipse.jface.text.Position;
import org.eclipse.jface.text.source.IAnnotationModel;
import org.eclipse.ptp.core.elements.IPJob;
import org.eclipse.ptp.core.resources.FileStorage;
import org.eclipse.ptp.debug.core.IPDebugEventListener;
import org.eclipse.ptp.debug.core.IPSession;
import org.eclipse.ptp.debug.core.PTPDebugCorePlugin;
import org.eclipse.ptp.debug.core.TaskSet;
import org.eclipse.ptp.debug.core.event.IPDebugEvent;
import org.eclipse.ptp.debug.core.event.IPDebugInfo;
import org.eclipse.ptp.debug.core.event.IPDebugSuspendInfo;
import org.eclipse.ptp.debug.core.model.IPDebugTarget;
import org.eclipse.ptp.debug.core.model.IPStackFrame;
import org.eclipse.ptp.debug.core.model.IPThread;
import org.eclipse.ptp.debug.core.pdi.PDIException;
import org.eclipse.ptp.debug.core.pdi.request.IPDIListStackFramesRequest;
import org.eclipse.ptp.debug.core.sourcelookup.PSourceLookupDirector;
import org.eclipse.ptp.debug.ui.IPTPDebugUIConstants;
import org.eclipse.ptp.debug.ui.PTPDebugUIPlugin;
import org.eclipse.ptp.debug.ui.UIDebugManager;
import org.eclipse.ptp.debug.ui.messages.Messages;
import org.eclipse.ptp.proxy.debug.client.ProxyDebugLocator;
import org.eclipse.ptp.proxy.debug.client.ProxyDebugStackFrame;
import org.eclipse.ptp.ui.IElementManager;
import org.eclipse.ptp.ui.listeners.IJobChangedListener;
import org.eclipse.ptp.ui.model.IElementHandler;
import org.eclipse.ptp.ui.model.IElementSet;
import org.eclipse.swt.custom.BusyIndicator;
import org.eclipse.swt.widgets.Display;
import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.IEditorReference;
import org.eclipse.ui.IFileEditorInput;
import org.eclipse.ui.IStorageEditorInput;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.progress.UIJob;
import org.eclipse.ui.progress.WorkbenchJob;
import org.eclipse.ui.texteditor.IDocumentProvider;
import org.eclipse.ui.texteditor.ITextEditor;
/*
* @author Clement chu
*
*/
public class PAnnotationManager implements IJobChangedListener, IPDebugEventListener {
private static PAnnotationManager instance = null;
private final Object LOCK = new Object();
protected Map<String, AnnotationGroup> annotationMap = Collections.synchronizedMap(new HashMap<String, AnnotationGroup>());
protected UIDebugManager uiDebugManager = null;
/* Constructor
* @param uiDebugManager
*/
public PAnnotationManager(UIDebugManager uiDebugManager) {
this.uiDebugManager = uiDebugManager;
// make sure every time created the same object reference
if (instance == null) {
uiDebugManager.addJobChangedListener(this);
PTPDebugCorePlugin.getDefault().addDebugEventListener(this);
instance = this;
}
}
/* Get instance of PAnnotationManager
* @return
*/
public static PAnnotationManager getDefault() {
if (instance == null)
instance = new PAnnotationManager(PTPDebugUIPlugin.getUIDebugManager());
return instance;
}
/* Clean all settings and listeners
*
*/
public void shutdown() {
clearAllAnnotations();
PTPDebugCorePlugin.getDefault().removeDebugEventListener(this);
uiDebugManager.removeJobChangedListener(this);
annotationMap = null;
}
/* Clean all stored annotations
*
*/
protected void clearAllAnnotations() {
synchronized (LOCK) {
for (Iterator<AnnotationGroup> i = annotationMap.values().iterator(); i.hasNext();) {
i.next().removeAnnotations();
}
annotationMap.clear();
}
}
/* Remove annotation group by given job
* @param job_id job ID
*/
protected void removeAnnotationGroup(String job_id) {
synchronized (LOCK) {
AnnotationGroup annotationGroup = (AnnotationGroup) annotationMap.remove(job_id);
if (annotationGroup != null) {
annotationGroup.removeAnnotations();
}
}
}
/* Add annotation to given job
* @param job_id Job ID
* @param annotationGroup
*/
protected void putAnnotationGroup(String job_id, AnnotationGroup annotationGroup) {
synchronized (LOCK) {
annotationMap.put(job_id, annotationGroup);
}
}
/* Get annotation by given hob ID
* @param job_id job ID
* @return
*/
protected AnnotationGroup getAnnotationGroup(String job_id) {
synchronized (LOCK) {
return (AnnotationGroup) annotationMap.get(job_id);
}
}
/* Get editor and open editor if it is not opened or focus on it if it is already opened
* @param page
* @param input
* @param id
* @return
*/
protected IEditorPart openEditor(final IWorkbenchPage page, final IEditorInput input, final String id) {
final IEditorPart[] editor = new IEditorPart[] { null };
Runnable r = new Runnable() {
public void run() {
try {
editor[0] = page.openEditor(input, id, false);
} catch (PartInitException e) {
PTPDebugUIPlugin.errorDialog(PTPDebugUIPlugin.getActiveWorkbenchShell(), Messages.PAnnotationManager_0, Messages.PAnnotationManager_1, e);
}
}
};
BusyIndicator.showWhile(Display.getDefault(), r);
return editor[0];
}
/* Get editor part
* @param file
* @return
*/
protected IEditorPart getEditorPart(final IFile file) {
final IEditorPart[] editor = new IEditorPart[] { null };
Display.getDefault().syncExec(new Runnable() {
public void run() {
IWorkbenchPage page = PTPDebugUIPlugin.getActiveWorkbenchWindow().getActivePage();
IEditorPart editorPart = page.getActiveEditor();
if (editorPart != null) {
IEditorInput editorInput = editorPart.getEditorInput();
if (editorInput instanceof IFileEditorInput) {
if (((IFileEditorInput) editorInput).getFile().equals(file)) {
page.bringToTop(editorPart);
editor[0] = editorPart;
return;
}
}
}
if (editor[0] == null) {
for (IEditorReference refs : page.getEditorReferences()) {
IEditorPart refEditor = refs.getEditor(false);
if (refEditor == null)
continue;
IEditorInput editorInput = refEditor.getEditorInput();
if (editorInput instanceof IFileEditorInput) {
if (((IFileEditorInput) editorInput).getFile().equals(file)) {
page.bringToTop(refEditor);
editor[0] = refEditor;
return;
}
}
}
}
try {
editor[0] = page.openEditor(PDebugUIUtils.getEditorInput(file), PDebugUIUtils.getEditorId(file), false);
} catch (PartInitException e) {
//PTPDebugUIPlugin.errorDialog(PTPDebugUIPlugin.getActiveWorkbenchShell(), "Error", "Cannot open editor", e);
}
}
});
return editor[0];
}
protected void displaySource(final ISourceLookupResult result) {
UIJob uiJob = new UIJob(Messages.PAnnotationManager_2) {
public IStatus runInUIThread(IProgressMonitor monitor) {
IWorkbenchPage page = PTPDebugUIPlugin.getActiveWorkbenchWindow().getActivePage();
if (!monitor.isCanceled() && result != null && page != null) {
DebugUITools.displaySource(result, page);
}
return Status.OK_STATUS;
}
};
uiJob.schedule();
}
/* Find file
* @param fileName
* @return
*/
protected IFile findFile(String filename) {
return findFile(new Path(filename));
}
protected IFile findFile(IPath location) {
IPath normalized = FileBuffers.normalizeLocation(location);
if (normalized.segmentCount() >= 2) {
return ResourcesPlugin.getWorkspace().getRoot().getFile(normalized);
}
return null;
}
/* Get text editor
* @param editorPart
* @return
*/
protected ITextEditor getTextEditor(IEditorPart editorPart) {
if (editorPart instanceof ITextEditor) {
return (ITextEditor) editorPart;
}
return (ITextEditor) editorPart.getAdapter(ITextEditor.class);
}
/* Get file
* @param editorInput
* @return
*/
protected IFile getFile(IEditorInput editorInput) {
if (editorInput instanceof IFileEditorInput)
return ((IFileEditorInput) editorInput).getFile();
if (editorInput instanceof IStorageEditorInput) {
try {
return findFile(((IStorageEditorInput)editorInput).getStorage().getFullPath());
} catch (CoreException e) {
return null;
}
}
if (editorInput instanceof IStorage) {
return findFile(((IStorage)editorInput).getName());
}
return null;
}
/* Create position in the source file
* @param lineNumber
* @param doc
* @return
*/
protected Position createPosition(int lineNumber, IDocument doc) {
if (doc == null)
return null;
try {
IRegion region = doc.getLineInformation(lineNumber - 1);
int charStart = region.getOffset();
int length = region.getLength();
if (charStart < 0)
return null;
return new Position(charStart, length);
} catch (BadLocationException ble) {
return null;
}
}
/* Get tasks from debug target
* @param debugTarget
* @return
*/
protected TaskSet getTasks(IDebugTarget debugTarget) {
if (debugTarget instanceof IPDebugTarget) {
return ((IPDebugTarget) debugTarget).getTasks();
}
return null;
}
/* Get tasks from thread
* @param thread
* @return
*/
protected TaskSet getTasks(IThread thread) {
return getTasks(thread.getDebugTarget());
}
/* Is given type register type
* @param type
* @return
*/
protected boolean isRegisterType(String type) {
return (type.equals(IPTPDebugUIConstants.REG_ANN_INSTR_POINTER_CURRENT) || type.equals(IPTPDebugUIConstants.REG_ANN_INSTR_POINTER_SECONDARY));
}
/* Focus to annotation in source editor
* @param editorPart
* @param stackFrame
* @throws CoreException
*/
protected void focusAnnotation(IEditorPart editorPart, IStackFrame stackFrame) throws CoreException {
ITextEditor textEditor = getTextEditor(editorPart);
int charStart = stackFrame.getCharStart();
if (charStart > 0) {
textEditor.selectAndReveal(charStart, 0);
return;
}
int lineNumber = stackFrame.getLineNumber();
lineNumber--;
IRegion region= getLineInformation(textEditor, lineNumber);
if (region != null) {
textEditor.selectAndReveal(region.getOffset(), 0);
}
}
/* Get line region in source editor
* @param editor
* @param lineNumber
* @return
*/
protected IRegion getLineInformation(ITextEditor editor, int lineNumber) {
IDocumentProvider provider= editor.getDocumentProvider();
IEditorInput input= editor.getEditorInput();
try {
provider.connect(input);
} catch (CoreException e) {
return null;
}
try {
IDocument document= provider.getDocument(input);
if (document != null)
return document.getLineInformation(lineNumber);
} catch (BadLocationException e) {
} finally {
provider.disconnect(input);
}
return null;
}
// called by debug view - PDebugModelPresentation
/* Add annotation called from Debug View
* @param editorPart
* @param stackFrame
* @throws CoreException
*/
public void addAnnotation(IEditorPart editorPart, IPStackFrame stackFrame) throws CoreException {
IPStackFrame selectedFrame = stackFrame;
TaskSet tasks = getTasks(stackFrame.getDebugTarget());
if (tasks == null) {
throw new CoreException(Status.CANCEL_STATUS);
}
ITextEditor textEditor = getTextEditor(editorPart);
if (textEditor == null) {
throw new CoreException(Status.CANCEL_STATUS);
}
IFile file = getFile(textEditor.getEditorInput());
if (file == null) {
throw new CoreException(Status.CANCEL_STATUS);
}
//try to find the stack frame with line number
if (selectedFrame.getLineNumber() == 0) {
IStackFrame[] frames = selectedFrame.getThread().getStackFrames();
for (IStackFrame frame : frames) {
if (frame.getLineNumber() > 0) {
selectedFrame = (IPStackFrame)frame;
break;
}
}
}
if (selectedFrame.getLineNumber() > 0) {
String job_id = uiDebugManager.getCurrentJobId();
synchronized (LOCK) {
AnnotationGroup annotationGroup = getAnnotationGroup(job_id);
if (annotationGroup == null) {
annotationGroup = new AnnotationGroup();
putAnnotationGroup(job_id, annotationGroup);
}
removeAnnotation(annotationGroup, tasks);
addAnnotation(annotationGroup, textEditor, file, selectedFrame.getLineNumber(), tasks, (selectedFrame.getLevel() > 1) ? IPTPDebugUIConstants.REG_ANN_INSTR_POINTER_SECONDARY : IPTPDebugUIConstants.REG_ANN_INSTR_POINTER_CURRENT);
}
}
}
/**
* Get the source locator for this debug launch
*
* @param job_id id of debug job
* @return source locator or null if not found
*/
private PSourceLookupDirector getSourceLocator(String job_id) {
IPSession session = uiDebugManager.getDebugSession(job_id);
if (session != null) {
ISourceLocator locator = session.getLaunch().getSourceLocator();
if (locator instanceof PSourceLookupDirector) {
return (PSourceLookupDirector)locator;
}
}
return null;
}
private IPath getFilePath(String job_id, String filename) {
PSourceLookupDirector locator = getSourceLocator(job_id);
if (locator != null) {
Object object = locator.getSourceElement(filename);
if (object instanceof IFile) {
return ((IFile)object).getFullPath();
}
if (object instanceof LocalFileStorage) {
return ((LocalFileStorage)object).getFullPath();
}
if (object instanceof FileStorage) {
return ((FileStorage)object).getFullPath();
}
}
return new Path(filename);
}
// called by event
/*
* Add annotation called from debug event
*/
protected void addUnregisterAnnotation(String job_id, int level, String filename, int lineNumber, TaskSet tasks) throws CoreException {
if (tasks.isEmpty())
return;
IFile file = findFile(getFilePath(job_id, filename));
if (file == null)
throw new CoreException(Status.CANCEL_STATUS);
IEditorPart editorPart = getEditorPart(file);
if (editorPart == null)
throw new CoreException(Status.CANCEL_STATUS);
ITextEditor textEditor = getTextEditor(editorPart);
if (textEditor == null)
throw new CoreException(Status.CANCEL_STATUS);
synchronized (LOCK) {
AnnotationGroup annotationGroup = getAnnotationGroup(job_id);
if (annotationGroup == null) {
annotationGroup = new AnnotationGroup();
putAnnotationGroup(job_id, annotationGroup);
}
addAnnotation(annotationGroup, textEditor, file, lineNumber, tasks, ((level > 1)?IPTPDebugUIConstants.SET_ANN_INSTR_POINTER_CURRENT:((containsCurrentSet(tasks)) ? IPTPDebugUIConstants.CURSET_ANN_INSTR_POINTER_CURRENT : IPTPDebugUIConstants.SET_ANN_INSTR_POINTER_CURRENT)));
}
}
/**
* Add annotation given filename and line number
*
* @param job_id
* @param level
* @param filename
* @param lineNumber
* @param rTasks
* @param uTasks
* @throws CoreException
*/
protected void addAnnotation(String job_id, int level, String filename, int lineNumber, TaskSet rTasks, TaskSet uTasks) throws CoreException {
IFile file = findFile(getFilePath(job_id, filename));
if (file == null) {
throw new CoreException(Status.CANCEL_STATUS);
}
IEditorPart editorPart = getEditorPart(file);
if (editorPart == null) {
throw new CoreException(Status.CANCEL_STATUS);
}
ITextEditor textEditor = getTextEditor(editorPart);
if (textEditor == null) {
throw new CoreException(Status.CANCEL_STATUS);
}
synchronized (LOCK) {
AnnotationGroup annotationGroup = getAnnotationGroup(job_id);
if (annotationGroup == null) {
annotationGroup = new AnnotationGroup();
putAnnotationGroup(job_id, annotationGroup);
}
addAnnotation(annotationGroup, textEditor, file, lineNumber, rTasks, ((level > 1)?IPTPDebugUIConstants.REG_ANN_INSTR_POINTER_SECONDARY: IPTPDebugUIConstants.REG_ANN_INSTR_POINTER_CURRENT));
addAnnotation(annotationGroup, textEditor, file, lineNumber, uTasks, ((level > 1)?IPTPDebugUIConstants.SET_ANN_INSTR_POINTER_CURRENT:((containsCurrentSet(uTasks)) ? IPTPDebugUIConstants.CURSET_ANN_INSTR_POINTER_CURRENT : IPTPDebugUIConstants.SET_ANN_INSTR_POINTER_CURRENT)));
}
}
/* Is given tasks in the current set
* @param aTasks
* @return
*/
protected boolean containsCurrentSet(TaskSet aTasks) {
String set_id = uiDebugManager.getCurrentSetId();
if (set_id.equals(IElementHandler.SET_ROOT_ID))
return true;
try {
TaskSet tasks = uiDebugManager.getTasks(set_id);
return (tasks != null && tasks.intersects(aTasks));
}
catch (CoreException e) {
return false;
}
}
// generic
/* Add annotation
* @param annotationGroup
* @param textEditor
* @param file
* @param lineNumber
* @param tasks
* @param type
* @throws CoreException
*/
protected void addAnnotation(AnnotationGroup annotationGroup, final ITextEditor textEditor, final IFile file, final int lineNumber, final TaskSet tasks, final String type) throws CoreException {
if (!tasks.isEmpty()) {
IDocumentProvider docProvider = textEditor.getDocumentProvider();
IAnnotationModel annotationModel = docProvider.getAnnotationModel(textEditor.getEditorInput());
if (annotationModel == null)
throw new CoreException(Status.CANCEL_STATUS);
final Position position = createPosition(lineNumber, docProvider.getDocument(textEditor.getEditorInput()));
if (position == null)
throw new CoreException(Status.CANCEL_STATUS);
synchronized (LOCK) {
PInstructionPointerAnnotation2 annotation = findAnnotation(annotationGroup, position, type);
if (annotation == null) {
annotation = new PInstructionPointerAnnotation2(file, type, position, annotationModel);
annotationGroup.addAnnotation(annotation);
}
annotation.addTasks(tasks);
annotation.setMessage(isRegisterType(type));
}
Display.getDefault().asyncExec(new Runnable() {
public void run() {
textEditor.selectAndReveal(position.getOffset(), 0);
}
});
}
}
/* Find annotation
* @param annotationGroup
* @param position
* @param type
* @return
*/
protected PInstructionPointerAnnotation2 findAnnotation(AnnotationGroup annotationGroup, Position position, String type) {
synchronized (LOCK) {
for (PInstructionPointerAnnotation2 annotation : annotationGroup.getAnnotations()) {
if (annotation.getPosition().equals(position)) {
if (annotation.getType().equals(type)) {
return annotation;
}
}
}
return null;
}
}
// called by debug view
/* Remove annotation called from Debug View
* @param editorPart
* @param thread
* @throws CoreException
*/
protected void removeAnnotation(IEditorPart editorPart, IPThread thread) throws CoreException {
removeAnnotation(uiDebugManager.getCurrentJobId(), getTasks(thread));
}
// called by event
/* Remove annotation called from debug event
* @param job_id
* @param tasks
* @throws CoreException
*/
protected void removeAnnotation(String job_id, TaskSet tasks) throws CoreException {
if (tasks == null || tasks.isEmpty())
throw new CoreException(Status.CANCEL_STATUS);
synchronized (LOCK) {
AnnotationGroup annotationGroup = getAnnotationGroup(job_id);
if (annotationGroup != null) {
removeAnnotation(annotationGroup, tasks);
if (annotationGroup.isEmpty())
removeAnnotationGroup(job_id);
}
}
}
// generic
/* Remove annotation
* @param annotationGroup
* @param tasks
* @throws CoreException
*/
protected void removeAnnotation(AnnotationGroup annotationGroup, TaskSet tasks) throws CoreException {
synchronized (LOCK) {
List<PInstructionPointerAnnotation2> removedList = new ArrayList<PInstructionPointerAnnotation2>(0);
for (PInstructionPointerAnnotation2 annotation : annotationGroup.getAnnotations()) {
annotation.removeTasks(tasks);
if (annotation.isEmpty()) {
annotation.removeAnnotation();
removedList.add(annotation);
} else {
annotation.setMessage(isRegisterType(annotation.getType()));
}
}
annotationGroup.removeAnnotations(removedList);
}
}
/* Get iterator of stored annotations
* @param annotationGroup
* @param type
* @return
*/
public PInstructionPointerAnnotation2[] findAnnotations(AnnotationGroup annotationGroup, String type) {
synchronized (LOCK) {
List<PInstructionPointerAnnotation2> foundAnnotations = new ArrayList<PInstructionPointerAnnotation2>();
for (PInstructionPointerAnnotation2 annotation : annotationGroup.getAnnotations()) {
if (annotation.getType().equals(type)) {
foundAnnotations.add(annotation);
}
}
return foundAnnotations.toArray(new PInstructionPointerAnnotation2[0]);
}
}
protected PInstructionPointerAnnotation2[] findAnnotations(AnnotationGroup annotationGroup, TaskSet tasks) {
synchronized (LOCK) {
List<PInstructionPointerAnnotation2> foundAnnotations = new ArrayList<PInstructionPointerAnnotation2>();
if (tasks.isEmpty())
return new PInstructionPointerAnnotation2[0];
for (PInstructionPointerAnnotation2 annotation : annotationGroup.getAnnotations()) {
if (!annotation.isMarkDeleted() && annotation.contains(tasks)) {
if (!foundAnnotations.contains(annotation))
foundAnnotations.add(annotation);
}
}
return foundAnnotations.toArray(new PInstructionPointerAnnotation2[0]);
}
}
/* Find other annotation
* @param annotationGroup
* @param position
* @param isRegister
* @return
*/
protected PInstructionPointerAnnotation2 findOtherTypeAnnotation(AnnotationGroup annotationGroup, Position position, boolean isRegister) {
synchronized (LOCK) {
for (PInstructionPointerAnnotation2 annotation : annotationGroup.getAnnotations()) {
if (annotation.getPosition().equals(position)) {
String annotationType = annotation.getType();
if (isRegister) {
if (annotationType.equals(IPTPDebugUIConstants.CURSET_ANN_INSTR_POINTER_CURRENT) || annotationType.equals(IPTPDebugUIConstants.SET_ANN_INSTR_POINTER_CURRENT))
return annotation;
} else {
if (annotationType.equals(IPTPDebugUIConstants.REG_ANN_INSTR_POINTER_CURRENT) || annotationType.equals(IPTPDebugUIConstants.REG_ANN_INSTR_POINTER_SECONDARY))
return annotation;
}
}
}
return null;
}
}
/* Change annotation type
* @param annotation
* @param type
*/
protected void changeAnnotationType(PInstructionPointerAnnotation2 annotation, String type) {
if (!annotation.getType().equals(type)) {
annotation.setType(type);
}
}
protected void register(String job_id, TaskSet tasks) {
synchronized (LOCK) {
AnnotationGroup annotationGroup = getAnnotationGroup(job_id);
if (annotationGroup != null) {
for (PInstructionPointerAnnotation2 annotation : findAnnotations(annotationGroup, tasks)) {
TaskSet cpTasks = tasks.copy();
cpTasks.and(annotation.getTasks());
if (cpTasks.isEmpty())
continue;
updateExistedAnnotation(annotationGroup, annotation, cpTasks, false);
/*
boolean isRegister = isRegisterType(annotation.getType());
if (!isRegister)// unregister annotation
updateExistedAnnotation(annotationGroup, annotation, cpTasks, isRegister);
*/
}
}
}
}
protected void unregister(String job_id, TaskSet tasks) {
synchronized (LOCK) {
AnnotationGroup annotationGroup = getAnnotationGroup(job_id);
if (annotationGroup != null) {
for (PInstructionPointerAnnotation2 annotation : findAnnotations(annotationGroup, tasks)) {
TaskSet cpTasks = tasks.copy();
cpTasks.and(annotation.getTasks());
if (cpTasks.isEmpty())
continue;
updateExistedAnnotation(annotationGroup, annotation, cpTasks, true);
/*
boolean isRegister = isRegisterType(annotation.getType());
if (isRegister)// register annotation
updateExistedAnnotation(annotationGroup, annotation, cpTasks, isRegister);
*/
}
}
}
}
/* Remove tasks from existed annotation
* @param annotationGroup
* @param annotation
* @param tasks Tasks being removed
* @param isRegister
* @throws CoreException
*/
protected void updateExistedAnnotation(AnnotationGroup annotationGroup, PInstructionPointerAnnotation2 annotation, TaskSet tasks, boolean isRegister) {
synchronized (LOCK) {
IResource file = annotation.getMakerResource();
Position position = annotation.getPosition();
annotation.removeTasks(tasks);
if (annotation.isEmpty()) {
annotation.removeAnnotation();
annotationGroup.removeAnnotation(annotation);
}
else {
annotation.setMessage(isRegister);
}
PInstructionPointerAnnotation2 oAnnotation = findOtherTypeAnnotation(annotationGroup, position, isRegister);
if (oAnnotation != null) {
oAnnotation.addTasks(tasks);
oAnnotation.setMessage(!isRegister);
}
else {
//String type = isRegister ? ((containsCurrentSet(tasks) ? IPTPDebugUIConstants.CURSET_ANN_INSTR_POINTER_CURRENT : IPTPDebugUIConstants.SET_ANN_INSTR_POINTER_CURRENT)) : IPTPDebugUIConstants.REG_ANN_INSTR_POINTER_CURRENT;
String type = IPTPDebugUIConstants.CURSET_ANN_INSTR_POINTER_CURRENT;
oAnnotation = new PInstructionPointerAnnotation2(file, type, position, annotation.getAnnotationModel());
annotationGroup.addAnnotation(oAnnotation);
oAnnotation.addTasks(tasks);
oAnnotation.setMessage(!isRegister);
}
}
}
/***************************************************************************************************************************************************************************************************
* Set Change Event
**************************************************************************************************************************************************************************************************/
/* Update annotation
* @param currentSet current set
* @param preSet previous set
* @throws CoreException
*/
public void updateAnnotation(final IElementSet currentSet, final IElementSet preSet) {
WorkbenchJob uiJob = new WorkbenchJob(Messages.PAnnotationManager_3) {
public IStatus runInUIThread(IProgressMonitor monitor) {
AnnotationGroup annotationGroup = getAnnotationGroup(uiDebugManager.getCurrentJobId());
if (annotationGroup != null) {
try {
TaskSet tasks = uiDebugManager.getTasks(currentSet.getID());
synchronized (LOCK) {
for (PInstructionPointerAnnotation2 annotation : annotationGroup.getAnnotations()) {
// change icon for unregistered processes only if the set is changed
if (!isRegisterType(annotation.getType())) {
// if all the tasks in current is not match the unregistered tasks, display SET_ANN
// simply only display SET_ANN when the current set only contain registered tasks
if (currentSet.isRootSet())
changeAnnotationType(annotation, IPTPDebugUIConstants.CURSET_ANN_INSTR_POINTER_CURRENT);
else
changeAnnotationType(annotation, annotation.contains(tasks) ? IPTPDebugUIConstants.CURSET_ANN_INSTR_POINTER_CURRENT : IPTPDebugUIConstants.SET_ANN_INSTR_POINTER_CURRENT);
}
}
}
}
catch (CoreException e) {
return e.getStatus();
}
}
return Status.OK_STATUS;
}
};
uiJob.setSystem(true);
uiJob.setPriority(Job.INTERACTIVE);
uiJob.schedule();
}
/***************************************************************************************************************************************************************************************************
* Job Change Listener
**************************************************************************************************************************************************************************************************/
/* (non-Javadoc)
* @see org.eclipse.ptp.ui.listeners.IJobChangedListener#jobChangedEvent(int, java.lang.String, java.lang.String)
*/
public void jobChangedEvent(final int type, final String cur_job_id, final String pre_job_id) {
WorkbenchJob uiJob = new WorkbenchJob(Messages.PAnnotationManager_3) {
public IStatus runInUIThread(IProgressMonitor monitor) {
doJobChangedEvent(type, cur_job_id, pre_job_id, monitor);
monitor.done();
return Status.OK_STATUS;
}
};
uiJob.setSystem(true);
uiJob.setPriority(Job.INTERACTIVE);
uiJob.schedule();
}
private void doJobChangedEvent(int type, String cur_job_id, String pre_job_id, IProgressMonitor monitor) {
if (type == IJobChangedListener.REMOVED || (pre_job_id != null && !pre_job_id.equals(IElementManager.EMPTY_ID))) {
AnnotationGroup preAnnotationGroup = getAnnotationGroup(pre_job_id);
if (preAnnotationGroup != null) {
preAnnotationGroup.throwAllAnnotations();
}
}
if (cur_job_id != null) {
AnnotationGroup curAnnotationGroup = getAnnotationGroup(cur_job_id);
if (curAnnotationGroup != null) {
curAnnotationGroup.retrieveAllAnnontations();
}
}
}
/* (non-Javadoc)
* @see org.eclipse.ptp.debug.core.IPDebugEventListener#handleDebugEvent(org.eclipse.ptp.debug.core.events.IPDebugEvent)
*/
public void handleDebugEvent(final IPDebugEvent event) {
WorkbenchJob uiJob = new WorkbenchJob(Messages.PAnnotationManager_3) {
public IStatus runInUIThread(IProgressMonitor monitor) {
doHandleDebugEvent(event, monitor);
monitor.done();
return Status.OK_STATUS;
}
};
uiJob.setSystem(true);
uiJob.setPriority(Job.INTERACTIVE);
uiJob.schedule();
}
/**
* Process the debug event
*
* @param event
* @param monitor
*/
private void doHandleDebugEvent(IPDebugEvent event, IProgressMonitor monitor) {
IPDebugInfo info = event.getInfo();
IPJob job = info.getJob();
switch(event.getKind()) {
case IPDebugEvent.CREATE:
switch (event.getDetail()) {
case IPDebugEvent.REGISTER:
register(job.getID(), info.getAllTasks());
break;
case IPDebugEvent.BREAKPOINT:
break;
}
break;
case IPDebugEvent.TERMINATE:
switch (event.getDetail()) {
case IPDebugEvent.DEBUGGER:
removeAnnotationGroup(job.getID());
break;
case IPDebugEvent.REGISTER:
unregister(job.getID(), info.getAllTasks());
break;
case IPDebugEvent.BREAKPOINT:
break;
default:
removeAnnotationAction(job, info.getAllTasks());
break;
}
break;
case IPDebugEvent.RESUME:
removeAnnotationAction(job, info.getAllTasks());
break;
case IPDebugEvent.SUSPEND:
IPDebugSuspendInfo susInfo = (IPDebugSuspendInfo)info;
try {
addAnnotation(job, susInfo);
} catch (final CoreException e) {
PTPDebugUIPlugin.getDisplay().asyncExec(new Runnable() {
public void run() {
PTPDebugUIPlugin.errorDialog(Messages.PAnnotationManager_0, e);
}
});
}
break;
case IPDebugEvent.CHANGE:
break;
case IPDebugEvent.ERROR:
//removeAnnotationAction(job, info.getAllTasks());
break;
}
}
/**
* Add annotation for a suspend event
*
* @param job debug job
* @param info suspend event information
* @throws CoreException
*/
private void addAnnotation(IPJob job, IPDebugSuspendInfo info) throws CoreException {
int line = info.getLineNumber();
if (line == 0) {
//FIXME: this method is only for unreg tasks, reg tasks depends on selection on stack frame on debug view
addAnnotationWithSourceFound(job, info.getAllUnregisteredTasks(), info.getLevel()+1, info.getDepth());
}
else {
addAnnotation(job.getID(), info.getLevel(), info.getFilename(), line, info.getAllRegisteredTasks(), info.getAllUnregisteredTasks());
}
}
private void addAnnotationWithSourceFound(IPJob job, TaskSet tasks, int low, int high) throws CoreException {
if (tasks.isEmpty())
return;
IPSession session = uiDebugManager.getDebugSession(job);
if (session != null) {
if (!session.isReady())
return;
IPDIListStackFramesRequest request = session.getPDISession().getRequestFactory().getListStackFramesRequest(session.getPDISession(),
tasks, low, high);
try {
session.getPDISession().getEventRequestManager().addEventRequest(request);
Map<TaskSet, Object> map = request.getResultMap(tasks);
for (Iterator<TaskSet> i = map.keySet().iterator(); i.hasNext();) {
TaskSet sTasks = i.next();
Object value = map.get(sTasks);
if (value instanceof ProxyDebugStackFrame[]) {
ProxyDebugStackFrame[] frames = (ProxyDebugStackFrame[])value;
for (ProxyDebugStackFrame frame : frames) {
ProxyDebugLocator locator = frame.getLocator();
if (locator.getLineNumber() > 0) {
addUnregisterAnnotation(job.getID(), frame.getLevel(), locator.getFile(), locator.getLineNumber(), sTasks);
break;
}
}
}
}
}
catch (PDIException e) {
//throw new CoreException(new Status(IStatus.ERROR, PTPDebugUIPlugin.getUniqueIdentifier(), IStatus.ERROR, e.getMessage(), null));
}
}
}
private void removeAnnotationAction(IPJob job, TaskSet tasks) {
try {
removeAnnotation(job.getID(), tasks);
}
catch (final CoreException e) {
PTPDebugUIPlugin.getDisplay().asyncExec(new Runnable() {
public void run() {
PTPDebugUIPlugin.errorDialog(Messages.PAnnotationManager_0, e);
}
});
}
}
}