1 /* 2 * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 package org.netbeans.jemmy.util; 26 27 import java.lang.reflect.InvocationTargetException; 28 29 import org.netbeans.jemmy.ClassReference; 30 import org.netbeans.jemmy.JemmyException; 31 import org.netbeans.jemmy.operators.Operator.StringComparator; 32 33 /** 34 * Be executed under 1.4 uses {@code java.util.regex.Pattern} 35 * functionality. Otherwise understands only "." and "*" simbols, i.e. regexprs 36 * like ".*Ques.ion.*". 37 */ 38 public class RegExComparator implements StringComparator { 39 40 private static final int ANY_SIMBOL = -1; 41 private static final int IGNORE_SIMBOL = -999; 42 43 @Override equals(String caption, String match)44 public boolean equals(String caption, String match) { 45 if (match == null) { 46 return true; 47 } 48 if (caption == null) { 49 return false; 50 } 51 if (System.getProperty("java.specification.version").compareTo("1.3") > 0) { 52 try { 53 Object result = new ClassReference("java.util.regex.Pattern"). 54 invokeMethod("matches", 55 new Object[]{match, caption}, 56 new Class<?>[]{String.class, Class.forName("java.lang.CharSequence")}); 57 return ((Boolean) result).booleanValue(); 58 } catch (InvocationTargetException e) { 59 throw (new JemmyException("Exception during regexpr using", 60 e)); 61 } catch (ClassNotFoundException e) { 62 throw (new JemmyException("Exception during regexpr using", 63 e)); 64 } catch (NoSuchMethodException e) { 65 throw (new JemmyException("Exception during regexpr using", 66 e)); 67 } catch (IllegalAccessException e) { 68 throw (new JemmyException("Exception during regexpr using", 69 e)); 70 } 71 } else { 72 return parse(caption, match); 73 } 74 } 75 76 /** 77 * Checks that caption matshes the pattern. Understands only "." (any 78 * symbol) and "*" (repeat symbol). Used for 1.3 and earclier javas, 79 * starting from 1.4 {@code java.util.regex.Pattern} class is used. 80 * 81 * @param caption a caption to compare with the pattern. 82 * @param match a pattern 83 * @return true if the caption matches the pattern. 84 */ parse(String caption, String match)85 public boolean parse(String caption, String match) { 86 if (match.length() == 0 87 && caption.length() == 0) { 88 return true; 89 } else if (match.length() == 0) { 90 return false; 91 } 92 int c0 = match.charAt(0); 93 int c1 = IGNORE_SIMBOL; 94 if (match.length() > 1) { 95 c1 = match.charAt(1); 96 } 97 int shift = 1; 98 switch (c0) { 99 case '\\': 100 if (match.length() == 1) { 101 throw (new RegExParsingException("\\ is not appropriate")); 102 } 103 c0 = match.charAt(1); 104 if (match.length() > 2) { 105 c1 = match.charAt(2); 106 } else { 107 c1 = IGNORE_SIMBOL; 108 } 109 shift = 2; 110 break; 111 case '.': 112 c0 = ANY_SIMBOL; 113 break; 114 case '*': 115 throw (new RegExParsingException("* is not appropriate")); 116 } 117 if (c1 == '*') { 118 shift = shift + 1; 119 int i = 0; 120 while (i <= caption.length()) { 121 if (i == 0 122 || checkOne(caption.substring(i - 1), c0)) { 123 if (parse(caption.substring(i), match.substring(shift))) { 124 return true; 125 } 126 } else { 127 return false; 128 } 129 i++; 130 } 131 return false; 132 } else { 133 if (caption.length() == 0) { 134 return false; 135 } 136 if (checkOne(caption, c0)) { 137 return parse(caption.substring(1), match.substring(shift)); 138 } else { 139 return false; 140 } 141 } 142 } 143 checkOne(String caption, int simbol)144 private boolean checkOne(String caption, int simbol) { 145 return (simbol == ANY_SIMBOL 146 || simbol == caption.charAt(0)); 147 } 148 149 /** 150 * Thrown in case of parsing error. 151 */ 152 public static class RegExParsingException extends JemmyException { 153 154 private static final long serialVersionUID = 42L; 155 156 /** 157 * Constructs a RegExComparator$RegExParsingException object. 158 * 159 * @param message an error message 160 */ RegExParsingException(String message)161 public RegExParsingException(String message) { 162 super(message); 163 } 164 165 /** 166 * Constructs a RegExComparator$RegExParsingException object. 167 * 168 * @param message an error message 169 * @param innerException a parsing exception. 170 */ RegExParsingException(String message, Exception innerException)171 public RegExParsingException(String message, Exception innerException) { 172 super(message, innerException); 173 } 174 } 175 } 176