Revision 1f31ca4f
Added by Andreas Müller over 9 years ago
cdmlib-persistence/src/main/java/eu/etaxonomy/cdm/persistence/hibernate/ValidationEventListenerBase.java | ||
---|---|---|
84 | 84 |
try { |
85 | 85 |
if (!(object instanceof CdmBase)) { |
86 | 86 |
if (object.getClass() != HashMap.class) { |
87 |
logger.warn(levelString() + " validation bypassed for entities of type " + object.getClass().getName());
|
|
87 |
if(logger.isDebugEnabled()){ logger.debug(levelString() + " validation bypassed for entities of type " + object.getClass().getName());}
|
|
88 | 88 |
} |
89 | 89 |
return; |
90 | 90 |
} |
cdmlib-persistence/src/main/java/eu/etaxonomy/cdm/persistence/validation/EntityValidationTaskBase.java | ||
---|---|---|
101 | 101 |
} |
102 | 102 |
} catch (Throwable t) { |
103 | 103 |
logger.error("Error while validating " + entity.toString() + ": " + t.getMessage()); |
104 |
t.printStackTrace(); |
|
104 | 105 |
} |
105 | 106 |
} |
106 | 107 |
|
cdmlib-persistence/src/main/java/eu/etaxonomy/cdm/persistence/validation/ValidationExecutor.java | ||
---|---|---|
82 | 82 |
* @author ayco_holleman |
83 | 83 |
* |
84 | 84 |
*/ |
85 |
//maybe we want to make this a spring component ? |
|
85 | 86 |
public class ValidationExecutor extends ThreadPoolExecutor implements RejectedExecutionHandler { |
86 | 87 |
|
87 | 88 |
private static final Logger logger = Logger.getLogger(ValidationExecutor.class); |
cdmlib-services/src/main/java/eu/etaxonomy/cdm/api/application/MonitoredListableBeanFactory.java | ||
---|---|---|
1 | 1 |
// $Id$ |
2 | 2 |
/** |
3 | 3 |
* Copyright (C) 2009 EDIT |
4 |
* European Distributed Institute of Taxonomy
|
|
4 |
* European Distributed Institute of Taxonomy |
|
5 | 5 |
* http://www.e-taxonomy.eu |
6 |
*
|
|
6 |
* |
|
7 | 7 |
* The contents of this file are subject to the Mozilla Public License Version 1.1 |
8 | 8 |
* See LICENSE.TXT at the top of this package for the full license terms. |
9 | 9 |
*/ |
... | ... | |
30 | 30 |
public class MonitoredListableBeanFactory extends DefaultListableBeanFactory { |
31 | 31 |
@SuppressWarnings("unused") |
32 | 32 |
private static final Logger logger = Logger.getLogger(MonitoredListableBeanFactory.class); |
33 |
|
|
33 |
|
|
34 | 34 |
private boolean isInitializingBeans = false; |
35 | 35 |
private IProgressMonitor currentMonitor; |
36 |
|
|
36 |
|
|
37 | 37 |
private static List<String> beansToMonitor = Arrays.asList("sessionFactory","defaultBeanInitializer","persistentTermInitializer"); |
38 |
private Set<String> alreadyMonitoredBeans = new HashSet<String>(); |
|
38 |
private final Set<String> alreadyMonitoredBeans = new HashSet<String>();
|
|
39 | 39 |
|
40 | 40 |
public MonitoredListableBeanFactory(){ |
41 | 41 |
} |
42 |
|
|
42 |
|
|
43 | 43 |
// @Override |
44 | 44 |
// protected RootBeanDefinition getMergedLocalBeanDefinition(String beanName) throws BeansException { |
45 | 45 |
// if (registeredBeanNames.contains(beanName)){ |
46 | 46 |
// return super.getMergedLocalBeanDefinition(beanName); |
47 |
//
|
|
47 |
// |
|
48 | 48 |
// } |
49 | 49 |
//// String message = "Handle bean '%s'"; |
50 | 50 |
//// message = String.format(message, beanName); |
... | ... | |
54 | 54 |
//// registeredBeanNames.add(beanName); |
55 | 55 |
// return result; |
56 | 56 |
// } |
57 |
|
|
58 |
public void preInstantiateSingletons() throws BeansException { |
|
57 |
|
|
58 |
@Override |
|
59 |
public void preInstantiateSingletons() throws BeansException { |
|
59 | 60 |
isInitializingBeans = true; |
60 | 61 |
checkMonitorCancelled(currentMonitor); |
61 | 62 |
int countBeans = 0; |
... | ... | |
86 | 87 |
// } |
87 | 88 |
// return result; |
88 | 89 |
// } |
89 |
|
|
90 |
|
|
91 |
@Override |
|
90 | 92 |
protected Object createBean(final String name, final RootBeanDefinition mbd, final Object[] args){ |
91 | 93 |
boolean doMonitor = isInitializingBeans && beansToMonitor.contains(name) && !alreadyMonitoredBeans.contains(name); |
92 | 94 |
checkMonitorCancelled(currentMonitor); |
... | ... | |
111 | 113 |
return result; |
112 | 114 |
} |
113 | 115 |
|
114 |
|
|
116 |
|
|
115 | 117 |
/** |
116 | 118 |
* @param mainMonitor the mainMonitor to set |
117 | 119 |
*/ |
118 | 120 |
public void setCurrentMonitor(IProgressMonitor monitor) { |
119 | 121 |
this.currentMonitor = monitor; |
120 | 122 |
} |
121 |
|
|
123 |
|
|
122 | 124 |
private void checkMonitorCancelled(IProgressMonitor monitor) { |
123 | 125 |
if (monitor != null && monitor.isCanceled()){ |
124 | 126 |
throw new CancellationException(); |
125 |
}
|
|
127 |
} |
|
126 | 128 |
} |
127 |
|
|
129 |
|
|
128 | 130 |
} |
cdmlib-services/src/main/java/eu/etaxonomy/cdm/api/validation/Level3TransactionalValidationTask.java | ||
---|---|---|
46 | 46 |
TransactionStatus tx = repository.startTransaction(true); |
47 | 47 |
//TODO what if getEntity() is not CdmBase? |
48 | 48 |
CdmBase cdmBase = CdmBase.deproxy(getEntity(), CdmBase.class); |
49 |
repository.getCommonService().updateEntity(cdmBase); |
|
49 |
repository.getCommonService().find(cdmBase.getId()); |
|
50 |
//was but create Entity in 2 open sessions error |
|
51 |
//not sure if the above works, should set the entity, but allowing to do so is critical the id is part of hash function, so we have to make sure that only entities with the same id can be replaced |
|
52 |
// repository.getCommonService().updateEntity(cdmBase); |
|
50 | 53 |
Set<ConstraintViolation<ICdmBase>> result = super.validate(); |
51 | 54 |
repository.commitTransaction(tx); |
52 | 55 |
return result; |
cdmlib-services/src/main/java/eu/etaxonomy/cdm/api/validation/ValidationManager.java | ||
---|---|---|
18 | 18 |
import org.hibernate.service.spi.ServiceRegistryImplementor; |
19 | 19 |
import org.springframework.beans.factory.annotation.Autowired; |
20 | 20 |
import org.springframework.beans.factory.annotation.Qualifier; |
21 |
import org.springframework.context.annotation.Lazy; |
|
21 | 22 |
import org.springframework.stereotype.Component; |
22 | 23 |
|
23 | 24 |
import eu.etaxonomy.cdm.api.application.ICdmApplicationConfiguration; |
... | ... | |
34 | 35 |
* |
35 | 36 |
*/ |
36 | 37 |
@Component |
38 |
@Lazy(false) |
|
37 | 39 |
public class ValidationManager { |
38 | 40 |
|
39 | 41 |
private final boolean level2Enabled = false; |
40 | 42 |
private final boolean level3Enabled = false; |
41 | 43 |
|
44 |
private boolean isInitialized = false; |
|
45 |
|
|
42 | 46 |
private Level2ValidationEventListener l2Listener; |
43 | 47 |
private Level3ValidationEventListener l3Listener; |
44 | 48 |
|
... | ... | |
56 | 60 |
|
57 | 61 |
@PostConstruct |
58 | 62 |
public void registerValidationListeners(){ |
59 |
if (sessionFactory != null && sessionFactory instanceof SessionFactoryImpl){ |
|
60 |
ServiceRegistryImplementor serviceRegistry = ((SessionFactoryImpl)sessionFactory).getServiceRegistry(); |
|
63 |
if (!isInitialized){ |
|
64 |
if (sessionFactory != null && sessionFactory instanceof SessionFactoryImpl){ |
|
65 |
ServiceRegistryImplementor serviceRegistry = ((SessionFactoryImpl)sessionFactory).getServiceRegistry(); |
|
66 |
|
|
67 |
final EventListenerRegistry eventRegistry = serviceRegistry.getService(EventListenerRegistry.class); |
|
61 | 68 |
|
62 |
final EventListenerRegistry eventRegistry = serviceRegistry.getService(EventListenerRegistry.class); |
|
69 |
//duplication strategy |
|
70 |
// eventRegistry.addDuplicationStrategy(CdmListenerDuplicationStrategy.NewInstance); |
|
71 |
eventRegistry.getEventListenerGroup(EventType.POST_INSERT); |
|
63 | 72 |
|
64 |
//duplication strategy |
|
65 |
// eventRegistry.addDuplicationStrategy(CdmListenerDuplicationStrategy.NewInstance); |
|
66 |
eventRegistry.getEventListenerGroup(EventType.POST_INSERT); |
|
73 |
ValidationExecutor validationExecutor = new ValidationExecutor(); |
|
67 | 74 |
|
68 |
ValidationExecutor validationExecutor = new ValidationExecutor(); |
|
75 |
//level2 |
|
76 |
l2Listener = new Level2ValidationEventListener(validationDao); |
|
77 |
l2Listener.setValidationExecutor(validationExecutor); |
|
69 | 78 |
|
70 |
//level2
|
|
71 |
l2Listener = new Level2ValidationEventListener(validationDao);
|
|
72 |
l2Listener.setValidationExecutor(validationExecutor);
|
|
79 |
//level3
|
|
80 |
l3Listener = new Level3TransactionalValidationEventListener(cdmApplicationDefaultConfiguration, validationDao);
|
|
81 |
l3Listener.setValidationExecutor(validationExecutor);
|
|
73 | 82 |
|
74 |
//level3 |
|
75 |
l3Listener = new Level3TransactionalValidationEventListener(cdmApplicationDefaultConfiguration, validationDao); |
|
76 |
l3Listener.setValidationExecutor(validationExecutor); |
|
83 |
// prepend to register before or append to register after |
|
77 | 84 |
|
78 |
// prepend to register before or append to register after |
|
85 |
eventRegistry.appendListeners(EventType.POST_INSERT, l2Listener , l3Listener); |
|
86 |
eventRegistry.appendListeners(EventType.POST_UPDATE, l2Listener , l3Listener); |
|
87 |
//TODO don't we need l2Listener validation also for deleting the results? |
|
88 |
eventRegistry.appendListeners(EventType.POST_DELETE, l3Listener); |
|
79 | 89 |
|
80 |
eventRegistry.appendListeners(EventType.POST_INSERT, l2Listener , l3Listener); |
|
81 |
eventRegistry.appendListeners(EventType.POST_UPDATE, l2Listener , l3Listener); |
|
82 |
//TODO don't we need l2Listener validation also for deleting the results? |
|
83 |
eventRegistry.appendListeners(EventType.POST_DELETE, l3Listener); |
|
90 |
isInitialized = true; |
|
84 | 91 |
|
85 |
}else{ |
|
86 |
throw new RuntimeException("Session factory not available or not of type SessionFactoryImpl"); |
|
92 |
}else{ |
|
93 |
throw new RuntimeException("Session factory not available or not of type SessionFactoryImpl"); |
|
94 |
} |
|
87 | 95 |
} |
88 | 96 |
} |
89 | 97 |
|
90 | 98 |
//for future use |
91 |
private void enableLevel2Listener(boolean enable){ |
|
92 |
|
|
99 |
private void enableLevel2Listener(boolean enabled){
|
|
100 |
l2Listener.setEnabled(enabled); |
|
93 | 101 |
} |
94 | 102 |
|
95 |
private void enableLevel3Listener(boolean enable){ |
|
96 |
|
|
103 |
private void enableLevel3Listener(boolean enabled){
|
|
104 |
l3Listener.setEnabled(enabled); |
|
97 | 105 |
} |
98 | 106 |
|
99 | 107 |
} |
cdmlib-services/src/main/resources/eu/etaxonomy/cdm/defaultApplicationContext.xml | ||
---|---|---|
25 | 25 |
|
26 | 26 |
<bean id="conversationHolder" class="eu.etaxonomy.cdm.api.conversation.ConversationHolder" scope="prototype"/> |
27 | 27 |
|
28 |
<bean id="validationManager" class="eu.etaxonomy.cdm.api.validation.ValidationManager" scope="prototype"/>
|
|
28 |
<bean id="validationManager" class="eu.etaxonomy.cdm.api.validation.ValidationManager"/> |
|
29 | 29 |
|
30 | 30 |
|
31 | 31 |
<!-- TODO move to io --> |
cdmlib-services/src/test/java/eu/etaxonomy/cdm/test/function/TestValidationManager.java | ||
---|---|---|
33 | 33 |
String path = "C:\\Users\\a.mueller\\.cdmLibrary\\writableResources\\h2\\testValidation2"; |
34 | 34 |
String username = "sa"; |
35 | 35 |
CdmDataSource dataSource = CdmDataSource.NewH2EmbeddedInstance("validationTest", username, "", path, NomenclaturalCode.ICNAFP); |
36 |
dataSource = getMySQLDatasource(schema); |
|
36 |
// dataSource = getMySQLDatasource(schema);
|
|
37 | 37 |
|
38 | 38 |
|
39 | 39 |
//CdmPersistentDataSource.save(dataSource.getName(), dataSource); |
Also available in: Unified diff
some bugfixes for validation management