InstantiatingClassBasedListenerObjectCreator.java

  1. /*
  2.  * Copyright (C) 2012-2025 RRiBbit.org
  3.  *
  4.  * Licensed under the Apache License, Version 2.0 (the "License");
  5.  * you may not use this file except in compliance with the License.
  6.  * You may obtain a copy of the License at
  7.  *
  8.  * https://www.apache.org/licenses/LICENSE-2.0
  9.  *
  10.  * Unless required by applicable law or agreed to in writing, software
  11.  * distributed under the License is distributed on an "AS IS" BASIS,
  12.  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13.  * See the License for the specific language governing permissions and
  14.  * limitations under the License.
  15.  */
  16. package org.rribbit.creation;

  17. import org.rribbit.Listener;
  18. import org.rribbit.ListenerObject;
  19. import org.slf4j.Logger;
  20. import org.slf4j.LoggerFactory;

  21. import java.lang.reflect.InvocationTargetException;
  22. import java.util.Collection;

  23. /**
  24.  * This {@link ListenerObjectCreator} creates {@link ListenerObject}s from classes. Users can pass in {@link Class}es or packagenames and this class will scan the {@link Class}es
  25.  * and create {@link ListenerObject}s for the public methods that are annotated with {@link Listener}. Note that public methods inherited from superclasses and superinterfaces will also be
  26.  * scanned. This means that users must take care not to scan a method twice, once as a method of a class and once as a method of a superclass, by passing a class/interface and its
  27.  * superclass/superinterface separately to this {@link ListenerObjectCreator}.
  28.  * <p />
  29.  * Please note that in Java, method annotations are NOT inherited. This means that, if you override/implement a method in a subclass or subinterface, and the overriding/implementing method
  30.  * does not have the annotation, then that method will not inherit it. If a class or interface just inherits a method, without overriding it, then the annotation WILL exist.
  31.  * <p />
  32.  * To get the actual {@link Object}s that the listeners run on, this class simply attempts to instantiate an {@link Object} for each {@link Class} that it scans.
  33.  * When there is no default constructor for a {@link Class}, the {@link Class} will simply be ignored.
  34.  *
  35.  * @author G.J. Schouten
  36.  *
  37.  */
  38. public class InstantiatingClassBasedListenerObjectCreator extends AbstractClassBasedListenerObjectCreator {

  39.     private static final Logger log = LoggerFactory.getLogger(InstantiatingClassBasedListenerObjectCreator.class);

  40.     /**
  41.      * @param classes
  42.      *
  43.      * @see AbstractClassBasedListenerObjectCreator#AbstractClassBasedListenerObjectCreator(Class...)
  44.      */
  45.     public InstantiatingClassBasedListenerObjectCreator(Class<?>... classes) {
  46.         super(classes);
  47.     }

  48.     /**
  49.      * @param excludedClasses
  50.      * @param scanSubPackages
  51.      * @param packageNames
  52.      *
  53.      * @see AbstractClassBasedListenerObjectCreator#AbstractClassBasedListenerObjectCreator(Collection, boolean, String...)
  54.      */
  55.     public InstantiatingClassBasedListenerObjectCreator(Collection<Class<?>> excludedClasses, boolean scanSubPackages, String... packageNames) {
  56.         super(excludedClasses, scanSubPackages, packageNames);
  57.     }

  58.     @Override
  59.     protected Object getTargetObjectForClass(Class<?> clazz) {

  60.         try {
  61.             log.debug("Attempting to construct instance of class '{}'", clazz.getName());
  62.             return clazz.getConstructor().newInstance();
  63.         } catch(InvocationTargetException e) {
  64.             throw new RuntimeException("Exception thrown from constructor of Listener", e.getCause());
  65.         } catch(Exception e) {
  66.             log.debug("No suitable constructor found, returning null");
  67.             return null;
  68.         }
  69.     }
  70. }