All Downloads are FREE. Search and download functionalities are using the official Maven repository.

grails.util.GrailsClassUtils Maven / Gradle / Ivy

The newest version!
/*
 * Copyright 2004-2023 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package grails.util;

import java.beans.PropertyDescriptor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.SortedSet;
import java.util.TreeSet;

import groovy.lang.AdaptingMetaClass;
import groovy.lang.ExpandoMetaClass;
import groovy.lang.ExpandoMetaClassCreationHandle;
import groovy.lang.GroovySystem;
import groovy.lang.MetaClass;
import groovy.lang.MetaClassRegistry;
import groovy.lang.MetaProperty;
import groovy.util.ConfigObject;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.BeanInstantiationException;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.BeanWrapper;
import org.springframework.beans.BeanWrapperImpl;
import org.springframework.beans.BeansException;
import org.springframework.beans.FatalBeanException;
import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
import org.springframework.util.ReflectionUtils;
import org.springframework.util.StringUtils;

/**
 * Utility methods for dealing with Grails class artifacts.
 *
 * @author Graeme Rocher
 */
public final class GrailsClassUtils {

    private static final Log logger = LogFactory.getLog(GrailsClassUtils.class);

    public static final Map, Class> PRIMITIVE_TYPE_COMPATIBLE_CLASSES = new HashMap<>();

    /**
     * Just add two entries to the class compatibility map
     * @param left
     * @param right
     */
    private static void registerPrimitiveClassPair(Class left, Class right) {
        PRIMITIVE_TYPE_COMPATIBLE_CLASSES.put(left, right);
        PRIMITIVE_TYPE_COMPATIBLE_CLASSES.put(right, left);
    }

    static {
        registerPrimitiveClassPair(Boolean.class, boolean.class);
        registerPrimitiveClassPair(Integer.class, int.class);
        registerPrimitiveClassPair(Short.class, short.class);
        registerPrimitiveClassPair(Byte.class, byte.class);
        registerPrimitiveClassPair(Character.class, char.class);
        registerPrimitiveClassPair(Long.class, long.class);
        registerPrimitiveClassPair(Float.class, float.class);
        registerPrimitiveClassPair(Double.class, double.class);
    }

    private GrailsClassUtils() {
    }

    /**
     * Return all interfaces that the given instance implements as array,
     * including ones implemented by superclasses.
     * @param instance the instance to analyze for interfaces
     * @return all interfaces that the given instance implements as array
     */
    public static Class[] getAllInterfaces(Object instance) {
        Assert.notNull(instance, "Instance must not be null");
        return getAllInterfacesForClass(instance.getClass());
    }

    /**
     * Return all interfaces that the given class implements as array,
     * including ones implemented by superclasses.
     * 

If the class itself is an interface, it gets returned as sole interface. * @param clazz the class to analyze for interfaces * @return all interfaces that the given object implements as array */ public static Class[] getAllInterfacesForClass(Class clazz) { return getAllInterfacesForClass(clazz, null); } /** * Return all interfaces that the given class implements as array, * including ones implemented by superclasses. *

If the class itself is an interface, it gets returned as sole interface. * @param clazz the class to analyze for interfaces * @param classLoader the ClassLoader that the interfaces need to be visible in * (may be {@code null} when accepting all declared interfaces) * @return all interfaces that the given object implements as array */ public static Class[] getAllInterfacesForClass(Class clazz, ClassLoader classLoader) { Set ifcs = getAllInterfacesForClassAsSet(clazz, classLoader); return ifcs.toArray(new Class[0]); } /** * Return all interfaces that the given instance implements as Set, * including ones implemented by superclasses. * @param instance the instance to analyze for interfaces * @return all interfaces that the given instance implements as Set */ public static Set getAllInterfacesAsSet(Object instance) { Assert.notNull(instance, "Instance must not be null"); return getAllInterfacesForClassAsSet(instance.getClass()); } /** * Return all interfaces that the given class implements as Set, * including ones implemented by superclasses. *

If the class itself is an interface, it gets returned as sole interface. * @param clazz the class to analyze for interfaces * @return all interfaces that the given object implements as Set */ public static Set getAllInterfacesForClassAsSet(Class clazz) { return getAllInterfacesForClassAsSet(clazz, null); } /** * Return all interfaces that the given class implements as Set, * including ones implemented by superclasses. *

If the class itself is an interface, it gets returned as sole interface. * @param clazz the class to analyze for interfaces * @param classLoader the ClassLoader that the interfaces need to be visible in * (may be {@code null} when accepting all declared interfaces) * @return all interfaces that the given object implements as Set */ public static Set getAllInterfacesForClassAsSet(Class clazz, ClassLoader classLoader) { Assert.notNull(clazz, "Class must not be null"); Set interfaces = new LinkedHashSet<>(); while (clazz != null) { Class[] ifcs = clazz.getInterfaces(); for (Class ifc : ifcs) { interfaces.add(ifc); interfaces.addAll(getAllInterfacesForClassAsSet(ifc, classLoader)); } clazz = clazz.getSuperclass(); } return interfaces; } /** * Check whether the given class is visible in the given ClassLoader. * @param clazz the class to check (typically an interface) * @param classLoader the ClassLoader to check against (may be {@code null}, * in which case this method will always return {@code true}) */ public static boolean isVisible(Class clazz, ClassLoader classLoader) { if (classLoader == null) { return true; } try { Class actualClass = classLoader.loadClass(clazz.getName()); return (clazz == actualClass); // Else: different interface class found... } catch (ClassNotFoundException ex) { // No interface class found... return false; } } /** * Returns true if the specified property in the specified class is of the specified type * * @param clazz The class which contains the property * @param propertyName The property name * @param type The type to check * * @return A boolean value */ public static boolean isPropertyOfType(Class clazz, String propertyName, Class type) { try { Class propType = getPropertyType(clazz, propertyName); return propType != null && propType.equals(type); } catch (Exception e) { return false; } } /** * Returns the value of the specified property and type from an instance of the specified Grails class * * @param clazz The name of the class which contains the property * @param propertyName The property name * @param propertyType The property type * * @return The value of the property or null if none exists */ @SuppressWarnings({ "unchecked", "rawtypes" }) public static Object getPropertyValueOfNewInstance(Class clazz, String propertyName, Class propertyType) { // validate if (clazz == null || !StringUtils.hasText(propertyName)) { return null; } try { return getPropertyOrStaticPropertyOrFieldValue(BeanUtils.instantiateClass(clazz), propertyName); } catch (BeanInstantiationException e) { return null; } } /** * Returns the value of the specified property and type from an instance of the specified Grails class * * @param clazz The name of the class which contains the property * @param propertyName The property name * * @return The value of the property or null if none exists */ public static Object getPropertyValueOfNewInstance(Class clazz, String propertyName) { // validate if (clazz == null || !StringUtils.hasText(propertyName)) { return null; } try { return getPropertyOrStaticPropertyOrFieldValue(BeanUtils.instantiateClass(clazz), propertyName); } catch (BeanInstantiationException e) { return null; } } /** * Retrieves a PropertyDescriptor for the specified instance and property value * * @param instance The instance * @param propertyValue The value of the property * @return The PropertyDescriptor */ public static PropertyDescriptor getPropertyDescriptorForValue(Object instance, Object propertyValue) { if (instance == null || propertyValue == null) { return null; } PropertyDescriptor[] descriptors = BeanUtils.getPropertyDescriptors(instance.getClass()); for (PropertyDescriptor pd : descriptors) { if (isAssignableOrConvertibleFrom(pd.getPropertyType(), propertyValue.getClass())) { Object value; try { ReflectionUtils.makeAccessible(pd.getReadMethod()); value = pd.getReadMethod().invoke(instance); } catch (Exception e) { throw new FatalBeanException("Problem calling readMethod of " + pd, e); } if (propertyValue.equals(value)) { return pd; } } } return null; } /** * Returns the type of the given property contained within the specified class * * @param clazz The class which contains the property * @param propertyName The name of the property * * @return The property type or null if none exists */ public static Class getPropertyType(Class clazz, String propertyName) { if (clazz == null || !StringUtils.hasText(propertyName)) { return null; } try { PropertyDescriptor desc = BeanUtils.getPropertyDescriptor(clazz, propertyName); if (desc != null) { return desc.getPropertyType(); } return null; } catch (Exception e) { // if there are any errors in instantiating just return null for the moment return null; } } /** * Retrieves all the properties of the given class for the given type * * @param clazz The class to retrieve the properties from * @param propertyType The type of the properties you wish to retrieve * * @return An array of PropertyDescriptor instances */ public static PropertyDescriptor[] getPropertiesOfType(Class clazz, Class propertyType) { if (clazz == null || propertyType == null) { return new PropertyDescriptor[0]; } Set properties = new HashSet<>(); PropertyDescriptor descriptor = null; try { PropertyDescriptor[] descriptors = BeanUtils.getPropertyDescriptors(clazz); for (PropertyDescriptor propertyDescriptor : descriptors) { descriptor = propertyDescriptor; Class currentPropertyType = descriptor.getPropertyType(); if (isTypeInstanceOfPropertyType(propertyType, currentPropertyType)) { properties.add(descriptor); } } } catch (Exception e) { if (descriptor == null) { logger.error(String.format("Got exception while checking property descriptors for class %s", clazz.getName()), e); } else { logger.error(String.format("Got exception while checking PropertyDescriptor.propertyType for field %s.%s", clazz.getName(), descriptor.getName()), e); } // if there are any errors in instantiating just return null for the moment return new PropertyDescriptor[0]; } return properties.toArray(new PropertyDescriptor[0]); } private static boolean isTypeInstanceOfPropertyType(Class type, Class propertyType) { return propertyType.isAssignableFrom(type) && !propertyType.equals(Object.class); } /** * Retrieves all the properties of the given class which are assignable to the given type * * @param clazz The class to retrieve the properties from * @param propertySuperType The type of the properties you wish to retrieve * @return An array of PropertyDescriptor instances */ public static PropertyDescriptor[] getPropertiesAssignableToType(Class clazz, Class propertySuperType) { if (clazz == null || propertySuperType == null) { return new PropertyDescriptor[0]; } Set properties = new HashSet<>(); PropertyDescriptor descriptor = null; try { PropertyDescriptor[] descriptors = BeanUtils.getPropertyDescriptors(clazz); for (PropertyDescriptor propertyDescriptor : descriptors) { descriptor = propertyDescriptor; Class currentPropertyType = descriptor.getPropertyType(); if (propertySuperType.isAssignableFrom(descriptor.getPropertyType())) { properties.add(descriptor); } } } catch (Exception e) { if (descriptor == null) { logger.error(String.format("Got exception while checking property descriptors for class %s", clazz.getName()), e); } else { logger.error(String.format("Got exception while checking PropertyDescriptor.propertyType for field %s.%s", clazz.getName(), descriptor.getName()), e); } return new PropertyDescriptor[0]; } return properties.toArray(new PropertyDescriptor[0]); } /** * Retrieves a property of the given class of the specified name and type * @param clazz The class to retrieve the property from * @param propertyName The name of the property * @param propertyType The type of the property * * @return A PropertyDescriptor instance or null if none exists */ public static PropertyDescriptor getProperty(Class clazz, String propertyName, Class propertyType) { if (clazz == null || propertyName == null || propertyType == null) { return null; } try { PropertyDescriptor pd = BeanUtils.getPropertyDescriptor(clazz, propertyName); if (pd != null && pd.getPropertyType().equals(propertyType)) { return pd; } return null; } catch (Exception e) { // if there are any errors in instantiating just return null for the moment return null; } } /** * Retrieves a property of the given class of the specified name and type * @param clazz The class to retrieve the property from * @param propertyName The name of the property * * @return A PropertyDescriptor instance or null if none exists */ public static PropertyDescriptor getProperty(Class clazz, String propertyName) { if (clazz == null || propertyName == null) { return null; } try { return BeanUtils.getPropertyDescriptor(clazz, propertyName); } catch (Exception e) { // if there are any errors in instantiating just return null for the moment return null; } } /** * Convenience method for converting a collection to an Object[] * @param c The collection * @return An object array */ @SuppressWarnings({ "unchecked", "rawtypes" }) public static Object[] collectionToObjectArray(Collection c) { if (c == null) { return new Object[0]; } return c.toArray(new Object[0]); } /** * Detect if left and right types are matching types. In particular, * test if one is a primitive type and the other is the corresponding * Java wrapper type. Primitive and wrapper classes may be passed to * either arguments. * * @param leftType * @param rightType * @return true if one of the classes is a native type and the other the object representation * of the same native type */ @SuppressWarnings("rawtypes") public static boolean isMatchBetweenPrimativeAndWrapperTypes(Class leftType, Class rightType) { if (leftType == null) { throw new NullPointerException("Left type is null!"); } if (rightType == null) { throw new NullPointerException("Right type is null!"); } Class r = PRIMITIVE_TYPE_COMPATIBLE_CLASSES.get(leftType); return r == rightType; } /** *

Tests whether or not the left hand type is compatible with the right hand type in Groovy * terms, i.e. can the left type be assigned a value of the right hand type in Groovy.

*

This handles Java primitive type equivalence and uses isAssignableFrom for all other types, * with a bit of magic for native types and polymorphism i.e. Number assigned an int. * If either parameter is null an exception is thrown

* * @param leftType The type of the left hand part of a notional assignment * @param rightType The type of the right hand part of a notional assignment * @return true if values of the right hand type can be assigned in Groovy to variables of the left hand type. */ public static boolean isGroovyAssignableFrom(Class leftType, Class rightType) { if (leftType == null) { throw new NullPointerException("Left type is null!"); } if (rightType == null) { throw new NullPointerException("Right type is null!"); } if (leftType == Object.class) { return true; } if (leftType == rightType) { return true; } // check for primitive type equivalence Class r = PRIMITIVE_TYPE_COMPATIBLE_CLASSES.get(leftType); boolean result = r == rightType; if (!result) { // If no primitive <-> wrapper match, it may still be assignable // from polymorphic primitives i.e. Number -> int (AKA Integer) if (rightType.isPrimitive()) { // see if incompatible r = PRIMITIVE_TYPE_COMPATIBLE_CLASSES.get(rightType); if (r != null) { result = leftType.isAssignableFrom(r); } } else { // Otherwise it may just be assignable using normal Java polymorphism result = leftType.isAssignableFrom(rightType); } } return result; } /** *

Work out if the specified property is readable and static. Java introspection does not * recognize this concept of static properties but Groovy does. We also consider public static fields * as static properties with no getters/setters

* * @param clazz The class to check for static property * @param propertyName The property name * @return true if the property with name propertyName has a static getter method */ @SuppressWarnings("rawtypes") public static boolean isStaticProperty(Class clazz, String propertyName) { Method getter = BeanUtils.findDeclaredMethod(clazz, getGetterName(propertyName), (Class[]) null); if (getter != null) { return isPublicStatic(getter); } try { Field f = clazz.getDeclaredField(propertyName); if (f != null) { return isPublicStatic(f); } } catch (NoSuchFieldException ignored) { } return false; } /** * Determine whether the method is declared public static * @param m * @return true if the method is declared public static */ public static boolean isPublicStatic(Method m) { int modifiers = m.getModifiers(); return Modifier.isPublic(modifiers) && Modifier.isStatic(modifiers); } /** * Determine whether the field is declared public static * @param f * @return true if the field is declared public static */ public static boolean isPublicStatic(Field f) { int modifiers = f.getModifiers(); return Modifier.isPublic(modifiers) && Modifier.isStatic(modifiers); } /** * Calculate the name for a getter method to retrieve the specified property * @param propertyName * @return The name for the getter method for this property, if it were to exist, i.e. getConstraints */ public static String getGetterName(String propertyName) { return GrailsNameUtils.getGetterName(propertyName); } /** *

Get a static field value.

* * @param clazz The class to check for static property * @param name The field name * @return The value if there is one, or null if unset OR there is no such field */ public static Object getStaticFieldValue(Class clazz, String name) { Field field = ReflectionUtils.findField(clazz, name); if (field != null) { ReflectionUtils.makeAccessible(field); try { return field.get(clazz); } catch (IllegalAccessException ignored) { } } return null; } /** *

Get a static property value, which has a public static getter or is just a public static field.

* * @param clazz The class to check for static property * @param name The property name * @return The value if there is one, or null if unset OR there is no such property */ public static Object getStaticPropertyValue(Class clazz, String name) { Method getter = BeanUtils.findDeclaredMethod(clazz, getGetterName(name), (Class[]) null); try { if (getter != null) { ReflectionUtils.makeAccessible(getter); return getter.invoke(clazz); } return getStaticFieldValue(clazz, name); } catch (Exception ignored) { } return null; } /** *

Looks for a property of the reference instance with a given name.

*

If found its value is returned. We follow the Java bean conventions with augmentation for groovy support * and static fields/properties. We will therefore match, in this order: *

*
    *
  1. Standard public bean property (with getter or just public field, using normal introspection) *
  2. Public static property with getter method *
  3. Public static field *
* * @return property value or null if no property found */ public static Object getPropertyOrStaticPropertyOrFieldValue(Object obj, String name) throws BeansException { BeanWrapper ref = new BeanWrapperImpl(obj); return getPropertyOrStaticPropertyOrFieldValue(ref, obj, name); } public static Object getPropertyOrStaticPropertyOrFieldValue(BeanWrapper ref, Object obj, String name) { if (ref.isReadableProperty(name)) { return ref.getPropertyValue(name); } // Look for public fields if (isPublicField(obj, name)) { return getFieldValue(obj, name); } // Look for statics Class clazz = obj.getClass(); if (isStaticProperty(clazz, name)) { return getStaticPropertyValue(clazz, name); } return null; } /** * Get the value of a declared field on an object * * @param obj * @param name * @return The object value or null if there is no such field or access problems */ public static Object getFieldValue(Object obj, String name) { Class clazz = obj.getClass(); try { Field f = clazz.getDeclaredField(name); return f.get(obj); } catch (Exception e) { return null; } } /** * Work out if the specified object has a public field with the name supplied. * * @param obj * @param name * @return true if a public field with the name exists */ public static boolean isPublicField(Object obj, String name) { Class clazz = obj.getClass(); try { Field f = clazz.getDeclaredField(name); return Modifier.isPublic(f.getModifiers()); } catch (NoSuchFieldException e) { return false; } } /** * Checks whether the specified property is inherited from a super class * * @param clz The class to check * @param propertyName The property name * @return true if the property is inherited */ @SuppressWarnings("rawtypes") public static boolean isPropertyInherited(Class clz, String propertyName) { if (clz == null) { return false; } Assert.isTrue(StringUtils.hasText(propertyName), "Argument [propertyName] cannot be null or blank"); Class superClass = clz.getSuperclass(); PropertyDescriptor pd = BeanUtils.getPropertyDescriptor(superClass, propertyName); if (pd != null && pd.getReadMethod() != null) { return true; } return false; } /** * Check whether the specified method is a property getter * * @param method The method * @return true if the method is a property getter */ public static boolean isPropertyGetter(Method method) { return !Modifier.isStatic(method.getModifiers()) && Modifier.isPublic(method.getModifiers()) && GrailsNameUtils.isGetter(method.getName(), method.getReturnType(), method.getParameterTypes()); } /** * Creates a concrete collection for the suppied interface * @param interfaceType The interface * @return ArrayList for List, TreeSet for SortedSet, HashSet for Set etc. */ @SuppressWarnings("rawtypes") public static Collection createConcreteCollection(Class interfaceType) { Collection elements; if (interfaceType.equals(List.class) || interfaceType.equals(Collection.class)) { elements = new ArrayList(); } else if (interfaceType.equals(SortedSet.class)) { elements = new TreeSet(); } else { elements = new HashSet(); } return elements; } /** * Returns true if the name of the method specified and the number of arguments make it a javabean property setter. * The name is assumed to be a valid Java method name, that is not verified. * * @param name The name of the method * @param args The arguments * @return true if it is a javabean property setter */ @SuppressWarnings("rawtypes") public static boolean isSetter(String name, Class[] args) { if (!StringUtils.hasText(name) || args == null) { return false; } if (name.startsWith("set")) { if (args.length != 1) { return false; } return GrailsNameUtils.isPropertyMethodSuffix(name.substring(3)); } return false; } @SuppressWarnings("rawtypes") public static MetaClass getExpandoMetaClass(Class clazz) { MetaClassRegistry registry = GroovySystem.getMetaClassRegistry(); Assert.isTrue(registry.getMetaClassCreationHandler() instanceof ExpandoMetaClassCreationHandle, "Grails requires an instance of [ExpandoMetaClassCreationHandle] to be set in Groovy's MetaClassRegistry! (current is : " + registry.getMetaClassCreationHandler() + ")"); MetaClass mc = registry.getMetaClass(clazz); AdaptingMetaClass adapter = null; if (mc instanceof AdaptingMetaClass) { adapter = (AdaptingMetaClass) mc; mc = ((AdaptingMetaClass) mc).getAdaptee(); } if (!(mc instanceof ExpandoMetaClass)) { // removes cached version registry.removeMetaClass(clazz); mc = registry.getMetaClass(clazz); if (adapter != null) { adapter.setAdaptee(mc); } } Assert.isTrue(mc instanceof ExpandoMetaClass, "BUG! Method must return an instance of [ExpandoMetaClass]!"); return mc; } /** * Returns true if the specified clazz parameter is either the same as, or is a superclass or superinterface * of, the specified type parameter. Converts primitive types to compatible class automatically. * * @param clazz * @param type * @return true if the class is a taglib * @see java.lang.Class#isAssignableFrom(Class) */ public static boolean isAssignableOrConvertibleFrom(Class clazz, Class type) { if (type == null || clazz == null) { return false; } if (type.isPrimitive()) { // convert primitive type to compatible class Class primitiveClass = GrailsClassUtils.PRIMITIVE_TYPE_COMPATIBLE_CLASSES.get(type); if (primitiveClass == null) { // no compatible class found for primitive type return false; } return clazz.isAssignableFrom(primitiveClass); } return clazz.isAssignableFrom(type); } /** * Retrieves a boolean value from a Map for the given key * * @param key The key that references the boolean value * @param map The map to look in * @return A boolean value which will be false if the map is null, the map doesn't contain the key or the value is false */ public static boolean getBooleanFromMap(String key, Map map) { boolean defaultValue = false; return getBooleanFromMap(key, map, defaultValue); } /** * Retrieves a boolean value from a Map for the given key * * @param key The key that references the boolean value * @param map The map to look in * @return A boolean value which will be false if the map is null, the map doesn't contain the key or the value is false */ public static boolean getBooleanFromMap(String key, Map map, boolean defaultValue) { if (map == null) { return defaultValue; } if (map.containsKey(key)) { Object o = map.get(key); if (o == null) { return defaultValue; } if (o instanceof Boolean) { return (Boolean) o; } return Boolean.parseBoolean(o.toString()); } return defaultValue; } /** * Locates the name of a property for the given value on the target object using Groovy's meta APIs. * Note that this method uses the reference so the incorrect result could be returned for two properties * that refer to the same reference. Use with caution. * * @param target The target * @param obj The property value * @return The property name or null */ public static String findPropertyNameForValue(Object target, Object obj) { MetaClass mc = GroovySystem.getMetaClassRegistry().getMetaClass(target.getClass()); List metaProperties = mc.getProperties(); for (MetaProperty metaProperty : metaProperties) { if (isAssignableOrConvertibleFrom(metaProperty.getType(), obj.getClass())) { Object val = metaProperty.getProperty(target); if (val != null && val.equals(obj)) { return metaProperty.getName(); } } } return null; } /** * Retrieves the name of a setter for the specified property name * @param propertyName The property name * @return The setter equivalent */ public static String getSetterName(String propertyName) { return GrailsNameUtils.getSetterName(propertyName); } /** * Returns true if the name of the method specified and the number of arguments make it a javabean property getter. * The name is assumed to be a valid Java method name, that is not verified. * * @param name The name of the method * @param args The arguments * @return true if it is a javabean property getter * @deprecated use {@link #isGetter(String, Class, Class[])} instead because this method has a defect for "is.." method with Boolean return types. */ @Deprecated public static boolean isGetter(String name, Class[] args) { return GrailsNameUtils.isGetter(name, boolean.class, args); } /** * Returns true if the name of the method specified and the number of arguments make it a javabean property getter. * The name is assumed to be a valid Java method name, that is not verified. * * @param name The name of the method * @param returnType The return type of the method * @param args The arguments * @return true if it is a javabean property getter */ public static boolean isGetter(String name, Class returnType, Class[] args) { return GrailsNameUtils.isGetter(name, returnType, args); } /** * Returns a property name equivalent for the given getter name or null if it is not a valid getter. If not null * or empty the getter name is assumed to be a valid identifier. * * @param getterName The getter name * @return The property name equivalent * @deprecated Use {@link #getPropertyForGetter(String, Class)} instead * because this method has a defect for "is.." method with Boolean return types. */ @Deprecated public static String getPropertyForGetter(String getterName) { return GrailsNameUtils.getPropertyForGetter(getterName); } /** * Returns a property name equivalent for the given getter name and return type or null if it is not a valid getter. If not null * or empty the getter name is assumed to be a valid identifier. * * @param getterName The getter name * @param returnType The type the method returns * @return The property name equivalent */ public static String getPropertyForGetter(String getterName, Class returnType) { return GrailsNameUtils.getPropertyForGetter(getterName, returnType); } /** * Returns a property name equivalent for the given getter name and return type or null if it is not a valid getter. If not null * or empty the getter name is assumed to be a valid identifier. * * @param getterName The getter name * @param returnType The class name the method returns * @return The property name equivalent */ public static String getPropertyForGetter(String getterName, String returnType) { return GrailsNameUtils.getPropertyForGetter(getterName, returnType); } /** * Returns a property name equivalent for the given setter name or null if it is not a valid setter. If not null * or empty the setter name is assumed to be a valid identifier. * * @param setterName The setter name, must be null or empty or a valid identifier name * @return The property name equivalent */ public static String getPropertyForSetter(String setterName) { return GrailsNameUtils.getPropertyForSetter(setterName); } /** * Returns whether the specified class is either within one of the specified packages or * within a subpackage of one of the packages * * @param theClass The class * @param packageList The list of packages * @return true if it is within the list of specified packages */ public static boolean isClassBelowPackage(Class theClass, List packageList) { String classPackage = theClass.getPackage().getName(); for (Object packageName : packageList) { if (packageName != null) { if (classPackage.startsWith(packageName.toString())) { return true; } } } return false; } @SuppressWarnings("unchecked") public static Object instantiateFromConfig(ConfigObject config, String configKey, String defaultClassName) throws InstantiationException, IllegalAccessException, ClassNotFoundException, LinkageError, InvocationTargetException, NoSuchMethodException { return instantiateFromFlatConfig(config.flatten(), configKey, defaultClassName); } public static Object instantiateFromFlatConfig(Map flatConfig, String configKey, String defaultClassName) throws InstantiationException, IllegalAccessException, ClassNotFoundException, LinkageError, NoSuchMethodException, InvocationTargetException { String className = defaultClassName; Object configName = flatConfig.get(configKey); if (configName instanceof CharSequence) { className = configName.toString(); } Class clazz = ClassUtils.forName(className, ClassUtils.getDefaultClassLoader()); return ReflectionUtils.accessibleConstructor(clazz).newInstance(); } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy