Search in sources :

Example 1 with Callback

use of org.hibernate.jpa.event.spi.Callback in project hibernate-orm by hibernate.

the class CallbackBuilderLegacyImpl method resolveCallbacks.

@SuppressWarnings({ "unchecked", "WeakerAccess" })
public Callback[] resolveCallbacks(XClass beanClass, CallbackType callbackType, ReflectionManager reflectionManager) {
    List<Callback> callbacks = new ArrayList<>();
    List<String> callbacksMethodNames = new ArrayList<>();
    List<Class> orderedListeners = new ArrayList<>();
    XClass currentClazz = beanClass;
    boolean stopListeners = false;
    boolean stopDefaultListeners = false;
    do {
        Callback callback = null;
        List<XMethod> methods = currentClazz.getDeclaredMethods();
        for (final XMethod xMethod : methods) {
            if (xMethod.isAnnotationPresent(callbackType.getCallbackAnnotation())) {
                Method method = reflectionManager.toMethod(xMethod);
                final String methodName = method.getName();
                if (!callbacksMethodNames.contains(methodName)) {
                    // overridden method, remove the superclass overridden method
                    if (callback == null) {
                        callback = new EntityCallback(method, callbackType);
                        Class returnType = method.getReturnType();
                        Class[] args = method.getParameterTypes();
                        if (returnType != Void.TYPE || args.length != 0) {
                            throw new RuntimeException("Callback methods annotated on the bean class must return void and take no arguments: " + callbackType.getCallbackAnnotation().getName() + " - " + xMethod);
                        }
                        ReflectHelper.ensureAccessibility(method);
                        log.debugf("Adding %s as %s callback for entity %s", methodName, callbackType.getCallbackAnnotation().getSimpleName(), beanClass.getName());
                        // superclass first
                        callbacks.add(0, callback);
                        callbacksMethodNames.add(0, methodName);
                    } else {
                        throw new PersistenceException("You can only annotate one callback method with " + callbackType.getCallbackAnnotation().getName() + " in bean class: " + beanClass.getName());
                    }
                }
            }
        }
        if (!stopListeners) {
            getListeners(currentClazz, orderedListeners);
            stopListeners = currentClazz.isAnnotationPresent(ExcludeSuperclassListeners.class);
            stopDefaultListeners = currentClazz.isAnnotationPresent(ExcludeDefaultListeners.class);
        }
        do {
            currentClazz = currentClazz.getSuperclass();
        } while (currentClazz != null && !(currentClazz.isAnnotationPresent(Entity.class) || currentClazz.isAnnotationPresent(MappedSuperclass.class)));
    } while (currentClazz != null);
    // handle default listeners
    if (!stopDefaultListeners) {
        List<Class> defaultListeners = (List<Class>) reflectionManager.getDefaults().get(EntityListeners.class);
        if (defaultListeners != null) {
            int defaultListenerSize = defaultListeners.size();
            for (int i = defaultListenerSize - 1; i >= 0; i--) {
                orderedListeners.add(defaultListeners.get(i));
            }
        }
    }
    for (Class listener : orderedListeners) {
        Callback callback = null;
        if (listener != null) {
            XClass xListener = reflectionManager.toXClass(listener);
            callbacksMethodNames = new ArrayList<>();
            List<XMethod> methods = xListener.getDeclaredMethods();
            for (final XMethod xMethod : methods) {
                if (xMethod.isAnnotationPresent(callbackType.getCallbackAnnotation())) {
                    final Method method = reflectionManager.toMethod(xMethod);
                    final String methodName = method.getName();
                    if (!callbacksMethodNames.contains(methodName)) {
                        // overridden method, remove the superclass overridden method
                        if (callback == null) {
                            callback = new ListenerCallback(managedBeanRegistry.getBean(listener), method, callbackType);
                            Class returnType = method.getReturnType();
                            Class[] args = method.getParameterTypes();
                            if (returnType != Void.TYPE || args.length != 1) {
                                throw new PersistenceException("Callback methods annotated in a listener bean class must return void and take one argument: " + callbackType.getCallbackAnnotation().getName() + " - " + method);
                            }
                            ReflectHelper.ensureAccessibility(method);
                            log.debugf("Adding %s as %s callback for entity %s", methodName, callbackType.getCallbackAnnotation().getSimpleName(), beanClass.getName());
                            // listeners first
                            callbacks.add(0, callback);
                        } else {
                            throw new PersistenceException("You can only annotate one callback method with " + callbackType.getCallbackAnnotation().getName() + " in bean class: " + beanClass.getName() + " and callback listener: " + listener.getName());
                        }
                    }
                }
            }
        }
    }
    return callbacks.toArray(new Callback[callbacks.size()]);
}
Also used : ArrayList(java.util.ArrayList) XMethod(org.hibernate.annotations.common.reflection.XMethod) Method(java.lang.reflect.Method) XClass(org.hibernate.annotations.common.reflection.XClass) EntityListeners(javax.persistence.EntityListeners) Callback(org.hibernate.jpa.event.spi.Callback) XMethod(org.hibernate.annotations.common.reflection.XMethod) ExcludeDefaultListeners(javax.persistence.ExcludeDefaultListeners) PersistenceException(javax.persistence.PersistenceException) XClass(org.hibernate.annotations.common.reflection.XClass) ArrayList(java.util.ArrayList) List(java.util.List) ExcludeSuperclassListeners(javax.persistence.ExcludeSuperclassListeners)

Example 2 with Callback

use of org.hibernate.jpa.event.spi.Callback in project hibernate-orm by hibernate.

the class CallbackBuilderLegacyImpl method buildCallbacksForEntity.

@Override
public void buildCallbacksForEntity(String entityClassName, CallbackRegistrar callbackRegistrar) {
    try {
        final XClass entityXClass = reflectionManager.classForName(entityClassName);
        final Class entityClass = reflectionManager.toClass(entityXClass);
        for (CallbackType callbackType : CallbackType.values()) {
            if (callbackRegistrar.hasRegisteredCallbacks(entityClass, callbackType)) {
                // this most likely means we have a class mapped multiple times using the hbm.xml
                // "entity name" feature
                log.debugf("CallbackRegistry reported that Class [%s] already had %s callbacks registered; " + "assuming this means the class was mapped twice " + "(using hbm.xml entity-name support) - skipping subsequent registrations", entityClassName, callbackType.getCallbackAnnotation().getSimpleName());
                continue;
            }
            final Callback[] callbacks = resolveCallbacks(entityXClass, callbackType, reflectionManager);
            callbackRegistrar.registerCallbacks(entityClass, callbacks);
        }
    } catch (ClassLoadingException e) {
        throw new MappingException("entity class not found: " + entityClassName, e);
    }
}
Also used : Callback(org.hibernate.jpa.event.spi.Callback) CallbackType(org.hibernate.jpa.event.spi.CallbackType) ClassLoadingException(org.hibernate.annotations.common.reflection.ClassLoadingException) XClass(org.hibernate.annotations.common.reflection.XClass) XClass(org.hibernate.annotations.common.reflection.XClass) MappingException(org.hibernate.MappingException)

Aggregations

XClass (org.hibernate.annotations.common.reflection.XClass)2 Callback (org.hibernate.jpa.event.spi.Callback)2 Method (java.lang.reflect.Method)1 ArrayList (java.util.ArrayList)1 List (java.util.List)1 EntityListeners (javax.persistence.EntityListeners)1 ExcludeDefaultListeners (javax.persistence.ExcludeDefaultListeners)1 ExcludeSuperclassListeners (javax.persistence.ExcludeSuperclassListeners)1 PersistenceException (javax.persistence.PersistenceException)1 MappingException (org.hibernate.MappingException)1 ClassLoadingException (org.hibernate.annotations.common.reflection.ClassLoadingException)1 XMethod (org.hibernate.annotations.common.reflection.XMethod)1 CallbackType (org.hibernate.jpa.event.spi.CallbackType)1