package org.rubypeople.rdt.internal.debug.ui; import java.io.File; import java.util.Hashtable; import java.util.Map; import org.eclipse.core.resources.IFile; 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.debug.core.DebugException; import org.eclipse.debug.core.DebugPlugin; import org.eclipse.debug.core.model.IBreakpoint; import org.eclipse.debug.core.model.IValue; import org.eclipse.debug.internal.ui.DebugUIPlugin; import org.eclipse.debug.ui.DebugUITools; import org.eclipse.debug.ui.IDebugModelPresentation; import org.eclipse.debug.ui.IDebugUIConstants; import org.eclipse.debug.ui.IValueDetailListener; import org.eclipse.jface.resource.ImageDescriptor; import org.eclipse.jface.viewers.LabelProvider; import org.eclipse.swt.graphics.Image; import org.eclipse.ui.IEditorInput; import org.eclipse.ui.IFileEditorInput; import org.eclipse.ui.IWorkbenchWindow; import org.eclipse.ui.ide.IDE; import org.eclipse.ui.part.FileEditorInput; import org.rubypeople.rdt.debug.core.IRubyBreakpoint; import org.rubypeople.rdt.debug.core.IRubyLineBreakpoint; import org.rubypeople.rdt.debug.core.IRubyMethodBreakpoint; import org.rubypeople.rdt.debug.core.model.IEvaluationResult; import org.rubypeople.rdt.debug.core.model.IRubyExceptionBreakpoint; import org.rubypeople.rdt.debug.core.model.IRubyStackFrame; import org.rubypeople.rdt.debug.core.model.IRubyThread; import org.rubypeople.rdt.debug.core.model.IRubyValue; import org.rubypeople.rdt.debug.core.model.IRubyVariable; import org.rubypeople.rdt.internal.ui.rubyeditor.ExternalRubyFileEditorInput; import org.rubypeople.rdt.ui.RubyUI; import org.rubypeople.rdt.ui.viewsupport.ImageDescriptorRegistry; public class DebugModelPresentation extends LabelProvider implements IDebugModelPresentation { private static Map<ImageDescriptor, Image> imageCache = new Hashtable<ImageDescriptor, Image>(); private static ImageDescriptorRegistry fgDebugImageRegistry; private Boolean isShowTypes; public String getText(Object item) { if (item instanceof IRubyMethodBreakpoint) { IRubyMethodBreakpoint breakpoint = (IRubyMethodBreakpoint) item; try { return breakpoint.getTypeName() + "." + breakpoint.getMethodName(); } catch (CoreException e) { DebugUIPlugin.log(e); return "--"; } } if (item instanceof IRubyLineBreakpoint) { IRubyLineBreakpoint breakpoint = (IRubyLineBreakpoint) item; try { return breakpoint.getFileName() + ":" + breakpoint.getLineNumber(); } catch (CoreException e) { DebugUIPlugin.log(e); return "--"; } } if (item instanceof IRubyExceptionBreakpoint) { IRubyExceptionBreakpoint exceptionBreakpoint = (IRubyExceptionBreakpoint) item; try { String exceptionType = exceptionBreakpoint.getTypeName(); if (exceptionType == null || exceptionType.length() == 0) { return "No Catchpoint defined"; } else { return "Suspend on exception: " + exceptionType; } } catch (CoreException e) { RdtDebugUiPlugin.log(e); return "Unable to grab exception type name"; } } if (item instanceof IRubyVariable) { IRubyVariable variable = (IRubyVariable) item; try { if (isShowTypes == Boolean.TRUE) { return ((IRubyValue) variable.getValue()).getReferenceTypeName() + " " + variable.toString(); } } catch (DebugException e) { RdtDebugUiPlugin.log(e); } return variable.toString(); } return DebugUIPlugin.getDefaultLabelProvider().getText(item); } protected IBreakpoint getBreakpoint(IMarker marker) { return DebugPlugin.getDefault().getBreakpointManager().getBreakpoint(marker); } public void computeDetail(IValue value, IValueDetailListener listener) { String string = ""; try { IRubyStackFrame frame = RdtDebugUiPlugin.getEvaluationContextManager().getEvaluationContext( (IWorkbenchWindow) null); IRubyValue rubyValue = (IRubyValue) value; IRubyVariable var = rubyValue.getOwner(); String snippet = var.getName() + ".inspect"; IEvaluationResult result = frame.evaluate(snippet); try { if (result != null && result.getValue() != null) string = result.getValue().getValueString(); if (string != null && string.startsWith("\"") && string.endsWith("\"")) { string = string.substring(1, string.length() - 1); } } catch (DebugException e) { // ignore } } catch (Throwable t) { // ignore } listener.detailComputed(value, string); } public void setAttribute(String attribute, Object value) { if (attribute.equals(IDebugModelPresentation.DISPLAY_VARIABLE_TYPE_NAMES)) { this.isShowTypes = (Boolean) value; } } public String getEditorId(IEditorInput input, Object element) { if (input instanceof ExternalRubyFileEditorInput) { return RubyUI.ID_EXTERNAL_EDITOR; } else if (input instanceof IFileEditorInput) { IFileEditorInput fileInput = (IFileEditorInput) input; return IDE.getDefaultEditor(fileInput.getFile()).getId(); } return null; } public IEditorInput getEditorInput(Object element) { if (element instanceof IRubyLineBreakpoint) { IRubyLineBreakpoint bp = (IRubyLineBreakpoint) element; IResource resource = bp.getMarker().getResource(); // If resource is workspace root, that means its external. Try to resolve via filename if (resource.equals(ResourcesPlugin.getWorkspace().getRoot())) { try { String filename = bp.getFileName(); if (filename == null) return null; return new ExternalRubyFileEditorInput(new File(filename)); } catch (CoreException e) { RdtDebugUiPlugin.log(e); } } else { if (resource instanceof IFile) // resource should be a file, stick it in a FileEditorInput return new FileEditorInput((IFile) resource); } } return null; } private Image getImage(ImageDescriptor imageDescriptor) { Image image = (Image) imageCache.get(imageDescriptor); if (image == null) { image = imageDescriptor.createImage(); imageCache.put(imageDescriptor, image); } return image; } public Image getImage(Object item) { try { ImageDescriptor descriptor; if (item instanceof IMarker) { IBreakpoint bp = getBreakpoint((IMarker) item); if (bp != null && bp instanceof IRubyBreakpoint) { return getBreakpointImage((IRubyBreakpoint) bp); } } if (item instanceof IRubyBreakpoint) { return getBreakpointImage((IRubyBreakpoint) item); } else if (item instanceof IRubyThread) { IRubyThread thread = (IRubyThread) item; if (thread.isSuspended()) { descriptor = DebugUITools.getImageDescriptor(IDebugUIConstants.IMG_OBJS_THREAD_SUSPENDED); } else if (thread.isTerminated()) { descriptor = DebugUITools.getImageDescriptor(IDebugUIConstants.IMG_OBJS_THREAD_TERMINATED); } else { descriptor = DebugUITools.getImageDescriptor(IDebugUIConstants.IMG_OBJS_THREAD_RUNNING); } } else { descriptor = DebugUITools.getDefaultImageDescriptor(item); } return getImage(descriptor); } catch (Exception e) { // ignore } return null; } protected Image getBreakpointImage(IRubyBreakpoint breakpoint) throws CoreException { if (breakpoint instanceof IRubyExceptionBreakpoint) { return getExceptionBreakpointImage((IRubyExceptionBreakpoint) breakpoint); } // if (breakpoint instanceof IRubyLineBreakpoint // && BreakpointUtils.isRunToLineBreakpoint((IRubyLineBreakpoint) breakpoint)) // { // return null; // } return getRubyBreakpointImage(breakpoint); } protected Image getExceptionBreakpointImage(IRubyExceptionBreakpoint exception) throws CoreException { int flags = computeBreakpointAdornmentFlags(exception); RubyDebugImageDescriptor descriptor = null; if ((flags & RubyDebugImageDescriptor.ENABLED) == 0) { descriptor = new RubyDebugImageDescriptor(getImageDescriptor(RubyDebugImages.IMG_OBJS_EXCEPTION_DISABLED), flags); // } else if (exception.isChecked()) { // descriptor= new RubyDebugImageDescriptor(getImageDescriptor(RubyDebugImages.IMG_OBJS_EXCEPTION), flags); } else { descriptor = new RubyDebugImageDescriptor(getImageDescriptor(RubyDebugImages.IMG_OBJS_ERROR), flags); } return getDebugImageRegistry().get(descriptor); } protected Image getRubyBreakpointImage(IRubyBreakpoint breakpoint) throws CoreException { if (breakpoint instanceof IRubyMethodBreakpoint) { IRubyMethodBreakpoint mBreakpoint = (IRubyMethodBreakpoint) breakpoint; return getRubyMethodBreakpointImage(mBreakpoint); // } else if (breakpoint instanceof IJavaWatchpoint) { // IJavaWatchpoint watchpoint= (IJavaWatchpoint)breakpoint; // return getJavaWatchpointImage(watchpoint); // } else if (breakpoint instanceof IJavaMethodEntryBreakpoint) { // IJavaMethodEntryBreakpoint meBreakpoint = (IJavaMethodEntryBreakpoint)breakpoint; // return getJavaMethodEntryBreakpointImage(meBreakpoint); } else { int flags = computeBreakpointAdornmentFlags(breakpoint); RubyDebugImageDescriptor descriptor = null; if (breakpoint.isEnabled()) { descriptor = new RubyDebugImageDescriptor(DebugUITools .getImageDescriptor(IDebugUIConstants.IMG_OBJS_BREAKPOINT), flags); } else { descriptor = new RubyDebugImageDescriptor(DebugUITools .getImageDescriptor(IDebugUIConstants.IMG_OBJS_BREAKPOINT_DISABLED), flags); } return getDebugImageRegistry().get(descriptor); } } protected Image getRubyMethodBreakpointImage(IRubyMethodBreakpoint mBreakpoint) throws CoreException { int flags = computeBreakpointAdornmentFlags(mBreakpoint); RubyDebugImageDescriptor descriptor = null; if (mBreakpoint.isEnabled()) { descriptor = new RubyDebugImageDescriptor(DebugUITools .getImageDescriptor(IDebugUIConstants.IMG_OBJS_BREAKPOINT), flags); } else { descriptor = new RubyDebugImageDescriptor(DebugUITools .getImageDescriptor(IDebugUIConstants.IMG_OBJS_BREAKPOINT_DISABLED), flags); } return getDebugImageRegistry().get(descriptor); } protected static ImageDescriptorRegistry getDebugImageRegistry() { if (fgDebugImageRegistry == null) { fgDebugImageRegistry = RdtDebugUiPlugin.getImageDescriptorRegistry(); } return fgDebugImageRegistry; } /** * Returns the adornment flags for the given breakpoint. These flags are used to render appropriate overlay icons * for the breakpoint. */ private int computeBreakpointAdornmentFlags(IRubyBreakpoint breakpoint) { int flags = 0; try { if (breakpoint.isEnabled()) { flags |= RubyDebugImageDescriptor.ENABLED; } if (breakpoint.isInstalled()) { flags |= RubyDebugImageDescriptor.INSTALLED; } if (breakpoint instanceof IRubyLineBreakpoint) { if (((IRubyLineBreakpoint) breakpoint).isConditionEnabled()) { flags |= RubyDebugImageDescriptor.CONDITIONAL; } if (breakpoint instanceof IRubyMethodBreakpoint) { IRubyMethodBreakpoint mBreakpoint = (IRubyMethodBreakpoint) breakpoint; // if (mBreakpoint.isEntry()) { flags |= RubyDebugImageDescriptor.ENTRY; // } // if (mBreakpoint.isExit()) { // flags |= JDIImageDescriptor.EXIT; // } } // if (breakpoint instanceof IRubyMethodEntryBreakpoint) { // flags |= JDIImageDescriptor.ENTRY; // } } else if (breakpoint instanceof IRubyExceptionBreakpoint) { IRubyExceptionBreakpoint eBreakpoint = (IRubyExceptionBreakpoint) breakpoint; // if (eBreakpoint.isCaught()) { // flags |= JDIImageDescriptor.CAUGHT; // } // if (eBreakpoint.isUncaught()) { flags |= RubyDebugImageDescriptor.UNCAUGHT; // } // if (eBreakpoint.getExclusionFilters().length > 0 || eBreakpoint.getInclusionFilters().length > 0) { // flags |= JDIImageDescriptor.SCOPED; // } } } catch (CoreException e) { } return flags; } private ImageDescriptor getImageDescriptor(String key) { return RubyDebugImages.getImageDescriptor(key); } }