You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
258 lines
7.0 KiB
258 lines
7.0 KiB
/*
|
|
* Copyright (c) 1999, 2008, Oracle and/or its affiliates. All rights reserved.
|
|
* ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
|
|
*
|
|
*
|
|
*
|
|
*
|
|
*
|
|
*
|
|
*
|
|
*
|
|
*
|
|
*
|
|
*
|
|
*
|
|
*
|
|
*
|
|
*
|
|
*
|
|
*
|
|
*
|
|
*
|
|
*
|
|
*/
|
|
|
|
package javax.management;
|
|
|
|
|
|
/**
|
|
* This class is used by the query-building mechanism to represent binary
|
|
* operations.
|
|
* @serial include
|
|
*
|
|
* @since 1.5
|
|
*/
|
|
class BinaryOpValueExp extends QueryEval implements ValueExp {
|
|
|
|
/* Serial version */
|
|
private static final long serialVersionUID = 1216286847881456786L;
|
|
|
|
/**
|
|
* @serial The operator
|
|
*/
|
|
private int op;
|
|
|
|
/**
|
|
* @serial The first value
|
|
*/
|
|
private ValueExp exp1;
|
|
|
|
/**
|
|
* @serial The second value
|
|
*/
|
|
private ValueExp exp2;
|
|
|
|
|
|
/**
|
|
* Basic Constructor.
|
|
*/
|
|
public BinaryOpValueExp() {
|
|
}
|
|
|
|
/**
|
|
* Creates a new BinaryOpValueExp using operator o applied on v1 and
|
|
* v2 values.
|
|
*/
|
|
public BinaryOpValueExp(int o, ValueExp v1, ValueExp v2) {
|
|
op = o;
|
|
exp1 = v1;
|
|
exp2 = v2;
|
|
}
|
|
|
|
|
|
/**
|
|
* Returns the operator of the value expression.
|
|
*/
|
|
public int getOperator() {
|
|
return op;
|
|
}
|
|
|
|
/**
|
|
* Returns the left value of the value expression.
|
|
*/
|
|
public ValueExp getLeftValue() {
|
|
return exp1;
|
|
}
|
|
|
|
/**
|
|
* Returns the right value of the value expression.
|
|
*/
|
|
public ValueExp getRightValue() {
|
|
return exp2;
|
|
}
|
|
|
|
/**
|
|
* Applies the BinaryOpValueExp on a MBean.
|
|
*
|
|
* @param name The name of the MBean on which the BinaryOpValueExp will be applied.
|
|
*
|
|
* @return The ValueExp.
|
|
*
|
|
* @exception BadStringOperationException
|
|
* @exception BadBinaryOpValueExpException
|
|
* @exception BadAttributeValueExpException
|
|
* @exception InvalidApplicationException
|
|
*/
|
|
public ValueExp apply(ObjectName name) throws BadStringOperationException, BadBinaryOpValueExpException,
|
|
BadAttributeValueExpException, InvalidApplicationException {
|
|
ValueExp val1 = exp1.apply(name);
|
|
ValueExp val2 = exp2.apply(name);
|
|
String sval1;
|
|
String sval2;
|
|
double dval1;
|
|
double dval2;
|
|
long lval1;
|
|
long lval2;
|
|
boolean numeric = val1 instanceof NumericValueExp;
|
|
|
|
if (numeric) {
|
|
if (((NumericValueExp)val1).isLong()) {
|
|
lval1 = ((NumericValueExp)val1).longValue();
|
|
lval2 = ((NumericValueExp)val2).longValue();
|
|
|
|
switch (op) {
|
|
case Query.PLUS:
|
|
return Query.value(lval1 + lval2);
|
|
case Query.TIMES:
|
|
return Query.value(lval1 * lval2);
|
|
case Query.MINUS:
|
|
return Query.value(lval1 - lval2);
|
|
case Query.DIV:
|
|
return Query.value(lval1 / lval2);
|
|
}
|
|
|
|
} else {
|
|
dval1 = ((NumericValueExp)val1).doubleValue();
|
|
dval2 = ((NumericValueExp)val2).doubleValue();
|
|
|
|
switch (op) {
|
|
case Query.PLUS:
|
|
return Query.value(dval1 + dval2);
|
|
case Query.TIMES:
|
|
return Query.value(dval1 * dval2);
|
|
case Query.MINUS:
|
|
return Query.value(dval1 - dval2);
|
|
case Query.DIV:
|
|
return Query.value(dval1 / dval2);
|
|
}
|
|
}
|
|
} else {
|
|
sval1 = ((StringValueExp)val1).getValue();
|
|
sval2 = ((StringValueExp)val2).getValue();
|
|
|
|
switch (op) {
|
|
case Query.PLUS:
|
|
return new StringValueExp(sval1 + sval2);
|
|
default:
|
|
throw new BadStringOperationException(opString());
|
|
}
|
|
}
|
|
|
|
throw new BadBinaryOpValueExpException(this);
|
|
}
|
|
|
|
/**
|
|
* Returns the string representing the object
|
|
*/
|
|
public String toString() {
|
|
try {
|
|
return parens(exp1, true) + " " + opString() + " " + parens(exp2, false);
|
|
} catch (BadBinaryOpValueExpException ex) {
|
|
return "invalid expression";
|
|
}
|
|
}
|
|
|
|
/*
|
|
* Add parentheses to the given subexpression if necessary to
|
|
* preserve meaning. Suppose this BinaryOpValueExp is
|
|
* Query.times(Query.plus(Query.attr("A"), Query.attr("B")), Query.attr("C")).
|
|
* Then the original toString() logic would return A + B * C.
|
|
* We check precedences in order to return (A + B) * C, which is the
|
|
* meaning of the ValueExp.
|
|
*
|
|
* We need to add parentheses if the unparenthesized expression would
|
|
* be parsed as a different ValueExp from the original.
|
|
* We cannot omit parentheses even when mathematically
|
|
* the result would be equivalent, because we do not know whether the
|
|
* numeric values will be integer or floating-point. Addition and
|
|
* multiplication are associative for integers but not always for
|
|
* floating-point.
|
|
*
|
|
* So the rule is that we omit parentheses if the ValueExp
|
|
* is (A op1 B) op2 C and the precedence of op1 is greater than or
|
|
* equal to that of op2; or if the ValueExp is A op1 (B op2 C) and
|
|
* the precedence of op2 is greater than that of op1. (There are two
|
|
* precedences: that of * and / is greater than that of + and -.)
|
|
* The case of (A op1 B) op2 (C op3 D) applies each rule in turn.
|
|
*
|
|
* The following examples show the rules in action. On the left,
|
|
* the original ValueExp. On the right, the string representation.
|
|
*
|
|
* (A + B) + C A + B + C
|
|
* (A * B) + C A * B + C
|
|
* (A + B) * C (A + B) * C
|
|
* (A * B) * C A * B * C
|
|
* A + (B + C) A + (B + C)
|
|
* A + (B * C) A + B * C
|
|
* A * (B + C) A * (B + C)
|
|
* A * (B * C) A * (B * C)
|
|
*/
|
|
private String parens(ValueExp subexp, boolean left)
|
|
throws BadBinaryOpValueExpException {
|
|
boolean omit;
|
|
if (subexp instanceof BinaryOpValueExp) {
|
|
int subop = ((BinaryOpValueExp) subexp).op;
|
|
if (left)
|
|
omit = (precedence(subop) >= precedence(op));
|
|
else
|
|
omit = (precedence(subop) > precedence(op));
|
|
} else
|
|
omit = true;
|
|
|
|
if (omit)
|
|
return subexp.toString();
|
|
else
|
|
return "(" + subexp + ")";
|
|
}
|
|
|
|
private int precedence(int xop) throws BadBinaryOpValueExpException {
|
|
switch (xop) {
|
|
case Query.PLUS: case Query.MINUS: return 0;
|
|
case Query.TIMES: case Query.DIV: return 1;
|
|
default:
|
|
throw new BadBinaryOpValueExpException(this);
|
|
}
|
|
}
|
|
|
|
private String opString() throws BadBinaryOpValueExpException {
|
|
switch (op) {
|
|
case Query.PLUS:
|
|
return "+";
|
|
case Query.TIMES:
|
|
return "*";
|
|
case Query.MINUS:
|
|
return "-";
|
|
case Query.DIV:
|
|
return "/";
|
|
}
|
|
|
|
throw new BadBinaryOpValueExpException(this);
|
|
}
|
|
|
|
@Deprecated
|
|
public void setMBeanServer(MBeanServer s) {
|
|
super.setMBeanServer(s);
|
|
}
|
|
}
|