1 /* 2 * Copyright (c) 2004, 2010, 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 if (debug) { 73 System.err.println("Warning: Unresolved Symbol: " 74 + id.getName() + " substituted NaN"); 75 } 76 return new Literal(Double.valueOf(Double.NaN)); 77 } 78 if (m.getVariability() == Variability.CONSTANT) { 79 if (debug) { 80 System.out.println("Converting constant " + id.getName() 81 + " to literal with value " 82 + m.getValue()); 83 } 84 return new Literal(m.getValue()); 85 } 86 id.setValue(m); 87 return id; 88 } 89 90 if (e instanceof Literal) { 91 return e; 92 } 93 94 Expression l = null; 95 Expression r = null; 96 97 if (e.getLeft() != null) { 98 l = (Expression)evaluate(e.getLeft()); 99 } 100 if (e.getRight() != null) { 101 r = (Expression)evaluate(e.getRight()); 102 } 103 104 if (l != null && r != null) { 105 if ((l instanceof Literal) && (r instanceof Literal)) { 106 Literal ll = (Literal)l; 107 Literal rl = (Literal)r; 108 boolean warn = false; 109 110 Double nan = Double.valueOf(Double.NaN); 111 if (ll.getValue() instanceof String) { 112 warn = true; ll.setValue(nan); 113 } 114 if (rl.getValue() instanceof String) { 115 warn = true; rl.setValue(nan); 116 } 117 if (debug && warn) { 118 System.out.println("Warning: String literal in " 119 + "numerical expression: " 120 + "substitutied NaN"); 121 } 122 123 // perform the operation 124 Number ln = (Number)ll.getValue(); 125 Number rn = (Number)rl.getValue(); 126 double result = e.getOperator().eval(ln.doubleValue(), 127 rn.doubleValue()); 128 if (debug) { 129 System.out.println("Converting expression " + e 130 + " (left = " + ln.doubleValue() + ")" 131 + " (right = " + rn.doubleValue() + ")" 132 + " to literal value " + result); 133 } 134 return new Literal(Double.valueOf(result)); 135 } 136 } 137 138 if (l != null && r == null) { 139 return l; 140 } 141 142 e.setLeft(l); 143 e.setRight(r); 144 145 return e; 146 } 147 }