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