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

com.avaje.ebeaninternal.server.deploy.BeanLifecycleAdapterFactory Maven / Gradle / Ivy

There is a newer version: 9.5.1
Show newest version
package com.avaje.ebeaninternal.server.deploy;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;

import javax.annotation.PostConstruct;
import javax.persistence.PersistenceException;
import javax.persistence.PostLoad;
import javax.persistence.PostPersist;
import javax.persistence.PostRemove;
import javax.persistence.PostUpdate;
import javax.persistence.PrePersist;
import javax.persistence.PreRemove;
import javax.persistence.PreUpdate;

import com.avaje.ebean.event.BeanPersistAdapter;
import com.avaje.ebean.event.BeanPersistRequest;
import com.avaje.ebean.event.BeanPostConstructListener;
import com.avaje.ebean.event.BeanPostLoad;
import com.avaje.ebeaninternal.server.deploy.meta.DeployBeanDescriptor;

/**
 * Helper that looks for methods annotated with lifecycle events and registers an adapter for them.
 * 

* This includes PrePersist, PostPersist, PreUpdate, PostUpdate, PreRemove, PostRemove and PostLoad * lifecycle events. *

*/ public class BeanLifecycleAdapterFactory { /** * Register a BeanPersistController for methods annotated with lifecycle events. */ public void addLifecycleMethods(DeployBeanDescriptor deployDesc) { Method[] methods = deployDesc.getBeanType().getMethods(); // look for annotated methods MethodsHolder methodHolder = new MethodsHolder(); for (Method m : methods) { methodHolder.checkMethod(m); } if (methodHolder.hasPersistMethods()) { // has pre/post persist annotated methods deployDesc.addPersistController(new PersistAdapter(new PersistMethodsHolder(methodHolder))); } if (!methodHolder.postLoads.isEmpty()) { // has postLoad methods deployDesc.addPostLoad(new PostLoadAdapter(methodHolder.postLoads)); } if (!methodHolder.postConstructs.isEmpty()) { // has postConstruct methods deployDesc.addPostConstructListener(new PostConstructAdapter(methodHolder.postConstructs)); } } /** * Holds Methods for the lifecycle events.s */ private static class MethodsHolder { private boolean hasPersistMethods; private final List preInserts = new ArrayList<>(); private final List postInserts = new ArrayList<>(); private final List preUpdates = new ArrayList<>(); private final List postUpdates = new ArrayList<>(); private final List preDeletes = new ArrayList<>(); private final List postDeletes = new ArrayList<>(); private final List postLoads = new ArrayList<>(); private final List postConstructs = new ArrayList<>(); /** * Has one of the pre or post insert update delete annotated methods. */ private boolean hasPersistMethods() { return hasPersistMethods; } /** * Check the method for all the annotations we are interested in. */ private void checkMethod(Method method) { if (method.isAnnotationPresent(PrePersist.class)) { preInserts.add(method); hasPersistMethods = true; } if (method.isAnnotationPresent(PostPersist.class)) { postInserts.add(method); hasPersistMethods = true; } if (method.isAnnotationPresent(PreUpdate.class)) { preUpdates.add(method); hasPersistMethods = true; } if (method.isAnnotationPresent(PostUpdate.class)) { postUpdates.add(method); hasPersistMethods = true; } if (method.isAnnotationPresent(PreRemove.class)) { preDeletes.add(method); hasPersistMethods = true; } if (method.isAnnotationPresent(PostRemove.class)) { postDeletes.add(method); hasPersistMethods = true; } if (method.isAnnotationPresent(PostLoad.class)) { postLoads.add(method); } if (method.isAnnotationPresent(PostConstruct.class)) { postConstructs.add(method); } } } /** * Utility method to covert List of Method into array (because we care about performance here). */ static Method[] toArray(List methodList) { return methodList.toArray(new Method[methodList.size()]); } /** * Holds Methods for the lifecycle events.s */ private static class PersistMethodsHolder { private final Method[] preInserts; private final Method[] postInserts; private final Method[] preUpdates; private final Method[] postUpdates; private final Method[] preDeletes; private final Method[] postDeletes; PersistMethodsHolder(MethodsHolder methodsHolder) { this.preInserts = toArray(methodsHolder.preInserts); this.preUpdates = toArray(methodsHolder.preUpdates); this.preDeletes = toArray(methodsHolder.preDeletes); this.postInserts = toArray(methodsHolder.postInserts); this.postUpdates = toArray(methodsHolder.postUpdates); this.postDeletes = toArray(methodsHolder.postDeletes); } } /** * BeanPersistAdapter using reflection to invoke lifecycle methods. */ private static class PersistAdapter extends BeanPersistAdapter { private final PersistMethodsHolder methodHolder; private PersistAdapter(PersistMethodsHolder methodHolder) { this.methodHolder = methodHolder; } @Override public boolean isRegisterFor(Class cls) { // Not used return false; } private void invoke(Method method, Object bean) { try { method.invoke(bean); } catch (InvocationTargetException | IllegalAccessException e) { throw new PersistenceException("Error invoking lifecycle method", e); } } private void invoke(Method[] methods, BeanPersistRequest request) { for (Method method : methods) { invoke(method, request.getBean()); } } @Override public boolean preDelete(BeanPersistRequest request) { invoke(methodHolder.preDeletes, request); return true; } @Override public boolean preInsert(BeanPersistRequest request) { invoke(methodHolder.preInserts, request); return true; } @Override public boolean preUpdate(BeanPersistRequest request) { invoke(methodHolder.preUpdates, request); return true; } @Override public void postDelete(BeanPersistRequest request) { invoke(methodHolder.postDeletes, request); } @Override public void postInsert(BeanPersistRequest request) { invoke(methodHolder.postInserts, request); } @Override public void postUpdate(BeanPersistRequest request) { invoke(methodHolder.postUpdates, request); } } /** * BeanPostLoad using reflection to invoke lifecycle methods. */ private static class PostLoadAdapter implements BeanPostLoad { private final Method[] postLoadMethods; private PostLoadAdapter(List postLoadMethods) { this.postLoadMethods = toArray(postLoadMethods); } @Override public boolean isRegisterFor(Class cls) { // Not used return false; } private void invoke(Method method, Object bean) { try { method.invoke(bean); } catch (InvocationTargetException | IllegalAccessException e) { throw new PersistenceException("Error invoking lifecycle method", e); } } @Override public void postLoad(Object bean) { for (Method postLoadMethod : postLoadMethods) { invoke(postLoadMethod, bean); } } } /** * PostConstructAdapter using reflection to invoke lifecycle methods. */ private static class PostConstructAdapter implements BeanPostConstructListener { private final Method[] postConstructMethods; private PostConstructAdapter(List postConstructMethods) { this.postConstructMethods = toArray(postConstructMethods); } @Override public boolean isRegisterFor(Class cls) { // Not used return false; } private void invoke(Method method, Object bean) { try { method.invoke(bean); } catch (InvocationTargetException | IllegalAccessException e) { throw new PersistenceException("Error invoking lifecycle method", e); } } @Override public void postConstruct(Object bean) { for (Method postConstructMethod : postConstructMethods) { invoke(postConstructMethod, bean); } } @Override public void autowire(Object bean) { // autowire is done by global PostConstructListener only } @Override public void postCreate(Object bean) { // postCreate is done by global PostConstructListener only } } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy