1 /* 2 * Copyright (c) 2004, 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. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 package sun.tools.jstat; 27 28 import sun.jvmstat.monitor.*; 29 30 /** 31 * A class implementing the ExpressionEvaluator to resolve unresolved 32 * symbols in an Expression in the context of the available monitoring data. 33 * This class also performs some minimal optimizations of the expressions, 34 * such as simplification of constant subexpressions. 35 * 36 * @author Brian Doherty 37 * @since 1.5 38 */ 39 public class ExpressionResolver implements ExpressionEvaluator { 40 private static boolean debug = Boolean.getBoolean("ExpressionResolver.debug"); 41 private MonitoredVm vm; 42 43 ExpressionResolver(MonitoredVm vm) { 44 this.vm = vm; 45 } 46 47 /* 48 * evaluate the given expression. evaluation in this case means 49 * to resolve the counter names in the expression 50 */ 51 public Object evaluate(Expression e) throws MonitorException { 52 53 if (e == null) { 54 return null; 55 } 56 57 if (debug) { 58 System.out.println("Resolving Expression:" + e); 59 } 60 61 if (e instanceof Identifier) { 62 Identifier id = (Identifier)e; 63 64 // check if it's already resolved 65 if (id.isResolved()) { 66 return id; 67 } 68 69 // look it up 70 Monitor m = vm.findByName(id.getName()); 71 if (m == null) { 72 System.err.println("Warning: Unresolved Symbol: " 73 + id.getName() + " substituted NaN"); 74 return new Literal(new Double(Double.NaN)); 75 } 76 if (m.getVariability() == Variability.CONSTANT) { 77 if (debug) { 78 System.out.println("Converting constant " + id.getName() 79 + " to literal with value " 80 + m.getValue()); 81 } 82 return new Literal(m.getValue()); 83 } 84 id.setValue(m); 85 return id; 86 } 87 88 if (e instanceof Literal) { 89 return e; 90 } 91 92 Expression l = null; 93 Expression r = null; 94 95 if (e.getLeft() != null) { 96 l = (Expression)evaluate(e.getLeft()); 97 } 98 if (e.getRight() != null) { 99 r = (Expression)evaluate(e.getRight()); 100 } 101 102 if (l != null && r != null) { 103 if ((l instanceof Literal) && (r instanceof Literal)) { 104 Literal ll = (Literal)l; 105 Literal rl = (Literal)r; 106 boolean warn = false; 107 108 Double nan = new Double(Double.NaN); 109 if (ll.getValue() instanceof String) { 110 warn = true; ll.setValue(nan); 111 } 112 if (rl.getValue() instanceof String) { 113 warn = true; rl.setValue(nan); 114 } 115 if (debug && warn) { 116 System.out.println("Warning: String literal in " 117 + "numerical expression: " 118 + "substitutied NaN"); 119 } 120 121 // perform the operation 122 Number ln = (Number)ll.getValue(); 123 Number rn = (Number)rl.getValue(); 124 double result = e.getOperator().eval(ln.doubleValue(), 125 rn.doubleValue()); 126 if (debug) { 127 System.out.println("Converting expression " + e 128 + " (left = " + ln.doubleValue() + ")" 129 + " (right = " + rn.doubleValue() + ")" 130 + " to literal value " + result); 131 } 132 return new Literal(new Double(result)); 133 } 134 } 135 136 if (l != null && r == null) { 137 return l; 138 } 139 140 e.setLeft(l); 141 e.setRight(r); 142 143 return e; 144 } 145 }