comparison agent/src/share/classes/sun/jvm/hotspot/utilities/soql/SOQLEngine.java @ 0:a61af66fc99e jdk7-b24

Initial load
author duke
date Sat, 01 Dec 2007 00:00:00 +0000
parents
children c18cbe5936b8
comparison
equal deleted inserted replaced
-1:000000000000 0:a61af66fc99e
1 /*
2 * Copyright 2003-2007 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
20 * CA 95054 USA or visit www.sun.com if you need additional information or
21 * have any questions.
22 *
23 */
24
25 package sun.jvm.hotspot.utilities.soql;
26
27 import java.util.*;
28 import sun.jvm.hotspot.oops.*;
29 import sun.jvm.hotspot.memory.*;
30 import sun.jvm.hotspot.runtime.*;
31 import sun.jvm.hotspot.utilities.*;
32
33 /**
34 * This is SOQL (Simple Object Query Language) engine. This
35 * uses JavaScript engine for the "select" and "where" expression
36 * parts.
37 */
38 public class SOQLEngine extends JSJavaScriptEngine {
39 public static synchronized SOQLEngine getEngine() {
40 if (soleInstance == null) {
41 soleInstance = new SOQLEngine();
42 }
43 return soleInstance;
44 }
45
46 /**
47 Query is of the form
48
49 select <java script code to select>
50 [ from [instanceof] <class name> [<identifier>]
51 [ where <java script boolean expression> ]
52 ]
53 */
54 public synchronized void executeQuery(String query, ObjectVisitor visitor)
55 throws SOQLException {
56 debugPrint("query : " + query);
57 StringTokenizer st = new StringTokenizer(query);
58 if (st.hasMoreTokens()) {
59 String first = st.nextToken();
60 if (! first.equals("select") ) {
61 throw new SOQLException("query syntax error: no 'select' clause");
62 }
63 } else {
64 throw new SOQLException("query syntax error: no 'select' clause");
65 }
66
67 int selectStart = query.indexOf("select");
68 int fromStart = query.indexOf("from");
69
70 String selectExpr = null;
71 String className = null;
72 boolean isInstanceOf = false;
73 String whereExpr = null;
74 String identifier = null;
75
76 if (fromStart != -1) {
77 selectExpr = query.substring(selectStart + "select".length(), fromStart);
78 st = new StringTokenizer(query.substring(fromStart + "from".length()));
79
80 if (st.hasMoreTokens()) {
81 String tmp = st.nextToken();
82 if (tmp.equals("instanceof")) {
83 isInstanceOf = true;
84 if (! st.hasMoreTokens()) {
85 throw new SOQLException("no class name after 'instanceof'");
86 }
87 className = st.nextToken();
88 } else {
89 className = tmp;
90 }
91 } else {
92 throw new SOQLException("query syntax error: class name must follow 'from'");
93 }
94
95 if (st.hasMoreTokens()) {
96 identifier = st.nextToken();
97 if (identifier.equals("where")) {
98 throw new SOQLException("query syntax error: identifier should follow class name");
99 }
100 if (st.hasMoreTokens()) {
101 String tmp = st.nextToken();
102 if (! tmp.equals("where")) {
103 throw new SOQLException("query syntax error: 'where' clause expected after 'from' clause");
104 }
105 int whereEnd = query.lastIndexOf("where") + 5; // "where".length
106 whereExpr = query.substring(whereEnd);
107 }
108 } else {
109 throw new SOQLException("query syntax error: identifier should follow class name");
110 }
111 } else { // no from clause
112 selectExpr = query.substring(selectStart + "select".length(), query.length());
113 }
114
115 executeQuery(new SOQLQuery(selectExpr, isInstanceOf, className, identifier, whereExpr), visitor);
116 }
117
118 private void executeQuery(SOQLQuery q, ObjectVisitor visitor) throws SOQLException {
119 InstanceKlass kls = null;
120 if (q.className != null) {
121 kls = SystemDictionaryHelper.findInstanceKlass(q.className);
122 if (kls == null) {
123 throw new SOQLException(q.className + " is not found!");
124 }
125 }
126
127
128 StringBuffer buf = new StringBuffer();
129 buf.append("function result(");
130 if (q.identifier != null) {
131 buf.append(q.identifier);
132 }
133 buf.append(") { return ");
134 buf.append(q.selectExpr.replace('\n', ' '));
135 buf.append("; }");
136
137 String selectCode = buf.toString();
138 debugPrint(selectCode);
139 String whereCode = null;
140 if (q.whereExpr != null) {
141 buf = new StringBuffer();
142 buf.append("function filter(");
143 buf.append(q.identifier);
144 buf.append(") { return ");
145 buf.append(q.whereExpr.replace('\n', ' '));
146 buf.append("; }");
147 whereCode = buf.toString();
148 debugPrint(whereCode);
149 } else {
150 whereCode = "filter = null;";
151 }
152
153 beginQuery();
154 // compile select expression and where condition
155 evalString(selectCode, "", 1);
156 evalString(whereCode, "", 1);
157
158 // iterate thru heap, if needed
159 if (q.className != null) {
160 try {
161 iterateOops(kls, visitor, q.isInstanceOf);
162 } finally {
163 endQuery();
164 }
165 } else {
166 // simple "select <expr>" query
167 try {
168 Object select = call("result", new Object[] {});
169 visitor.visit(select);
170 } catch (Exception e) {
171 e.printStackTrace();
172 }
173 }
174 }
175
176 private void dispatchObject(Oop oop, ObjectVisitor visitor, boolean filterExists) {
177 JSJavaObject jsObj = factory.newJSJavaObject(oop);
178 Object[] args = new Object[] { jsObj };
179 boolean b = true;
180
181 try {
182 if (filterExists) {
183 Object res = call("filter", args);
184 if (res instanceof Boolean) {
185 b = ((Boolean)res).booleanValue();
186 } else if (res instanceof Number) {
187 b = ((Number)res).intValue() != 0;
188 } else {
189 b = (res != null);
190 }
191 }
192
193 if (b) {
194 Object select = call("result", args);
195 visitor.visit(select);
196 }
197 } catch (Exception e) {
198 throw new RuntimeException(e);
199 }
200 }
201
202 private void iterateOops(final InstanceKlass ik, final ObjectVisitor visitor,
203 boolean includeSubtypes) {
204 ObjectHeap oh = VM.getVM().getObjectHeap();
205 oh.iterateObjectsOfKlass(new HeapVisitor() {
206 boolean filterExists;
207 public void prologue(long usedSize) {
208 filterExists = getScriptEngine().get("filter") != null;
209 }
210 public boolean doObj(Oop obj) {
211 dispatchObject(obj, visitor, filterExists);
212 return false;
213 }
214 public void epilogue() {}
215 }, ik, includeSubtypes);
216 }
217
218 // we create fresh ObjectReader and factory to avoid
219 // excessive cache across queries.
220 private void beginQuery() {
221 objReader = new ObjectReader();
222 factory = new JSJavaFactoryImpl();
223 }
224
225 // at the end of query we clear object reader cache
226 // and factory cache
227 private void endQuery() {
228 objReader = null;
229 factory = null;
230 }
231
232 protected ObjectReader getObjectReader() {
233 return objReader;
234 }
235
236 protected JSJavaFactory getJSJavaFactory() {
237 return factory;
238 }
239
240 protected boolean isQuitting() {
241 return false;
242 }
243
244 protected void quit() {
245 // do nothing
246 }
247
248 private static void debugPrint(String msg) {
249 if (debug) System.out.println(msg);
250 }
251
252 private static final boolean debug;
253 static {
254 debug = System.getProperty("sun.jvm.hotspot.utilities.soql.SOQLEngine.debug") != null;
255 }
256
257 protected SOQLEngine() {
258 super(debug);
259 start();
260 }
261
262 private ObjectReader objReader;
263 private JSJavaFactory factory;
264 private static SOQLEngine soleInstance;
265 }