| GNU Classpath (0.95) | |
| Frames | No Frames |
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: