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: }