Package org.eclim.plugin.jdt.command.debug.ui

Source Code of org.eclim.plugin.jdt.command.debug.ui.ThreadView

/**
* Copyright (C) 2014  Eric Van Dewoestine
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/
package org.eclim.plugin.jdt.command.debug.ui;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import org.eclim.plugin.jdt.command.debug.context.ThreadContext;

import org.eclipse.debug.core.DebugException;

import org.eclipse.debug.core.model.IStackFrame;

import org.eclipse.jdt.debug.core.IJavaStackFrame;
import org.eclipse.jdt.debug.core.IJavaThread;

/**
* UI model for displaying threads.
*
* <p>
* The formatting code is borrowed from Eclipse JDT UI.
* @see org.eclipse.jdt.internal.debug.ui.JDIModelPresentation
*/
public class ThreadView
{
  // Thread status
  private static final String RUNNING = "Running";
  private static final String SUSPENDED = "Suspended";

  private static final String SUSPENDED_THREAD_PREFIX =
    ViewUtils.NON_LEAF_NODE_INDENT +
    ViewUtils.EXPANDED_NODE_SYMBOL;

  private static final String RUNNING_THREAD_PREFIX =
    ViewUtils.LEAF_NODE_INDENT +
    ViewUtils.LEAF_NODE_SYMBOL;

  private static final String STACK_FRAME_PREFIX =
    ViewUtils.LEAF_NODE_INDENT +
    ViewUtils.LEAF_NODE_INDENT +
    ViewUtils.LEAF_NODE_SYMBOL;

  private ThreadContext threadCtx;

  public ThreadView(ThreadContext threadCtx)
  {
    this.threadCtx = threadCtx;
  }

  public List<String> get()
    throws DebugException
  {
    List<String> results = new ArrayList<String>();
    for (IJavaThread thread : threadCtx.getThreads()) {
      getThreadText(thread, results);
    }
    return results;
  }

  public List<String> get(IJavaThread thread)
    throws DebugException
  {
    List<String> results = new ArrayList<String>();
    getThreadText(thread, results);
    return results;
  }

  private void getThreadText(IJavaThread thread, List<String> results)
    throws DebugException
  {
    long threadId = thread.getThreadObject().getUniqueId();
    String threadName = thread.getName();

    String prefix = null;
    String status = null;
    if (thread.isSuspended()) {
      prefix = SUSPENDED_THREAD_PREFIX;
      status = SUSPENDED;
    } else {
      prefix = RUNNING_THREAD_PREFIX;
      status = RUNNING;
    }

    results.add(prefix + "Thread-" + threadName +
        " (id=" + threadId  + ") : " +
        " (" + status  + ")");

    IStackFrame[] stackFrames = thread.getStackFrames();
    if (stackFrames != null) {
      // Protect against invalid stack frame. When debug session is resumed,
      // all threads are resumed first. Then notification is sent for each
      // thread. While processing for one thread, we might end up using old
      // stack frames for some other thread, that are no longer valid.
      // This should not happen normally since we have a handler for debug
      // target itself, but this is being defensive.
      try {
        for (IStackFrame stackFrame : stackFrames) {
          results.add(getStackFrameText(stackFrame));
        }
      } catch (DebugException e) {}
    }
  }

  private String getStackFrameText(IStackFrame stackFrame)
    throws DebugException
  {
    StringBuilder result = new StringBuilder();
    result.append(STACK_FRAME_PREFIX);

    IJavaStackFrame frame = (IJavaStackFrame) stackFrame.getAdapter(
        IJavaStackFrame.class);
    if (frame != null) {
      String dec = frame.getDeclaringTypeName();

      if (frame.isObsolete()) {
        result.append(dec);
        result.append('>');
        return result.toString();
      }

      boolean javaStratum = true;
      javaStratum = frame.getReferenceType().getDefaultStratum().equals("Java");

      if (javaStratum) {
        // receiver name
        String rec = frame.getReceivingTypeName();
        result.append(ViewUtils.getQualifiedName(rec));

        // append declaring type name if different
        if (!dec.equals(rec)) {
          result.append('(');
          result.append(ViewUtils.getQualifiedName(dec));
          result.append(')');
        }
        // append a dot separator and method name
        result.append('.');
        result.append(frame.getMethodName());
        List<String> args = frame.getArgumentTypeNames();
        if (args.isEmpty()) {
          result.append("()");
        } else {
          result.append('(');
          Iterator<String> iter = args.iterator();
          while (iter.hasNext()) {
            result.append(ViewUtils.getQualifiedName(iter.next()));
            if (iter.hasNext()) {
              result.append(", ");
            } else if (frame.isVarArgs()) {
              result.replace(result.length() - 2, result.length(), "...");
            }
          }
          result.append(')');
        }
      } else {
        result.append(frame.getSourcePath());
      }

      int lineNumber = frame.getLineNumber();
      result.append(' ');
      result.append(' ');
      if (lineNumber >= 0) {
        result.append(lineNumber);
      } else {
        if (frame.isNative()) {
          result.append(' ');
        }
      }

      if (!frame.wereLocalsAvailable()) {
        result.append(' ');
      }

      return result.toString();

    }
    return null;
  }
}
TOP

Related Classes of org.eclim.plugin.jdt.command.debug.ui.ThreadView

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.