com.gorillalogic.fonemonkey.PropertyUtil.java Source code

Java tutorial

Introduction

Here is the source code for com.gorillalogic.fonemonkey.PropertyUtil.java

Source

/*  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;
    // }
    // }
}