2 * Copyright (C) 2018 EDIT
3 * European Distributed Institute of Taxonomy
4 * http://www.e-taxonomy.eu
6 * The contents of this file are subject to the Mozilla Public License Version 1.1
7 * See LICENSE.TXT at the top of this package for the full license terms.
9 package eu
.etaxonomy
.cdm
.persistence
.hibernate
;
11 import java
.lang
.reflect
.Constructor
;
12 import java
.lang
.reflect
.InvocationTargetException
;
13 import java
.util
.HashMap
;
16 import org
.apache
.log4j
.Logger
;
17 import org
.hibernate
.action
.spi
.BeforeTransactionCompletionProcess
;
18 import org
.hibernate
.event
.spi
.PostInsertEvent
;
19 import org
.hibernate
.event
.spi
.PostUpdateEvent
;
20 import org
.hibernate
.persister
.entity
.EntityPersister
;
22 import eu
.etaxonomy
.cdm
.config
.CdmHibernateListenerConfiguration
;
23 import eu
.etaxonomy
.cdm
.model
.name
.TaxonName
;
26 * The {@code TaxonGraphHibernateListener} it the implementation of the
27 * according interface. The listener in initially empty and thus will do nothing
28 * unless configured with the {@link TaxonGraphBeforeTransactionCompleteProces}
31 * "https://dev.e-taxonomy.eu/redmine/issues/7648">https://dev.e-taxonomy.eu/redmine/issues/7648</a>
32 * @see {@link TaxonGraphBeforeTransactionCompleteProcess}
33 * @see {@link CdmHibernateListenerConfiguration}
35 * @author a.kohlbecker
39 public class TaxonGraphHibernateListener
implements ITaxonGraphHibernateListener
{
41 private static final long serialVersionUID
= 5062518307839173935L;
43 private Map
<Class
<?
extends BeforeTransactionCompletionProcess
>, ProcessConstructorData
<?
extends BeforeTransactionCompletionProcess
>> beforeTransactionCompletionProcessTypes
= new HashMap
<>();
46 public void registerProcessClass(Class
<?
extends BeforeTransactionCompletionProcess
> processClass
, Object
[] constructorArgs
, Class
<?
>[] paramterTypes
) throws NoSuchMethodException
, SecurityException
{
47 if(constructorArgs
== null){
48 constructorArgs
= new Object
[]{};
50 beforeTransactionCompletionProcessTypes
.put(processClass
, new ProcessConstructorData(processClass
, constructorArgs
, paramterTypes
));
54 public void unRegisterProcessClass(Class
<?
extends BeforeTransactionCompletionProcess
> processClass
){
55 beforeTransactionCompletionProcessTypes
.remove(processClass
);
59 public void onPostUpdate(PostUpdateEvent event
) {
61 if(event
.getEntity() instanceof TaxonName
){
62 for(Class
<?
extends BeforeTransactionCompletionProcess
> type
: beforeTransactionCompletionProcessTypes
.keySet()){
64 ProcessConstructorData
<?
extends BeforeTransactionCompletionProcess
> pcd
= beforeTransactionCompletionProcessTypes
.get(type
);
65 BeforeTransactionCompletionProcess processorInstance
= pcd
.postUpdateEventConstructor
.newInstance(pcd
.buildConstructorArgs(event
));
66 event
.getSession().getActionQueue().registerProcess(processorInstance
);
67 } catch (InstantiationException
| IllegalAccessException
| IllegalArgumentException
68 | InvocationTargetException
| SecurityException e
) {
69 Logger
.getLogger(TaxonGraphHibernateListener
.class).error("Error creating new instance of " + type
.toString(), e
);
76 public void onPostInsert(PostInsertEvent event
) {
78 if(event
.getEntity() instanceof TaxonName
){
79 for(Class
<?
extends BeforeTransactionCompletionProcess
> type
: beforeTransactionCompletionProcessTypes
.keySet()){
81 ProcessConstructorData
<?
extends BeforeTransactionCompletionProcess
> pcd
= beforeTransactionCompletionProcessTypes
.get(type
);
82 BeforeTransactionCompletionProcess processorInstance
= pcd
.postInsertEventConstructor
.newInstance(pcd
.buildConstructorArgs(event
));
83 event
.getSession().getActionQueue().registerProcess(processorInstance
);
84 } catch (InstantiationException
| IllegalAccessException
| IllegalArgumentException
85 | InvocationTargetException
| SecurityException e
) {
86 Logger
.getLogger(TaxonGraphHibernateListener
.class).error("Error creating new instance of " + type
.toString(), e
);
93 public boolean requiresPostCommitHanding(EntityPersister persister
) {
97 class ProcessConstructorData
<T
extends BeforeTransactionCompletionProcess
> {
99 Constructor
<T
> postInsertEventConstructor
;
100 Constructor
<T
> postUpdateEventConstructor
;
101 Object
[] constructorArgs
;
103 public ProcessConstructorData(Class
<T
> type
, Object
[] constructorArgs
, Class
<?
>[] paramterTypes
) throws NoSuchMethodException
, SecurityException
{
105 this.constructorArgs
= constructorArgs
;
107 Class
<?
>[] postInsertEventConstructorArgTypes
= new Class
<?
>[constructorArgs
.length
+ 1];
108 Class
<?
>[] postUpdateEventConstructorArgTypes
= new Class
<?
>[constructorArgs
.length
+ 1];
109 postInsertEventConstructorArgTypes
[0] = PostInsertEvent
.class;
110 postUpdateEventConstructorArgTypes
[0] = PostUpdateEvent
.class;
112 for(Class
<?
> ptype
: paramterTypes
){
113 postInsertEventConstructorArgTypes
[i
] = ptype
;
114 postUpdateEventConstructorArgTypes
[i
] = ptype
;
116 postInsertEventConstructor
= type
.getConstructor(postInsertEventConstructorArgTypes
);
117 postUpdateEventConstructor
= type
.getConstructor(postUpdateEventConstructorArgTypes
);
120 public Object
[] buildConstructorArgs(Object firstArg
){
121 Object
[] cargs
= new Object
[constructorArgs
.length
+ 1];
124 for(Object arg
: constructorArgs
){