001: /*
002: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
003: *
004: * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
005: *
006: * The contents of this file are subject to the terms of either the GNU
007: * General Public License Version 2 only ("GPL") or the Common
008: * Development and Distribution License("CDDL") (collectively, the
009: * "License"). You may not use this file except in compliance with the
010: * License. You can obtain a copy of the License at
011: * http://www.netbeans.org/cddl-gplv2.html
012: * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
013: * specific language governing permissions and limitations under the
014: * License. When distributing the software, include this License Header
015: * Notice in each file and include the License file at
016: * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this
017: * particular file as subject to the "Classpath" exception as provided
018: * by Sun in the GPL Version 2 section of the License file that
019: * accompanied this code. If applicable, add the following below the
020: * License Header, with the fields enclosed by brackets [] replaced by
021: * your own identifying information:
022: * "Portions Copyrighted [year] [name of copyright owner]"
023: *
024: * Contributor(s): Alexandre Iline.
025: *
026: * The Original Software is the Jemmy library.
027: * The Initial Developer of the Original Software is Alexandre Iline.
028: * All Rights Reserved.
029: *
030: * If you wish your version of this file to be governed by only the CDDL
031: * or only the GPL Version 2, indicate your decision by adding
032: * "[Contributor] elects to include this software in this distribution
033: * under the [CDDL or GPL Version 2] license." If you do not indicate a
034: * single choice of license, a recipient has the option to distribute
035: * your version of this file under either the CDDL, the GPL Version 2 or
036: * to extend the choice of license to its licensees as provided above.
037: * However, if you add GPL Version 2 code and therefore, elected the GPL
038: * Version 2 license, then the option applies only if the new code is
039: * made subject to such option by the copyright holder.
040: *
041: *
042: *
043: * $Id$ $Revision$ $Date$
044: *
045: */
046:
047: package org.netbeans.jemmy.util;
048:
049: import java.lang.reflect.InvocationTargetException;
050:
051: import org.netbeans.jemmy.ClassReference;
052: import org.netbeans.jemmy.JemmyException;
053:
054: import org.netbeans.jemmy.operators.Operator.StringComparator;
055:
056: /**
057: * Be executed under 1.4 uses <code>java.util.regex.Pattern</code> functionality.
058: * Otherwise understands only "." and "*" simbols, i.e. regexprs like ".*Ques.ion.*".
059: */
060: public class RegExComparator implements StringComparator {
061: private static final int ANY_SIMBOL = -1;
062: private static final int IGNORE_SIMBOL = -999;
063:
064: public boolean equals(String caption, String match) {
065: if (match == null) {
066: return (true);
067: }
068: if (caption == null) {
069: return (false);
070: }
071: if (System.getProperty("java.specification.version").compareTo(
072: "1.3") > 0) {
073: try {
074: Object result = new ClassReference(
075: "java.util.regex.Pattern")
076: .invokeMethod(
077: "matches",
078: new Object[] {
079: match,
080: (caption == null) ? ""
081: : caption },
082: new Class[] {
083: String.class,
084: Class
085: .forName("java.lang.CharSequence") });
086: return (((Boolean) result).booleanValue());
087: } catch (InvocationTargetException e) {
088: throw (new JemmyException(
089: "Exception during regexpr using", e));
090: } catch (ClassNotFoundException e) {
091: throw (new JemmyException(
092: "Exception during regexpr using", e));
093: } catch (NoSuchMethodException e) {
094: throw (new JemmyException(
095: "Exception during regexpr using", e));
096: } catch (IllegalAccessException e) {
097: throw (new JemmyException(
098: "Exception during regexpr using", e));
099: }
100: } else {
101: return (parse(new String(caption), new String(match)));
102: }
103: }
104:
105: /**
106: * Checks that caption matshes the pattern.
107: * Understands only "." (any symbol) and "*" (repeat symbol).
108: * Used for 1.3 and earclier javas, starting from 1.4
109: * <code>java.util.regex.Pattern</code> class is used.
110: * @param caption a caption to compare with the pattern.
111: * @param match a pattern
112: * @return true if the caption matches the pattern.
113: */
114: public boolean parse(String caption, String match) {
115: if (match.length() == 0 && caption.length() == 0) {
116: return (true);
117: } else if (match.length() == 0) {
118: return (false);
119: }
120: int c0 = match.charAt(0);
121: int c1 = IGNORE_SIMBOL;
122: if (match.length() > 1) {
123: c1 = match.charAt(1);
124: }
125: int shift = 1;
126: switch (c0) {
127: case '\\':
128: if (match.length() == 1) {
129: throw (new RegExParsingException(
130: "\\ is not appropriate"));
131: }
132: c0 = match.charAt(1);
133: if (match.length() > 2) {
134: c1 = match.charAt(2);
135: } else {
136: c1 = IGNORE_SIMBOL;
137: }
138: shift = 2;
139: break;
140: case '.':
141: c0 = ANY_SIMBOL;
142: break;
143: case '*':
144: throw (new RegExParsingException("* is not appropriate"));
145: }
146: if (c1 == '*') {
147: shift = shift + 1;
148: int i = 0;
149: while (i <= caption.length()) {
150: if (i == 0 || checkOne(caption.substring(i - 1), c0)) {
151: if (parse(caption.substring(i), match
152: .substring(shift))) {
153: return (true);
154: }
155: } else {
156: return (false);
157: }
158: i++;
159: }
160: return (false);
161: } else {
162: if (caption.length() == 0) {
163: return (false);
164: }
165: if (checkOne(caption, c0)) {
166: return (parse(caption.substring(1), match
167: .substring(shift)));
168: } else {
169: return (false);
170: }
171: }
172: }
173:
174: private boolean checkOne(String caption, int simbol) {
175: return (simbol == ANY_SIMBOL || simbol == caption.charAt(0));
176: }
177:
178: /**
179: * Thrown in case of parsing error.
180: */
181: public static class RegExParsingException extends JemmyException {
182: /**
183: * Constructs a RegExComparator$RegExParsingException object.
184: * @param message an error message
185: */
186: public RegExParsingException(String message) {
187: super (message);
188: }
189:
190: /**
191: * Constructs a RegExComparator$RegExParsingException object.
192: * @param message an error message
193: * @param innerException a parsing exception.
194: */
195: public RegExParsingException(String message,
196: Exception innerException) {
197: super(message, innerException);
198: }
199: }
200: }
|