001: /*
002: * Copyright (C) The MX4J Contributors.
003: * All rights reserved.
004: *
005: * This software is distributed under the terms of the MX4J License version 1.0.
006: * See the terms of the MX4J License in the documentation provided with this software.
007: */
008:
009: package javax.management;
010:
011: /**
012: * @version $Revision: 1.7 $
013: * @serial include
014: */
015: class MatchQueryExp extends QueryEval implements QueryExp {
016: private static final long serialVersionUID = -7156603696948215014L;
017:
018: /**
019: * @serial The value to match
020: */
021: private final AttributeValueExp exp;
022: /**
023: * @serial The matching pattern
024: */
025: private final String pattern;
026:
027: MatchQueryExp(AttributeValueExp exp, StringValueExp pattern) {
028: this .exp = exp;
029: this .pattern = pattern == null ? null : pattern.getValue();
030: }
031:
032: public void setMBeanServer(MBeanServer server) {
033: super .setMBeanServer(server);
034: if (exp != null)
035: exp.setMBeanServer(server);
036: }
037:
038: public boolean apply(ObjectName name)
039: throws BadStringOperationException,
040: BadBinaryOpValueExpException,
041: BadAttributeValueExpException, InvalidApplicationException {
042: ValueExp value = exp.apply(name);
043: if (value instanceof StringValueExp) {
044: return wildcardMatch(((StringValueExp) value).getValue(),
045: pattern);
046: }
047: return false;
048: }
049:
050: /**
051: * Tests whether string s is matched by pattern p.
052: * Supports "?", "*", "[", each of which may be escaped with "\";
053: * Character classes may use "!" for negation and "-" for range.
054: * Not yet supported: internationalization; "\" inside brackets.<P>
055: * Wildcard matching routine by Karl Heuer. Public Domain.<P>
056: */
057: private boolean wildcardMatch(String s, String p) {
058: if (s == null && p == null)
059: return true;
060: if (s == null)
061: return false;
062: if (p == null)
063: return true;
064:
065: char c;
066: int si = 0, pi = 0;
067: int slen = s.length();
068: int plen = p.length();
069:
070: while (pi < plen) // While still string
071: {
072: c = p.charAt(pi++);
073: if (c == '?') {
074: if (++si > slen)
075: return false;
076: } else if (c == '[') // Start of choice
077: {
078: boolean wantit = true;
079: boolean seenit = false;
080: if (p.charAt(pi) == '!') {
081: wantit = false;
082: ++pi;
083: }
084: while (++pi < plen && (c = p.charAt(pi)) != ']') {
085: if (p.charAt(pi) == '-' && pi + 1 < plen) {
086: if (s.charAt(si) >= c
087: && s.charAt(si) <= p.charAt(pi + 1)) {
088: seenit = true;
089: }
090: pi += 1;
091: } else {
092: if (c == s.charAt(si)) {
093: seenit = true;
094: }
095: }
096: }
097:
098: if ((pi >= plen) || (wantit != seenit))
099: return false;
100:
101: ++pi;
102: ++si;
103: } else if (c == '*') // Wildcard
104: {
105: if (pi >= plen)
106: return true;
107:
108: do {
109: if (wildcardMatch(s.substring(si), p.substring(pi)))
110: return true;
111: } while (++si < slen);
112: return false;
113: } else if (c == '\\') {
114: if (pi >= plen || p.charAt(pi++) != s.charAt(si++))
115: return false;
116: } else {
117: if (si >= slen || c != s.charAt(si++))
118: return false;
119: }
120: }
121: return (si == slen);
122: }
123: }
|