Package org.apache.kato.katoview.commands.infocommands

Source Code of org.apache.kato.katoview.commands.infocommands.InfoClassCommand$Datum

/*******************************************************************************
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*   http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
******************************************************************************/
package org.apache.kato.katoview.commands.infocommands;

import java.util.Map;
import java.util.HashMap;
import java.util.Stack;
import java.util.Iterator;

import javax.tools.diagnostics.image.CorruptData;
import javax.tools.diagnostics.image.CorruptDataException;
import javax.tools.diagnostics.image.Image;
import javax.tools.diagnostics.runtime.ManagedRuntime;
import javax.tools.diagnostics.runtime.java.JavaClass;
import javax.tools.diagnostics.runtime.java.JavaClassLoader;
import javax.tools.diagnostics.runtime.java.JavaHeap;
import javax.tools.diagnostics.runtime.java.JavaObject;
import javax.tools.diagnostics.runtime.java.JavaRuntime;

import org.apache.kato.katoview.Output;
import org.apache.kato.katoview.commands.Command;
import org.apache.kato.katoview.commands.helpers.ClassOutput;
import org.apache.kato.katoview.commands.helpers.Exceptions;
import org.apache.kato.katoview.commands.helpers.Utils;


public class InfoClassCommand extends Command{
 
  public InfoClassCommand(Output o){
    super(o, "class", "prints inheritance chain and other data for a given class",
        "parameters: none, class name\n\n" +
        "if no parameters are passed to \"info class\", it prints the " +
        "number of instances of each class and the total size of all " +
        "instances of each class as well as the total number of instances " +
        "of all classes and the total size of all objects.\n\n" +
        "if a class name is passed to \"info class\", it prints the " +
        "following information about that class:\n" +
        "  - name\n" +
        "  - ID\n" +
        "  - superclass ID\n" +
        "  - class loader ID\n" +
        "  - modifiers\n" +
        "  - number of instances and total size of instances\n" +
        "  - inheritance chain\n" +
        "  - fields with modifiers (and values for static fields)\n" +
        "  - methods with modifiers\n"
        );
    child_commands = null;
  }
 
  public void doCommand(Stack args, Image loadedImage, HashMap systemProperties){
    if (args.isEmpty())
    {
      printImageClasses(loadedImage);
     
      return;
    }

    String className = (String)args.pop();
   
    if (!args.isEmpty())
    {
      out.error("\"info class\" takes at most one parameter, which, if " +
          "specified, must be a class name");
      return;
    }
   
    printImageClass(loadedImage, className);
  }
 
  private void printImageClass(Image loadedImage, String className)
  {
    ManagedRuntime mr;
    Iterator itRuntime = Utils.getRuntimes(loadedImage);
    int count = 1;

    out.print("\n");
    while (itRuntime.hasNext()) {
      mr = (ManagedRuntime)itRuntime.next();
      if (mr instanceof JavaRuntime)
      {
        out.print("Runtime #" + count + ": \n\n");
       
        printRuntimeClass((JavaRuntime)mr, className);
      }
      count++;
    }
  }
 
  private void printRuntimeClass(JavaRuntime jr, String className)
  {
    JavaClass jc = Utils.getClassGivenName(className, jr, out);
   
    // if we couldn't find a class of that name, return; the passed in class name could
    //  still be an array type or it might not exist
    if (null == jc)
    {
      out.print("\t  could not find class with name \"" + className + "\"\n\n");
      return;
    }

    String spaces = "    ";
    String cdeInfo = "N/A (CorruptDataException occurred)";
    out.print("name = " + className);
    out.print(spaces);
    out.print("\n\n\t");
    out.print("ID = 0x" + Long.toHexString(jc.getID().getAddress()));
   
    String superClassInfo;
    try{
      JavaClass superClass = jc.getSuperclass();
      if (null == superClass) {
        superClassInfo = "<no superclass>";
      } else {
        superClassInfo = "0x" + Long.toHexString(superClass.getID().getAddress());
      }
    }catch (CorruptDataException dce){
      superClassInfo = cdeInfo;
    }
    out.print(spaces);
    out.print("superID = " + superClassInfo);
/*
* Omitting size of class because that might differ between instances (ie. arrays)
*
    sb.append(spaces);
    sb.append("instance size = " + datum.getSize());
*/
   
    String classLoaderInfo;
    try{
      JavaClassLoader jClassLoader = jc.getClassLoader();
      classLoaderInfo = "0x" + Long.toHexString(jClassLoader.getObject().getJavaClass().getID().getAddress());
    }catch (CorruptDataException cde){
      classLoaderInfo = cdeInfo;
    }
    out.print(spaces);
    out.print("\n\t");
    out.print("classLoader = " + classLoaderInfo);
   
    String modifiersInfo;
    try{
      int modifiers = jc.getModifiers();
      modifiersInfo = Utils.getModifierString(modifiers);
    }catch (CorruptDataException cde){
      modifiersInfo = cdeInfo;
    }
    out.print(spaces);
    out.print("modifers: " + modifiersInfo);
    out.print("\n\n");
   
    Map classMap = new HashMap();
    classMap.put(jc, new Datum());
    updateInstanceCount(jr, classMap);
    Datum d = (Datum)classMap.get(jc);
   
    out.print("\tnumber of instances:     " + d.getCount() + "\n");
    out.print("\ttotal size of instances: " + d.getSize() + " bytes");
   
    out.print("\n\n");
   
    printClassHierarchy(jc);
    out.print("\n");
    printFields(jc);
    out.print("\n");
    printMethods(jc);
  }

  private void printClassHierarchy(JavaClass jClass) {
    Stack stack = new Stack();
    while (null != jClass){
      try{
        stack.add(jClass.getName());
        jClass = jClass.getSuperclass();
      }catch(CorruptDataException cde){
        stack.add("N/A (CorruptDataException occurred)");
        break;
      }
    }
    printStack(stack);
  }
 
  private void printStack(Stack stack){
    out.print("Inheritance chain....\n\n");
    String tab = "\t";
    String spaces = "";
    while(stack.size() > 0){
      out.print(tab + spaces + (String)stack.pop() + "\n");
      spaces += "   ";
    }
  }
 
  private void printFields(JavaClass jClass) {
    out.print("Fields......\n\n");
    ClassOutput.printStaticFields(jClass, out);
    ClassOutput.printNonStaticFields(jClass, out);
  }
 
  private void printMethods(JavaClass jClass){
    out.print("Methods......\n\n");
    ClassOutput.printMethods(jClass.getDeclaredMethods().iterator(), out);
    out.print("\n");
  }
 
 
  // below methods are for "info class" (with no parameters)
 
  private void printImageClasses(Image loadedImage) {
    ManagedRuntime mr;
    Iterator itRuntime = Utils.getRuntimes(loadedImage);
    int count = 1;

    out.print("\n");
    while (itRuntime.hasNext()) {
      mr = (ManagedRuntime)itRuntime.next();
      if (mr instanceof JavaRuntime)
      {
        out.print("Runtime #" + count + ": \n\n");
       
        printRuntimeClasses((JavaRuntime)mr);
        out.print("\n\n");
      }
      count++;
    }
  }
 
  private void printRuntimeClasses(JavaRuntime jr) {
    Map javaClasses = new HashMap();
    Iterator itClassLoader = jr.getJavaClassLoaders().iterator();
   
    // create Map of all classes in this JavaRuntime's class loaders
    while (itClassLoader.hasNext()) {
      JavaClassLoader jcl = (JavaClassLoader)itClassLoader.next();
     
      // Check for any corrupt data for this classloader
      Iterator itCache = jcl.getCachedClasses().iterator();
      while (itCache.hasNext()) {
        Object next = itCache.next();
        if (next instanceof CorruptData){
          // Warn the user that the classloader data is corrupt
          try {
            long jclAddress = jcl.getObject().getID().getAddress();
            out.print("\t classloader ID: " + Utils.toHex(jclAddress) + " " + Exceptions.getCorruptDataExceptionString() + "\n");
          } catch (CorruptDataException e) {
            out.print("\t classloader ID: <unknown> " + Exceptions.getCorruptDataExceptionString() + "\n");
          }
          break;
        }
      }
     
      Iterator itClass = jcl.getDefinedClasses().iterator();
      while (itClass.hasNext()) {
        javaClasses.put((JavaClass)itClass.next(), new Datum());
      }
    }
   
    // update count of objects and sizes in Map of classes
    updateInstanceCount(jr, javaClasses);
   
    // print out results of object counting
    long objCount = 0;
    long totalSize = 0;
    Iterator itClass = javaClasses.keySet().iterator();
    if (itClass.hasNext()) {
      printClassListHeader();
    } else {
      out.print("\n\t No information found for loaded classes\n");
    }
    while (itClass.hasNext()) {
      JavaClass jc = (JavaClass)itClass.next();
      String className;
     
      try {
        className = jc.getName();
      } catch (CorruptDataException cde) {
        className = Exceptions.getCorruptDataExceptionString();
      }
      Datum d = (Datum)javaClasses.get(jc);
      totalSize += d.getSize();
      objCount += d.getCount();
      printOneClass(className, d);
    }
   
    out.print("\n");
    if ( objCount > 0) {
      out.print("\t Total number of objects: " + objCount + "\n");
      out.print("\t Total size of objects: " + totalSize + "\n");
    }
  }
 
  private void updateInstanceCount(JavaRuntime jr, Map javaClasses) {
    Iterator itHeap = jr.getHeaps().iterator();
    while (itHeap.hasNext()) {
      JavaHeap jh = (JavaHeap)itHeap.next();
      Iterator itObject = jh.getObjects().iterator();
      while (itObject.hasNext()) {
        Object next = itObject.next();
        // Check that this is a JavaObject (there may be CorruptData objects in the
        // JavaHeap, we don't attempt to count these as instances of known classes).
        if (next instanceof JavaObject) {
          JavaObject jo = (JavaObject)next;
          Datum d = null;
          JavaClass jc;
       
          try {
            jc = jo.getJavaClass();
          } catch (CorruptDataException cde) {
            jc = null;
          }
       
          if (null != jc) {
            long size;
         
            d = (Datum)javaClasses.get(jc);
            if (null == d) {
              d = new Datum();
              javaClasses.put(jc, d);
              // FIXME: the below is for debugging purposes
              //  this should not be needed when Kato reports array classes
              //  in the class loaders
/*              try {
                out.print("\"" + jo.getJavaClass().getName() + "\"\n");
              } catch (CorruptDataException cde) {
              out.print(Exceptions.getCorruptDataExceptionString() + "\n");
            }
*/
            }
            try {
              size = jo.getSize();
            } catch (CorruptDataException cde) {
              size = 0;
            }
            d.addToSize(size);
            d.incrementCount();
          } else // FIXME: DEBUG
            try {
              out.print(jo.getJavaClass().getName() + "\n");
            } catch (CorruptDataException cde) {
              out.print(Exceptions.getCorruptDataExceptionString() + "\n");
            }
          }
        }
      }
    }
  }

  private void printClassListHeader() {
    out.print("\t");
    out.print(Utils.prePadWithSpaces("instances", 16));
    out.print(Utils.prePadWithSpaces("total size", 16));
    out.print("  class name");
    out.print("\n");
  }

  private void printOneClass(String className, Datum datum){
    out.print("\t");
    out.print(Utils.prePadWithSpaces(String.valueOf(datum.getCount()), 16));
    out.print(Utils.prePadWithSpaces(String.valueOf(datum.getSize()), 16));
    out.print("  " + className);
    out.print("\n");
  }
 
/*
  private void printOneClass(String className, Datum datum){
    out.print("\t " + className + "\t" 
        + "has " + datum.getCount() + " instances "
        + "(total size = " + (long)datum.getSize()*datum.getCount() + ")"
        + "\n");
  }
*/
 
  public class Datum{
    private int count;
    private long size;
   
    public Datum(){
      this.count = 0;
      this.size = 0;
    }
   
    public int getCount(){
      return this.count;
    }
   
    public long getSize(){
      return this.size;
    }
   
    public void incrementCount(){
      this.count++;
    }
   
    public void addToSize(long sizeToAdd){
      this.size += sizeToAdd;
    }
  }
}
TOP

Related Classes of org.apache.kato.katoview.commands.infocommands.InfoClassCommand$Datum

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.