001: /*
002: * JBoss, Home of Professional Open Source.
003: * Copyright 2006, Red Hat Middleware LLC, and individual contributors
004: * as indicated by the @author tags. See the copyright.txt file in the
005: * distribution for a full listing of individual contributors.
006: *
007: * This is free software; you can redistribute it and/or modify it
008: * under the terms of the GNU Lesser General Public License as
009: * published by the Free Software Foundation; either version 2.1 of
010: * the License, or (at your option) any later version.
011: *
012: * This software is distributed in the hope that it will be useful,
013: * but WITHOUT ANY WARRANTY; without even the implied warranty of
014: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
015: * Lesser General Public License for more details.
016: *
017: * You should have received a copy of the GNU Lesser General Public
018: * License along with this software; if not, write to the Free
019: * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
020: * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
021: */
022: package javax.management;
023:
024: import java.io.IOException;
025: import java.io.ObjectInputStream;
026: import java.util.regex.Pattern;
027:
028: /**
029: * A Match Query Expression.<p>
030: *
031: * Returns true when an attribute value matches the string expression.
032: *
033: * <p><b>Revisions:</b>
034: * <p><b>20020314 Adrian Brock:</b>
035: * <ul>
036: * <li>Fixed most of the escaping
037: * </ul>
038: * <p><b>20020317 Adrian Brock:</b>
039: * <ul>
040: * <li>Make queries thread safe
041: * </ul>
042: *
043: * @author <a href="mailto:Adrian.Brock@HappeningTimes.com">Adrian Brock</a>.
044: * @version $Revision: 57200 $
045: */
046: class MatchQueryExp extends QueryEval implements QueryExp {
047: // Constants ---------------------------------------------------
048:
049: private static final long serialVersionUID = -7156603696948215014L;
050:
051: // Attributes --------------------------------------------------
052:
053: /**
054: * The attribute to test
055: */
056: private AttributeValueExp exp;
057:
058: /**
059: * The string to test
060: */
061: private String pattern;
062:
063: /**
064: * Regular Expression
065: */
066: private transient Pattern re;
067:
068: // Static ------------------------------------------------------
069:
070: // Constructors ------------------------------------------------
071:
072: public MatchQueryExp() {
073: }
074:
075: /**
076: * Construct a new MATCH query expression
077: *
078: * @param attr the attribute to test
079: * @param string the string to test
080: */
081: public MatchQueryExp(AttributeValueExp attr, String string) {
082: this .exp = attr;
083: this .pattern = string;
084:
085: generateRegExp();
086: }
087:
088: // Public ------------------------------------------------------
089:
090: // QueryExp implementation -------------------------------------
091:
092: public boolean apply(ObjectName name)
093: throws BadStringOperationException,
094: BadBinaryOpValueExpException,
095: BadAttributeValueExpException, InvalidApplicationException {
096: ValueExp calcAttr = exp.apply(name);
097:
098: if (calcAttr instanceof StringValueExp) {
099: return re.matcher(calcAttr.toString()).matches();
100: }
101: // Correct?
102: return false;
103: }
104:
105: // Object overrides --------------------------------------------
106:
107: private void readObject(ObjectInputStream ois) throws IOException,
108: ClassNotFoundException {
109: ois.defaultReadObject();
110: generateRegExp();
111: }
112:
113: public String toString() {
114: return new String("(" + exp.toString() + " matches "
115: + pattern.toString() + ")");
116: }
117:
118: // Protected ---------------------------------------------------
119:
120: // Private -----------------------------------------------------
121:
122: private void generateRegExp() {
123: // Translate the pattern to a regexp
124: StringBuffer buffer = new StringBuffer();
125: char[] chars = pattern.toCharArray();
126: boolean escaping = false;
127: for (int i = 0; i < chars.length; i++) {
128: // Turn on escaping
129: if (chars[i] == '\\' && escaping == false)
130: escaping = true;
131: else {
132: // Match any character
133: if (chars[i] == '?' && escaping == false)
134: buffer.append("(?:.)");
135: // A literal question mark
136: else if (chars[i] == '?')
137: buffer.append("\\?");
138: // Match any number of characters including none
139: else if (chars[i] == '*' && escaping == false)
140: buffer.append("(?:.)*");
141: // A literal asterisk
142: else if (chars[i] == '*')
143: buffer.append("\\*");
144: // The hat character is literal
145: else if (chars[i] == '^')
146: buffer.append("\\^");
147: // The dollar sign is literal
148: else if (chars[i] == '$')
149: buffer.append("\\$");
150: // The back slash character is literal (avoids escaping)
151: else if (chars[i] == '\\')
152: buffer.append("\\\\");
153: // The dot character is literal
154: else if (chars[i] == '.')
155: buffer.append("\\.");
156: // The vertical line character is literal
157: else if (chars[i] == '|')
158: buffer.append("\\|");
159: // Escaping the open bracket
160: else if (chars[i] == '[' && escaping == true)
161: buffer.append("\\[");
162: // REVIEW: There are other more complicated expressions to escape
163: else
164: buffer.append(chars[i]);
165: escaping = false;
166: }
167: }
168: // REVIEW: Should this be an error?
169: if (escaping)
170: buffer.append("\\\\");
171:
172: re = Pattern.compile(buffer.toString());
173: }
174:
175: // Inner classes -----------------------------------------------
176: }
|