Path: blob/master/src/java.management/share/classes/javax/management/BinaryOpValueExp.java
41155 views
/*1* Copyright (c) 1999, 2008, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation. Oracle designates this7* particular file as subject to the "Classpath" exception as provided8* by Oracle in the LICENSE file that accompanied this code.9*10* This code is distributed in the hope that it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License13* version 2 for more details (a copy is included in the LICENSE file that14* accompanied this code).15*16* You should have received a copy of the GNU General Public License version17* 2 along with this work; if not, write to the Free Software Foundation,18* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.19*20* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA21* or visit www.oracle.com if you need additional information or have any22* questions.23*/2425package javax.management;262728/**29* This class is used by the query-building mechanism to represent binary30* operations.31* @serial include32*33* @since 1.534*/35class BinaryOpValueExp extends QueryEval implements ValueExp {3637/* Serial version */38private static final long serialVersionUID = 1216286847881456786L;3940/**41* @serial The operator42*/43private int op;4445/**46* @serial The first value47*/48private ValueExp exp1;4950/**51* @serial The second value52*/53private ValueExp exp2;545556/**57* Basic Constructor.58*/59public BinaryOpValueExp() {60}6162/**63* Creates a new BinaryOpValueExp using operator o applied on v1 and64* v2 values.65*/66public BinaryOpValueExp(int o, ValueExp v1, ValueExp v2) {67op = o;68exp1 = v1;69exp2 = v2;70}717273/**74* Returns the operator of the value expression.75*/76public int getOperator() {77return op;78}7980/**81* Returns the left value of the value expression.82*/83public ValueExp getLeftValue() {84return exp1;85}8687/**88* Returns the right value of the value expression.89*/90public ValueExp getRightValue() {91return exp2;92}9394/**95* Applies the BinaryOpValueExp on a MBean.96*97* @param name The name of the MBean on which the BinaryOpValueExp will be applied.98*99* @return The ValueExp.100*101* @exception BadStringOperationException102* @exception BadBinaryOpValueExpException103* @exception BadAttributeValueExpException104* @exception InvalidApplicationException105*/106public ValueExp apply(ObjectName name) throws BadStringOperationException, BadBinaryOpValueExpException,107BadAttributeValueExpException, InvalidApplicationException {108ValueExp val1 = exp1.apply(name);109ValueExp val2 = exp2.apply(name);110String sval1;111String sval2;112double dval1;113double dval2;114long lval1;115long lval2;116boolean numeric = val1 instanceof NumericValueExp;117118if (numeric) {119if (((NumericValueExp)val1).isLong()) {120lval1 = ((NumericValueExp)val1).longValue();121lval2 = ((NumericValueExp)val2).longValue();122123switch (op) {124case Query.PLUS:125return Query.value(lval1 + lval2);126case Query.TIMES:127return Query.value(lval1 * lval2);128case Query.MINUS:129return Query.value(lval1 - lval2);130case Query.DIV:131return Query.value(lval1 / lval2);132}133134} else {135dval1 = ((NumericValueExp)val1).doubleValue();136dval2 = ((NumericValueExp)val2).doubleValue();137138switch (op) {139case Query.PLUS:140return Query.value(dval1 + dval2);141case Query.TIMES:142return Query.value(dval1 * dval2);143case Query.MINUS:144return Query.value(dval1 - dval2);145case Query.DIV:146return Query.value(dval1 / dval2);147}148}149} else {150sval1 = ((StringValueExp)val1).getValue();151sval2 = ((StringValueExp)val2).getValue();152153switch (op) {154case Query.PLUS:155return new StringValueExp(sval1 + sval2);156default:157throw new BadStringOperationException(opString());158}159}160161throw new BadBinaryOpValueExpException(this);162}163164/**165* Returns the string representing the object166*/167public String toString() {168try {169return parens(exp1, true) + " " + opString() + " " + parens(exp2, false);170} catch (BadBinaryOpValueExpException ex) {171return "invalid expression";172}173}174175/*176* Add parentheses to the given subexpression if necessary to177* preserve meaning. Suppose this BinaryOpValueExp is178* Query.times(Query.plus(Query.attr("A"), Query.attr("B")), Query.attr("C")).179* Then the original toString() logic would return A + B * C.180* We check precedences in order to return (A + B) * C, which is the181* meaning of the ValueExp.182*183* We need to add parentheses if the unparenthesized expression would184* be parsed as a different ValueExp from the original.185* We cannot omit parentheses even when mathematically186* the result would be equivalent, because we do not know whether the187* numeric values will be integer or floating-point. Addition and188* multiplication are associative for integers but not always for189* floating-point.190*191* So the rule is that we omit parentheses if the ValueExp192* is (A op1 B) op2 C and the precedence of op1 is greater than or193* equal to that of op2; or if the ValueExp is A op1 (B op2 C) and194* the precedence of op2 is greater than that of op1. (There are two195* precedences: that of * and / is greater than that of + and -.)196* The case of (A op1 B) op2 (C op3 D) applies each rule in turn.197*198* The following examples show the rules in action. On the left,199* the original ValueExp. On the right, the string representation.200*201* (A + B) + C A + B + C202* (A * B) + C A * B + C203* (A + B) * C (A + B) * C204* (A * B) * C A * B * C205* A + (B + C) A + (B + C)206* A + (B * C) A + B * C207* A * (B + C) A * (B + C)208* A * (B * C) A * (B * C)209*/210private String parens(ValueExp subexp, boolean left)211throws BadBinaryOpValueExpException {212boolean omit;213if (subexp instanceof BinaryOpValueExp) {214int subop = ((BinaryOpValueExp) subexp).op;215if (left)216omit = (precedence(subop) >= precedence(op));217else218omit = (precedence(subop) > precedence(op));219} else220omit = true;221222if (omit)223return subexp.toString();224else225return "(" + subexp + ")";226}227228private int precedence(int xop) throws BadBinaryOpValueExpException {229switch (xop) {230case Query.PLUS: case Query.MINUS: return 0;231case Query.TIMES: case Query.DIV: return 1;232default:233throw new BadBinaryOpValueExpException(this);234}235}236237private String opString() throws BadBinaryOpValueExpException {238switch (op) {239case Query.PLUS:240return "+";241case Query.TIMES:242return "*";243case Query.MINUS:244return "-";245case Query.DIV:246return "/";247}248249throw new BadBinaryOpValueExpException(this);250}251252@Deprecated253public void setMBeanServer(MBeanServer s) {254super.setMBeanServer(s);255}256}257258259