com.aptana.ide.debug.internal.ui.JSDebugModelPresentation.java Source code

Java tutorial

Introduction

Here is the source code for com.aptana.ide.debug.internal.ui.JSDebugModelPresentation.java

Source

/**
 * This file Copyright (c) 2005-2008 Aptana, Inc. This program is
 * dual-licensed under both the Aptana Public License and the GNU General
 * Public license. You may elect to use one or the other of these licenses.
 * 
 * This program is distributed in the hope that it will be useful, but
 * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
 * NONINFRINGEMENT. Redistribution, except as permitted by whichever of
 * the GPL or APL you select, is prohibited.
 *
 * 1. For the GPL license (GPL), you can redistribute and/or modify this
 * program under the terms of the GNU General Public License,
 * Version 3, as published by the Free Software Foundation.  You should
 * have received a copy of the GNU General Public License, Version 3 along
 * with this program; if not, write to the Free Software Foundation, Inc., 51
 * Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 * 
 * Aptana provides a special exception to allow redistribution of this file
 * with certain other free and open source software ("FOSS") code and certain additional terms
 * pursuant to Section 7 of the GPL. You may view the exception and these
 * terms on the web at http://www.aptana.com/legal/gpl/.
 * 
 * 2. For the Aptana Public License (APL), this program and the
 * accompanying materials are made available under the terms of the APL
 * v1.0 which accompanies this distribution, and is available at
 * http://www.aptana.com/legal/apl/.
 * 
 * You may view the GPL, Aptana's exception and additional terms, and the
 * APL in the file titled license.html at the root of the corresponding
 * plugin containing this source file.
 * 
 * Any modifications to this file must keep this entire header intact.
 */
package com.aptana.ide.debug.internal.ui;

import java.net.URI;

import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IMarker;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IWorkspaceRoot;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.jobs.Job;
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.IDebugTarget;
import org.eclipse.debug.core.model.ILineBreakpoint;
import org.eclipse.debug.core.model.IStackFrame;
import org.eclipse.debug.core.model.IThread;
import org.eclipse.debug.core.model.IValue;
import org.eclipse.debug.core.model.IVariable;
import org.eclipse.debug.ui.DebugUITools;
import org.eclipse.debug.ui.IDebugModelPresentation;
import org.eclipse.debug.ui.IValueDetailListener;
import org.eclipse.jface.viewers.LabelProvider;
import org.eclipse.swt.graphics.Image;
import org.eclipse.ui.IEditorInput;

import com.aptana.ide.core.IdeLog;
import com.aptana.ide.core.PathUtils;
import com.aptana.ide.core.StringUtils;
import com.aptana.ide.core.resources.IUniformResourceMarker;
import com.aptana.ide.debug.core.IDebugConstants;
import com.aptana.ide.debug.core.JSDebugPlugin;
import com.aptana.ide.debug.core.model.IJSDebugTarget;
import com.aptana.ide.debug.core.model.IJSExceptionBreakpoint;
import com.aptana.ide.debug.core.model.IJSImplicitBreakpoint;
import com.aptana.ide.debug.core.model.IJSLineBreakpoint;
import com.aptana.ide.debug.core.model.IJSScriptElement;
import com.aptana.ide.debug.core.model.IJSStackFrame;
import com.aptana.ide.debug.core.model.IJSVariable;
import com.aptana.ide.debug.core.model.IJSWatchpoint;
import com.aptana.ide.debug.core.model.ISourceLink;
import com.aptana.ide.debug.core.model.JSInspectExpression;
import com.aptana.ide.debug.internal.ui.util.SourceDisplayUtil;
import com.aptana.ide.debug.ui.DebugUiPlugin;

/**
 * @author Max Stepanov
 */
public class JSDebugModelPresentation extends LabelProvider implements IDebugModelPresentation {
    private boolean showTypes = false;

    /**
     * @see org.eclipse.debug.ui.IDebugModelPresentation#setAttribute(java.lang.String, java.lang.Object)
     */
    public void setAttribute(String attribute, Object value) {
        if (IDebugModelPresentation.DISPLAY_VARIABLE_TYPE_NAMES.equals(attribute)) {
            showTypes = ((Boolean) value).booleanValue();
        }
    }

    /**
     * @see org.eclipse.jface.viewers.ILabelProvider#getText(java.lang.Object)
     */
    public String getText(Object element) {
        try {
            if (element instanceof IStackFrame) {
                return getStackFrameText((IStackFrame) element);
            } else if (element instanceof IThread) {
                return getThreadText((IThread) element);
            } else if (element instanceof IBreakpoint) {
                return getBreakpointText((IBreakpoint) element);
                // } else if ( element instanceof IVariable ) {
                // return getVariableText((IVariable)element);
                // } else if ( element instanceof IValue ) {
                // return getValueText((IValue) element);
            } else if (element instanceof IJSScriptElement) {
                return getScriptElementText((IJSScriptElement) element);
            } else if (element instanceof ISourceLink) {
                return ((ISourceLink) element).getLocation();
            } else if (element instanceof IMarker) {
                IBreakpoint breakpoint = getBreakpoint((IMarker) element);
                if (breakpoint != null) {
                    return getBreakpointText(breakpoint);
                }
            }
        } catch (CoreException e) {
            IdeLog.logError(JSDebugPlugin.getDefault(), StringUtils.EMPTY, e);
        }
        return null;
    }

    /**
     * @see org.eclipse.jface.viewers.ILabelProvider#getImage(java.lang.Object)
     */
    public Image getImage(Object element) {
        try {
            if (element instanceof IVariable) {
                return getVariableImage((IVariable) element);
            } else if (element instanceof IBreakpoint) {
                return getBreakpointImage((IBreakpoint) element);
            } else if (element instanceof IJSScriptElement) {
                return getScriptElementImage((IJSScriptElement) element);
            } else if (element instanceof IMarker) {
                IBreakpoint breakpoint = getBreakpoint((IMarker) element);
                if (breakpoint != null) {
                    return getBreakpointImage(breakpoint);
                }
            } else if (element instanceof JSInspectExpression) {
                return DebugUIImages.get(DebugUIImages.IMG_OBJS_INSPECT);
            }
        } catch (CoreException e) {
            IdeLog.logError(JSDebugPlugin.getDefault(), StringUtils.EMPTY, e);
        }
        return super.getImage(element);
    }

    /**
     * getStackFrameText
     * 
     * @param frame
     * @return String
     * @throws DebugException
     */
    private String getStackFrameText(IStackFrame frame) throws DebugException {
        String fileName;
        if (frame instanceof IJSStackFrame) {
            fileName = ((IJSStackFrame) frame).getSourceFileName();
            IFile file = PathUtils.findWorkspaceFile(fileName);
            if (file != null) {
                fileName = file.getFullPath().lastSegment();
            }
        } else {
            fileName = Messages.JSDebugModelPresentation_line;
        }
        int line = frame.getLineNumber();
        return StringUtils.format("{0} [{1}:{2}]", //$NON-NLS-1$
                new String[] { frame.getName(), fileName,
                        line >= 0 ? Integer.toString(line) : Messages.JSDebugModelPresentation_notavailable });
    }

    /**
     * getThreadText
     * 
     * @param thread
     * @return String
     * @throws CoreException
     */
    private String getThreadText(IThread thread) throws CoreException {
        String stateString = null;
        if (thread.isTerminated()) {
            stateString = Messages.JSDebugModelPresentation_Terminated;
        } else if (thread.isSuspended()) {
            stateString = Messages.JSDebugModelPresentation_Suspended;
            IBreakpoint[] breakpoints = thread.getBreakpoints();
            if (breakpoints.length > 0) {
                IBreakpoint breakpoint = breakpoints[0];
                String fileName;
                String lineNumber;
                if (breakpoint instanceof IJSImplicitBreakpoint) {
                    IJSImplicitBreakpoint implicitBreakpoint = (IJSImplicitBreakpoint) breakpoint;
                    fileName = implicitBreakpoint.getFileName();
                    IFile file = PathUtils.findWorkspaceFile(fileName);
                    if (file != null) {
                        fileName = file.getFullPath().toString();
                    }

                    try {
                        lineNumber = Integer.toString(implicitBreakpoint.getLineNumber());
                    } catch (CoreException impossible) {
                        lineNumber = "-1"; //$NON-NLS-1$
                    }
                    String format = Messages.JSDebugModelPresentation_lineIn_0_1_2;
                    if (implicitBreakpoint.isDebuggerKeyword()) {
                        format = Messages.JSDebugModelPresentation_keywordAtLine_0_1_2;
                    } else if (implicitBreakpoint.isFirstLine()) {
                        format = Messages.JSDebugModelPresentation_atStartLine_0_1_2;
                    } else if (implicitBreakpoint.isException()) {
                        format = Messages.JSDebugModelPresentation_exceptionAtLine_0_1_2;
                    } else if (implicitBreakpoint.isWatchpoint()) {
                        format = Messages.JSDebugModelPresentation_watchpointAtLine_0_1_2;
                    }
                    stateString = StringUtils.format(format, new String[] { stateString, lineNumber, fileName });
                } else {
                    IMarker marker = breakpoint.getMarker();
                    if (marker instanceof IUniformResourceMarker) {
                        fileName = PathUtils.getPath(((IUniformResourceMarker) marker).getUniformResource());
                    } else if (marker.getResource() instanceof IWorkspaceRoot) {
                        URI uri = URI.create((String) marker.getAttribute(IDebugConstants.BREAKPOINT_LOCATION));
                        if ("file".equals(uri.getScheme())) { //$NON-NLS-1$
                            fileName = PathUtils.getPath(uri);
                            IFile file = PathUtils.findWorkspaceFile(fileName);
                            if (file != null) {
                                fileName = file.getFullPath().toString();
                            }
                        } else {
                            fileName = uri.toString();
                        }
                    } else {
                        fileName = marker.getResource().getFullPath().toString();
                    }
                    lineNumber = Integer.toString(marker.getAttribute(IMarker.LINE_NUMBER, -1));
                    if (breakpoint instanceof IJSLineBreakpoint && ((IJSLineBreakpoint) breakpoint).isRunToLine()) {
                        stateString = StringUtils.format(Messages.JSDebugModelPresentation_runToLine_0_1_2,
                                new String[] { stateString, lineNumber, fileName });
                    } else {
                        stateString = StringUtils.format(Messages.JSDebugModelPresentation_breakpointAtLine_0_1_2,
                                new String[] { stateString, lineNumber, fileName });
                    }
                }
            }
        } else if (thread.isStepping()) {
            stateString = Messages.JSDebugModelPresentation_Stepping;
        } else {
            stateString = Messages.JSDebugModelPresentation_Running;
        }
        if (stateString != null) {
            return StringUtils.format("{0} ({1})", new String[] { thread.getName(), stateString }); //$NON-NLS-1$
        }
        return thread.getName();
    }

    /**
     * getBreakpointText
     * 
     * @param breakpoint
     * @return String
     * @throws CoreException
     */
    private String getBreakpointText(IBreakpoint breakpoint) throws CoreException {
        if (breakpoint instanceof IJSExceptionBreakpoint) {
            return getExceptionBreakpointText((IJSExceptionBreakpoint) breakpoint);
        }
        if (breakpoint instanceof IJSWatchpoint) {
            return getWatchpointText((IJSWatchpoint) breakpoint);
        }

        StringBuffer label = new StringBuffer();
        IMarker marker = breakpoint.getMarker();
        if (marker instanceof IUniformResourceMarker) {
            label.append(PathUtils.getPath(((IUniformResourceMarker) marker).getUniformResource()));
        } else {
            IResource resource = marker.getResource();
            if (resource != null) {
                label.append(resource.getFullPath().toString());
            }
        }
        if (breakpoint instanceof ILineBreakpoint) {
            try {
                int lineNumber = ((ILineBreakpoint) breakpoint).getLineNumber();
                label.append(StringUtils.format(" [{0}: {1}]", //$NON-NLS-1$
                        new String[] { Messages.JSDebugModelPresentation_line, Integer.toString(lineNumber) }));
            } catch (CoreException e) {
            }
        }
        return label.toString();
    }

    /**
     * getBreakpointImage
     * 
     * @param breakpoint
     * @return Image
     * @throws CoreException
     */
    private Image getBreakpointImage(IBreakpoint breakpoint) throws CoreException {
        if (breakpoint instanceof IJSExceptionBreakpoint) {
            return DebugUIImages.get(DebugUIImages.IMG_OBJS_JSEXCEPTION);
        } else if (breakpoint instanceof IJSWatchpoint) {
            return DebugUIImages.get(DebugUIImages.IMG_OBJS_JSWATCHPOINT);
        } else {
            int flags = computeBreakpointAdornmentFlags(breakpoint);
            JSDebugImageDescriptor descriptor = null;
            if (breakpoint.isEnabled()) {
                descriptor = new JSDebugImageDescriptor(
                        DebugUITools.getImageDescriptor(org.eclipse.debug.ui.IDebugUIConstants.IMG_OBJS_BREAKPOINT),
                        flags);
            } else {
                descriptor = new JSDebugImageDescriptor(DebugUITools.getImageDescriptor(
                        org.eclipse.debug.ui.IDebugUIConstants.IMG_OBJS_BREAKPOINT_DISABLED), flags);
            }
            return DebugUIImages.getImageDescriptorRegistry().get(descriptor);
        }
    }

    /**
     * computeBreakpointAdornmentFlags
     * 
     * @param breakpoint
     * @return int
     */
    private int computeBreakpointAdornmentFlags(IBreakpoint breakpoint) {
        int flags = 0;
        try {
            if (breakpoint.isEnabled()) {
                flags |= JSDebugImageDescriptor.ENABLED;
            }
            if (breakpoint instanceof IJSLineBreakpoint) {
                if (((IJSLineBreakpoint) breakpoint).isConditionEnabled()
                        || ((IJSLineBreakpoint) breakpoint).getHitCount() > 0) {
                    flags |= JSDebugImageDescriptor.CONDITIONAL;
                }
            }
        } catch (CoreException e) {
            IdeLog.logError(DebugUiPlugin.getDefault(), StringUtils.EMPTY, e);
        }
        return flags;
    }

    /**
     * getExceptionBreakpointText
     * 
     * @param breakpoint
     * @return String
     * @throws CoreException
     */
    private String getExceptionBreakpointText(IJSExceptionBreakpoint breakpoint) throws CoreException {
        return StringUtils.format(Messages.JSDebugModelPresentation_Exception,
                new String[] { breakpoint.getExceptionTypeName() });
    }

    /**
     * getWatchpointText
     * 
     * @param watchpoint
     * @return String
     * @throws CoreException
     */
    private String getWatchpointText(IJSWatchpoint watchpoint) throws CoreException {
        return StringUtils.format("{0}", new String[] { watchpoint.getVariableName() }); //$NON-NLS-1$
    }

    /**
     * getScriptElementText
     * 
     * @param scriptElement
     * @return String
     * @throws CoreException
     */
    private String getScriptElementText(IJSScriptElement scriptElement) throws CoreException {
        if (scriptElement.getParent() == null) {
            return scriptElement.getName();
        }
        return StringUtils.format("{0}()", new String[] { scriptElement.getName() }); //$NON-NLS-1$
    }

    /**
     * getScriptElementImage
     * 
     * @param scriptElement
     * @return Image
     */
    private Image getScriptElementImage(IJSScriptElement scriptElement) {
        if (scriptElement.getParent() == null) {
            return DebugUIImages.get(DebugUIImages.IMG_OBJS_TOP_SCRIPT_ELEMENT);
        }
        return DebugUIImages.get(DebugUIImages.IMG_OBJS_SCRIPT_ELEMENT);
    }

    /**
     * @see org.eclipse.debug.ui.IDebugModelPresentation#computeDetail(org.eclipse.debug.core.model.IValue,
     *      org.eclipse.debug.ui.IValueDetailListener)
     */
    public void computeDetail(IValue value, IValueDetailListener listener) {
        IDebugTarget target = value.getDebugTarget();
        if (target.isSuspended() && target instanceof IJSDebugTarget) {
            Job job = new DetailsJob(value, listener);
            job.schedule();
            return;
        }
        String details = StringUtils.EMPTY;
        try {
            details = value.getValueString();
        } catch (DebugException e) {
            IdeLog.logError(DebugUiPlugin.getDefault(), StringUtils.EMPTY, e);
        }
        listener.detailComputed(value, details);
    }

    /**
     * @see org.eclipse.debug.ui.ISourcePresentation#getEditorInput(java.lang.Object)
     */
    public IEditorInput getEditorInput(Object element) {
        return SourceDisplayUtil.getEditorInput(element);
    }

    /**
     * @see org.eclipse.debug.ui.ISourcePresentation#getEditorId(org.eclipse.ui.IEditorInput, java.lang.Object)
     */
    public String getEditorId(IEditorInput input, Object element) {
        return SourceDisplayUtil.getEditorId(input, element);
    }

    /**
     * getVariableText
     * 
     * @param variable
     * @return String
     */
    public String getVariableText(IVariable variable) {
        String varLabel = Messages.JSDebugModelPresentation_UnknownName;
        try {
            varLabel = variable.getName();
        } catch (DebugException e) {
        }
        String typeName = Messages.JSDebugModelPresentation_UnknownType;
        try {
            typeName = variable.getReferenceTypeName();
        } catch (DebugException e) {
        }
        IValue value = null;
        try {
            value = variable.getValue();
        } catch (DebugException e) {
        }
        String valueString = Messages.JSDebugModelPresentation_UnknownValue;
        if (value != null) {
            try {
                valueString = getValueText(value);
            } catch (DebugException e) {
            }
        }

        StringBuffer sb = new StringBuffer();
        if (showTypes) {
            sb.append(typeName).append(' ');
        }

        sb.append(varLabel);

        if (valueString.length() != 0) {
            sb.append("= "); //$NON-NLS-1$
            sb.append(valueString);
        }
        return sb.toString();
    }

    /**
     * getValueText
     * 
     * @param value
     * @return String
     * @throws DebugException
     */
    protected String getValueText(IValue value) throws DebugException {
        String valueString = value.getValueString();
        return valueString;
    }

    /**
     * getVariableImage
     * 
     * @param variable
     * @return Image
     * @throws DebugException
     */
    protected Image getVariableImage(IVariable variable) throws DebugException {
        if (variable instanceof IJSVariable) {
            IJSVariable jsVar = (IJSVariable) variable;
            if (jsVar.isException()) {
                return DebugUIImages.get(DebugUIImages.IMG_OBJS_EXCEPTION_VARIABLE);
            }
            if (jsVar.isLocal()) {
                return DebugUIImages.get(DebugUIImages.IMG_OBJS_LOCAL_VARIABLE);
            }
            if (jsVar.isTopLevel()) {
                return DebugUIImages.get(DebugUIImages.IMG_OBJS_VARIABLE);
            }
            if (jsVar.isConst()) {
                return DebugUIImages.get(DebugUIImages.IMG_OBJS_CONSTANT_FIELD);
            }
            return DebugUIImages.get(DebugUIImages.IMG_OBJS_FIELD);
        }
        return null;
    }

    /**
     * getBreakpoint
     * 
     * @param marker
     * @return IBreakpoint
     */
    private IBreakpoint getBreakpoint(IMarker marker) {
        return DebugPlugin.getDefault().getBreakpointManager().getBreakpoint(marker);
    }

    /**
     * Details evaluation job
     */
    private final class DetailsJob extends Job {

        private IValue value;
        private IValueDetailListener listener;

        /**
         * DetailsJob
         * 
         * @param value
         * @param listener
         */
        public DetailsJob(IValue value, IValueDetailListener listener) {
            super(Messages.JSDebugModelPresentation_DetailsComputing);
            setSystem(true);
            this.value = value;
            this.listener = listener;
        }

        protected IStatus run(IProgressMonitor monitor) {
            IJSDebugTarget target = (IJSDebugTarget) value.getDebugTarget();
            String details = StringUtils.EMPTY;
            try {
                details = target.computeValueDetails(value);
            } catch (DebugException e) {
                IdeLog.logError(DebugUiPlugin.getDefault(), StringUtils.EMPTY, e);
            }
            listener.detailComputed(value, details);
            return Status.OK_STATUS;
        }
    }
}