Source for javax.management.Query

   1: /* Query.java -- Static methods for query construction.
   2:    Copyright (C) 2007 Free Software Foundation, Inc.
   3: 
   4: This file is part of GNU Classpath.
   5: 
   6: GNU Classpath is free software; you can redistribute it and/or modify
   7: it under the terms of the GNU General Public License as published by
   8: the Free Software Foundation; either version 2, or (at your option)
   9: any later version.
  10: 
  11: GNU Classpath is distributed in the hope that it will be useful, but
  12: WITHOUT ANY WARRANTY; without even the implied warranty of
  13: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  14: General Public License for more details.
  15: 
  16: You should have received a copy of the GNU General Public License
  17: along with GNU Classpath; see the file COPYING.  If not, write to the
  18: Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
  19: 02110-1301 USA.
  20: 
  21: Linking this library statically or dynamically with other modules is
  22: making a combined work based on this library.  Thus, the terms and
  23: conditions of the GNU General Public License cover the whole
  24: combination.
  25: 
  26: As a special exception, the copyright holders of this library give you
  27: permission to link this library with independent modules to produce an
  28: executable, regardless of the license terms of these independent
  29: modules, and to copy and distribute the resulting executable under
  30: terms of your choice, provided that you also meet, for each linked
  31: independent module, the terms and conditions of the license of that
  32: module.  An independent module is a module which is not derived from
  33: or based on this library.  If you modify this library, you may extend
  34: this exception to your version of the library, but you are not
  35: obligated to do so.  If you do not wish to do so, delete this
  36: exception statement from your version. */
  37: 
  38: package javax.management;
  39: 
  40: /**
  41:  * Provides static methods for constructing queries.  Queries
  42:  * may be used to list and enumerate management beans, via
  43:  * the {@link MBeanServer}.  By using the methods in this class,
  44:  * complex queries can be created from their more basic
  45:  * components.
  46:  *
  47:  * @author Andrew John Hughes (gnu_andrew@member.fsf.org)
  48:  * @since 1.5
  49:  */
  50: public class Query
  51: {
  52: 
  53:   /**
  54:    * A code representing the {@link #plus(ValueExp, ValueExp)
  55:    * query to be used in serialization.
  56:    */
  57:   public static final int PLUS = 0;
  58: 
  59:   /**
  60:    * A code representing the {@link #minus(ValueExp, ValueExp)
  61:    * query to be used in serialization.
  62:    */
  63:   public static final int MINUS = 1;
  64: 
  65:   /**
  66:    * A code representing the {@link #times(ValueExp, ValueExp)
  67:    * query to be used in serialization.
  68:    */
  69:   public static final int TIMES = 2;
  70: 
  71:   /**
  72:    * A code representing the {@link #div(ValueExp, ValueExp)
  73:    * query to be used in serialization.
  74:    */
  75:   public static final int DIV = 3;
  76: 
  77:   /**
  78:    * A code representing the {@link #gt(ValueExp, ValueExp)
  79:    * query to be used in serialization.
  80:    */
  81:   public static final int GT = 0;
  82: 
  83:   /**
  84:    * A code representing the {@link #lt(ValueExp, ValueExp)
  85:    * query to be used in serialization.
  86:    */
  87:   public static final int LT = 1;
  88: 
  89:   /**
  90:    * A code representing the {@link #ge(ValueExp, ValueExp)
  91:    * query to be used in serialization.
  92:    */
  93:   public static final int GE = 2;
  94: 
  95:   /**
  96:    * A code representing the {@link #le(ValueExp, ValueExp)
  97:    * query to be used in serialization.
  98:    */
  99:   public static final int LE = 3;
 100: 
 101:   /**
 102:    * A code representing the {@link #eq(ValueExp, ValueExp)
 103:    * query to be used in serialization.
 104:    */
 105:   public static final int EQ = 4;
 106: 
 107:   /**
 108:    * Returns a query expression formed from the conjunction
 109:    * of the two supplied query expressions.
 110:    *
 111:    * @param q1 the first query expression.
 112:    * @param q2 the second query expression.
 113:    * @return a query expression representing q1 && q2.  This
 114:    *         will be serialized as the non-public class
 115:    *         {@link AndQueryExp}.
 116:    */
 117:   public static QueryExp and(QueryExp q1, QueryExp q2)
 118:   {
 119:     return new AndQueryExp(q1, q2);
 120:   }
 121: 
 122:   /**
 123:    * Returns a query expression which checks that an
 124:    * attribute value held by the specified
 125:    * {@link AttributeValueExp} contains the string
 126:    * specified by the given {@link StringValueExp}.
 127:    *
 128:    * @param attrib the attribute to match.
 129:    * @param string the substring to find.
 130:    * @return a query expression representing
 131:    *         <code>attrib.matches("*" + string + "*")</code>.
 132:    *         This will be serialized as the non-public class
 133:    *         {@link MatchQueryExp}.
 134:    */
 135:   public static QueryExp anySubString(AttributeValueExp attrib,
 136:                                       StringValueExp string)
 137:   {
 138:     return new MatchQueryExp(attrib, "*" + string.getValue() + "*");
 139:   }
 140: 
 141:   /**
 142:    * Returns a value expression for the value of the
 143:    * named attribute.  Evaluating this using an
 144:    * {@link ObjectName} involves an underlying call
 145:    * to {@link MBeanServer#getAttribute(ObjectName,String)}.
 146:    *
 147:    * @param name the name of the attribute.
 148:    * @return a value expression which returns the value
 149:    *         of the named attribute when applied.
 150:    */
 151:   public static AttributeValueExp attr(String name)
 152:   {
 153:     return new AttributeValueExp(name);
 154:   }
 155: 
 156:   /**
 157:    * Returns a value expression for the value of the
 158:    * named attribute from the specified class.  Evaluating
 159:    * this using an {@link ObjectName} involves an underlying call
 160:    * to both {@link MBeanServer#getObjectInstance(ObjectName)} and
 161:    * {@link MBeanServer#getAttribute(ObjectName,String)}.
 162:    *
 163:    * @param className the class containing the attribute.
 164:    * @param name the name of the attribute.
 165:    * @return a value expression which returns the value
 166:    *         of the named attribute when applied.
 167:    *         This will be serialized as the non-public class
 168:    *         {@link QualifiedAttributeValueExp}.
 169:    */
 170:   public static AttributeValueExp attr(String className,
 171:                                        String name)
 172:   {
 173:     return new QualifiedAttributeValueExp(className, name);
 174:   }
 175: 
 176:   /**
 177:    * Returns a query expression representing the constraint
 178:    * that the value, <code>v1</code>, lies between <code>v2</code>
 179:    * and <code>v3</code>.
 180:    *
 181:    * @param v1 the value to compare against the boundaries.
 182:    * @param v2 the lower boundary.
 183:    * @param v3 the upper boundary.
 184:    * @return a query expression representing a comparison
 185:    *         of <code>v1</code> against <code>v2</code>
 186:    *         and <code>v3</code>.  It returns true if
 187:    *         <code>v2 <= v1 <= v3</code>.  This
 188:    *         will be serialized as the non-public class
 189:    *         {@link BetweenQueryExp}.
 190:    */
 191:   public static QueryExp between(ValueExp v1, ValueExp v2,
 192:                                  ValueExp v3)
 193:   {
 194:     return new BetweenQueryExp(v1, v2, v3);
 195:   }
 196: 
 197:   /**
 198:    * Returns a value expression which evaluates to the name of
 199:    * the class of the bean when applied. Associating the expression
 200:    * with an {@link ObjectName} involves an underlying call
 201:    * to both {@link MBeanServer#getObjectInstance(ObjectName)}
 202:    * to obtain this information.
 203:    *
 204:    * @return a value expression which returns the class name
 205:    *         of the bean to which it is applied.
 206:    *         This will be serialized as the non-public class
 207:    *         {@link ClassAttributeValueExp}.
 208:    */
 209:   public static AttributeValueExp classattr()
 210:   {
 211:     return new ClassAttributeValueExp();
 212:   }
 213: 
 214:   /**
 215:    * Returns a value expression which evaluates to the result of
 216:    * dividing <code>v1</code> by <code>v2</code>.
 217:    *
 218:    * @param v1 the left-hand operand.
 219:    * @param v2 the right-hand operand.
 220:    * @return a value expression which returns the result of
 221:    *         the division when applied.  This will be serialized
 222:    *         as the non-public class {@link BinaryOpValueExp}
 223:    *         with an operation of {@link #DIV}.
 224:    */
 225:   public static ValueExp div(ValueExp v1, ValueExp v2)
 226:   {
 227:     return new BinaryOpValueExp(DIV, v1, v2);
 228:   }
 229: 
 230:   /**
 231:    * Returns a query expression which evaluates to the result of
 232:    * comparing <code>v1</code> to <code>v2</code> for equality.
 233:    *
 234:    * @param v1 the left-hand operand.
 235:    * @param v2 the right-hand operand.
 236:    * @return a value expression which returns the result of
 237:    *         the comparison when applied.  This will be serialized
 238:    *         as the non-public class {@link BinaryRelQueryExp}
 239:    *         with an operation of {@link #EQ}.
 240:    */
 241:   public static QueryExp eq(ValueExp v1, ValueExp v2)
 242:   {
 243:     return new BinaryRelQueryExp(EQ, v1, v2);
 244:   }
 245: 
 246:   /**
 247:    * Returns a query expression which checks that an
 248:    * attribute value held by the specified
 249:    * {@link AttributeValueExp} ends with the string
 250:    * specified by the given {@link StringValueExp}.
 251:    *
 252:    * @param attrib the attribute to match.
 253:    * @param string the substring to find.
 254:    * @return a query expression representing
 255:    *         <code>attrib.matches("*" + string)</code>.
 256:    *         This will be serialized as the non-public class
 257:    *         {@link MatchQueryExp}.
 258:    */
 259:   public static QueryExp finalSubString(AttributeValueExp attrib,
 260:                                         StringValueExp string)
 261:   {
 262:     return new MatchQueryExp(attrib, "*" + string.getValue());
 263:   }
 264: 
 265:   /**
 266:    * Returns a query expression which evaluates to the result of
 267:    * comparing <code>v1</code> to <code>v2</code> to see if
 268:    * <code>v1</code> is greater than or equal to <code>v2</code>.
 269:    *
 270:    * @param v1 the left-hand operand.
 271:    * @param v2 the right-hand operand.
 272:    * @return a value expression which returns the result of
 273:    *         the comparison when applied.  This will be serialized
 274:    *         as the non-public class {@link BinaryRelQueryExp}
 275:    *         with an operation of {@link #GE}.
 276:    */
 277:   public static QueryExp geq(ValueExp v1, ValueExp v2)
 278:   {
 279:     return new BinaryRelQueryExp(GE, v1, v2);
 280:   }
 281: 
 282:   /**
 283:    * Returns a query expression which evaluates to the result of
 284:    * comparing <code>v1</code> to <code>v2</code> to see if
 285:    * <code>v1</code> is greater than <code>v2</code>.
 286:    *
 287:    * @param v1 the left-hand operand.
 288:    * @param v2 the right-hand operand.
 289:    * @return a value expression which returns the result of
 290:    *         the comparison when applied.  This will be serialized
 291:    *         as the non-public class {@link BinaryRelQueryExp}
 292:    *         with an operation of {@link #GT}.
 293:    */
 294:   public static QueryExp gt(ValueExp v1, ValueExp v2)
 295:   {
 296:     return new BinaryRelQueryExp(GT, v1, v2);
 297:   }
 298: 
 299:   /**
 300:    * Returns a query expression representing the constraint
 301:    * that the value, <code>v</code>, is a member of the
 302:    * list, <code>vlist</code>.
 303:    *
 304:    * @param v the value to look for in the list.
 305:    * @param vlist the list of allowed values.
 306:    * @return a query expression representing a membership check
 307:    *         of <code>v</code> against the list, <code>vlist</code>.
 308:    *         This will be serialized as the non-public class
 309:    *         {@link InQueryExp}.
 310:    */
 311:   public static QueryExp in(ValueExp v, ValueExp[] vlist)
 312:   {
 313:     return new InQueryExp(v, vlist);
 314:   }
 315: 
 316:   /**
 317:    * Returns a query expression which checks that an
 318:    * attribute value held by the specified
 319:    * {@link AttributeValueExp} starts with the string
 320:    * specified by the given {@link StringValueExp}.
 321:    *
 322:    * @param attrib the attribute to match.
 323:    * @param string the substring to find.
 324:    * @return a query expression representing
 325:    *         <code>attrib.matches(string + "*")</code>.
 326:    *         This will be serialized as the non-public class
 327:    *         {@link MatchQueryExp}.
 328:    */
 329:   public static QueryExp initialSubString(AttributeValueExp attrib,
 330:                                           StringValueExp string)
 331:   {
 332:     return new MatchQueryExp(attrib, string.getValue() + "*");
 333:   }
 334: 
 335:   /**
 336:    * Returns a query expression which checks that a
 337:    * bean is an instance of the class specified
 338:    * by the given {@link StringValueExp}.  Associating the
 339:    * expression with an {@link ObjectName} involves an underlying
 340:    * call to {@link MBeanServer#isInstanceOf(ObjectName, String)}
 341:    * using the value of <code>((StringValueExp)
 342:    * className.apply(objectName)).getValue()</code> as the
 343:    * class name.
 344:    *
 345:    * @param className the name of the class which the bean
 346:    *                  should be an instance of.
 347:    * @return a query expression representing
 348:    *         the inheritance check.  This will be serialized
 349:    *         as the non-public class {@link InstanceOfQueryExp}.
 350:    * @since 1.6
 351:    */
 352:   public static QueryExp isInstanceOf(StringValueExp className)
 353:   {
 354:     return new InstanceOfQueryExp(className);
 355:   }
 356: 
 357:   /**
 358:    * Returns a query expression which evaluates to the result of
 359:    * comparing <code>v1</code> to <code>v2</code> to see if
 360:    * <code>v1</code> is less than or equal to <code>v2</code>.
 361:    *
 362:    * @param v1 the left-hand operand.
 363:    * @param v2 the right-hand operand.
 364:    * @return a value expression which returns the result of
 365:    *         the comparison when applied.  This will be serialized
 366:    *         as the non-public class {@link BinaryRelQueryExp}
 367:    *         with an operation of {@link #LE}.
 368:    */
 369:   public static QueryExp leq(ValueExp v1, ValueExp v2)
 370:   {
 371:     return new BinaryRelQueryExp(LE, v1, v2);
 372:   }
 373: 
 374:   /**
 375:    * Returns a query expression which evaluates to the result of
 376:    * comparing <code>v1</code> to <code>v2</code> to see if
 377:    * <code>v1</code> is less than <code>v2</code>.
 378:    *
 379:    * @param v1 the left-hand operand.
 380:    * @param v2 the right-hand operand.
 381:    * @return a value expression which returns the result of
 382:    *         the comparison when applied.  This will be serialized
 383:    *         as the non-public class {@link BinaryRelQueryExp}
 384:    *         with an operation of {@link #LT}.
 385:    */
 386:   public static QueryExp lt(ValueExp v1, ValueExp v2)
 387:   {
 388:     return new BinaryRelQueryExp(LT, v1, v2);
 389:   }
 390: 
 391:   /**
 392:    * <p>
 393:    * Returns a query expression which checks that an
 394:    * attribute value matches the pattern
 395:    * specified by the given {@link StringValueExp}.
 396:    * The pattern uses file-globbing syntax:
 397:    * </p>
 398:    * <ul>
 399:    * <li>'*' stands for any number of arbitrary characters.</li>
 400:    * <li>'?' stands for a single arbitrary characters.</li>
 401:    * <li>An expression within '[' and ']' specify a character
 402:    * class.</li>
 403:    * <ul>
 404:    * <li>A range of characters can be specified by separating
 405:    * the start and end character with '-'.</li>
 406:    * <li>The complement of the class can be obtained by using
 407:    * '!' as the first character of the class.</li>
 408:    * <li>'?', '*' and '[' can occur freely within the class. '-'
 409:    * may occur as the first or last character.  '!' may occur
 410:    * normally in any position other than the first.  ']' may occur
 411:    * as the first element of the class.</li>
 412:    * </ul>
 413:    * <li>'?', '*' and '[' may be escaped using a backslash
 414:    * character, '\'.</li>
 415:    * </ul>
 416:    *
 417:    * @param attrib the attribute to match.
 418:    * @param string the substring to find.
 419:    * @return a query expression representing the result of
 420:    *         matching the pattern against the evaluated
 421:    *         value of the attribute.  This will be serialized
 422:    *         as the non-public class {@link MatchQueryExp}.
 423:    */
 424:   public static QueryExp match(AttributeValueExp attrib,
 425:                                StringValueExp string)
 426:   {
 427:     return new MatchQueryExp(attrib, string.getValue());
 428:   }
 429: 
 430:   /**
 431:    * Returns a value expression which evaluates to the result of
 432:    * subtracting <code>v2</code> from <code>v1</code>.
 433:    *
 434:    * @param v1 the left-hand operand.
 435:    * @param v2 the right-hand operand.
 436:    * @return a value expression which returns the result of
 437:    *         the subtraction when applied.  This will be serialized
 438:    *         as the non-public class {@link BinaryOpValueExp}
 439:    *         with an operation of {@link #MINUS}.
 440:    */
 441:   public static ValueExp minus(ValueExp v1, ValueExp v2)
 442:   {
 443:     return new BinaryOpValueExp(MINUS, v1, v2);
 444:   }
 445: 
 446:   /**
 447:    * Returns a query expression representing the negation
 448:    * of the specified query expression.
 449:    *
 450:    * @param q the query to negate.
 451:    * @return a query expression representing the negation of
 452:    *         <code>q</code>.  This will be serialized as the
 453:    *         non-public class {@link NotQueryExp}.
 454:    */
 455:   public static QueryExp not(QueryExp q)
 456:   {
 457:     return new NotQueryExp(q);
 458:   }
 459: 
 460:   /**
 461:    * Returns a query expression formed from the disjunction
 462:    * of the two supplied query expressions.
 463:    *
 464:    * @param q1 the first query expression.
 465:    * @param q2 the second query expression.
 466:    * @return a query expression representing q1 || q2.  This
 467:    *         will be serialized as the non-public class
 468:    *         {@link OrQueryExp}.
 469:    */
 470:   public static QueryExp or(QueryExp q1, QueryExp q2)
 471:   {
 472:     return new OrQueryExp(q1, q2);
 473:   }
 474: 
 475:   /**
 476:    * Returns a value expression which evaluates to the result of
 477:    * adding <code>v1</code> to <code>v2</code>.
 478:    *
 479:    * @param v1 the left-hand operand.
 480:    * @param v2 the right-hand operand.
 481:    * @return a value expression which returns the result of
 482:    *         the addition when applied.  This will be serialized
 483:    *         as the non-public class {@link BinaryOpValueExp}
 484:    *         with an operation of {@link #PLUS}.
 485:    */
 486:   public static ValueExp plus(ValueExp v1, ValueExp v2)
 487:   {
 488:     return new BinaryOpValueExp(PLUS, v1, v2);
 489:   }
 490: 
 491:   /**
 492:    * Returns a value expression which evaluates to the result of
 493:    * multiplying <code>v1</code> by <code>v2</code>.
 494:    *
 495:    * @param v1 the left-hand operand.
 496:    * @param v2 the right-hand operand.
 497:    * @return a value expression which returns the result of
 498:    *         the multiplication when applied.  This will be serialized
 499:    *         as the non-public class {@link BinaryOpValueExp}
 500:    *         with an operation of {@link #TIMES}.
 501:    */
 502:   public static ValueExp times(ValueExp v1, ValueExp v2)
 503:   {
 504:     return new BinaryOpValueExp(TIMES, v1, v2);
 505:   }
 506: 
 507:   /**
 508:    * Returns a value expression wrapping the specified value.
 509:    *
 510:    * @param val the boolean value to wrap.
 511:    * @return a value expression wrapping <code>val</code>.  This
 512:    *         will be serialized as the non-public class
 513:    *         {@link BooleanValueExp}.
 514:    */
 515:   public static ValueExp value(boolean val)
 516:   {
 517:     return new BooleanValueExp(val);
 518:   }
 519: 
 520:   /**
 521:    * Returns a value expression wrapping the specified value.
 522:    *
 523:    * @param val the double value to wrap.
 524:    * @return a value expression wrapping <code>val</code>.  This
 525:    *         will be serialized as the non-public class
 526:    *         {@link NumericValueExp}.
 527:    */
 528:   public static ValueExp value(double val)
 529:   {
 530:     return new NumericValueExp(val);
 531:   }
 532: 
 533:   /**
 534:    * Returns a value expression wrapping the specified value.
 535:    *
 536:    * @param val the float value to wrap.
 537:    * @return a value expression wrapping <code>val</code>.  This
 538:    *         will be serialized as the non-public class
 539:    *         {@link NumericValueExp}.
 540:    */
 541:   public static ValueExp value(float val)
 542:   {
 543:     return new NumericValueExp(val);
 544:   }
 545: 
 546:   /**
 547:    * Returns a value expression wrapping the specified value.
 548:    *
 549:    * @param val the integer value to wrap.
 550:    * @return a value expression wrapping <code>val</code>.  This
 551:    *         will be serialized as the non-public class
 552:    *         {@link NumericValueExp}.
 553:    */
 554:   public static ValueExp value(int val)
 555:   {
 556:     return new NumericValueExp(val);
 557:   }
 558: 
 559:   /**
 560:    * Returns a value expression wrapping the specified value.
 561:    *
 562:    * @param val the long value to wrap.
 563:    * @return a value expression wrapping <code>val</code>.  This
 564:    *         will be serialized as the non-public class
 565:    *         {@link NumericValueExp}.
 566:    */
 567:   public static ValueExp value(long val)
 568:   {
 569:     return new NumericValueExp(val);
 570:   }
 571: 
 572:   /**
 573:    * Returns a value expression wrapping the specified value.
 574:    *
 575:    * @param val the {@link Number} value to wrap.
 576:    * @return a value expression wrapping <code>val</code>.  This
 577:    *         will be serialized as the non-public class
 578:    *         {@link NumericValueExp}.
 579:    */
 580:   public static ValueExp value(Number val)
 581:   {
 582:     return new NumericValueExp(val);
 583:   }
 584: 
 585:   /**
 586:    * Returns a value expression wrapping the specified string.
 587:    *
 588:    * @param val the {@link String} to wrap.
 589:    * @return a {@link StringValueExp} wrapping <code>val</code>.
 590:    */
 591:   public static StringValueExp value(String val)
 592:   {
 593:     return new StringValueExp(val);
 594:   }
 595: 
 596:   /**
 597:    * Representation of the conjunction formed using
 598:    * {@link #and(QueryExp, QueryExp).
 599:    *
 600:    * @author Andrew John Hughes (gnu_andrew@member.fsf.org)
 601:    * @since 1.5
 602:    */
 603:   private static final class AndQueryExp
 604:     extends QueryEval
 605:     implements QueryExp
 606:   {
 607: 
 608:     /**
 609:      * Compatible with JDK 1.6
 610:      */
 611:     private static final long serialVersionUID = -1081892073854801359L;
 612: 
 613:     /**
 614:      * The first operand.
 615:      */
 616:     private QueryExp exp1;
 617: 
 618:     /**
 619:      * The second operand.
 620:      */
 621:     private QueryExp exp2;
 622: 
 623:     /**
 624:      * Constructs a new {@link AndQueryExp} using
 625:      * the two specified operands.
 626:      *
 627:      * @param exp1 the first query expression.
 628:      * @param exp2 the second query expression.
 629:      */
 630:     public AndQueryExp(QueryExp exp1, QueryExp exp2)
 631:     {
 632:       this.exp1 = exp1;
 633:       this.exp2 = exp2;
 634:     }
 635: 
 636:     /**
 637:      * Returns the conjunction of the two query
 638:      * expressions.
 639:      *
 640:      * @param name the {@link ObjectName} to apply
 641:      *             the query to.
 642:      * @return the conjunction of applying the name
 643:      *         to both operands.
 644:      * @throws BadStringOperationException if an invalid string
 645:      *                                     operation is used by
 646:      *                                     the query.
 647:      * @throws BadBinaryOpValueExpException if an invalid expression
 648:      *                                      is used by the query.
 649:      * @throws BadAttributeValueExpException if an invalid attribute
 650:      *                                       is used by the query.
 651:      * @throws InvalidApplicationException if the query is applied
 652:      *                                     to the wrong type of bean.
 653:      */
 654:     public boolean apply(ObjectName name)
 655:       throws BadStringOperationException, BadBinaryOpValueExpException,
 656:              BadAttributeValueExpException, InvalidApplicationException
 657:     {
 658:       return exp1.apply(name) && exp2.apply(name);
 659:     }
 660: 
 661:   }
 662: 
 663:   /**
 664:    * Representation of a query that matches an
 665:    * attribute's value against a given pattern.
 666:    *
 667:    * @author Andrew John Hughes (gnu_andrew@member.fsf.org)
 668:    * @since 1.5
 669:    */
 670:   private static final class MatchQueryExp
 671:     extends QueryEval
 672:     implements QueryExp
 673:   {
 674: 
 675:     /**
 676:      * Compatible with JDK 1.6
 677:      */
 678:     private static final long serialVersionUID = -7156603696948215014L;
 679: 
 680:     /**
 681:      * The attribute to match against.
 682:      */
 683:     private AttributeValueExp exp;
 684: 
 685:     /**
 686:      * The pattern to be matched.
 687:      */
 688:     private String pattern;
 689: 
 690:     /**
 691:      * Constructs a new {@link MatchQueryExp} using
 692:      * the specified attribute value and pattern.
 693:      *
 694:      * @param exp the attribute value expression.
 695:      * @param pattern the pattern.
 696:      */
 697:     public MatchQueryExp(AttributeValueExp exp,
 698:                          String pattern)
 699:     {
 700:       this.exp = exp;
 701:       this.pattern = pattern;
 702:     }
 703: 
 704:     /**
 705:      * Returns the result of matching the attribute
 706:      * value against the pattern.
 707:      *
 708:      * @param name the {@link ObjectName} to apply
 709:      *             the query to.
 710:      * @return the result of the match.
 711:      * @throws BadStringOperationException if an invalid string
 712:      *                                     operation is used by
 713:      *                                     the query.
 714:      * @throws BadBinaryOpValueExpException if an invalid expression
 715:      *                                      is used by the query.
 716:      * @throws BadAttributeValueExpException if an invalid attribute
 717:      *                                       is used by the query.
 718:      * @throws InvalidApplicationException if the query is applied
 719:      *                                     to the wrong type of bean.
 720:      */
 721:     public boolean apply(ObjectName name)
 722:       throws BadStringOperationException, BadBinaryOpValueExpException,
 723:              BadAttributeValueExpException, InvalidApplicationException
 724:     {
 725:       String val = ((StringValueExp) exp.apply(name)).getValue();
 726:       int valPos = 0;
 727:       int fallback = -1;
 728:       int fallbackP = -1;
 729:       boolean backslash = false;
 730:       for (int a = 0; a < pattern.length(); ++a)
 731:         {
 732:           boolean matched = false;
 733:           int next = pattern.codePointAt(a);
 734:           if (!backslash)
 735:             {
 736:               if (next == '?' && valPos < val.length())
 737:                 {
 738:                   ++valPos;
 739:                   matched = true;
 740:                 }
 741:               else if (next == '*')
 742:                 {
 743:                   fallback = valPos;
 744:                   fallbackP = a;
 745:                   matched = true;
 746:                 }
 747:               else if (next == '[' && valPos < val.length())
 748:                 {
 749:                   boolean negated = false;
 750:                   int b = a + 1;
 751:                   int classChar = pattern.codePointAt(b);
 752:                   do
 753:                     {
 754:                       if (classChar == '!' && b == a + 1)
 755:                         negated = true;
 756:                       else if (pattern.codePointAt(b + 1) == '-' &&
 757:                                pattern.codePointAt(b + 2) != ']')
 758:                         {
 759:                           if (classChar > pattern.codePointAt(b + 2))
 760:                             throw new BadStringOperationException("Invalid range: " +
 761:                                                                   classChar + " to " +
 762:                                                                   pattern.codePointAt(b+2));
 763:                           for (int c = classChar; c <= pattern.codePointAt(b+2); ++c)
 764:                             if (val.codePointAt(valPos) == c)
 765:                               matched = true;
 766:                           b = b + 2;
 767:                         }
 768:                       else if (val.codePointAt(valPos) == classChar)
 769:                         matched = true;
 770:                       ++b;
 771:                       classChar = pattern.codePointAt(b);
 772:                     } while (classChar != ']');
 773:                   if (negated)
 774:                     matched = !matched;
 775:                   ++valPos;
 776:                   a = b;
 777:                 }
 778:               else if (next == '\\')
 779:                 backslash = true;
 780:               else if (valPos < val.length() && next == val.codePointAt(valPos))
 781:                 {
 782:                   matched = true;
 783:                   ++valPos;
 784:                 }
 785:             }
 786:           else
 787:             {
 788:               backslash = false;
 789:               if (valPos < val.length() && next == val.codePointAt(valPos))
 790:                 {
 791:                   matched = true;
 792:                   ++valPos;
 793:                 }
 794:             }
 795:           if (!matched)
 796:             if (fallback != -1)
 797:               {
 798:                 ++fallback;
 799:                 valPos = fallback;
 800:                 a = fallbackP;
 801:                 if (valPos == val.length())
 802:                   return false;
 803:                 continue;
 804:               }
 805:             else
 806:               return false;
 807:         }
 808:       return true;
 809:     }
 810:   }
 811: 
 812:   /**
 813:    * Representation of the retrieval of an attribute
 814:    * value from a certain class for {@link #attr(String,String)}.
 815:    *
 816:    * @author Andrew John Hughes (gnu_andrew@member.fsf.org)
 817:    * @since 1.5
 818:    */
 819:   private static final class QualifiedAttributeValueExp
 820:     extends AttributeValueExp
 821:   {
 822: 
 823:     /**
 824:      * Compatible with JDK 1.6
 825:      */
 826:     private static final long serialVersionUID = 8832517277410933254L;
 827: 
 828:     /**
 829:      * The name of the class from which the attribute is taken.
 830:      */
 831:     private String className;
 832: 
 833:     /**
 834:      * Constructs a new {@link QualifiedAttributeValueExp} using
 835:      * the specified class name and attribute name.
 836:      *
 837:      * @param className the class name.
 838:      * @param name the attribute name.
 839:      */
 840:     public QualifiedAttributeValueExp(String className, String name)
 841:     {
 842:       super(name);
 843:       this.className = className;
 844:     }
 845: 
 846:     /**
 847:      * Applies the {@link AttributeValueExp} to the specified
 848:      * management bean by checking that the attribute will be
 849:      * obtained from the correct class (by a class to
 850:      * {@link MBeanServer#getObjectInstance(ObjectName)} and
 851:      * then obtaining the attribute value from the
 852:      * {@link MBeanServer}, using it to create a
 853:      * {@link StringValueExp}.
 854:      *
 855:      * @param name the {@link ObjectName} of the bean to obtain
 856:      *             the value from.
 857:      * @return a {@link StringValueExp} containing the result.
 858:      * @throws BadStringOperationException if an invalid string
 859:      *                                     operation is used by
 860:      *                                     the value expression.
 861:      * @throws BadBinaryOpValueExpException if an invalid expression
 862:      *                                      is used by the value expression.
 863:      * @throws BadAttributeValueExpException if an invalid attribute
 864:      *                                       is used by the value expression.
 865:      * @throws InvalidApplicationException if the value expression is applied
 866:      *                                     to the wrong type of bean.
 867:      */
 868:     public ValueExp apply(ObjectName name)
 869:       throws BadStringOperationException, BadBinaryOpValueExpException,
 870:              BadAttributeValueExpException, InvalidApplicationException
 871:     {
 872:       try
 873:         {
 874:           if (!(QueryEval.getMBeanServer().getObjectInstance(name).getClassName().equals(className)))
 875:             throw new BadAttributeValueExpException("The value is not from " +
 876:                                                     "the correct class.");
 877:         }
 878:       catch (InstanceNotFoundException e)
 879:         {
 880:           throw (BadAttributeValueExpException)
 881:             new BadAttributeValueExpException("The named bean is not registered.").initCause(e);
 882:         }
 883:       return super.apply(name);
 884:     }
 885: 
 886:   }
 887: 
 888:   /**
 889:    * Representation of the comparison of a value with
 890:    * a pair of bounds formed using
 891:    * {@link #between(ValueExp, ValueExp, ValueExp).
 892:    *
 893:    * @author Andrew John Hughes (gnu_andrew@member.fsf.org)
 894:    * @since 1.5
 895:    */
 896:   private static final class BetweenQueryExp
 897:     extends QueryEval
 898:     implements QueryExp
 899:   {
 900: 
 901:     /**
 902:      * Compatible with JDK 1.6
 903:      */
 904:     private static final long serialVersionUID = -2933597532866307444L;
 905: 
 906:     /**
 907:      * The value to compare.
 908:      */
 909:     private ValueExp exp1;
 910: 
 911:     /**
 912:      * The lower boundary.
 913:      */
 914:     private ValueExp exp2;
 915: 
 916:     /**
 917:      * The upper boundary.
 918:      */
 919:     private ValueExp exp3;
 920: 
 921:     /**
 922:      * Constructs a new {@link BetweenQueryExp} using
 923:      * the specified comparison value and the given
 924:      * bounds.
 925:      *
 926:      * @param exp1 the value to compare.
 927:      * @param exp2 the lower bound.
 928:      * @param exp3 the upper bound.
 929:      */
 930:     public BetweenQueryExp(ValueExp exp1, ValueExp exp2,
 931:                            ValueExp exp3)
 932:     {
 933:       this.exp1 = exp1;
 934:       this.exp2 = exp2;
 935:       this.exp3 = exp3;
 936:     }
 937: 
 938:     /**
 939:      * Returns the result of the comparison between
 940:      * the value and the two bounds.
 941:      *
 942:      * @param name the {@link ObjectName} to apply
 943:      *             the query to.
 944:      * @return the result of the comparison.
 945:      * @throws BadStringOperationException if an invalid string
 946:      *                                     operation is used by
 947:      *                                     the query.
 948:      * @throws BadBinaryOpValueExpException if an invalid expression
 949:      *                                      is used by the query.
 950:      * @throws BadAttributeValueExpException if an invalid attribute
 951:      *                                       is used by the query.
 952:      * @throws InvalidApplicationException if the query is applied
 953:      *                                     to the wrong type of bean.
 954:      */
 955:     public boolean apply(ObjectName name)
 956:       throws BadStringOperationException, BadBinaryOpValueExpException,
 957:              BadAttributeValueExpException, InvalidApplicationException
 958:     {
 959:       String v1 = exp1.apply(name).toString();
 960:       String v2 = exp2.apply(name).toString();
 961:       String v3 = exp3.apply(name).toString();
 962:       return v1.compareTo(v2) >= 0 && v1.compareTo(v3) <= 0;
 963:     }
 964: 
 965:   }
 966: 
 967:   /**
 968:    * Representation of the retrieval of the name of
 969:    * a bean's class for {@link #classattr()}.
 970:    *
 971:    * @author Andrew John Hughes (gnu_andrew@member.fsf.org)
 972:    * @since 1.5
 973:    */
 974:   private static final class ClassAttributeValueExp
 975:     extends AttributeValueExp
 976:   {
 977: 
 978:     /**
 979:      * Compatible with JDK 1.6
 980:      */
 981:     private static final long serialVersionUID = -1081892073854801359L;
 982: 
 983:     /**
 984:      * Obtains the name of the specified bean's class using a call
 985:      * to {@link MBeanServer#getObjectInstance(ObjectName)}.
 986:      *
 987:      * @param name the {@link ObjectName} of the bean to obtain
 988:      *             the class name from.
 989:      * @return a {@link StringValueExp} containing the result.
 990:      * @throws BadStringOperationException if an invalid string
 991:      *                                     operation is used by
 992:      *                                     the value expression.
 993:      * @throws BadBinaryOpValueExpException if an invalid expression
 994:      *                                      is used by the value expression.
 995:      * @throws BadAttributeValueExpException if an invalid attribute
 996:      *                                       is used by the value expression.
 997:      * @throws InvalidApplicationException if the value expression is applied
 998:      *                                     to the wrong type of bean.
 999:      */
1000:     public ValueExp apply(ObjectName name)
1001:       throws BadStringOperationException, BadBinaryOpValueExpException,
1002:              BadAttributeValueExpException, InvalidApplicationException
1003:     {
1004:       try
1005:         {
1006:           return new StringValueExp(QueryEval.getMBeanServer().getObjectInstance(name).getClassName());
1007:         }
1008:       catch (InstanceNotFoundException e)
1009:         {
1010:           throw (BadAttributeValueExpException)
1011:             new BadAttributeValueExpException("The named bean is not registered.").initCause(e);
1012:         }
1013:     }
1014: 
1015:   }
1016: 
1017:   /**
1018:    * Representation of a binary operation formed using
1019:    * {@link #div(ValueExp, ValueExp), {@link #plus(ValueExp,ValueExp)},
1020:    * {@link #minus(ValueExp, ValueExp) or
1021:    * {@link #times(ValueExp, ValueExp)}.
1022:    *
1023:    * @author Andrew John Hughes (gnu_andrew@member.fsf.org)
1024:    * @since 1.5
1025:    */
1026:   private static final class BinaryOpValueExp
1027:     extends QueryEval
1028:     implements ValueExp
1029:   {
1030: 
1031:     /**
1032:      * Compatible with JDK 1.6
1033:      */
1034:     private static final long serialVersionUID = 1216286847881456786L;
1035: 
1036:     /**
1037:      * The operation to perform.
1038:      */
1039:     private int op;
1040: 
1041:     /**
1042:      * The left-hand operand.
1043:      */
1044:     private ValueExp exp1;
1045: 
1046:     /**
1047:      * The right-hand operand.
1048:      */
1049:     private ValueExp exp2;
1050: 
1051:     /**
1052:      * Constructs a new {@link BinaryOpValueExp} using
1053:      * the specified operation and the two values supplied.
1054:      *
1055:      * @param op the operation to perform.
1056:      * @param exp1 the left-hand operand.
1057:      * @param exp2 the right-hand operand.
1058:      */
1059:     public BinaryOpValueExp(int op, ValueExp exp1, ValueExp exp2)
1060:     {
1061:       this.op = op;
1062:       this.exp1 = exp1;
1063:       this.exp2 = exp2;
1064:     }
1065: 
1066:     /**
1067:      * Returns the result of performing the operation on
1068:      * <code>exp1</code> and <code>exp2</code>.
1069:      *
1070:      * @param name the {@link ObjectName} to apply
1071:      *             the query to.
1072:      * @return the result of the operation.
1073:      * @throws BadStringOperationException if an invalid string
1074:      *                                     operation is used by
1075:      *                                     the query.
1076:      * @throws BadBinaryOpValueExpException if an invalid expression
1077:      *                                      is used by the query.
1078:      * @throws BadAttributeValueExpException if an invalid attribute
1079:      *                                       is used by the query.
1080:      * @throws InvalidApplicationException if the query is applied
1081:      *                                     to the wrong type of bean.
1082:      */
1083:     public ValueExp apply(ObjectName name)
1084:       throws BadStringOperationException, BadBinaryOpValueExpException,
1085:              BadAttributeValueExpException, InvalidApplicationException
1086:     {
1087:       NumericValueExp v1 = (NumericValueExp) exp1.apply(name);
1088:       NumericValueExp v2 = (NumericValueExp) exp2.apply(name);
1089:       switch (op)
1090:         {
1091:         case PLUS:
1092:           return v1.plus(v2);
1093:         case MINUS:
1094:           return v1.minus(v2);
1095:         case TIMES:
1096:           return v1.times(v2);
1097:         case DIV:
1098:           return v1.div(v2);
1099:         default:
1100:           throw new BadBinaryOpValueExpException(this);
1101:         }
1102:     }
1103: 
1104:     /**
1105:      * Returns a textual representation of the operation.
1106:      *
1107:      * @return a textual version of the operation.
1108:      */
1109:     public String toString()
1110:     {
1111:       String opS;
1112:       switch (op)
1113:         {
1114:         case PLUS:
1115:           opS = "+";
1116:           break;
1117:         case MINUS:
1118:           opS = "-";
1119:           break;
1120:         case TIMES:
1121:           opS = "x";
1122:           break;
1123:         case DIV:
1124:           opS = "/";
1125:           break;
1126:         default:
1127:           opS = "?";
1128:         }
1129:       return exp1 + " " + opS + " " + exp2;
1130:     }
1131:   }
1132: 
1133:   /**
1134:    * Representation of a binary operation formed using
1135:    * {@link #eq(ValueExp, ValueExp), {@link #geq(ValueExp, ValueExp)},
1136:    * {@link #leq(ValueExp, ValueExp), {@link #gt(ValueExp, ValueExp)}
1137:    * or {@link #lt(ValueExp, ValueExp)}.
1138:    *
1139:    * @author Andrew John Hughes (gnu_andrew@member.fsf.org)
1140:    * @since 1.5
1141:    */
1142:   private static final class BinaryRelQueryExp
1143:     extends QueryEval
1144:     implements QueryExp
1145:   {
1146: 
1147:     /**
1148:      * Compatible with JDK 1.6
1149:      */
1150:     private static final long serialVersionUID = -5690656271650491000L;
1151: 
1152:     /**
1153:      * The operation to perform.
1154:      */
1155:     private int relOp;
1156: 
1157:     /**
1158:      * The left-hand operand.
1159:      */
1160:     private ValueExp exp1;
1161: 
1162:     /**
1163:      * The right-hand operand.
1164:      */
1165:     private ValueExp exp2;
1166: 
1167:     /**
1168:      * Constructs a new {@link BinaryRelQueryExp} using
1169:      * the specified operation and the two values supplied.
1170:      *
1171:      * @param relOp the operation to perform.
1172:      * @param exp1 the left-hand operand.
1173:      * @param exp2 the right-hand operand.
1174:      */
1175:     public BinaryRelQueryExp(int relOp, ValueExp exp1, ValueExp exp2)
1176:     {
1177:       this.relOp = relOp;
1178:       this.exp1 = exp1;
1179:       this.exp2 = exp2;
1180:     }
1181: 
1182:     /**
1183:      * Returns the result of performing the operation on
1184:      * <code>exp1</code> and <code>exp2</code>.
1185:      *
1186:      * @param name the {@link ObjectName} to apply
1187:      *             the query to.
1188:      * @return the result of the comparison.
1189:      * @throws BadStringOperationException if an invalid string
1190:      *                                     operation is used by
1191:      *                                     the query.
1192:      * @throws BadBinaryOpValueExpException if an invalid expression
1193:      *                                      is used by the query.
1194:      * @throws BadAttributeValueExpException if an invalid attribute
1195:      *                                       is used by the query.
1196:      * @throws InvalidApplicationException if the query is applied
1197:      *                                     to the wrong type of bean.
1198:      */
1199:     public boolean apply(ObjectName name)
1200:       throws BadStringOperationException, BadBinaryOpValueExpException,
1201:              BadAttributeValueExpException, InvalidApplicationException
1202:     {
1203:       String v1 = exp1.apply(name).toString();
1204:       String v2 = exp2.apply(name).toString();
1205:       switch (relOp)
1206:         {
1207:         case EQ:
1208:           return v1.equals(v2);
1209:         case GT:
1210:           return v1.compareTo(v2) > 0;
1211:         case GE:
1212:           return v1.compareTo(v2) >= 0;
1213:         case LE:
1214:           return v1.compareTo(v2) <= 0;
1215:         case LT:
1216:           return v1.compareTo(v2) < 0;
1217:         default:
1218:           throw new BadStringOperationException("Invalid operator: " + relOp);
1219:         }
1220:     }
1221: 
1222:     /**
1223:      * Returns a textual representation of the operation.
1224:      *
1225:      * @return a textual version of the operation.
1226:      */
1227:     public String toString()
1228:     {
1229:       String op;
1230:       switch (relOp)
1231:         {
1232:         case EQ:
1233:           op = "=";
1234:           break;
1235:         case GT:
1236:           op = ">";
1237:           break;
1238:         case GE:
1239:           op = ">=";
1240:           break;
1241:         case LE:
1242:           op = "<=";
1243:           break;
1244:         case LT:
1245:           op = "<";
1246:           break;
1247:         default:
1248:           op = "?";
1249:         }
1250:       return exp1 + " " + op + " " + exp2;
1251:     }
1252:   }
1253: 
1254:   /**
1255:    * Representation of the comparison of a value with
1256:    * the members of a list formed using
1257:    * {@link #in(ValueExp, ValueExp[]).
1258:    *
1259:    * @author Andrew John Hughes (gnu_andrew@member.fsf.org)
1260:    * @since 1.5
1261:    */
1262:   private static final class InQueryExp
1263:     extends QueryEval
1264:     implements QueryExp
1265:   {
1266: 
1267:     /**
1268:      * Compatible with JDK 1.6
1269:      */
1270:     private static final long serialVersionUID = -5801329450358952434L;
1271: 
1272:     /**
1273:      * The value to look for.
1274:      */
1275:     private ValueExp val;
1276: 
1277:     /**
1278:      * The array to search.
1279:      */
1280:     private ValueExp[] valueList;
1281: 
1282:     /**
1283:      * Constructs a new {@link InQueryExp} using
1284:      * the specified comparison value and the given
1285:      * list.
1286:      *
1287:      * @param val the value to compare.
1288:      * @param valueList the list of values.
1289:      */
1290:     public InQueryExp(ValueExp val, ValueExp[] valueList)
1291:     {
1292:       this.val = val;
1293:       this.valueList = valueList;
1294:     }
1295: 
1296:     /**
1297:      * Returns the result of the comparison between
1298:      * the value and the list of allowed values.
1299:      *
1300:      * @param name the {@link ObjectName} to apply
1301:      *             the query to.
1302:      * @return the result of the comparison.
1303:      * @throws BadStringOperationException if an invalid string
1304:      *                                     operation is used by
1305:      *                                     the query.
1306:      * @throws BadBinaryOpValueExpException if an invalid expression
1307:      *                                      is used by the query.
1308:      * @throws BadAttributeValueExpException if an invalid attribute
1309:      *                                       is used by the query.
1310:      * @throws InvalidApplicationException if the query is applied
1311:      *                                     to the wrong type of bean.
1312:      */
1313:     public boolean apply(ObjectName name)
1314:       throws BadStringOperationException, BadBinaryOpValueExpException,
1315:              BadAttributeValueExpException, InvalidApplicationException
1316:     {
1317:       String v = val.apply(name).toString();
1318:       for (ValueExp vl : valueList)
1319:         if (v.equals(vl.apply(name).toString()))
1320:           return true;
1321:       return false;
1322:     }
1323: 
1324:   }
1325: 
1326:   /**
1327:    * Representation of the inheritance check on a
1328:    * bean for {@link #isInstanceOf(StringValueExp)}.
1329:    *
1330:    * @author Andrew John Hughes (gnu_andrew@member.fsf.org)
1331:    * @since 1.6
1332:    */
1333:   private static final class InstanceOfQueryExp
1334:     extends QueryEval
1335:     implements QueryExp
1336:   {
1337: 
1338:     /**
1339:      * Compatible with JDK 1.6
1340:      */
1341:     private static final long serialVersionUID = -1081892073854801359L;
1342: 
1343:     /**
1344:      * The name of the class from which the attribute is taken.
1345:      */
1346:     private StringValueExp classNameValue;
1347: 
1348:     /**
1349:      * Constructs a new {@link InstanceOfQueryExp} using
1350:      * the specified class name.
1351:      *
1352:      * @param classNameValue the class name.
1353:      */
1354:     public InstanceOfQueryExp(StringValueExp classNameValue)
1355:     {
1356:       this.classNameValue = classNameValue;
1357:     }
1358: 
1359:     /**
1360:      * Checks that the bean specified by the supplied
1361:      * {@link ObjectName} is of the correct class
1362:      * using {@link MBeanServer#isInstanceOf(ObjectName,String)}.
1363:      * where the string is obtained by evaluating
1364:      * <code>classNameValue</code>.
1365:      *
1366:      * @param name the {@link ObjectName} of the bean to obtain
1367:      *             the value from.
1368:      * @return true if the bean is an instance of the class.
1369:      * @throws BadStringOperationException if an invalid string
1370:      *                                     operation is used by
1371:      *                                     the value expression.
1372:      * @throws BadBinaryOpValueExpException if an invalid expression
1373:      *                                      is used by the value expression.
1374:      * @throws BadAttributeValueExpException if an invalid attribute
1375:      *                                       is used by the value expression.
1376:      * @throws InvalidApplicationException if the value expression is applied
1377:      *                                     to the wrong type of bean.
1378:      */
1379:     public boolean apply(ObjectName name)
1380:       throws BadStringOperationException, BadBinaryOpValueExpException,
1381:              BadAttributeValueExpException, InvalidApplicationException
1382:     {
1383:       try
1384:         {
1385:           String className = ((StringValueExp)
1386:                               classNameValue.apply(name)).getValue();
1387:           return QueryEval.getMBeanServer().isInstanceOf(name, className);
1388:         }
1389:       catch (InstanceNotFoundException e)
1390:         {
1391:           throw (BadAttributeValueExpException)
1392:             new BadAttributeValueExpException("The named bean is not registered.").initCause(e);
1393:         }
1394:     }
1395: 
1396:   }
1397: 
1398:   /**
1399:    * Representation of the negation of a query formed using
1400:    * {@link #not(QueryExp).
1401:    *
1402:    * @author Andrew John Hughes (gnu_andrew@member.fsf.org)
1403:    * @since 1.5
1404:    */
1405:   private static final class NotQueryExp
1406:     extends QueryEval
1407:     implements QueryExp
1408:   {
1409: 
1410:     /**
1411:      * Compatible with JDK 1.6
1412:      */
1413:     private static final long serialVersionUID = 5269643775896723397L;
1414: 
1415:     /**
1416:      * The expression to negate.
1417:      */
1418:     private QueryExp exp;
1419: 
1420:     /**
1421:      * Constructs a new {@link NotQueryExp} using
1422:      * the specified query expression.
1423:      *
1424:      * @param exp the expression to negate.
1425:      */
1426:     public NotQueryExp(QueryExp exp)
1427:     {
1428:       this.exp = exp;
1429:     }
1430: 
1431:     /**
1432:      * Returns the result of the negation.
1433:      *
1434:      * @param name the {@link ObjectName} to apply
1435:      *             the query to.
1436:      * @return the result of the negation.
1437:      * @throws BadStringOperationException if an invalid string
1438:      *                                     operation is used by
1439:      *                                     the query.
1440:      * @throws BadBinaryOpValueExpException if an invalid expression
1441:      *                                      is used by the query.
1442:      * @throws BadAttributeValueExpException if an invalid attribute
1443:      *                                       is used by the query.
1444:      * @throws InvalidApplicationException if the query is applied
1445:      *                                     to the wrong type of bean.
1446:      */
1447:     public boolean apply(ObjectName name)
1448:       throws BadStringOperationException, BadBinaryOpValueExpException,
1449:              BadAttributeValueExpException, InvalidApplicationException
1450:     {
1451:       return !(exp.apply(name));
1452:     }
1453: 
1454:   }
1455: 
1456:   /**
1457:    * Representation of the disjunction formed using
1458:    * {@link #or(QueryExp, QueryExp).
1459:    *
1460:    * @author Andrew John Hughes (gnu_andrew@member.fsf.org)
1461:    * @since 1.5
1462:    */
1463:   private static final class OrQueryExp
1464:     extends QueryEval
1465:     implements QueryExp
1466:   {
1467: 
1468:     /**
1469:      * Compatible with JDK 1.6
1470:      */
1471:     private static final long serialVersionUID = 2962973084421716523L;
1472: 
1473:     /**
1474:      * The first operand.
1475:      */
1476:     private QueryExp exp1;
1477: 
1478:     /**
1479:      * The second operand.
1480:      */
1481:     private QueryExp exp2;
1482: 
1483:     /**
1484:      * Constructs a new {@link OrQueryExp} using
1485:      * the two specified operands.
1486:      *
1487:      * @param exp1 the first query expression.
1488:      * @param exp2 the second query expression.
1489:      */
1490:     public OrQueryExp(QueryExp exp1, QueryExp exp2)
1491:     {
1492:       this.exp1 = exp1;
1493:       this.exp2 = exp2;
1494:     }
1495: 
1496:     /**
1497:      * Returns the disjunction of the two query
1498:      * expressions.
1499:      *
1500:      * @param name the {@link ObjectName} to apply
1501:      *             the query to.
1502:      * @return the disjunction of applying the name
1503:      *         to both operands.
1504:      * @throws BadStringOperationException if an invalid string
1505:      *                                     operation is used by
1506:      *                                     the query.
1507:      * @throws BadBinaryOpValueExpException if an invalid expression
1508:      *                                      is used by the query.
1509:      * @throws BadAttributeValueExpException if an invalid attribute
1510:      *                                       is used by the query.
1511:      * @throws InvalidApplicationException if the query is applied
1512:      *                                     to the wrong type of bean.
1513:      */
1514:     public boolean apply(ObjectName name)
1515:       throws BadStringOperationException, BadBinaryOpValueExpException,
1516:              BadAttributeValueExpException, InvalidApplicationException
1517:     {
1518:       return exp1.apply(name) || exp2.apply(name);
1519:     }
1520: 
1521:   }
1522: 
1523:   /**
1524:    * Representation of a boolean being used as an argument
1525:    * to a relational constraint, formed using
1526:    * {@link #value(boolean)}.
1527:    *
1528:    * @author Andrew John Hughes (gnu_andrew@member.fsf.org)
1529:    * @since 1.5
1530:    */
1531:   private static final class BooleanValueExp
1532:     extends QueryEval
1533:     implements ValueExp
1534:   {
1535: 
1536:     /**
1537:      * Compatible with JDK 1.6
1538:      */
1539:     private static final long serialVersionUID = 7754922052666594581L;
1540: 
1541:     /**
1542:      * The boolean value.
1543:      */
1544:     private boolean val;
1545: 
1546:     /**
1547:      * Constructs a new {@link BooleanValueExp} using the
1548:      * specified value.
1549:      *
1550:      * @param val the boolean value used for this expression.
1551:      */
1552:     public BooleanValueExp(boolean val)
1553:     {
1554:       this.val = val;
1555:     }
1556: 
1557:     /**
1558:      * Applies the {@link BooleanValueExp} to the specified
1559:      * management bean by simply returning the value.
1560:      *
1561:      * @param name the {@link ObjectName} of the bean.
1562:      * @return the {@link BooleanValueExp} itself.
1563:      * @throws BadStringOperationException if an invalid string
1564:      *                                     operation is used by
1565:      *                                     the value expression.
1566:      * @throws BadBinaryOpValueExpException if an invalid expression
1567:      *                                      is used by the value expression.
1568:      * @throws BadAttributeValueExpException if an invalid attribute
1569:      *                                       is used by the value expression.
1570:      * @throws InvalidApplicationException if the value expression is applied
1571:      *                                     to the wrong type of bean.
1572:      */
1573:     public ValueExp apply(ObjectName name)
1574:       throws BadStringOperationException, BadBinaryOpValueExpException,
1575:              BadAttributeValueExpException, InvalidApplicationException
1576:     {
1577:       return this;
1578:     }
1579: 
1580:     /**
1581:      * Returns the value as a string.
1582:      *
1583:      * @return the value in textual form.
1584:      */
1585:     public String toString()
1586:     {
1587:       return Boolean.toString(val);
1588:     }
1589: 
1590:   }
1591: 
1592:   /**
1593:    * Representation of a number being used as an argument
1594:    * to a relational constraint, formed using
1595:    * {@link #value(double)}, {@link #value(float)},
1596:    * {@link #value(int)}, {@link #value(long)} or
1597:    * {@link #value(Number)}.
1598:    *
1599:    * @author Andrew John Hughes (gnu_andrew@member.fsf.org)
1600:    * @since 1.5
1601:    */
1602:   private static final class NumericValueExp
1603:     extends QueryEval
1604:     implements ValueExp
1605:   {
1606: 
1607:     /**
1608:      * Compatible with JDK 1.6
1609:      */
1610:     private static final long serialVersionUID = -4679739485102359104L;
1611: 
1612:     /**
1613:      * The numeric value.
1614:      */
1615:     private Number val;
1616: 
1617:     /**
1618:      * Constructs a new {@link NumericValueExp} using the
1619:      * specified value.
1620:      *
1621:      * @param val the numeric value used for this expression.
1622:      */
1623:     public NumericValueExp(Number val)
1624:     {
1625:       this.val = val;
1626:     }
1627: 
1628:     /**
1629:      * Applies the {@link NumericValueExp} to the specified
1630:      * management bean by simply returning the value.
1631:      *
1632:      * @param name the {@link ObjectName} of the bean.
1633:      * @return the {@link NumericValueExp} itself.
1634:      * @throws BadStringOperationException if an invalid string
1635:      *                                     operation is used by
1636:      *                                     the value expression.
1637:      * @throws BadBinaryOpValueExpException if an invalid expression
1638:      *                                      is used by the value expression.
1639:      * @throws BadAttributeValueExpException if an invalid attribute
1640:      *                                       is used by the value expression.
1641:      * @throws InvalidApplicationException if the value expression is applied
1642:      *                                     to the wrong type of bean.
1643:      */
1644:     public ValueExp apply(ObjectName name)
1645:       throws BadStringOperationException, BadBinaryOpValueExpException,
1646:              BadAttributeValueExpException, InvalidApplicationException
1647:     {
1648:       return this;
1649:     }
1650: 
1651:     /**
1652:      * Returns the value.
1653:      */
1654:     public Number getValue()
1655:     {
1656:       return val;
1657:     }
1658: 
1659:     /**
1660:      * Returns the value as a string.
1661:      *
1662:      * @return the value in textual form.
1663:      */
1664:     public String toString()
1665:     {
1666:       return val.toString();
1667:     }
1668: 
1669:     /**
1670:      * Return the result of adding the specified
1671:      * {@link NumericValueExp} to this one.
1672:      *
1673:      * @param o the value to add.
1674:      * @return the result of the addition.
1675:      */
1676:     public NumericValueExp plus(NumericValueExp o)
1677:     {
1678:       Number v = o.getValue();
1679:       if (val instanceof Double)
1680:         {
1681:           double d = val.doubleValue();
1682:           if (v instanceof Double)
1683:             return new NumericValueExp(d + v.doubleValue());
1684:           else if (v instanceof Float)
1685:             return new NumericValueExp(d + v.floatValue());
1686:           else if (v instanceof Long)
1687:             return new NumericValueExp(d + v.longValue());
1688:           else
1689:             return new NumericValueExp(d + v.intValue());
1690:         }
1691:       else if (val instanceof Float)
1692:         {
1693:           float f = val.floatValue();
1694:           if (v instanceof Double)
1695:             return new NumericValueExp(f + v.doubleValue());
1696:           else if (v instanceof Float)
1697:             return new NumericValueExp(f + v.floatValue());
1698:           else if (v instanceof Long)
1699:             return new NumericValueExp(f + v.longValue());
1700:           else
1701:             return new NumericValueExp(f + v.intValue());
1702:         }
1703:       else if (val instanceof Long)
1704:         {
1705:           long l = val.longValue();
1706:           if (v instanceof Double)
1707:             return new NumericValueExp(l + v.doubleValue());
1708:           else if (v instanceof Float)
1709:             return new NumericValueExp(l + v.floatValue());
1710:           else if (v instanceof Long)
1711:             return new NumericValueExp(l + v.longValue());
1712:           else
1713:             return new NumericValueExp(l + v.intValue());
1714:         }
1715:       int i = val.intValue();
1716:       if (v instanceof Double)
1717:         return new NumericValueExp(i + v.doubleValue());
1718:       else if (v instanceof Float)
1719:         return new NumericValueExp(i + v.floatValue());
1720:       else if (v instanceof Long)
1721:         return new NumericValueExp(i + v.longValue());
1722:       else
1723:         return new NumericValueExp(i + v.intValue());
1724:     }
1725: 
1726:     /**
1727:      * Return New NumericValueExp(the result of subtracting the specified
1728:      * {@link NumericValueExp} from this one.
1729:      *
1730:      * @param o the value to subtract.
1731:      * @return new NumericValueExp(the result of the subtraction.
1732:      */
1733:     public NumericValueExp minus(NumericValueExp o)
1734:     {
1735:       Number v = o.getValue();
1736:       if (val instanceof Double)
1737:         {
1738:           double d = val.doubleValue();
1739:           if (v instanceof Double)
1740:             return new NumericValueExp(d - v.doubleValue());
1741:           else if (v instanceof Float)
1742:             return new NumericValueExp(d - v.floatValue());
1743:           else if (v instanceof Long)
1744:             return new NumericValueExp(d - v.longValue());
1745:           else
1746:             return new NumericValueExp(d - v.intValue());
1747:         }
1748:       else if (val instanceof Float)
1749:         {
1750:           float f = val.floatValue();
1751:           if (v instanceof Double)
1752:             return new NumericValueExp(f - v.doubleValue());
1753:           else if (v instanceof Float)
1754:             return new NumericValueExp(f - v.floatValue());
1755:           else if (v instanceof Long)
1756:             return new NumericValueExp(f - v.longValue());
1757:           else
1758:             return new NumericValueExp(f - v.intValue());
1759:         }
1760:       else if (val instanceof Long)
1761:         {
1762:           long l = val.longValue();
1763:           if (v instanceof Double)
1764:             return new NumericValueExp(l - v.doubleValue());
1765:           else if (v instanceof Float)
1766:             return new NumericValueExp(l - v.floatValue());
1767:           else if (v instanceof Long)
1768:             return new NumericValueExp(l - v.longValue());
1769:           else
1770:             return new NumericValueExp(l - v.intValue());
1771:         }
1772:       int i = val.intValue();
1773:       if (v instanceof Double)
1774:         return new NumericValueExp(i - v.doubleValue());
1775:       else if (v instanceof Float)
1776:         return new NumericValueExp(i - v.floatValue());
1777:       else if (v instanceof Long)
1778:         return new NumericValueExp(i - v.longValue());
1779:       else
1780:         return new NumericValueExp(i - v.intValue());
1781:     }
1782: 
1783:     /**
1784:      * Return New NumericValueExp(the result of multiplying the specified
1785:      * {@link NumericValueExp} to this one.
1786:      *
1787:      * @param o the value to multiply by.
1788:      * @return new NumericValueExp(the result of the multiplication.
1789:      */
1790:     public NumericValueExp times(NumericValueExp o)
1791:     {
1792:       Number v = o.getValue();
1793:       if (val instanceof Double)
1794:         {
1795:           double d = val.doubleValue();
1796:           if (v instanceof Double)
1797:             return new NumericValueExp(d * v.doubleValue());
1798:           else if (v instanceof Float)
1799:             return new NumericValueExp(d * v.floatValue());
1800:           else if (v instanceof Long)
1801:             return new NumericValueExp(d * v.longValue());
1802:           else
1803:             return new NumericValueExp(d * v.intValue());
1804:         }
1805:       else if (val instanceof Float)
1806:         {
1807:           float f = val.floatValue();
1808:           if (v instanceof Double)
1809:             return new NumericValueExp(f * v.doubleValue());
1810:           else if (v instanceof Float)
1811:             return new NumericValueExp(f * v.floatValue());
1812:           else if (v instanceof Long)
1813:             return new NumericValueExp(f * v.longValue());
1814:           else
1815:             return new NumericValueExp(f * v.intValue());
1816:         }
1817:       else if (val instanceof Long)
1818:         {
1819:           long l = val.longValue();
1820:           if (v instanceof Double)
1821:             return new NumericValueExp(l * v.doubleValue());
1822:           else if (v instanceof Float)
1823:             return new NumericValueExp(l * v.floatValue());
1824:           else if (v instanceof Long)
1825:             return new NumericValueExp(l * v.longValue());
1826:           else
1827:             return new NumericValueExp(l * v.intValue());
1828:         }
1829:       int i = val.intValue();
1830:       if (v instanceof Double)
1831:         return new NumericValueExp(i * v.doubleValue());
1832:       else if (v instanceof Float)
1833:         return new NumericValueExp(i * v.floatValue());
1834:       else if (v instanceof Long)
1835:         return new NumericValueExp(i * v.longValue());
1836:       else
1837:         return new NumericValueExp(i * v.intValue());
1838:     }
1839: 
1840:     /**
1841:      * Return New NumericValueExp(the result of dividing this
1842:      * number by value of the specified
1843:      * {@link NumericValueExp}.
1844:      *
1845:      * @param o the value to divide by.
1846:      * @return new NumericValueExp(the result of the division.
1847:      */
1848:     public NumericValueExp div(NumericValueExp o)
1849:     {
1850:       Number v = o.getValue();
1851:       if (val instanceof Double)
1852:         {
1853:           double d = val.doubleValue();
1854:           if (v instanceof Double)
1855:             return new NumericValueExp(d / v.doubleValue());
1856:           else if (v instanceof Float)
1857:             return new NumericValueExp(d / v.floatValue());
1858:           else if (v instanceof Long)
1859:             return new NumericValueExp(d / v.longValue());
1860:           else
1861:             return new NumericValueExp(d / v.intValue());
1862:         }
1863:       else if (val instanceof Float)
1864:         {
1865:           float f = val.floatValue();
1866:           if (v instanceof Double)
1867:             return new NumericValueExp(f / v.doubleValue());
1868:           else if (v instanceof Float)
1869:             return new NumericValueExp(f / v.floatValue());
1870:           else if (v instanceof Long)
1871:             return new NumericValueExp(f / v.longValue());
1872:           else
1873:             return new NumericValueExp(f / v.intValue());
1874:         }
1875:       else if (val instanceof Long)
1876:         {
1877:           long l = val.longValue();
1878:           if (v instanceof Double)
1879:             return new NumericValueExp(l / v.doubleValue());
1880:           else if (v instanceof Float)
1881:             return new NumericValueExp(l / v.floatValue());
1882:           else if (v instanceof Long)
1883:             return new NumericValueExp(l / v.longValue());
1884:           else
1885:             return new NumericValueExp(l / v.intValue());
1886:         }
1887:       int i = val.intValue();
1888:       if (v instanceof Double)
1889:         return new NumericValueExp(i / v.doubleValue());
1890:       else if (v instanceof Float)
1891:         return new NumericValueExp(i / v.floatValue());
1892:       else if (v instanceof Long)
1893:         return new NumericValueExp(i / v.longValue());
1894:       else
1895:         return new NumericValueExp(i / v.intValue());
1896:     }
1897: 
1898:   }
1899: 
1900: }