1 /*
   2  * Copyright (c) 2003, 2012, 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    public SOQL() {
  48       super();
  49    }
  50 
  51    public SOQL(JVMDebugger d) {
  52       super(d);
  53    }
  54 
  55    protected SOQLEngine soqlEngine;
  56    protected BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
  57    protected PrintStream out       = System.out;
  58    static protected String prompt       = "soql> ";
  59    static protected String secondPrompt = "> ";
  60 
  61    public void run() {
  62       soqlEngine = SOQLEngine.getEngine();
  63       while (true) {
  64          try {
  65             out.print(prompt);
  66             String line = in.readLine();
  67             if (line == null) {
  68                return;
  69             }
  70             StringTokenizer st = new StringTokenizer(line);
  71             if (st.hasMoreTokens()) {
  72                String cmd = st.nextToken();
  73                if (cmd.equals("select")) {
  74                   handleSelect(line);
  75                } else if (cmd.equals("classes")) {
  76                   handleClasses(line);
  77                } else if (cmd.equals("class")) {
  78                   handleClass(line);
  79                } else if (cmd.equals("object")) {
  80                   handleObject(line);
  81                } else if (cmd.equals("quit")) {
  82                   out.println("Bye!");
  83                   return;
  84                } else if (cmd.equals("")) {
  85                   // do nothing ...
  86                } else {
  87                   handleUnknown(line);
  88                }
  89             }
  90          } catch (IOException e) {
  91             e.printStackTrace();
  92             return;
  93          }
  94       }
  95    }
  96 
  97    protected void handleSelect(String query) {
  98       StringBuffer buf = new StringBuffer(query);
  99       String tmp = null;
 100       while (true) {
 101          out.print(secondPrompt);
 102          try {
 103             tmp = in.readLine();
 104          } catch (IOException ioe) {
 105             break;
 106          }
 107          if (tmp.equals("") || tmp.equals("go"))
 108             break;
 109          buf.append('\n');
 110          buf.append(tmp);
 111       }
 112       query = buf.toString();
 113 
 114       try {
 115          soqlEngine.executeQuery(query,
 116                            new ObjectVisitor() {
 117                               public void visit(Object o) {
 118                                  if (o != null && o instanceof JSJavaObject) {
 119                                      String oopAddr = ((JSJavaObject)o).getOop().getHandle().toString();
 120                                      out.println(oopAddr);
 121                                  } else {
 122                                      out.println((o == null)? "null" : o.toString());
 123                                  }
 124                               }
 125                            });
 126       } catch (SOQLException se) {
 127          se.printStackTrace();
 128       }
 129    }
 130 
 131    protected void handleClasses(String line) {
 132       // just list all InstanceKlasses
 133       InstanceKlass[] klasses = SystemDictionaryHelper.getAllInstanceKlasses();
 134       for (int i = 0; i < klasses.length; i++) {
 135          out.print(klasses[i].getName().asString().replace('/', '.'));
 136          out.print(" @");
 137          out.println(klasses[i].getAddress());
 138       }
 139    }
 140 
 141    protected void handleClass(String line) {
 142       StringTokenizer st = new StringTokenizer(line);
 143       st.nextToken(); // ignore "class"
 144       if (st.hasMoreTokens()) {
 145          String className = st.nextToken();
 146          InstanceKlass klass = SystemDictionaryHelper.findInstanceKlass(className);
 147          if (klass == null) {
 148             out.println("class " + className + " not found");
 149          } else {
 150             // klass.iterate(new OopPrinter(out), true);
 151 
 152             // base class
 153             InstanceKlass base = (InstanceKlass) klass.getSuper();
 154             if (base != null) {
 155                out.println("super");
 156                out.print("\t");
 157                out.println(base.getName().asString().replace('/', '.'));
 158             }
 159 
 160             // list immediate fields only
 161             U2Array fields = klass.getFields();
 162             int numFields = (int) fields.length();
 163             ConstantPool cp = klass.getConstants();
 164             out.println("fields");
 165             if (numFields != 0) {
 166               for (int f = 0; f < numFields; f++){
 167                  Symbol f_name = klass.getFieldName(f);
 168                  Symbol f_sig  = klass.getFieldSignature(f);
 169                  StringBuffer sigBuf = new StringBuffer();
 170                  new SignatureConverter(f_sig, sigBuf).dispatchField();
 171                  out.print('\t');
 172                  out.print(sigBuf.toString().replace('/', '.'));
 173                  out.print(' ');
 174                  out.println(f_name.asString());
 175                }
 176             } else {
 177                out.println("\tno fields in this class");
 178             }
 179          }
 180       } else {
 181          out.println("usage: class <name of the class>");
 182       }
 183    }
 184 
 185    protected Oop getOopAtAddress(Address addr) {
 186       OopHandle oopHandle = addr.addOffsetToAsOopHandle(0);
 187       return VM.getVM().getObjectHeap().newOop(oopHandle);
 188    }
 189 
 190    protected void handleObject(String line) {
 191       StringTokenizer st = new StringTokenizer(line);
 192       st.nextToken(); // ignore "object"
 193       if (st.hasMoreTokens()) {
 194          String addrStr = st.nextToken();
 195          Address addr = null;
 196          Debugger dbg = VM.getVM().getDebugger();
 197          try {
 198             addr = dbg.parseAddress(addrStr);
 199          } catch (Exception e) {
 200             out.println("invalid address : " + e.getMessage());
 201             return;
 202          }
 203 
 204          Oop oop = null;
 205          try {
 206             oop = getOopAtAddress(addr);
 207          } catch (Exception e) {
 208             out.println("invalid object : " + e.getMessage());
 209          }
 210 
 211          if (oop != null) {
 212             oop.iterate(new OopPrinter(out), true);
 213          } else {
 214             out.println("null object!");
 215          }
 216       } else {
 217          out.println("usage: object <address>");
 218       }
 219    }
 220 
 221    protected void handleUnknown(String line) {
 222       out.println("Unknown command!");
 223    }
 224 }