/* MonkeyTalk - a cross-platform functional testing tool Copyright (C) 2012 Gorilla Logic, Inc. This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. */ package com.gorillalogic.fonemonkey; import java.lang.reflect.Method; import java.util.regex.Pattern; public class PropertyUtil { /** * Gets a property from a root object and a path. e.g. "font.name" would translate to * getFont().getName() */ public static String getProperty(Object obj, String path) throws Throwable { int dot = path.indexOf('.'); if (dot < 0) { return "" + getValue(obj, path); } Object ret = getValue(obj, path.substring(0, dot)); if (ret == null) { throw new IllegalArgumentException("No such property or unable to retrieve value for " + path.substring(0, dot) + " on object " + obj); } return getProperty(ret, path.substring(dot + 1)); } private static Object getValue(Object obj, String name) throws Throwable { String method = "get" + Character.toUpperCase(name.charAt(0)) + name.substring(1); String method2 = "is" + Character.toUpperCase(name.charAt(0)) + name.substring(1); try { // Not supported in API 8 // Method meth = obj.getClass().getMethod(method, null); Method meth = getMethod(obj.getClass(), method, method2); if (meth == null) { throw new IllegalArgumentException("No such property method " + method + " or " + method2 + " on class " + obj.getClass().getName()); } return meth.invoke(obj); } catch (Throwable e) { Log.log(e); throw e; } } private static Method getMethod(Class<?> klass, String name, String name2) throws Exception { Method[] methods = klass.getMethods(); for (int i = 0; i < methods.length; ++i) { if (methods[i].getParameterTypes().length == 0) { if (methods[i].getName().equals(name) || methods[i].getName().equals(name2)) return methods[i]; } } return null; } public static boolean wildcardMatch(String wc, String s) { if (s == null || wc == null) { return false; } return matchWildcard(s, wc); } /** * A better wildcard pattern matcher (written by Justin). * * @param src * the string to search for the pattern * @param pattern * the wildcard pattern (containing * and ?) * @return true if matches, otherwise false */ private static boolean matchWildcard(String src, String pattern) { // first, escape everything in the pattern that's not a wildcard char (either * or ?) StringBuilder sb = new StringBuilder(); for (char c : pattern.toCharArray()) { if ("*?".indexOf(c) != -1) { sb.append(c); } else { // not wildcard char, so escape it sb.append("\\Q").append(c).append("\\E"); } } // 1. replace * (or repeated *'s) with .* // 2. replace ? with . pattern = sb.toString().replaceAll("\\*+", ".*").replaceAll("\\?", "."); Pattern p = Pattern.compile(pattern, Pattern.DOTALL | Pattern.MULTILINE); return p.matcher(src).matches(); } /** * Adapted from org.apache.commons.digester.SimpleRegexMatcher */ // private static boolean wcmatch(String basePattern, String regexPattern, int baseAt, int // regexAt) { // if (regexAt >= regexPattern.length()) { // // maybe we've got a match // if (baseAt >= basePattern.length()) { // // ok! // return true; // } // // run out early // return false; // } else { // if (baseAt >= basePattern.length()) { // // run out early // return false; // } // } // // // ok both within bounds // char regexCurrent = regexPattern.charAt(regexAt); // switch (regexCurrent) { // case '*': // // this is the tricky case // // check for terminal // if (++regexAt >= regexPattern.length()) { // // this matches anything let - so return true // return true; // } // // go through every subsequent apperance of the next character // // and so if the rest of the regex matches // char nextRegex = regexPattern.charAt(regexAt); // int nextMatch = basePattern.indexOf(nextRegex, baseAt); // while (nextMatch != -1) { // if (wcmatch(basePattern, regexPattern, nextMatch, regexAt)) { // return true; // } // nextMatch = basePattern.indexOf(nextRegex, nextMatch + 1); // } // return false; // case '?': // // this matches anything // return wcmatch(basePattern, regexPattern, ++baseAt, ++regexAt); // default: // if (regexCurrent == basePattern.charAt(baseAt)) { // // still got more to go // return wcmatch(basePattern, regexPattern, ++baseAt, ++regexAt); // } // return false; // } // } }