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

org.nuiton.validator.bean.BeanUtil Maven / Gradle / Ivy

The newest version!
package org.nuiton.validator.bean;

/*-
 * #%L
 * Validation :: API
 * %%
 * Copyright (C) 2021 - 2024 Ultreia.io
 * %%
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU 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 General Public License for more details.
 *
 * You should have received a copy of the GNU General Public
 * License along with this program.  If not, see
 * .
 * #L%
 */

import java.beans.IntrospectionException;
import java.beans.Introspector;
import java.beans.PropertyChangeListener;
import java.beans.PropertyDescriptor;
import java.lang.reflect.InvocationTargetException;
import java.util.HashSet;
import java.util.Set;

/**
 * Created on 03/05/2022.
 *
 * @author Tony Chemit - [email protected]
 * @since 1.0.3
 */
public class BeanUtil {

    public static final String ADD_PROPERTY_CHANGE_LISTENER =
            "addPropertyChangeListener";

    public static final String REMOVE_PROPERTY_CHANGE_LISTENER =
            "removePropertyChangeListener";


    /**
     * Test if the given type is JavaBean compiliant, says that it has two
     * public methods :
     * 
    *
  • {@code addPropertyChangeListener}
  • *
  • {@code removePropertyChangeListener}
  • *
* * @param type type to test * @return {@code true} if type is Javabean compiliant, {@code false} * otherwise * @since 2.0 */ public static boolean isJavaBeanCompiliant(Class type) { try { type.getMethod(ADD_PROPERTY_CHANGE_LISTENER, PropertyChangeListener.class); } catch (NoSuchMethodException e) { // no add method return false; } try { type.getMethod(REMOVE_PROPERTY_CHANGE_LISTENER, PropertyChangeListener.class); } catch (NoSuchMethodException e) { // no add method return false; } return true; } /** * Add the given {@code listener} to the given {@code bean} using the * normalized method named {@code addPropertyChangeListener}. * * @param listener the listener to add * @param bean the bean on which the listener is added * @throws InvocationTargetException if could not invoke the method * {@code addPropertyChangeListener} * @throws NoSuchMethodException if method * {@code addPropertyChangeListener} * does not exist on given bean * @throws IllegalAccessException if an illegal access occurs when * invoking the method * {@code addPropertyChangeListener} */ public static void addPropertyChangeListener(PropertyChangeListener listener, Object bean) throws InvocationTargetException, NoSuchMethodException, IllegalAccessException { bean.getClass().getMethod(ADD_PROPERTY_CHANGE_LISTENER, PropertyChangeListener.class).invoke(bean, listener); // MethodUtils.invokeExactMethod(bean, // ADD_PROPERTY_CHANGE_LISTENER, // new Object[]{listener}, // new Class[]{PropertyChangeListener.class} // ); } /** * Remove the given {@code listener} from the given {@code bean} using the * normalized method named {@code removePropertyChangeListener}. * * @param listener the listener to remove * @param bean the bean on which the listener is removed * @throws InvocationTargetException if could not invoke the method * {@code removePropertyChangeListener} * @throws NoSuchMethodException if method * {@code removePropertyChangeListener} * does not exist on given bean * @throws IllegalAccessException if an illegal access occurs when * invoking the method * {@code removePropertyChangeListener} */ public static void removePropertyChangeListener(PropertyChangeListener listener, Object bean) throws InvocationTargetException, NoSuchMethodException, IllegalAccessException { bean.getClass().getMethod(REMOVE_PROPERTY_CHANGE_LISTENER, PropertyChangeListener.class).invoke(bean, listener); // MethodUtils.invokeExactMethod(bean, // REMOVE_PROPERTY_CHANGE_LISTENER, // new Object[]{listener}, // new Class[]{PropertyChangeListener.class} // ); } /** * Obtains all readable properties from a given type. * * @param beanType the type to seek * @return the set of all readable properties for the given type * @since 2.0 */ public static Set getReadableProperties(Class beanType) { Set> exploredTypes = new HashSet<>(); Set result = new HashSet<>(); // get properties for the class getReadableProperties(beanType, result, exploredTypes); // the special getClass will never be a JavaBean property... result.remove("class"); return result; } protected static void getReadableProperties(Class beanType, Set result, Set> exploredTypes) { if (exploredTypes.contains(beanType)) { // already explored return; } exploredTypes.add(beanType); // get properties for the class getReadableProperties(beanType, result); if (beanType.getSuperclass() != null) { // get properties fro super-class getReadableProperties(beanType.getSuperclass(), result, exploredTypes); } Class[] interfaces = beanType.getInterfaces(); for (Class anInterface : interfaces) { // get properties fro super-class getReadableProperties(anInterface, result, exploredTypes); } } protected static void getReadableProperties(Class beanType, Set result) { PropertyDescriptor[] descriptors = /*PropertyUtils.*/getPropertyDescriptors(beanType); for (PropertyDescriptor descriptor : descriptors) { String name = descriptor.getName(); if (descriptor.getReadMethod() != null) { result.add(name); } } } private static PropertyDescriptor[] getPropertyDescriptors(Class beanType) { PropertyDescriptor[] descriptors; try { descriptors = Introspector.getBeanInfo(beanType).getPropertyDescriptors(); } catch (IntrospectionException e) { throw new RuntimeException(e); } return descriptors; } /** * Obtains all readable properties from a given type. * * @param beanType the type to seek * @param propertyName FIXME * @return the set of all readable properties for the given type * @since 2.0 */ public static boolean isNestedReadableProperty(Class beanType, String propertyName) { boolean result = propertyName.contains("."); if (result) { int dotIndex = propertyName.indexOf("."); String firstLevelProperty = propertyName.substring(0, dotIndex); Class nestedType = getReadableType(beanType, firstLevelProperty); if (nestedType == null) { result = false; } else { String rest = propertyName.substring(dotIndex + 1); result = isNestedReadableProperty(nestedType, rest); } } else { // not a nested property check it directly Class nestedType = getReadableType(beanType, propertyName); result = nestedType != null; } return result; } public static Class getReadableType(Class beanType, String propertyName) { PropertyDescriptor[] descriptors = /*PropertyUtils.*/getPropertyDescriptors(beanType); Class result = null; for (PropertyDescriptor descriptor : descriptors) { String name = descriptor.getName(); if (descriptor.getReadMethod() != null && propertyName.equals(name)) { result = descriptor.getReadMethod().getReturnType(); break; } } if (result == null) { // try with super-class if (beanType.getSuperclass() != null) { // get properties fro super-class result = getReadableType(beanType.getSuperclass(), propertyName); } } if (result == null) { // try it with interfaces Class[] interfaces = beanType.getInterfaces(); for (Class anInterface : interfaces) { result = getReadableType(anInterface, propertyName); if (result != null) { // found it break; } } } return result; } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy