1 /*
   2  * Copyright (c) 2003, 2007, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  *
  23  */
  24 
  25 package sun.jvm.hotspot.tools.soql;
  26 
  27 import java.io.*;
  28 import java.util.*;
  29 import sun.jvm.hotspot.debugger.*;
  30 import sun.jvm.hotspot.oops.*;
  31 import sun.jvm.hotspot.runtime.*;
  32 import sun.jvm.hotspot.tools.*;
  33 import sun.jvm.hotspot.utilities.*;
  34 import sun.jvm.hotspot.utilities.soql.*;
  35 
  36 /**
  37   This is command line SOQL (Simple Object Query Language) interpreter.
  38 */
  39 
  40 public class SOQL extends Tool {
  41    public static void main(String[] args) {
  42       SOQL soql = new SOQL();
  43       soql.start(args);
  44       soql.stop();
  45    }
  46 
  47    protected SOQLEngine soqlEngine;
  48    protected BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
  49    protected PrintStream out       = System.out;
  50    static protected String prompt       = "soql> ";
  51    static protected String secondPrompt = "> ";
  52 
  53    public void run() {
  54       soqlEngine = SOQLEngine.getEngine();
  55       while (true) {
  56          try {
  57             out.print(prompt);
  58             String line = in.readLine();
  59             if (line == null) {
  60                return;
  61             }
  62             StringTokenizer st = new StringTokenizer(line);
  63             if (st.hasMoreTokens()) {
  64                String cmd = st.nextToken();
  65                if (cmd.equals("select")) {
  66                   handleSelect(line);
  67                } else if (cmd.equals("classes")) {
  68                   handleClasses(line);
  69                } else if (cmd.equals("class")) {
  70                   handleClass(line);
  71                } else if (cmd.equals("object")) {
  72                   handleObject(line);
  73                } else if (cmd.equals("quit")) {
  74                   out.println("Bye!");
  75                   return;
  76                } else if (cmd.equals("")) {
  77                   // do nothing ...
  78                } else {
  79                   handleUnknown(line);
  80                }
  81             }
  82          } catch (IOException e) {
  83             e.printStackTrace();
  84             return;
  85          }
  86       }
  87    }
  88 
  89    protected void handleSelect(String query) {
  90       StringBuffer buf = new StringBuffer(query);
  91       String tmp = null;
  92       while (true) {
  93          out.print(secondPrompt);
  94          try {
  95             tmp = in.readLine();
  96          } catch (IOException ioe) {
  97             break;
  98          }
  99          if (tmp.equals("") || tmp.equals("go"))
 100             break;
 101          buf.append('\n');
 102          buf.append(tmp);
 103       }
 104       query = buf.toString();
 105 
 106       try {
 107          soqlEngine.executeQuery(query,
 108                            new ObjectVisitor() {
 109                               public void visit(Object o) {
 110                                  if (o != null && o instanceof JSJavaObject) {
 111                                      String oopAddr = ((JSJavaObject)o).getOop().getHandle().toString();
 112                                      out.println(oopAddr);
 113                                  } else {
 114                                      out.println((o == null)? "null" : o.toString());
 115                                  }
 116                               }
 117                            });
 118       } catch (SOQLException se) {
 119          se.printStackTrace();
 120       }
 121    }
 122 
 123    protected void handleClasses(String line) {
 124       // just list all InstanceKlasses
 125       InstanceKlass[] klasses = SystemDictionaryHelper.getAllInstanceKlasses();
 126       for (int i = 0; i < klasses.length; i++) {
 127          out.print(klasses[i].getName().asString().replace('/', '.'));
 128          out.print(" @");
 129          out.println(klasses[i].getHandle());
 130       }
 131    }
 132 
 133    protected void handleClass(String line) {
 134       StringTokenizer st = new StringTokenizer(line);
 135       st.nextToken(); // ignore "class"
 136       if (st.hasMoreTokens()) {
 137          String className = st.nextToken();
 138          InstanceKlass klass = SystemDictionaryHelper.findInstanceKlass(className);
 139          if (klass == null) {
 140             out.println("class " + className + " not found");
 141          } else {
 142             // klass.iterate(new OopPrinter(out), true);
 143 
 144             // base class
 145             InstanceKlass base = (InstanceKlass) klass.getSuper();
 146             if (base != null) {
 147                out.println("super");
 148                out.print("\t");
 149                out.println(base.getName().asString().replace('/', '.'));
 150             }
 151 
 152             // list immediate fields only
 153             int numFields = klass.getJavaFieldsCount();
 154             ConstantPool cp = klass.getConstants();
 155             out.println("fields");
 156             if (numFields != 0) {
 157               for (int f = 0; f < numFields; f++){
 158                  Symbol f_name = klass.getFieldName(f);
 159                  Symbol f_sig  = klass.getFieldSignature(f);
 160                  StringBuffer sigBuf = new StringBuffer();
 161                  new SignatureConverter(f_sig, sigBuf).dispatchField();
 162                  out.print('\t');
 163                  out.print(sigBuf.toString().replace('/', '.'));
 164                  out.print(' ');
 165                  out.println(f_name.asString());
 166                }
 167             } else {
 168                out.println("\tno fields in this class");
 169             }
 170          }
 171       } else {
 172          out.println("usage: class <name of the class>");
 173       }
 174    }
 175 
 176    protected Oop getOopAtAddress(Address addr) {
 177       OopHandle oopHandle = addr.addOffsetToAsOopHandle(0);
 178       return VM.getVM().getObjectHeap().newOop(oopHandle);
 179    }
 180 
 181    protected void handleObject(String line) {
 182       StringTokenizer st = new StringTokenizer(line);
 183       st.nextToken(); // ignore "object"
 184       if (st.hasMoreTokens()) {
 185          String addrStr = st.nextToken();
 186          Address addr = null;
 187          Debugger dbg = VM.getVM().getDebugger();
 188          try {
 189             addr = dbg.parseAddress(addrStr);
 190          } catch (Exception e) {
 191             out.println("invalid address : " + e.getMessage());
 192             return;
 193          }
 194 
 195          Oop oop = null;
 196          try {
 197             oop = getOopAtAddress(addr);
 198          } catch (Exception e) {
 199             out.println("invalid object : " + e.getMessage());
 200          }
 201 
 202          if (oop != null) {
 203             oop.iterate(new OopPrinter(out), true);
 204          } else {
 205             out.println("null object!");
 206          }
 207       } else {
 208          out.println("usage: object <address>");
 209       }
 210    }
 211 
 212    protected void handleUnknown(String line) {
 213       out.println("Unknown command!");
 214    }
 215 }