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

com.helger.commons.lang.GenericReflection Maven / Gradle / Ivy

The newest version!
/*
 * Copyright (C) 2014-2024 Philip Helger (www.helger.com)
 * philip[at]helger[dot]com
 *
 * 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
 *
 *         http://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 com.helger.commons.lang;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import javax.annotation.concurrent.Immutable;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.helger.commons.ValueEnforcer;
import com.helger.commons.annotation.PresentForCodeCoverage;
import com.helger.commons.collection.ArrayHelper;

/**
 * This is a special helper class that provides many utility methods concerning
 * the usage of reflection etc..
 *
 * @author Philip Helger
 */
@Immutable
public final class GenericReflection
{
  private static final Logger LOGGER = LoggerFactory.getLogger (GenericReflection.class);

  private static final Class  [] EMPTY_CLASS_ARRAY = new Class  [0];

  @PresentForCodeCoverage
  private static final GenericReflection INSTANCE = new GenericReflection ();

  private GenericReflection ()
  {}

  @SuppressWarnings ("unchecked")
  public static  DSTTYPE uncheckedCast (@Nullable final SRCTYPE aObject)
  {
    return (DSTTYPE) aObject;
  }

  @Nonnull
  public static  Class  getClassFromName (@Nonnull final ClassLoader aClassLoader,
                                                              @Nonnull final String sName) throws ClassNotFoundException
  {
    ValueEnforcer.notNull (aClassLoader, "ClassLoader");
    return uncheckedCast (aClassLoader.loadClass (sName));
  }

  @Nonnull
  public static  Class  getClassFromName (@Nonnull final String sName) throws ClassNotFoundException
  {
    return uncheckedCast (Class.forName (sName));
  }

  /**
   * Get the class of the given name
   *
   * @param 
   *        The return type
   * @param aClassLoader
   *        The class loader to be used. May not be null.
   * @param sName
   *        The name to be resolved.
   * @return null if the class could not be resolved
   */
  @Nullable
  public static  Class  getClassFromNameSafe (@Nonnull final ClassLoader aClassLoader, @Nonnull final String sName)
  {
    ValueEnforcer.notNull (aClassLoader, "ClassLoader");
    try
    {
      return getClassFromName (aClassLoader, sName);
    }
    catch (final ClassNotFoundException e)
    {
      return null;
    }
  }

  /**
   * Get the class of the given name
   *
   * @param 
   *        The return type
   * @param sName
   *        The name to be resolved.
   * @return null if the class could not be resolved
   */
  @Nullable
  public static  Class  getClassFromNameSafe (@Nonnull final String sName)
  {
    try
    {
      return getClassFromName (sName);
    }
    catch (final ClassNotFoundException e)
    {
      return null;
    }
  }

  /**
   * Get an array with all the classes of the passed object array.
   *
   * @param aObjs
   *        The object array. May be null. No contained element may
   *        be null.
   * @return A non-null array of classes.
   */
  @Nonnull
  public static Class  [] getClassArray (@Nullable final Object... aObjs)
  {
    if (ArrayHelper.isEmpty (aObjs))
      return EMPTY_CLASS_ARRAY;

    final Class  [] ret = new Class  [aObjs.length];
    for (int i = 0; i < aObjs.length; ++i)
      ret[i] = aObjs[i].getClass ();
    return ret;
  }

  /**
   * This method dynamically invokes the method with the given name on the given
   * object.
   *
   * @param 
   *        The method return type
   * @param aSrcObj
   *        The source object on which the method is to be invoked. May not be
   *        null.
   * @param sMethodName
   *        The method to be invoked.
   * @param aArgs
   *        The arguments to be passed into the method. May be null
   *        . If not null, the members of the array may not be
   *        null because otherwise the classes of the arguments
   *        cannot be determined and will throw an Exception!
   * @return The return value of the invoked method or null for
   *         void methods.
   * @throws NoSuchMethodException
   *         Thrown by reflection
   * @throws IllegalAccessException
   *         Thrown by reflection
   * @throws InvocationTargetException
   *         Thrown by reflection
   */
  @Nullable
  public static  RETURNTYPE invokeMethod (@Nonnull final Object aSrcObj,
                                                      @Nonnull final String sMethodName,
                                                      @Nullable final Object... aArgs) throws NoSuchMethodException,
                                                                                       IllegalAccessException,
                                                                                       InvocationTargetException
  {
    return GenericReflection. invokeMethod (aSrcObj, sMethodName, getClassArray (aArgs), aArgs);
  }

  @Nullable
  public static  RETURNTYPE invokeMethod (@Nonnull final Object aSrcObj,
                                                      @Nonnull final String sMethodName,
                                                      @Nullable final Class  [] aArgClasses,
                                                      @Nullable final Object [] aArgs) throws NoSuchMethodException,
                                                                                       IllegalAccessException,
                                                                                       InvocationTargetException
  {
    final Method aMethod = aSrcObj.getClass ().getDeclaredMethod (sMethodName, aArgClasses);
    final Object aReturn = aMethod.invoke (aSrcObj, aArgs);
    return GenericReflection.uncheckedCast (aReturn);
  }

  @Nullable
  public static  RETURNTYPE invokeStaticMethod (@Nonnull final String sClassName,
                                                            @Nonnull final String sMethodName,
                                                            @Nullable final Object... aArgs) throws NoSuchMethodException,
                                                                                             IllegalAccessException,
                                                                                             InvocationTargetException,
                                                                                             ClassNotFoundException
  {
    return GenericReflection. invokeStaticMethod (getClassFromName (sClassName), sMethodName, aArgs);
  }

  @Nullable
  public static  RETURNTYPE invokeStaticMethod (@Nonnull final Class  aClass,
                                                            @Nonnull final String sMethodName,
                                                            @Nullable final Object... aArgs) throws NoSuchMethodException,
                                                                                             IllegalAccessException,
                                                                                             InvocationTargetException
  {
    return GenericReflection. invokeStaticMethod (aClass, sMethodName, getClassArray (aArgs), aArgs);
  }

  @Nullable
  public static  RETURNTYPE invokeStaticMethod (@Nonnull final String sClassName,
                                                            @Nonnull final String sMethodName,
                                                            @Nullable final Class  [] aArgClasses,
                                                            @Nullable final Object [] aArgs) throws NoSuchMethodException,
                                                                                             IllegalAccessException,
                                                                                             InvocationTargetException,
                                                                                             ClassNotFoundException
  {
    return GenericReflection. invokeStaticMethod (getClassFromName (sClassName), sMethodName, aArgClasses, aArgs);
  }

  @Nullable
  public static  RETURNTYPE invokeStaticMethod (@Nonnull final Class  aClass,
                                                            @Nonnull final String sMethodName,
                                                            @Nullable final Class  [] aArgClasses,
                                                            @Nullable final Object [] aArgs) throws NoSuchMethodException,
                                                                                             IllegalAccessException,
                                                                                             InvocationTargetException
  {
    final Method aMethod = aClass.getDeclaredMethod (sMethodName, aArgClasses);
    final Object aReturn = aMethod.invoke (null, aArgs);
    return GenericReflection.uncheckedCast (aReturn);
  }

  @Nonnull
  public static  Constructor  findConstructor (@Nonnull final DATATYPE aObj,
                                                                   final Class ... aCtorArgs) throws NoSuchMethodException
  {
    return uncheckedCast (aObj.getClass ().getConstructor (aCtorArgs));
  }

  /**
   * Create a new instance of the class identified by the passed object. The
   * default constructor will be invoked.
   *
   * @param 
   *        The type of object to be created.
   * @param aObj
   *        The object from which the class should be used.
   * @return A new instance of the object or an exception is thrown.
   * @throws IllegalAccessException
   *         Reflection exception
   * @throws NoSuchMethodException
   *         Reflection exception
   * @throws InvocationTargetException
   *         Reflection exception
   * @throws InstantiationException
   *         Reflection exception
   */
  @Nonnull
  public static  DATATYPE newInstance (@Nonnull final DATATYPE aObj) throws IllegalAccessException,
                                                                               NoSuchMethodException,
                                                                               InvocationTargetException,
                                                                               InstantiationException
  {
    return findConstructor (aObj).newInstance ();
  }

  @Nullable
  public static  DATATYPE newInstance (@Nullable final Class  aClass)
  {
    if (aClass != null)
      try
      {
        return aClass.getDeclaredConstructor ().newInstance ();
      }
      catch (final Exception ex)
      {
        /*
         * Catch all exceptions because any exception thrown from the
         * constructor may also end up in this catch block
         */
        LOGGER.error ("Failed to instantiate " + aClass, ex);
      }
    return null;
  }

  @Nullable
  public static  DATATYPE newInstance (@Nonnull final ClassLoader aClassLoader,
                                                 @Nullable final String sClassName,
                                                 @Nullable final Class  aDesiredType)
  {
    if (sClassName != null && aDesiredType != null)
      try
      {
        return aDesiredType.cast (getClassFromName (aClassLoader, sClassName).getDeclaredConstructor ().newInstance ());
      }
      catch (final Exception ex)
      {
        /*
         * Catch all exceptions because any exception thrown from the
         * constructor (indirectly invoked by newInstance) may also end up in
         * this catch block
         */
        LOGGER.error ("Failed to instantiate '" + sClassName + "'", ex);
      }
    return null;
  }

  @Nullable
  public static  DATATYPE newInstance (@Nullable final String sClassName, @Nullable final Class  aDesiredType)
  {
    if (sClassName != null && aDesiredType != null)
      try
      {
        return aDesiredType.cast (getClassFromName (sClassName).getDeclaredConstructor ().newInstance ());
      }
      catch (final Exception ex)
      {
        /*
         * Catch all exceptions because any exception thrown from the
         * constructor (indirectly invoked by newInstance) may also end up in
         * this catch block
         */
        LOGGER.error ("Failed to instantiate '" + sClassName + "'", ex);
      }
    return null;
  }

  @Nullable
  public static  DATATYPE newInstance (@Nullable final String sClassName,
                                                 @Nullable final Class  aDesiredType,
                                                 @Nullable final ClassLoader aClassLoaderToUse)
  {
    if (sClassName != null && aDesiredType != null && aClassLoaderToUse != null)
      try
      {
        return aDesiredType.cast (Class.forName (sClassName, true, aClassLoaderToUse).getDeclaredConstructor ().newInstance ());
      }
      catch (final Exception ex)
      {
        /*
         * Catch all exceptions because any exception thrown from the
         * constructor (indirectly invoked by newInstance) may also end up in
         * this catch block
         */
        LOGGER.error ("Failed to instantiate '" + sClassName + "' with CL " + aClassLoaderToUse, ex);
      }
    return null;
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy