Search in sources :

Example 1 with ClassFactory

use of org.h2.util.Utils.ClassFactory in project h2database by h2database.

the class JdbcUtils method loadUserClass.

/**
 * Load a class, but check if it is allowed to load this class first. To
 * perform access rights checking, the system property h2.allowedClasses
 * needs to be set to a list of class file name prefixes.
 *
 * @param className the name of the class
 * @return the class object
 */
@SuppressWarnings("unchecked")
public static <Z> Class<Z> loadUserClass(String className) {
    if (allowedClassNames == null) {
        // initialize the static fields
        String s = SysProperties.ALLOWED_CLASSES;
        ArrayList<String> prefixes = New.arrayList();
        boolean allowAll = false;
        HashSet<String> classNames = new HashSet<>();
        for (String p : StringUtils.arraySplit(s, ',', true)) {
            if (p.equals("*")) {
                allowAll = true;
            } else if (p.endsWith("*")) {
                prefixes.add(p.substring(0, p.length() - 1));
            } else {
                classNames.add(p);
            }
        }
        allowedClassNamePrefixes = prefixes.toArray(new String[0]);
        allowAllClasses = allowAll;
        allowedClassNames = classNames;
    }
    if (!allowAllClasses && !allowedClassNames.contains(className)) {
        boolean allowed = false;
        for (String s : allowedClassNamePrefixes) {
            if (className.startsWith(s)) {
                allowed = true;
            }
        }
        if (!allowed) {
            throw DbException.get(ErrorCode.ACCESS_DENIED_TO_CLASS_1, className);
        }
    }
    // Use provided class factory first.
    for (ClassFactory classFactory : getUserClassFactories()) {
        if (classFactory.match(className)) {
            try {
                Class<?> userClass = classFactory.loadClass(className);
                if (userClass != null) {
                    return (Class<Z>) userClass;
                }
            } catch (Exception e) {
                throw DbException.get(ErrorCode.CLASS_NOT_FOUND_1, e, className);
            }
        }
    }
    // Use local ClassLoader
    try {
        return (Class<Z>) Class.forName(className);
    } catch (ClassNotFoundException e) {
        try {
            return (Class<Z>) Class.forName(className, true, Thread.currentThread().getContextClassLoader());
        } catch (Exception e2) {
            throw DbException.get(ErrorCode.CLASS_NOT_FOUND_1, e, className);
        }
    } catch (NoClassDefFoundError e) {
        throw DbException.get(ErrorCode.CLASS_NOT_FOUND_1, e, className);
    } catch (Error e) {
        // UnsupportedClassVersionError
        throw DbException.get(ErrorCode.GENERAL_ERROR_1, e, className);
    }
}
Also used : ClassFactory(org.h2.util.Utils.ClassFactory) IOException(java.io.IOException) DbException(org.h2.message.DbException) ObjectStreamClass(java.io.ObjectStreamClass) HashSet(java.util.HashSet)

Aggregations

IOException (java.io.IOException)1 ObjectStreamClass (java.io.ObjectStreamClass)1 HashSet (java.util.HashSet)1 DbException (org.h2.message.DbException)1 ClassFactory (org.h2.util.Utils.ClassFactory)1