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
.model
.name
.TaxonName
;
25 * see https://dev.e-taxonomy.eu/redmine/issues/7648
27 * @author a.kohlbecker
31 public class TaxonGraphHibernateListener
implements ITaxonGraphHibernateListener
{
33 private static final long serialVersionUID
= 5062518307839173935L;
35 private Map
<Class
<?
extends BeforeTransactionCompletionProcess
>, ProcessConstructorData
<?
extends BeforeTransactionCompletionProcess
>> beforeTransactionCompletionProcessTypes
= new HashMap
<>();
38 public void registerProcessClass(Class
<?
extends BeforeTransactionCompletionProcess
> processClass
, Object
[] constructorArgs
, Class
<?
>[] paramterTypes
) throws NoSuchMethodException
, SecurityException
{
39 if(constructorArgs
== null){
40 constructorArgs
= new Object
[]{};
42 beforeTransactionCompletionProcessTypes
.put(processClass
, new ProcessConstructorData(processClass
, constructorArgs
, paramterTypes
));
46 public void unRegisterProcessClass(Class
<?
extends BeforeTransactionCompletionProcess
> processClass
){
47 beforeTransactionCompletionProcessTypes
.remove(processClass
);
51 public void onPostUpdate(PostUpdateEvent event
) {
53 if(event
.getEntity() instanceof TaxonName
){
54 for(Class
<?
extends BeforeTransactionCompletionProcess
> type
: beforeTransactionCompletionProcessTypes
.keySet()){
56 ProcessConstructorData
<?
extends BeforeTransactionCompletionProcess
> pcd
= beforeTransactionCompletionProcessTypes
.get(type
);
57 BeforeTransactionCompletionProcess processorInstance
= pcd
.postUpdateEventConstructor
.newInstance(pcd
.buildConstructorArgs(event
));
58 event
.getSession().getActionQueue().registerProcess(processorInstance
);
59 } catch (InstantiationException
| IllegalAccessException
| IllegalArgumentException
60 | InvocationTargetException
| SecurityException e
) {
61 Logger
.getLogger(TaxonGraphHibernateListener
.class).error("Error creating new instance of " + type
.toString(), e
);
68 public void onPostInsert(PostInsertEvent event
) {
70 if(event
.getEntity() instanceof TaxonName
){
71 for(Class
<?
extends BeforeTransactionCompletionProcess
> type
: beforeTransactionCompletionProcessTypes
.keySet()){
73 ProcessConstructorData
<?
extends BeforeTransactionCompletionProcess
> pcd
= beforeTransactionCompletionProcessTypes
.get(type
);
74 BeforeTransactionCompletionProcess processorInstance
= pcd
.postInsertEventConstructor
.newInstance(pcd
.buildConstructorArgs(event
));
75 event
.getSession().getActionQueue().registerProcess(processorInstance
);
76 } catch (InstantiationException
| IllegalAccessException
| IllegalArgumentException
77 | InvocationTargetException
| SecurityException e
) {
78 Logger
.getLogger(TaxonGraphHibernateListener
.class).error("Error creating new instance of " + type
.toString(), e
);
85 public boolean requiresPostCommitHanding(EntityPersister persister
) {
89 class ProcessConstructorData
<T
extends BeforeTransactionCompletionProcess
> {
91 Constructor
<T
> postInsertEventConstructor
;
93 Constructor
<T
> postUpdateEventConstructor
;
95 Object
[] constructorArgs
;
98 * @param constructorArgs
100 public ProcessConstructorData(Class
<T
> type
, Object
[] constructorArgs
, Class
<?
>[] paramterTypes
) throws NoSuchMethodException
, SecurityException
{
102 this.constructorArgs
= constructorArgs
;
104 Class
<?
>[] postInsertEventConstructorArgTypes
= new Class
<?
>[constructorArgs
.length
+ 1];
105 Class
<?
>[] postUpdateEventConstructorArgTypes
= new Class
<?
>[constructorArgs
.length
+ 1];
106 postInsertEventConstructorArgTypes
[0] = PostInsertEvent
.class;
107 postUpdateEventConstructorArgTypes
[0] = PostUpdateEvent
.class;
109 for(Class
<?
> ptype
: paramterTypes
){
110 postInsertEventConstructorArgTypes
[i
] = ptype
;
111 postUpdateEventConstructorArgTypes
[i
] = ptype
;
113 postInsertEventConstructor
= type
.getConstructor(postInsertEventConstructorArgTypes
);
114 postUpdateEventConstructor
= type
.getConstructor(postUpdateEventConstructorArgTypes
);
117 public Object
[] buildConstructorArgs(Object firstArg
){
118 Object
[] cargs
= new Object
[constructorArgs
.length
+ 1];
121 for(Object arg
: constructorArgs
){