001: //** Copyright Statement ***************************************************
002: //The Salmon Open Framework for Internet Applications (SOFIA)
003: // Copyright (C) 1999 - 2002, Salmon LLC
004: //
005: // This program is free software; you can redistribute it and/or
006: // modify it under the terms of the GNU General Public License version 2
007: // as published by the Free Software Foundation;
008: //
009: // This program is distributed in the hope that it will be useful,
010: // but WITHOUT ANY WARRANTY; without even the implied warranty of
011: // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
012: // GNU General Public License for more details.
013: //
014: // You should have received a copy of the GNU General Public License
015: // along with this program; if not, write to the Free Software
016: // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
017: //
018: // For more information please visit http://www.salmonllc.com
019: //** End Copyright Statement ***************************************************
020: package com.salmonllc.util;
021:
022: import java.io.Serializable;
023: import java.lang.reflect.Field;
024: import java.lang.reflect.Method;
025:
026: /**
027: * A class that encapsulates JDK 1.4 regular expression matching.
028: *
029: * This was built as a wrapper so the framework would compile in JDK 1.3 and below, but the class only runs in JDK 1.4 and above.
030: */
031: public class RegularExpressionMatcher implements Serializable {
032: private Object _pattern;
033: private String _patternString;
034: private String _javaScriptFlags = "";
035: private int _handleNull = HANDLE_NULL_DEFAULT;
036:
037: public static final int HANDLE_NULL_DEFAULT = 0;
038: public static final int HANDLE_NULL_RETURN_TRUE = 1;
039: public static final int HANDLE_NULL_RETURN_FALSE = 2;
040:
041: /**
042: * Creates a regular expression pattern matcher
043: * @param pattern The pattern is in the form of a javascript regexp pattern - /regexp/flags - where regexp is the expression pattern and flags are additional qualifiers. Flags can be i=case insensitive, m=multiline mode, t=nulls always return true, f=nulls always return false. Flags can be placed in any order in the flag string or may be excluded althgether.
044: */
045:
046: public RegularExpressionMatcher(String pattern) {
047: Class c = null;
048:
049: try {
050: c = Class.forName("java.util.regex.Pattern");
051: } catch (Exception e) {
052: MessageLog.writeErrorMessage(
053: "Error creating regular expression matcher", e,
054: this );
055: }
056:
057: //StringTokenizer st = new StringTokenizer(pattern, "/");
058: String flagString = "";
059: String pat = "";
060: if (pattern.startsWith("/")) {
061: pattern = pattern.substring(1);
062: int pos = pattern.lastIndexOf("/");
063: if (pos == -1)
064: pat = pattern;
065: else {
066: pat = pattern.substring(0, pos);
067: flagString = pattern.substring(pos + 1);
068: }
069: } else
070: pat = pattern;
071:
072: int flags = 0;
073: _patternString = pat;
074: if (flagString.length() > 0) {
075: if (flagString.indexOf("i") != -1) {
076: flags = addToFlag(c, "CASE_INSENSITIVE", flags);
077: _javaScriptFlags += "i";
078: }
079: if (flagString.indexOf("m") != -1) {
080: flags = addToFlag(c, "MULTILINE", flags);
081: _javaScriptFlags += "m";
082: }
083: if (flagString.indexOf("g") != -1)
084: _javaScriptFlags += "g";
085: if (flagString.indexOf("t") != -1)
086: _handleNull = HANDLE_NULL_RETURN_TRUE;
087: else if (flagString.indexOf("f") != -1)
088: _handleNull = HANDLE_NULL_RETURN_FALSE;
089: }
090:
091: Class types[] = { String.class, Integer.TYPE };
092:
093: Object args[] = { pat, new Integer(flags) };
094: try {
095: Method m = c.getMethod("compile", types);
096: _pattern = m.invoke(null, args);
097: } catch (Exception e) {
098: MessageLog.writeErrorMessage(
099: "Error creating regular expression matcher", e,
100: this );
101: }
102: }
103:
104: /**
105: * Returns true if the string passed matches the regular expression pattern
106: */
107: public boolean match(String valueToMatch) {
108: if (valueToMatch == null) {
109: if (_handleNull == HANDLE_NULL_RETURN_FALSE)
110: return false;
111: else if (_handleNull == HANDLE_NULL_RETURN_TRUE)
112: return true;
113: }
114:
115: Class types[] = { String.class };
116: Class emptyTypes[] = new Class[0];
117: Object emptyObjects[] = new Object[0];
118: String args[] = { valueToMatch };
119: if (valueToMatch == null) {
120: String temp = null;
121: args[0] = temp;
122: }
123:
124: try {
125: Method ms[] = _pattern.getClass().getMethods();
126: Method m = null;
127: for (int i = 0; i < ms.length; i++) {
128: if (ms[i].getName().equals("matcher")
129: && ms[i].getParameterTypes().length == 1
130: && ms[i].getParameterTypes()[0].getName()
131: .endsWith("CharSequence")) {
132: m = ms[i];
133: break;
134: }
135: }
136: Object matcher = m.invoke(_pattern, args);
137: m = matcher.getClass().getMethod("matches", emptyTypes);
138: Object ret = m.invoke(matcher, emptyObjects);
139: if (ret instanceof Boolean)
140: return ((Boolean) ret).booleanValue();
141: } catch (Exception e) {
142: MessageLog.writeErrorMessage("match()", e, this );
143: }
144: return false;
145: }
146:
147: private int addToFlag(Class c, String fieldName, int flags) {
148: try {
149: Field f = c.getField(fieldName);
150: Integer fv = (Integer) f.get(null);
151: flags = flags | fv.intValue();
152: } catch (Exception e) {
153: MessageLog.writeErrorMessage("addToFlag()", e, this );
154: }
155: return flags;
156: }
157:
158: /**
159: * @returns the regular expression pattern for this component not including the flags
160: */
161: public String getPattern() {
162: return _patternString;
163: }
164:
165: /**
166: * Returns a flag string for this regular expression suitable for javascript
167: *
168: */
169: public String getJavaScriptFlage() {
170: return _javaScriptFlags;
171: }
172:
173: /**
174: * Returns how the matcher will handle null values
175: */
176: public int getHandleNull() {
177: return _handleNull;
178: }
179:
180: }
|