Revision 02ec8d6b
Added by Andreas Kohlbecker over 6 years ago
src/main/java/eu/etaxonomy/cdm/addon/config/CdmVaadinConfiguration.java | ||
---|---|---|
68 | 68 |
@EnableVaadin // this imports VaadinConfiguration |
69 | 69 |
@EnableVaadinSpringNavigation // activate the NavigationManagerBean |
70 | 70 |
@EnableAnnotationBasedAccessControl // enable annotation based per view access control |
71 |
// @EnableTransactionManagement(mode=AdviceMode.ASPECTJ) // has no effect here |
|
71 | 72 |
public class CdmVaadinConfiguration implements ApplicationContextAware { |
72 | 73 |
|
73 | 74 |
/** |
src/main/java/eu/etaxonomy/cdm/cache/CdmEntityCache.java | ||
---|---|---|
1 |
/** |
|
2 |
* Copyright (C) 2017 EDIT |
|
3 |
* European Distributed Institute of Taxonomy |
|
4 |
* http://www.e-taxonomy.eu |
|
5 |
* |
|
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. |
|
8 |
*/ |
|
9 |
package eu.etaxonomy.cdm.cache; |
|
10 |
|
|
11 |
import java.beans.PropertyDescriptor; |
|
12 |
import java.io.PrintStream; |
|
13 |
import java.lang.reflect.InvocationTargetException; |
|
14 |
import java.util.ArrayList; |
|
15 |
import java.util.Collection; |
|
16 |
import java.util.HashMap; |
|
17 |
import java.util.HashSet; |
|
18 |
import java.util.List; |
|
19 |
import java.util.Map; |
|
20 |
import java.util.Set; |
|
21 |
|
|
22 |
import org.apache.commons.beanutils.PropertyUtils; |
|
23 |
import org.apache.commons.lang.builder.HashCodeBuilder; |
|
24 |
import org.apache.log4j.Logger; |
|
25 |
import org.hibernate.Hibernate; |
|
26 |
import org.hibernate.collection.internal.AbstractPersistentCollection; |
|
27 |
import org.hibernate.envers.internal.entities.mapper.relation.lazy.proxy.CollectionProxy; |
|
28 |
import org.hibernate.envers.internal.entities.mapper.relation.lazy.proxy.MapProxy; |
|
29 |
import org.hibernate.envers.internal.entities.mapper.relation.lazy.proxy.SortedMapProxy; |
|
30 |
|
|
31 |
import eu.etaxonomy.cdm.hibernate.HibernateProxyHelper; |
|
32 |
import eu.etaxonomy.cdm.model.common.CdmBase; |
|
33 |
import eu.etaxonomy.cdm.persistence.dao.initializer.AbstractBeanInitializer; |
|
34 |
|
|
35 |
/** |
|
36 |
* @author a.kohlbecker |
|
37 |
* @since 08.11.2017 |
|
38 |
* |
|
39 |
*/ |
|
40 |
public class CdmEntityCache implements EntityCache { |
|
41 |
|
|
42 |
|
|
43 |
private final static Logger logger = Logger.getLogger(CdmEntityCache.class); |
|
44 |
|
|
45 |
private static final String COPY_ENTITY = "!"; |
|
46 |
|
|
47 |
private CdmBase entity; |
|
48 |
|
|
49 |
private Map<EntityKey, CdmBase> entityyMap = new HashMap<>(); |
|
50 |
|
|
51 |
private List<String> entityPathList = new ArrayList<>(); |
|
52 |
|
|
53 |
private Map<EntityKey, List<String>> entityPathsMap = new HashMap<>(); |
|
54 |
|
|
55 |
private Set<EntityKey> copyEntitiyKeys = new HashSet<>(); |
|
56 |
|
|
57 |
private Set<Object> objectsSeen = new HashSet<>(); |
|
58 |
|
|
59 |
public CdmEntityCache(CdmBase entity){ |
|
60 |
this.entity = entity; |
|
61 |
update(); |
|
62 |
} |
|
63 |
|
|
64 |
@Override |
|
65 |
public boolean update() { |
|
66 |
|
|
67 |
entityPathList.clear(); |
|
68 |
entityPathsMap.clear(); |
|
69 |
objectsSeen.clear(); |
|
70 |
copyEntitiyKeys.clear(); |
|
71 |
|
|
72 |
String propertyPath = ""; |
|
73 |
|
|
74 |
analyzeEntity(entity, propertyPath); |
|
75 |
|
|
76 |
return copyEntitiyKeys.isEmpty(); |
|
77 |
} |
|
78 |
|
|
79 |
/** |
|
80 |
* |
|
81 |
*/ |
|
82 |
protected void analyzeEntity(CdmBase bean, String propertyPath) { |
|
83 |
|
|
84 |
EntityKey entityKey = new EntityKey(bean); |
|
85 |
|
|
86 |
propertyPath += "[" + entityKey; |
|
87 |
String flags = ""; |
|
88 |
CdmBase mappedEntity = entityyMap.put(entityKey, bean); |
|
89 |
|
|
90 |
if(mappedEntity != null && mappedEntity != bean) { |
|
91 |
copyEntitiyKeys.add(entityKey); |
|
92 |
flags += COPY_ENTITY + bean.hashCode(); |
|
93 |
} |
|
94 |
|
|
95 |
flags = analyzeMore(bean, entityKey, flags, mappedEntity); |
|
96 |
|
|
97 |
if(!flags.isEmpty()){ |
|
98 |
propertyPath += "(" + flags + ")"; |
|
99 |
} |
|
100 |
propertyPath += "]"; |
|
101 |
|
|
102 |
logger.debug(propertyPath); |
|
103 |
|
|
104 |
entityPathList.add(propertyPath); |
|
105 |
if(!entityPathsMap.containsKey(entityKey)){ |
|
106 |
entityPathsMap.put(entityKey, new ArrayList<>()); |
|
107 |
} |
|
108 |
entityPathsMap.get(entityKey).add(propertyPath); |
|
109 |
|
|
110 |
if(!objectsSeen.add(bean)){ |
|
111 |
// avoid cycles, do not recurse into properties of objects that have been analyzed already |
|
112 |
return; |
|
113 |
} |
|
114 |
|
|
115 |
Set<PropertyDescriptor> properties = AbstractBeanInitializer.getProperties(bean, null); |
|
116 |
for(PropertyDescriptor prop : properties){ |
|
117 |
|
|
118 |
try { |
|
119 |
Object propertyValue = PropertyUtils.getProperty(bean, prop.getName()); |
|
120 |
|
|
121 |
if(propertyValue == null){ |
|
122 |
continue; |
|
123 |
} |
|
124 |
|
|
125 |
String propertyPathSuffix = "." + prop.getName(); |
|
126 |
|
|
127 |
if(Hibernate.isInitialized(propertyValue)) { |
|
128 |
|
|
129 |
if(CdmBase.class.isAssignableFrom(prop.getPropertyType())){ |
|
130 |
analyzeEntity(HibernateProxyHelper.deproxy(propertyValue, CdmBase.class), propertyPath + propertyPathSuffix); |
|
131 |
continue; |
|
132 |
} |
|
133 |
|
|
134 |
Collection<CdmBase> collection = null; |
|
135 |
if(propertyValue instanceof AbstractPersistentCollection){ |
|
136 |
if (propertyValue instanceof Collection) { |
|
137 |
collection = (Collection<CdmBase>) propertyValue; |
|
138 |
} else if (propertyValue instanceof Map) { |
|
139 |
collection = ((Map<?,CdmBase>)propertyValue).values(); |
|
140 |
} else { |
|
141 |
logger.error("unhandled subtype of AbstractPersistentCollection"); |
|
142 |
} |
|
143 |
} else if (propertyValue instanceof CollectionProxy |
|
144 |
|| propertyValue instanceof MapProxy<?, ?> |
|
145 |
|| propertyValue instanceof SortedMapProxy<?, ?>){ |
|
146 |
//hibernate envers collections |
|
147 |
collection = (Collection<CdmBase>)propertyValue; |
|
148 |
} |
|
149 |
|
|
150 |
if(collection != null){ |
|
151 |
for(CdmBase collectionItem : collection){ |
|
152 |
analyzeEntity(HibernateProxyHelper.deproxy(collectionItem, CdmBase.class), propertyPath + propertyPathSuffix); |
|
153 |
} |
|
154 |
} else { |
|
155 |
// logger.error("Unhandled property type " + propertyValue.getClass().getName()); |
|
156 |
} |
|
157 |
} |
|
158 |
|
|
159 |
} catch (IllegalAccessException e) { |
|
160 |
String message = "Illegal access on property " + prop; |
|
161 |
logger.error(message); |
|
162 |
throw new RuntimeException(message, e); |
|
163 |
} catch (InvocationTargetException e) { |
|
164 |
String message = "Cannot invoke property " + prop + " not found"; |
|
165 |
logger.error(message); |
|
166 |
throw new RuntimeException(message, e); |
|
167 |
} catch (NoSuchMethodException e) { |
|
168 |
String message = "Property " + prop.getName() + " not found for class " + bean.getClass(); |
|
169 |
logger.error(message); |
|
170 |
} |
|
171 |
|
|
172 |
} |
|
173 |
} |
|
174 |
|
|
175 |
/** |
|
176 |
* Empty method which can be implemented by subclasses which do further analysis. |
|
177 |
* |
|
178 |
* @param bean |
|
179 |
* @param entityKey |
|
180 |
* @param flags |
|
181 |
* @param mappedEntity |
|
182 |
* @return |
|
183 |
*/ |
|
184 |
protected String analyzeMore(CdmBase bean, EntityKey entityKey, String flags, CdmBase mappedEntity) { |
|
185 |
return flags; |
|
186 |
} |
|
187 |
|
|
188 |
|
|
189 |
public void printEntityGraph(PrintStream printStream){ |
|
190 |
printLegend(printStream); |
|
191 |
for(String path : entityPathList) { |
|
192 |
printStream.println(path); |
|
193 |
} |
|
194 |
} |
|
195 |
|
|
196 |
public void printCopyEntities(PrintStream printStream){ |
|
197 |
printLegend(printStream); |
|
198 |
for(EntityKey key : copyEntitiyKeys){ |
|
199 |
for(String path : entityPathsMap.get(key)) { |
|
200 |
printStream.println(path); |
|
201 |
} |
|
202 |
} |
|
203 |
} |
|
204 |
|
|
205 |
/** |
|
206 |
* @param printStream |
|
207 |
*/ |
|
208 |
protected void printLegend(PrintStream printStream) { |
|
209 |
printStream.println(this.getClass().getSimpleName() + " legend: "); |
|
210 |
printStream.println(" - '!{objectHash}': detected copy entity, followed by object hash"); |
|
211 |
} |
|
212 |
|
|
213 |
public class EntityKey { |
|
214 |
|
|
215 |
Class type; |
|
216 |
int id; |
|
217 |
|
|
218 |
public EntityKey(Class type, int id){ |
|
219 |
this.type = type; |
|
220 |
this.id = id; |
|
221 |
} |
|
222 |
|
|
223 |
public EntityKey(CdmBase entity){ |
|
224 |
type = entity.getClass(); |
|
225 |
id = entity.getId(); |
|
226 |
} |
|
227 |
|
|
228 |
/** |
|
229 |
* @return the type |
|
230 |
*/ |
|
231 |
public Class getType() { |
|
232 |
return type; |
|
233 |
} |
|
234 |
|
|
235 |
/** |
|
236 |
* @return the id |
|
237 |
*/ |
|
238 |
public int getId() { |
|
239 |
return id; |
|
240 |
} |
|
241 |
|
|
242 |
/** |
|
243 |
* {@inheritDoc} |
|
244 |
*/ |
|
245 |
@Override |
|
246 |
public int hashCode() { |
|
247 |
return new HashCodeBuilder(15, 33) |
|
248 |
.append(type) |
|
249 |
.append(id) |
|
250 |
.toHashCode(); |
|
251 |
} |
|
252 |
|
|
253 |
@Override |
|
254 |
public boolean equals(Object obj) { |
|
255 |
EntityKey other = (EntityKey)obj; |
|
256 |
return this.id == other.id && this.type == other.type; |
|
257 |
|
|
258 |
} |
|
259 |
|
|
260 |
@Override |
|
261 |
public String toString() { |
|
262 |
return type.getSimpleName() + "#" + getId(); |
|
263 |
} |
|
264 |
|
|
265 |
} |
|
266 |
|
|
267 |
/** |
|
268 |
* {@inheritDoc} |
|
269 |
*/ |
|
270 |
@Override |
|
271 |
public <CDM extends CdmBase> CDM find(CDM value) { |
|
272 |
EntityKey entityKey = new EntityKey(HibernateProxyHelper.deproxy(value)); |
|
273 |
return (CDM) entityyMap.get(entityKey); |
|
274 |
} |
|
275 |
|
|
276 |
/** |
|
277 |
* {@inheritDoc} |
|
278 |
*/ |
|
279 |
@Override |
|
280 |
public <CDM extends CdmBase> CDM find(Class<CDM> type, int id) { |
|
281 |
EntityKey entityKey = new EntityKey(type, id); |
|
282 |
return (CDM) entityyMap.get(entityKey); |
|
283 |
} |
|
284 |
|
|
285 |
|
|
286 |
} |
src/main/java/eu/etaxonomy/cdm/cache/EntityCache.java | ||
---|---|---|
1 |
/** |
|
2 |
* Copyright (C) 2017 EDIT |
|
3 |
* European Distributed Institute of Taxonomy |
|
4 |
* http://www.e-taxonomy.eu |
|
5 |
* |
|
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. |
|
8 |
*/ |
|
9 |
package eu.etaxonomy.cdm.cache; |
|
10 |
|
|
11 |
import eu.etaxonomy.cdm.model.common.CdmBase; |
|
12 |
|
|
13 |
/** |
|
14 |
* @author a.kohlbecker |
|
15 |
* @since 09.11.2017 |
|
16 |
* |
|
17 |
*/ |
|
18 |
public interface EntityCache { |
|
19 |
|
|
20 |
/** |
|
21 |
* @param value |
|
22 |
* @return |
|
23 |
*/ |
|
24 |
public <CDM extends CdmBase> CDM find(CDM value); |
|
25 |
|
|
26 |
public boolean update(); |
|
27 |
|
|
28 |
/** |
|
29 |
* @param type |
|
30 |
* @param id |
|
31 |
* @return |
|
32 |
*/ |
|
33 |
public <CDM extends CdmBase> CDM find(Class<CDM> type, int id); |
|
34 |
|
|
35 |
|
|
36 |
} |
src/main/java/eu/etaxonomy/cdm/dataInserter/RegistrationRequiredDataInserter.java | ||
---|---|---|
55 | 55 |
import eu.etaxonomy.cdm.vaadin.security.RolesAndPermissions; |
56 | 56 |
|
57 | 57 |
/** |
58 |
* |
|
59 |
* Can create missing registrations for names which have Extensions of the Type <code>IAPTRegdata.json</code>. |
|
60 |
* See https://dev.e-taxonomy.eu/redmine/issues/6621 for further details. |
|
61 |
* This feature can be activated by by supplying one of the following jvm command line arguments: |
|
62 |
* <ul> |
|
63 |
* <li><code>-DregistrationCreate=iapt</code>: create all iapt Registrations if missing</li> |
|
64 |
* <li><code>-DregistrationWipeout=iapt</code>: remove all iapt Registrations</li> |
|
65 |
* <li><code>-DregistrationWipeout=all</code>: remove all Registrations</li> |
|
66 |
* </ul> |
|
67 |
* The <code>-DregistrationWipeout</code> commands are executed before the <code>-DregistrationCreate</code> and will not change the name and type designations. |
|
68 |
* |
|
58 | 69 |
* @author a.kohlbecker |
59 | 70 |
* @since May 9, 2017 |
60 | 71 |
* |
src/main/java/eu/etaxonomy/cdm/debug/PersistentContextAnalyzer.java | ||
---|---|---|
1 |
/** |
|
2 |
* Copyright (C) 2017 EDIT |
|
3 |
* European Distributed Institute of Taxonomy |
|
4 |
* http://www.e-taxonomy.eu |
|
5 |
* |
|
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. |
|
8 |
*/ |
|
9 |
package eu.etaxonomy.cdm.debug; |
|
10 |
|
|
11 |
import java.beans.PropertyDescriptor; |
|
12 |
import java.io.PrintStream; |
|
13 |
import java.lang.reflect.InvocationTargetException; |
|
14 |
import java.util.ArrayList; |
|
15 |
import java.util.Collection; |
|
16 |
import java.util.HashMap; |
|
17 |
import java.util.HashSet; |
|
18 |
import java.util.List; |
|
19 |
import java.util.Map; |
|
20 |
import java.util.Set; |
|
21 |
|
|
22 |
import org.apache.commons.beanutils.PropertyUtils; |
|
23 |
import org.apache.commons.lang.builder.HashCodeBuilder; |
|
24 |
import org.apache.log4j.Logger; |
|
25 |
import org.hibernate.Hibernate; |
|
26 |
import org.hibernate.Session; |
|
27 |
import org.hibernate.collection.internal.AbstractPersistentCollection; |
|
28 |
import org.hibernate.envers.internal.entities.mapper.relation.lazy.proxy.CollectionProxy; |
|
29 |
import org.hibernate.envers.internal.entities.mapper.relation.lazy.proxy.MapProxy; |
|
30 |
import org.hibernate.envers.internal.entities.mapper.relation.lazy.proxy.SortedMapProxy; |
|
31 |
|
|
32 |
import eu.etaxonomy.cdm.hibernate.HibernateProxyHelper; |
|
33 |
import eu.etaxonomy.cdm.model.common.CdmBase; |
|
34 |
import eu.etaxonomy.cdm.persistence.dao.initializer.AbstractBeanInitializer; |
|
35 |
|
|
36 |
/** |
|
37 |
* @author a.kohlbecker |
|
38 |
* @since 08.11.2017 |
|
39 |
* |
|
40 |
*/ |
|
41 |
public class PersistentContextAnalyzer { |
|
42 |
|
|
43 |
/** |
|
44 |
* |
|
45 |
*/ |
|
46 |
private static final String COPY_ENTITY = "!"; |
|
47 |
|
|
48 |
/** |
|
49 |
* |
|
50 |
*/ |
|
51 |
private static final String IN_PERSITENT_CONTEXT = "*"; |
|
52 |
|
|
53 |
private final static Logger logger = Logger.getLogger(PersistentContextAnalyzer.class); |
|
54 |
|
|
55 |
private Session session; |
|
56 |
|
|
57 |
private CdmBase entity; |
|
58 |
|
|
59 |
private Map<EntityKey, CdmBase> entityyMap = new HashMap<>(); |
|
60 |
|
|
61 |
private List<String> entityPathList = new ArrayList<>(); |
|
62 |
|
|
63 |
private Map<EntityKey, List<String>> entityPathsMap = new HashMap<>(); |
|
64 |
|
|
65 |
private Set<EntityKey> copyEntitiyKeys = new HashSet<>(); |
|
66 |
|
|
67 |
private Set<Object> objectsSeen = new HashSet<>(); |
|
68 |
|
|
69 |
|
|
70 |
public PersistentContextAnalyzer(CdmBase entity, Session session){ |
|
71 |
this.session = session; |
|
72 |
this.entity = entity; |
|
73 |
update(); |
|
74 |
} |
|
75 |
|
|
76 |
public PersistentContextAnalyzer(CdmBase entity){ |
|
77 |
this(entity, null); |
|
78 |
} |
|
79 |
|
|
80 |
/** |
|
81 |
* - find copied entities in the graph |
|
82 |
*/ |
|
83 |
private void update() { |
|
84 |
|
|
85 |
String propertyPath = ""; |
|
86 |
analyzeEntity(entity, propertyPath); |
|
87 |
} |
|
88 |
|
|
89 |
public void printEntityGraph(PrintStream printStream){ |
|
90 |
printLegend(printStream); |
|
91 |
for(String path : entityPathList) { |
|
92 |
printStream.println(path); |
|
93 |
} |
|
94 |
} |
|
95 |
|
|
96 |
public void printCopyEntities(PrintStream printStream){ |
|
97 |
printLegend(printStream); |
|
98 |
for(EntityKey key : copyEntitiyKeys){ |
|
99 |
for(String path : entityPathsMap.get(key)) { |
|
100 |
printStream.println(path); |
|
101 |
} |
|
102 |
} |
|
103 |
} |
|
104 |
|
|
105 |
/** |
|
106 |
* @param printStream |
|
107 |
*/ |
|
108 |
protected void printLegend(PrintStream printStream) { |
|
109 |
printStream.println("PersistentContextAnalyzer legend: "); |
|
110 |
printStream.println(" - '*': entity mapped in persistent context"); |
|
111 |
printStream.println(" - '!{objectHash}': detected copy entity, followed by object hash"); |
|
112 |
} |
|
113 |
|
|
114 |
/** |
|
115 |
* |
|
116 |
*/ |
|
117 |
protected void analyzeEntity(CdmBase bean, String propertyPath) { |
|
118 |
|
|
119 |
EntityKey entityKey = new EntityKey(bean); |
|
120 |
|
|
121 |
propertyPath += "[" + entityKey; |
|
122 |
String flags = ""; |
|
123 |
CdmBase mappedEntity = entityyMap.put(entityKey, bean); |
|
124 |
|
|
125 |
if(session != null && session.contains(bean)){ |
|
126 |
flags += IN_PERSITENT_CONTEXT; |
|
127 |
} |
|
128 |
if(mappedEntity != null && mappedEntity != bean) { |
|
129 |
copyEntitiyKeys.add(entityKey); |
|
130 |
flags += COPY_ENTITY + bean.hashCode(); |
|
131 |
} |
|
132 |
if(!flags.isEmpty()){ |
|
133 |
propertyPath += "(" + flags + ")"; |
|
134 |
} |
|
135 |
propertyPath += "]"; |
|
136 |
|
|
137 |
logger.debug(propertyPath); |
|
138 |
|
|
139 |
entityPathList.add(propertyPath); |
|
140 |
if(!entityPathsMap.containsKey(entityKey)){ |
|
141 |
entityPathsMap.put(entityKey, new ArrayList<>()); |
|
142 |
} |
|
143 |
entityPathsMap.get(entityKey).add(propertyPath); |
|
144 |
|
|
145 |
if(!objectsSeen.add(bean)){ |
|
146 |
// avoid cycles, do not recurse into properties of objects that have been analyzed already |
|
147 |
return; |
|
148 |
} |
|
149 |
|
|
150 |
Set<PropertyDescriptor> properties = AbstractBeanInitializer.getProperties(bean, null); |
|
151 |
for(PropertyDescriptor prop : properties){ |
|
152 |
|
|
153 |
try { |
|
154 |
Object propertyValue = PropertyUtils.getProperty(bean, prop.getName()); |
|
155 |
|
|
156 |
if(propertyValue == null){ |
|
157 |
continue; |
|
158 |
} |
|
159 |
|
|
160 |
String propertyPathSuffix = "." + prop.getName(); |
|
161 |
|
|
162 |
if(Hibernate.isInitialized(propertyValue)) { |
|
163 |
|
|
164 |
if(CdmBase.class.isAssignableFrom(prop.getPropertyType())){ |
|
165 |
analyzeEntity(HibernateProxyHelper.deproxy(propertyValue, CdmBase.class), propertyPath + propertyPathSuffix); |
|
166 |
continue; |
|
167 |
} |
|
168 |
|
|
169 |
Collection<CdmBase> collection = null; |
|
170 |
if(propertyValue instanceof AbstractPersistentCollection){ |
|
171 |
if (propertyValue instanceof Collection) { |
|
172 |
collection = (Collection<CdmBase>) propertyValue; |
|
173 |
} else if (propertyValue instanceof Map) { |
|
174 |
collection = ((Map<?,CdmBase>)propertyValue).values(); |
|
175 |
} else { |
|
176 |
logger.error("unhandled subtype of AbstractPersistentCollection"); |
|
177 |
} |
|
178 |
} else if (propertyValue instanceof CollectionProxy |
|
179 |
|| propertyValue instanceof MapProxy<?, ?> |
|
180 |
|| propertyValue instanceof SortedMapProxy<?, ?>){ |
|
181 |
//hibernate envers collections |
|
182 |
collection = (Collection<CdmBase>)propertyValue; |
|
183 |
} |
|
184 |
|
|
185 |
if(collection != null){ |
|
186 |
for(CdmBase collectionItem : collection){ |
|
187 |
analyzeEntity(HibernateProxyHelper.deproxy(collectionItem, CdmBase.class), propertyPath + propertyPathSuffix); |
|
188 |
} |
|
189 |
} else { |
|
190 |
// logger.error("Unhandled property type " + propertyValue.getClass().getName()); |
|
191 |
} |
|
192 |
} |
|
193 |
|
|
194 |
} catch (IllegalAccessException e) { |
|
195 |
String message = "Illegal access on property " + prop; |
|
196 |
logger.error(message); |
|
197 |
throw new RuntimeException(message, e); |
|
198 |
} catch (InvocationTargetException e) { |
|
199 |
String message = "Cannot invoke property " + prop + " not found"; |
|
200 |
logger.error(message); |
|
201 |
throw new RuntimeException(message, e); |
|
202 |
} catch (NoSuchMethodException e) { |
|
203 |
String message = "Property " + prop.getName() + " not found for class " + bean.getClass(); |
|
204 |
logger.error(message); |
|
205 |
} |
|
206 |
|
|
207 |
} |
|
208 |
} |
|
209 |
|
|
210 |
class EntityKey { |
|
211 |
|
|
212 |
Class type; |
|
213 |
int id; |
|
214 |
|
|
215 |
public EntityKey(CdmBase entity){ |
|
216 |
type = entity.getClass(); |
|
217 |
id = entity.getId(); |
|
218 |
} |
|
219 |
|
|
220 |
/** |
|
221 |
* @return the type |
|
222 |
*/ |
|
223 |
public Class getType() { |
|
224 |
return type; |
|
225 |
} |
|
226 |
|
|
227 |
/** |
|
228 |
* @return the id |
|
229 |
*/ |
|
230 |
public int getId() { |
|
231 |
return id; |
|
232 |
} |
|
233 |
|
|
234 |
/** |
|
235 |
* {@inheritDoc} |
|
236 |
*/ |
|
237 |
@Override |
|
238 |
public int hashCode() { |
|
239 |
return new HashCodeBuilder(17, 31) |
|
240 |
.append(type) |
|
241 |
.append(id) |
|
242 |
.toHashCode(); |
|
243 |
} |
|
244 |
|
|
245 |
@Override |
|
246 |
public String toString() { |
|
247 |
return type.getSimpleName() + "#" + getId(); |
|
248 |
} |
|
249 |
|
|
250 |
} |
|
251 |
|
|
252 |
|
|
253 |
} |
src/main/java/eu/etaxonomy/cdm/service/CdmStore.java | ||
---|---|---|
176 | 176 |
/** |
177 | 177 |
* |
178 | 178 |
* @param bean |
179 |
|
|
179 |
* |
|
180 | 180 |
* @return the merged bean, this bean is <b>not reloaded</b> from the |
181 | 181 |
* persistent storage. |
182 | 182 |
*/ |
... | ... | |
203 | 203 |
// merge the changes into the session, ... |
204 | 204 |
|
205 | 205 |
T mergedBean = mergedBean(bean); |
206 |
//T mergedBean = bean; |
|
206 |
|
|
207 | 207 |
// NOTE: saveOrUpdate is really needed here even if we to a merge before |
208 | 208 |
repo.getCommonService().saveOrUpdate(mergedBean); |
209 | 209 |
session.flush(); |
src/main/java/eu/etaxonomy/cdm/service/ISpecimenTypeDesignationWorkingSetService.java | ||
---|---|---|
1 |
/** |
|
2 |
* Copyright (C) 2017 EDIT |
|
3 |
* European Distributed Institute of Taxonomy |
|
4 |
* http://www.e-taxonomy.eu |
|
5 |
* |
|
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. |
|
8 |
*/ |
|
9 |
package eu.etaxonomy.cdm.service; |
|
10 |
|
|
11 |
import eu.etaxonomy.cdm.model.common.VersionableEntity; |
|
12 |
import eu.etaxonomy.cdm.model.name.Registration; |
|
13 |
import eu.etaxonomy.cdm.model.name.TaxonName; |
|
14 |
import eu.etaxonomy.cdm.model.reference.Reference; |
|
15 |
import eu.etaxonomy.cdm.vaadin.model.registration.SpecimenTypeDesignationWorkingSetDTO; |
|
16 |
|
|
17 |
/** |
|
18 |
* @author a.kohlbecker |
|
19 |
* @since May 4, 2017 |
|
20 |
* |
|
21 |
*/ |
|
22 |
public interface ISpecimenTypeDesignationWorkingSetService { |
|
23 |
|
|
24 |
public SpecimenTypeDesignationWorkingSetDTO<Registration> create(int registrationId, int publicationId, int typifiedNameId); |
|
25 |
|
|
26 |
/** |
|
27 |
* @param id the CDM Entity id |
|
28 |
* @return |
|
29 |
*/ |
|
30 |
public SpecimenTypeDesignationWorkingSetDTO<Registration> loadDtoByIds(int registrationId, int workingsetId); |
|
31 |
|
|
32 |
SpecimenTypeDesignationWorkingSetDTO<Registration> fixMissingFieldUnit(SpecimenTypeDesignationWorkingSetDTO<Registration> bean); |
|
33 |
|
|
34 |
|
|
35 |
/** |
|
36 |
* Saves the SpecimenTypeDesignationWorkingSetDTO and takes care for consistency in the working set: |
|
37 |
* <ul> |
|
38 |
* <li>New TypeDesignations are associated with the OWNER.</li> |
|
39 |
* <li>The citation and typified name of newly created TypeDesignations are set to the supplied entities.</li> |
|
40 |
* <li>All type specimens are assured to be derivatives of the FieldUnit which is the base entity of the set.</li> |
|
41 |
* </ul> |
|
42 |
* |
|
43 |
* @param dto the DTO to be persisted |
|
44 |
* @param citation The Reference entity to be used for new TypeDesignations. |
|
45 |
* @param typifiedName |
|
46 |
*/ |
|
47 |
void save(SpecimenTypeDesignationWorkingSetDTO<? extends VersionableEntity> dto, Reference citation, TaxonName typifiedName); |
|
48 |
|
|
49 |
} |
src/main/java/eu/etaxonomy/cdm/service/RegistrationWorkingSetService.java | ||
---|---|---|
40 | 40 |
|
41 | 41 |
/** |
42 | 42 |
* Provides RegistrationDTOs and RegistrationWorkingsets for Registrations in the database. |
43 |
* <p> |
|
44 |
* Can create missing registrations for names which have Extensions of the Type <code>IAPTRegdata.json</code>. |
|
45 |
* See https://dev.e-taxonomy.eu/redmine/issues/6621 for further details. |
|
46 |
* This feature can be activated by by supplying one of the following jvm command line arguments: |
|
47 |
* <ul> |
|
48 |
* <li><code>-DregistrationCreate=iapt</code>: create all iapt Registrations if missing</li> |
|
49 |
* <li><code>-DregistrationWipeout=iapt</code>: remove all iapt Registrations</li> |
|
50 |
* <li><code>-DregistrationWipeout=all</code>: remove all Registrations</li> |
|
51 |
* </ul> |
|
52 |
* The <code>-DregistrationWipeout</code> commands are executed before the <code>-DregistrationCreate</code> and will not change the name and type designations. |
|
53 | 43 |
* |
54 | 44 |
* |
55 | 45 |
* @author a.kohlbecker |
... | ... | |
63 | 53 |
public static final List<String> REGISTRATION_INIT_STRATEGY = Arrays.asList(new String []{ |
64 | 54 |
// typeDesignation |
65 | 55 |
"typeDesignations.typeStatus", |
66 |
"typeDesignations.typifiedNames",
|
|
56 |
"typeDesignations.typifiedNames.typeDesignations", // important !!
|
|
67 | 57 |
"typeDesignations.typeSpecimen", |
68 | 58 |
"typeDesignations.typeName", |
69 | 59 |
"typeDesignations.citation", |
... | ... | |
74 | 64 |
"name.nomenclaturalReference.inReference", |
75 | 65 |
"name.rank", |
76 | 66 |
"name.status.type", |
67 |
"name.typeDesignations", // important !!" |
|
77 | 68 |
// institution |
78 | 69 |
"institution", |
79 | 70 |
} |
80 | 71 |
); |
81 | 72 |
|
82 |
/** |
|
83 |
* |
|
84 |
*/ |
|
85 |
private static final List<String> FIELDUNIT_INIT_STRATEGY = Arrays.asList(new String[]{ |
|
86 |
"$", |
|
87 |
"gatheringEvent.$", |
|
88 |
"gatheringEvent.country", |
|
89 |
"gatheringEvent.collectingAreas", |
|
90 |
"gatheringEvent.actor" |
|
91 |
}); |
|
92 |
|
|
93 | 73 |
/** |
94 | 74 |
* |
95 | 75 |
*/ |
96 |
private static final List<String> DERIVEDUNIT_INIT_STRATEGY = Arrays.asList(new String[]{
|
|
76 |
private List<String> DERIVEDUNIT_INIT_STRATEGY = Arrays.asList(new String[]{ |
|
97 | 77 |
"collection", |
98 | 78 |
"storedUnder", |
99 | 79 |
"preservation", |
... | ... | |
103 | 83 |
"kindOfUnit", |
104 | 84 |
"derivedFrom.$", |
105 | 85 |
"derivedFrom.type", |
106 |
"specimenTypeDesignations" |
|
86 |
"derivedFrom.originals.derivationEvents", // important!! |
|
87 |
"specimenTypeDesignations.typifiedNames.typeDesignations", // important!! |
|
107 | 88 |
}); |
108 | 89 |
|
90 |
/** |
|
91 |
* |
|
92 |
*/ |
|
93 |
private List<String> FIELDUNIT_INIT_STRATEGY = Arrays.asList(new String[]{ |
|
94 |
"$", |
|
95 |
"gatheringEvent.$", |
|
96 |
"gatheringEvent.country", |
|
97 |
"gatheringEvent.collectingAreas", |
|
98 |
"gatheringEvent.actor", |
|
99 |
"derivationEvents.derivatives" // important, otherwise the DerivedUnits are not included into the graph of initialized entities!!! |
|
100 |
}); |
|
101 |
|
|
109 | 102 |
/** |
110 | 103 |
* |
111 | 104 |
*/ |
... | ... | |
196 | 189 |
* @param reg |
197 | 190 |
*/ |
198 | 191 |
protected void inititializeSpecimen(Registration reg) { |
192 |
|
|
199 | 193 |
for(TypeDesignationBase<?> td : reg.getTypeDesignations()){ |
200 | 194 |
if(td instanceof SpecimenTypeDesignation){ |
201 | 195 |
|
... | ... | |
214 | 208 |
} |
215 | 209 |
if(sob instanceof FieldUnit){ |
216 | 210 |
defaultBeanInitializer.initialize(sob, FIELDUNIT_INIT_STRATEGY); |
217 |
int i = 0; |
|
218 | 211 |
} |
219 | 212 |
} |
220 | 213 |
sobs = nextSobs; |
src/main/java/eu/etaxonomy/cdm/service/SpecimenTypeDesignationWorkingSetServiceImpl.java | ||
---|---|---|
1 |
/** |
|
2 |
* Copyright (C) 2017 EDIT |
|
3 |
* European Distributed Institute of Taxonomy |
|
4 |
* http://www.e-taxonomy.eu |
|
5 |
* |
|
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. |
|
8 |
*/ |
|
9 |
package eu.etaxonomy.cdm.service; |
|
10 |
|
|
11 |
import java.util.HashSet; |
|
12 |
import java.util.Iterator; |
|
13 |
import java.util.Set; |
|
14 |
|
|
15 |
import org.hibernate.Session; |
|
16 |
import org.jboss.logging.Logger; |
|
17 |
import org.springframework.beans.factory.annotation.Autowired; |
|
18 |
import org.springframework.beans.factory.annotation.Qualifier; |
|
19 |
import org.springframework.stereotype.Service; |
|
20 |
import org.springframework.transaction.annotation.Transactional; |
|
21 |
|
|
22 |
import eu.etaxonomy.cdm.api.application.CdmRepository; |
|
23 |
import eu.etaxonomy.cdm.model.common.VersionableEntity; |
|
24 |
import eu.etaxonomy.cdm.model.name.Registration; |
|
25 |
import eu.etaxonomy.cdm.model.name.SpecimenTypeDesignation; |
|
26 |
import eu.etaxonomy.cdm.model.name.TaxonName; |
|
27 |
import eu.etaxonomy.cdm.model.name.TypeDesignationBase; |
|
28 |
import eu.etaxonomy.cdm.model.occurrence.DerivationEvent; |
|
29 |
import eu.etaxonomy.cdm.model.occurrence.DerivationEventType; |
|
30 |
import eu.etaxonomy.cdm.model.occurrence.DerivedUnit; |
|
31 |
import eu.etaxonomy.cdm.model.occurrence.FieldUnit; |
|
32 |
import eu.etaxonomy.cdm.model.occurrence.GatheringEvent; |
|
33 |
import eu.etaxonomy.cdm.model.occurrence.SpecimenOrObservationBase; |
|
34 |
import eu.etaxonomy.cdm.model.reference.Reference; |
|
35 |
import eu.etaxonomy.cdm.vaadin.model.TypedEntityReference; |
|
36 |
import eu.etaxonomy.cdm.vaadin.model.registration.SpecimenTypeDesignationDTO; |
|
37 |
import eu.etaxonomy.cdm.vaadin.model.registration.SpecimenTypeDesignationWorkingSetDTO; |
|
38 |
import eu.etaxonomy.cdm.vaadin.util.converter.TypeDesignationSetManager.TypeDesignationWorkingSet; |
|
39 |
import eu.etaxonomy.cdm.vaadin.view.registration.RegistrationDTO; |
|
40 |
|
|
41 |
/** |
|
42 |
* @author a.kohlbecker |
|
43 |
* @since Nov 13, 2017 |
|
44 |
* |
|
45 |
*/ |
|
46 |
@Service("specimenTypeDesignationWorkingSetService") |
|
47 |
@Transactional(readOnly=true) |
|
48 |
public class SpecimenTypeDesignationWorkingSetServiceImpl implements ISpecimenTypeDesignationWorkingSetService { |
|
49 |
|
|
50 |
private final Logger logger = Logger.getLogger(SpecimenTypeDesignationWorkingSetServiceImpl.class); |
|
51 |
|
|
52 |
@Autowired |
|
53 |
IRegistrationWorkingSetService registrationWorkingSetService; |
|
54 |
|
|
55 |
@Qualifier("cdmRepository") |
|
56 |
@Autowired |
|
57 |
CdmRepository repo; |
|
58 |
|
|
59 |
|
|
60 |
/** |
|
61 |
* {@inheritDoc} |
|
62 |
*/ |
|
63 |
@Override |
|
64 |
public SpecimenTypeDesignationWorkingSetDTO<Registration> create(int registrationId, int publicationId, int typifiedNameId) { |
|
65 |
FieldUnit newfieldUnit = FieldUnit.NewInstance(); |
|
66 |
Registration reg = repo.getRegistrationService().load(registrationId, RegistrationWorkingSetService.REGISTRATION_INIT_STRATEGY); |
|
67 |
SpecimenTypeDesignationWorkingSetDTO<Registration> workingSetDto = new SpecimenTypeDesignationWorkingSetDTO<Registration>(reg, newfieldUnit, publicationId, typifiedNameId); |
|
68 |
return workingSetDto; |
|
69 |
} |
|
70 |
|
|
71 |
/** |
|
72 |
* {@inheritDoc} |
|
73 |
*/ |
|
74 |
@Override |
|
75 |
@Transactional |
|
76 |
public SpecimenTypeDesignationWorkingSetDTO<Registration> loadDtoByIds(int registrationId, int workingsetId) { |
|
77 |
RegistrationDTO regDTO = registrationWorkingSetService.loadDtoById(registrationId); |
|
78 |
// find the working set |
|
79 |
TypeDesignationWorkingSet typeDesignationWorkingSet = regDTO.getTypeDesignationWorkingSet(workingsetId); |
|
80 |
SpecimenTypeDesignationWorkingSetDTO<Registration> workingSetDto = regDTO.getSpecimenTypeDesignationWorkingSetDTO(typeDesignationWorkingSet.getBaseEntityReference()); |
|
81 |
workingSetDto.setCitationEntityID(regDTO.getCitation().getId()); |
|
82 |
workingSetDto.setTypifiedNameEntityID(regDTO.getTypifiedName().getId()); |
|
83 |
return workingSetDto; |
|
84 |
} |
|
85 |
|
|
86 |
@Override |
|
87 |
public SpecimenTypeDesignationWorkingSetDTO<Registration> fixMissingFieldUnit(SpecimenTypeDesignationWorkingSetDTO<Registration> bean) { |
|
88 |
|
|
89 |
if(bean.getFieldUnit() == null){ |
|
90 |
// in case the base unit of the working set is not a FieldUnit all contained TypeDesignations must be modified |
|
91 |
// so that they are based on an empty FieldUnit with an associated Gathering Event |
|
92 |
|
|
93 |
Registration reg = repo.getRegistrationService().find(bean.getOwner().getId()); |
|
94 |
RegistrationDTO regDTO = new RegistrationDTO(reg); |
|
95 |
|
|
96 |
FieldUnit fieldUnit = FieldUnit.NewInstance(); |
|
97 |
GatheringEvent gatheringEvent = GatheringEvent.NewInstance(); |
|
98 |
fieldUnit.setGatheringEvent(gatheringEvent); |
|
99 |
repo.getOccurrenceService().save(fieldUnit); |
|
100 |
|
|
101 |
VersionableEntity baseEntity = bean.getBaseEntity(); |
|
102 |
Set<TypeDesignationBase> typeDesignations = regDTO.getTypeDesignationsInWorkingSet( |
|
103 |
new TypedEntityReference(baseEntity.getClass(), baseEntity.getId(), baseEntity.toString()) |
|
104 |
); |
|
105 |
for(TypeDesignationBase td : typeDesignations){ |
|
106 |
DerivationEvent de = DerivationEvent.NewInstance();// |
|
107 |
de.addOriginal(fieldUnit); |
|
108 |
de.addDerivative(((SpecimenTypeDesignation)td).getTypeSpecimen()); |
|
109 |
de.setType(DerivationEventType.GATHERING_IN_SITU()); |
|
110 |
} |
|
111 |
|
|
112 |
repo.getRegistrationService().saveOrUpdate(reg); |
|
113 |
} |
|
114 |
return bean; |
|
115 |
} |
|
116 |
|
|
117 |
/** |
|
118 |
* {@inheritDoc} |
|
119 |
*/ |
|
120 |
@Override |
|
121 |
@Transactional(readOnly=false) |
|
122 |
public void save(SpecimenTypeDesignationWorkingSetDTO<? extends VersionableEntity> dto, Reference citation, TaxonName typifiedName) { |
|
123 |
|
|
124 |
if(dto.getOwner() instanceof Registration){ |
|
125 |
Registration regPremerge = (Registration) dto.getOwner(); |
|
126 |
|
|
127 |
// find the newly created type designations |
|
128 |
Set<SpecimenTypeDesignation> newTypeDesignations = findNewTypeDesignations((SpecimenTypeDesignationWorkingSetDTO<Registration>) dto); |
|
129 |
|
|
130 |
FieldUnit fieldUnit = (FieldUnit) dto.getBaseEntity(); |
|
131 |
|
|
132 |
// associate the new typeDesignations with the registration |
|
133 |
for(SpecimenTypeDesignation std : newTypeDesignations){ |
|
134 |
assureFieldUnit(fieldUnit, std); |
|
135 |
std.setCitation(citation); |
|
136 |
typifiedName.addTypeDesignation(std, false); |
|
137 |
regPremerge.addTypeDesignation(std); |
|
138 |
} |
|
139 |
|
|
140 |
for(SpecimenTypeDesignationDTO stdDTO : dto.getSpecimenTypeDesignationDTOs()){ |
|
141 |
SpecimenTypeDesignation specimenTypeDesignation = stdDTO.asSpecimenTypeDesignation(); |
|
142 |
// associate all type designations with the fieldUnit |
|
143 |
assureFieldUnit(fieldUnit, specimenTypeDesignation); |
|
144 |
} |
|
145 |
|
|
146 |
Session session = repo.getSession(); |
|
147 |
|
|
148 |
session.merge(dto.getOwner()); |
|
149 |
|
|
150 |
session.flush(); |
|
151 |
} |
|
152 |
|
|
153 |
|
|
154 |
} |
|
155 |
|
|
156 |
/** |
|
157 |
* @param session |
|
158 |
* @param fieldUnit |
|
159 |
* @param specimenTypeDesignation |
|
160 |
*/ |
|
161 |
protected void assureFieldUnit(FieldUnit fieldUnit, |
|
162 |
SpecimenTypeDesignation specimenTypeDesignation) { |
|
163 |
try { |
|
164 |
SpecimenOrObservationBase<?> original = findEarliestOriginal(specimenTypeDesignation.getTypeSpecimen()); |
|
165 |
if(original instanceof DerivedUnit){ |
|
166 |
DerivedUnit du = (DerivedUnit)original; |
|
167 |
du.getDerivedFrom().addOriginal(fieldUnit); |
|
168 |
} |
|
169 |
} catch (Exception e) { |
|
170 |
// has more than one originals !!! |
|
171 |
logger.error(e); |
|
172 |
} |
|
173 |
} |
|
174 |
|
|
175 |
/** |
|
176 |
* @param std |
|
177 |
* @return |
|
178 |
* @throws Exception |
|
179 |
*/ |
|
180 |
private SpecimenOrObservationBase<?> findEarliestOriginal(DerivedUnit du) throws Exception { |
|
181 |
|
|
182 |
SpecimenOrObservationBase original = du; |
|
183 |
|
|
184 |
while(du != null && du.getDerivedFrom() != null && !du.getDerivedFrom().getOriginals().isEmpty()) { |
|
185 |
Iterator<SpecimenOrObservationBase> it = du.getDerivedFrom().getOriginals().iterator(); |
|
186 |
SpecimenOrObservationBase nextOriginal = it.next(); |
|
187 |
if(nextOriginal == null){ |
|
188 |
break; |
|
189 |
} |
|
190 |
original = nextOriginal; |
|
191 |
if(original instanceof DerivedUnit){ |
|
192 |
du = (DerivedUnit)original; |
|
193 |
} else { |
|
194 |
// so this must be a FieldUnit, |
|
195 |
break; |
|
196 |
} |
|
197 |
if(it.hasNext()){ |
|
198 |
throw new Exception(String.format("%s has more than one originals", du.toString())); |
|
199 |
} |
|
200 |
} |
|
201 |
return original; |
|
202 |
} |
|
203 |
|
|
204 |
private Set<SpecimenTypeDesignation> findNewTypeDesignations(SpecimenTypeDesignationWorkingSetDTO<Registration> workingSetDto) { |
|
205 |
|
|
206 |
Registration reg = workingSetDto.getOwner(); |
|
207 |
Set<SpecimenTypeDesignation> addCandidates = new HashSet<>(); |
|
208 |
for(SpecimenTypeDesignationDTO stdDTO : workingSetDto.getSpecimenTypeDesignationDTOs()){ |
|
209 |
SpecimenTypeDesignation std = stdDTO.asSpecimenTypeDesignation(); |
|
210 |
if(reg.getTypeDesignations().isEmpty() || !reg.getTypeDesignations().stream().filter(td -> td.equals(std)).findFirst().isPresent()){ |
|
211 |
addCandidates.add(std); |
|
212 |
} |
|
213 |
} |
|
214 |
return addCandidates; |
|
215 |
} |
|
216 |
|
|
217 |
} |
src/main/java/eu/etaxonomy/cdm/vaadin/event/ToOneRelatedEntityButtonUpdater.java | ||
---|---|---|
27 | 27 |
|
28 | 28 |
ToOneRelatedEntityField<CDM> toOneRelatedEntityField; |
29 | 29 |
|
30 |
private Class<? extends CDM> type; |
|
31 |
|
|
32 |
|
|
30 | 33 |
public ToOneRelatedEntityButtonUpdater(ToOneRelatedEntityField<CDM> toOneRelatedEntityField){ |
31 | 34 |
this.toOneRelatedEntityField = toOneRelatedEntityField; |
35 |
this.type = toOneRelatedEntityField.getType(); |
|
32 | 36 |
} |
33 | 37 |
|
34 | 38 |
/** |
... | ... | |
39 | 43 |
|
40 | 44 |
CdmBase value = (CdmBase)event.getProperty().getValue(); |
41 | 45 |
|
42 |
boolean userIsAllowedToUpdate = UserHelper.fromSession().userHasPermission(value, CRUD.UPDATE); |
|
43 |
boolean userIsAllowedToCreate = UserHelper.fromSession().userHasPermission(value.getClass(), CRUD.CREATE);
|
|
46 |
boolean userIsAllowedToUpdate = value != null && UserHelper.fromSession().userHasPermission(value, CRUD.UPDATE);
|
|
47 |
boolean userIsAllowedToCreate = UserHelper.fromSession().userHasPermission(type, CRUD.CREATE);
|
|
44 | 48 |
|
45 | 49 |
toOneRelatedEntityField.setAddButtonEnabled(userIsAllowedToCreate); |
46 | 50 |
toOneRelatedEntityField.setEditButtonEnabled(userIsAllowedToUpdate); |
src/main/java/eu/etaxonomy/cdm/vaadin/event/ToOneRelatedEntityReloader.java | ||
---|---|---|
1 |
/** |
|
2 |
* Copyright (C) 2017 EDIT |
|
3 |
* European Distributed Institute of Taxonomy |
|
4 |
* http://www.e-taxonomy.eu |
|
5 |
* |
|
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. |
|
8 |
*/ |
|
9 |
package eu.etaxonomy.cdm.vaadin.event; |
|
10 |
|
|
11 |
import org.vaadin.viritin.fields.LazyComboBox; |
|
12 |
|
|
13 |
import com.vaadin.data.Property.ValueChangeEvent; |
|
14 |
import com.vaadin.data.Property.ValueChangeListener; |
|
15 |
|
|
16 |
import eu.etaxonomy.cdm.cache.EntityCache; |
|
17 |
import eu.etaxonomy.cdm.hibernate.HibernateProxyHelper; |
|
18 |
import eu.etaxonomy.cdm.model.common.CdmBase; |
|
19 |
import eu.etaxonomy.cdm.vaadin.view.name.CachingPresenter; |
|
20 |
|
|
21 |
/** |
|
22 |
* |
|
23 |
* @author a.kohlbecker |
|
24 |
* @since 19.10.2017 |
|
25 |
* |
|
26 |
*/ |
|
27 |
public class ToOneRelatedEntityReloader<CDM extends CdmBase> implements ValueChangeListener { |
|
28 |
|
|
29 |
private static final long serialVersionUID = -1141764783149024788L; |
|
30 |
|
|
31 |
LazyComboBox<CDM> toOneRelatedEntityField; |
|
32 |
|
|
33 |
CachingPresenter cachingPresenter; |
|
34 |
|
|
35 |
public ToOneRelatedEntityReloader( LazyComboBox<CDM> toOneRelatedEntityField, CachingPresenter entityCache){ |
|
36 |
this.toOneRelatedEntityField = toOneRelatedEntityField; |
|
37 |
this.cachingPresenter = entityCache; |
|
38 |
} |
|
39 |
|
|
40 |
/** |
|
41 |
* {@inheritDoc} |
|
42 |
*/ |
|
43 |
@Override |
|
44 |
public void valueChange(ValueChangeEvent event) { |
|
45 |
|
|
46 |
CDM value = (CDM)event.getProperty().getValue(); |
|
47 |
value = HibernateProxyHelper.deproxy(value); |
|
48 |
|
|
49 |
EntityCache cache = cachingPresenter.getCache(); |
|
50 |
if(cache != null){ |
|
51 |
cache.update(); |
|
52 |
CDM cachedEntity = cache.find(value); |
|
53 |
if(cachedEntity != null && cachedEntity != value){ |
|
54 |
toOneRelatedEntityField.removeValueChangeListener(this); |
|
55 |
toOneRelatedEntityField.setValue(null); // reset to trick equals check in vaadin |
|
56 |
toOneRelatedEntityField.setValue(cachedEntity); |
|
57 |
toOneRelatedEntityField.addValueChangeListener(this); |
|
58 |
|
|
59 |
} |
|
60 |
} |
|
61 |
} |
|
62 |
|
|
63 |
} |
src/main/java/eu/etaxonomy/cdm/vaadin/model/registration/SpecimenTypeDesignationWorkingSetDTO.java | ||
---|---|---|
29 | 29 |
* @since Jun 16, 2017 |
30 | 30 |
* |
31 | 31 |
*/ |
32 |
public class SpecimenTypeDesignationWorkingSetDTO { |
|
32 |
public class SpecimenTypeDesignationWorkingSetDTO<OWNER extends VersionableEntity> {
|
|
33 | 33 |
|
34 | 34 |
FieldUnit fieldUnit; |
35 | 35 |
|
... | ... | |
39 | 39 |
|
40 | 40 |
List<SpecimenTypeDesignationDTO> specimenTypeDesignationsDTOs = new ArrayList<>(); |
41 | 41 |
|
42 |
VersionableEntity owner; |
|
42 |
OWNER owner; |
|
43 |
|
|
44 |
private Integer citationEntityID; |
|
45 |
|
|
46 |
private Integer typifiedNameEntityID; |
|
43 | 47 |
|
44 | 48 |
/** |
45 | 49 |
* |
... | ... | |
47 | 51 |
* @param baseEntity |
48 | 52 |
* @param specimenTypeDesignations can be <code>null</code> |
49 | 53 |
*/ |
50 |
public SpecimenTypeDesignationWorkingSetDTO(VersionableEntity owner, VersionableEntity baseEntity, List<SpecimenTypeDesignation> specimenTypeDesignations) {
|
|
54 |
public SpecimenTypeDesignationWorkingSetDTO(OWNER owner, VersionableEntity baseEntity, List<SpecimenTypeDesignation> specimenTypeDesignations) {
|
|
51 | 55 |
super(); |
52 | 56 |
this.owner = owner; |
53 | 57 |
this.baseEntity = baseEntity; |
... | ... | |
63 | 67 |
} |
64 | 68 |
} |
65 | 69 |
|
70 |
/** |
|
71 |
* @param reg |
|
72 |
* @param newfieldUnit |
|
73 |
* @param citationEntityID |
|
74 |
* @param typifiedNameEntityID |
|
75 |
*/ |
|
76 |
public SpecimenTypeDesignationWorkingSetDTO(OWNER reg, FieldUnit newfieldUnit, Integer citationEntityID, |
|
77 |
Integer typifiedNameEntityID) { |
|
78 |
this(reg, newfieldUnit, null); |
|
79 |
this.citationEntityID = citationEntityID; |
|
80 |
this.typifiedNameEntityID = typifiedNameEntityID; |
|
81 |
} |
|
82 |
|
|
66 | 83 |
/** |
67 | 84 |
* @return the fieldUnit |
68 | 85 |
* <code>null</code> if the base baseEntity is a not a fieldUnit |
... | ... | |
93 | 110 |
} |
94 | 111 |
|
95 | 112 |
/** |
96 |
* The IdentifiableEntity which contains the DerivedUnit in this working set.
|
|
97 |
* |
|
113 |
* The {@link VersionableEntity} which contains the DerivedUnit in this working set.
|
|
114 |
* This can be for example a {@link Registration} entity
|
|
98 | 115 |
* |
99 | 116 |
* @return |
100 | 117 |
*/ |
101 |
public VersionableEntity getOwner() {
|
|
118 |
public OWNER getOwner() {
|
|
102 | 119 |
return owner; |
103 | 120 |
} |
104 | 121 |
|
... | ... | |
263 | 280 |
fieldUnit.getGatheringEvent().setGatheringDate(gatheringDate); |
264 | 281 |
} |
265 | 282 |
|
283 |
/** |
|
284 |
* @param id |
|
285 |
*/ |
|
286 |
public void setCitationEntityID(int id) { |
|
287 |
citationEntityID = id; |
|
288 |
|
|
289 |
} |
|
290 |
|
|
291 |
/** |
|
292 |
* @return |
|
293 |
*/ |
|
294 |
public int getCitationEntityID() { |
|
295 |
return citationEntityID; |
|
296 |
} |
|
297 |
|
|
298 |
/** |
|
299 |
* @param id |
|
300 |
*/ |
|
301 |
public void setTypifiedNameEntityID(int id) { |
|
302 |
typifiedNameEntityID = id; |
|
303 |
|
|
304 |
} |
|
305 |
|
|
306 |
/** |
|
307 |
* @return |
|
308 |
*/ |
|
309 |
public int getTypifiedNameEntityID() { |
|
310 |
return typifiedNameEntityID; |
|
311 |
} |
|
312 |
|
|
266 | 313 |
} |
src/main/java/eu/etaxonomy/cdm/vaadin/util/converter/TypeDesignationSetManager.java | ||
---|---|---|
21 | 21 |
import java.util.Optional; |
22 | 22 |
import java.util.Set; |
23 | 23 |
|
24 |
import org.hibernate.search.hcore.util.impl.HibernateHelper; |
|
25 |
|
|
24 | 26 |
import eu.etaxonomy.cdm.api.facade.DerivedUnitFacadeCacheStrategy; |
25 | 27 |
import eu.etaxonomy.cdm.model.common.CdmBase; |
26 | 28 |
import eu.etaxonomy.cdm.model.common.IdentifiableEntity; |
... | ... | |
189 | 191 |
* @return |
190 | 192 |
*/ |
191 | 193 |
protected TypedEntityReference<IdentifiableEntity<?>> makeEntityReference(IdentifiableEntity<?> baseEntity) { |
192 |
; |
|
194 |
|
|
195 |
baseEntity = (IdentifiableEntity<?>) HibernateHelper.unproxy(baseEntity); |
|
193 | 196 |
String label = ""; |
194 | 197 |
if(baseEntity instanceof FieldUnit){ |
195 | 198 |
label = ((FieldUnit)baseEntity).getTitleCache(); |
src/main/java/eu/etaxonomy/cdm/vaadin/view/name/CachingPresenter.java | ||
---|---|---|
1 |
/** |
|
2 |
* Copyright (C) 2017 EDIT |
|
3 |
* European Distributed Institute of Taxonomy |
|
4 |
* http://www.e-taxonomy.eu |
|
5 |
* |
|
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. |
|
8 |
*/ |
|
9 |
package eu.etaxonomy.cdm.vaadin.view.name; |
|
10 |
|
|
11 |
import eu.etaxonomy.cdm.cache.EntityCache; |
|
12 |
|
|
13 |
/** |
|
14 |
* @author a.kohlbecker |
|
15 |
* @since 09.11.2017 |
|
16 |
* |
|
17 |
*/ |
|
18 |
public interface CachingPresenter { |
|
19 |
|
|
20 |
public EntityCache getCache(); |
|
21 |
|
|
22 |
} |
src/main/java/eu/etaxonomy/cdm/vaadin/view/name/SpecimenTypeDesignationDTORow.java | ||
---|---|---|
42 | 42 |
|
43 | 43 |
public SpecimenTypeDesignationDTORow(){ |
44 | 44 |
kindOfUnit.setRows(1); |
45 |
kindOfUnit.setRequired(true); |
|
45 | 46 |
typeStatus.setRows(1); |
47 |
typeStatus.setRequired(true); |
|
46 | 48 |
accessionNumber.setWidth(100, Unit.PIXELS); |
47 | 49 |
collection.setWidth(150, Unit.PIXELS); |
48 | 50 |
mediaUri.setWidth(150, Unit.PIXELS); |
src/main/java/eu/etaxonomy/cdm/vaadin/view/name/SpecimenTypeDesignationWorkingsetEditorPresenter.java | ||
---|---|---|
9 | 9 |
package eu.etaxonomy.cdm.vaadin.view.name; |
10 | 10 |
|
11 | 11 |
import java.util.EnumSet; |
12 |
import java.util.HashSet; |
|
13 |
import java.util.Iterator; |
|
14 |
import java.util.Set; |
|
15 | 12 |
|
16 |
import org.hibernate.Session; |
|
17 |
import org.springframework.beans.factory.BeanFactory; |
|
18 | 13 |
import org.springframework.beans.factory.annotation.Autowired; |
19 | 14 |
import org.vaadin.viritin.fields.AbstractElementCollection; |
20 | 15 |
|
21 | 16 |
import eu.etaxonomy.cdm.api.service.IRegistrationService; |
17 |
import eu.etaxonomy.cdm.cache.CdmEntityCache; |
|
18 |
import eu.etaxonomy.cdm.cache.EntityCache; |
|
22 | 19 |
import eu.etaxonomy.cdm.model.common.DefinedTerm; |
23 |
import eu.etaxonomy.cdm.model.common.VersionableEntity; |
|
24 | 20 |
import eu.etaxonomy.cdm.model.location.Country; |
25 | 21 |
import eu.etaxonomy.cdm.model.name.Registration; |
26 |
import eu.etaxonomy.cdm.model.name.SpecimenTypeDesignation; |
|
27 | 22 |
import eu.etaxonomy.cdm.model.name.TaxonName; |
28 |
import eu.etaxonomy.cdm.model.name.TypeDesignationBase; |
|
29 | 23 |
import eu.etaxonomy.cdm.model.occurrence.Collection; |
30 |
import eu.etaxonomy.cdm.model.occurrence.DerivationEvent; |
|
31 |
import eu.etaxonomy.cdm.model.occurrence.DerivationEventType; |
|
32 |
import eu.etaxonomy.cdm.model.occurrence.DerivedUnit; |
|
33 |
import eu.etaxonomy.cdm.model.occurrence.FieldUnit; |
|
34 |
import eu.etaxonomy.cdm.model.occurrence.GatheringEvent; |
|
35 |
import eu.etaxonomy.cdm.model.occurrence.SpecimenOrObservationBase; |
|
36 | 24 |
import eu.etaxonomy.cdm.model.reference.Reference; |
37 | 25 |
import eu.etaxonomy.cdm.persistence.hibernate.permission.CRUD; |
38 | 26 |
import eu.etaxonomy.cdm.service.CdmFilterablePagingProvider; |
39 | 27 |
import eu.etaxonomy.cdm.service.CdmStore; |
40 |
import eu.etaxonomy.cdm.service.IRegistrationWorkingSetService; |
|
41 |
import eu.etaxonomy.cdm.service.RegistrationWorkingSetService; |
|
28 |
import eu.etaxonomy.cdm.service.ISpecimenTypeDesignationWorkingSetService; |
|
42 | 29 |
import eu.etaxonomy.cdm.vaadin.component.CdmBeanItemContainerFactory; |
43 | 30 |
import eu.etaxonomy.cdm.vaadin.event.ToOneRelatedEntityButtonUpdater; |
44 |
import eu.etaxonomy.cdm.vaadin.model.TypedEntityReference;
|
|
31 |
import eu.etaxonomy.cdm.vaadin.event.ToOneRelatedEntityReloader;
|
|
45 | 32 |
import eu.etaxonomy.cdm.vaadin.model.registration.KindOfUnitTerms; |
46 | 33 |
import eu.etaxonomy.cdm.vaadin.model.registration.RegistrationTermLists; |
47 |
import eu.etaxonomy.cdm.vaadin.model.registration.SpecimenTypeDesignationDTO; |
|
48 | 34 |
import eu.etaxonomy.cdm.vaadin.model.registration.SpecimenTypeDesignationWorkingSetDTO; |
49 | 35 |
import eu.etaxonomy.cdm.vaadin.security.UserHelper; |
50 | 36 |
import eu.etaxonomy.cdm.vaadin.util.CdmTitleCacheCaptionGenerator; |
51 |
import eu.etaxonomy.cdm.vaadin.util.converter.TypeDesignationSetManager.TypeDesignationWorkingSet; |
|
52 |
import eu.etaxonomy.cdm.vaadin.view.registration.RegistrationDTO; |
|
53 | 37 |
import eu.etaxonomy.vaadin.mvp.AbstractEditorPresenter; |
54 |
import eu.etaxonomy.vaadin.ui.view.PopupEditorFactory;
|
|
38 |
import eu.etaxonomy.vaadin.mvp.AbstractPopupEditor;
|
|
55 | 39 |
/** |
56 | 40 |
* SpecimenTypeDesignationWorkingsetPopupEditorView implementation must override the showInEditor() method, |
57 | 41 |
* see {@link #prepareAsFieldGroupDataSource()} for details. |
... | ... | |
61 | 45 |
* |
62 | 46 |
*/ |
63 | 47 |
public class SpecimenTypeDesignationWorkingsetEditorPresenter |
64 |
extends AbstractEditorPresenter<SpecimenTypeDesignationWorkingSetDTO , SpecimenTypeDesignationWorkingsetPopupEditorView> { |
|
48 |
extends AbstractEditorPresenter<SpecimenTypeDesignationWorkingSetDTO , SpecimenTypeDesignationWorkingsetPopupEditorView> |
|
49 |
implements CachingPresenter { |
|
65 | 50 |
|
66 | 51 |
private static final long serialVersionUID = 4255636253714476918L; |
67 | 52 |
|
68 | 53 |
CdmStore<Registration, IRegistrationService> store; |
69 | 54 |
|
70 |
private Reference citation; |
|
71 |
|
|
72 |
private TaxonName typifiedName; |
|
73 | 55 |
|
74 | 56 |
/** |
75 | 57 |
* This object for this field will either be injected by the {@link PopupEditorFactory} or by a Spring |
76 | 58 |
* {@link BeanFactory} |
77 | 59 |
*/ |
78 | 60 |
@Autowired |
79 |
private IRegistrationWorkingSetService registrationWorkingSetService;
|
|
61 |
private ISpecimenTypeDesignationWorkingSetService specimenTypeDesignationWorkingSetService;
|
|
80 | 62 |
|
81 | 63 |
/** |
82 | 64 |
* if not null, this CRUD set is to be used to create a CdmAuthoritiy for the base entitiy which will be |
... | ... | |
84 | 66 |
*/ |
85 | 67 |
private EnumSet<CRUD> crud = null; |
86 | 68 |
|
69 |
private CdmEntityCache cache = null; |
|
70 |
|
|
87 | 71 |
protected CdmStore<Registration, IRegistrationService> getStore() { |
88 | 72 |
if(store == null){ |
89 | 73 |
store = new CdmStore<>(getRepo(), getRepo().getRegistrationService()); |
... | ... | |
104 | 88 |
* @param identifier a {@link TypeDesignationWorkingsetEditorIdSet} |
105 | 89 |
*/ |
106 | 90 |
@Override |
107 |
protected SpecimenTypeDesignationWorkingSetDTO loadBeanById(Object identifier) { |
|
91 |
protected SpecimenTypeDesignationWorkingSetDTO<Registration> loadBeanById(Object identifier) {
|
|
108 | 92 |
|
109 |
SpecimenTypeDesignationWorkingSetDTO workingSetDto; |
|
93 |
SpecimenTypeDesignationWorkingSetDTO<Registration> workingSetDto;
|
|
110 | 94 |
if(identifier != null){ |
111 | 95 |
|
112 | 96 |
TypeDesignationWorkingsetEditorIdSet idset = (TypeDesignationWorkingsetEditorIdSet)identifier; |
113 | 97 |
|
114 | 98 |
if(idset.workingsetId != null){ |
115 |
RegistrationDTO regDTO = registrationWorkingSetService.loadDtoById(idset.registrationId); |
|
116 |
// find the working set |
|
117 |
TypeDesignationWorkingSet typeDesignationWorkingSet = regDTO.getTypeDesignationWorkingSet(idset.workingsetId); |
|
118 |
workingSetDto = regDTO.getSpecimenTypeDesignationWorkingSetDTO(typeDesignationWorkingSet.getBaseEntityReference()); |
|
119 |
citation = (Reference) regDTO.getCitation(); |
|
120 |
workingSetDto = fixMissingFieldUnit(workingSetDto); |
|
99 |
workingSetDto = specimenTypeDesignationWorkingSetService.loadDtoByIds(idset.registrationId, idset.workingsetId); |
|
100 |
if(workingSetDto.getFieldUnit() == null){ |
|
101 |
workingSetDto = specimenTypeDesignationWorkingSetService.fixMissingFieldUnit(workingSetDto); |
|
102 |
// FIXME open Dialog to warn user about adding an empty fieldUnit to the typeDesignations |
|
103 |
// This method must go again into the presenter !!!! |
|
104 |
logger.info("Basing all typeDesignations on a new fieldUnit"); |
|
105 |
} |
|
106 |
cache = new CdmEntityCache(workingSetDto.getOwner()); |
|
121 | 107 |
} else { |
122 | 108 |
// create a new workingset, for a new fieldunit which is the base for the workingset |
123 |
FieldUnit newfieldUnit = FieldUnit.NewInstance(); |
|
124 |
Registration reg = getRepo().getRegistrationService().load(idset.registrationId, |
|
125 |
RegistrationWorkingSetService.REGISTRATION_INIT_STRATEGY); |
|
126 |
//TODO checkif passing reg as owner parameter is needed at all |
|
127 |
workingSetDto = new SpecimenTypeDesignationWorkingSetDTO(reg, newfieldUnit, null); |
|
128 |
citation = getRepo().getReferenceService().find(idset.publicationId); |
|
129 |
typifiedName = getRepo().getNameService().find(idset.typifiedNameId); |
|
109 |
workingSetDto = specimenTypeDesignationWorkingSetService.create(idset.registrationId, idset.publicationId, idset.typifiedNameId); |
|
110 |
cache = new CdmEntityCache(workingSetDto.getOwner()); |
|
130 | 111 |
} |
131 | 112 |
|
132 | 113 |
} else { |
133 | 114 |
workingSetDto = null; |
134 | 115 |
} |
116 |
|
|
135 | 117 |
return workingSetDto; |
136 | 118 |
} |
137 | 119 |
|
... | ... | |
180 | 162 |
); |
181 | 163 |
row.collection.getSelect().setCaptionGenerator(new CdmTitleCacheCaptionGenerator<Collection>()); |
182 | 164 |
row.collection.getSelect().addValueChangeListener(new ToOneRelatedEntityButtonUpdater<Collection>(row.collection)); |
165 |
row.collection.getSelect().addValueChangeListener(new ToOneRelatedEntityReloader<Collection>(row.collection.getSelect(), SpecimenTypeDesignationWorkingsetEditorPresenter.this)); |
|
183 | 166 |
|
184 | 167 |
row.mediaSpecimenReference.loadFrom( |
185 | 168 |
referencePagingProvider, |
186 | 169 |
referencePagingProvider, |
187 | 170 |
collectionPagingProvider.getPageSize() |
188 | 171 |
); |
172 |
|
|
189 | 173 |
row.mediaSpecimenReference.getSelect().setCaptionGenerator(new CdmTitleCacheCaptionGenerator<Reference>()); |
190 | 174 |
row.mediaSpecimenReference.getSelect().addValueChangeListener(new ToOneRelatedEntityButtonUpdater<Reference>(row.mediaSpecimenReference)); |
191 | 175 |
|
... | ... | |
212 | 196 |
} |
213 | 197 |
|
214 | 198 |
|
215 |
private SpecimenTypeDesignationWorkingSetDTO fixMissingFieldUnit(SpecimenTypeDesignationWorkingSetDTO bean) { |
|
216 |
|
|
217 |
if(bean.getFieldUnit() == null){ |
|
218 |
// in case the base unit of the working set is not a FieldUnit all contained TypeDesignations must be modified |
|
219 |
// so that they are based on an empty FieldUnit with an associated Gathering Event |
|
220 |
if(Registration.class.isAssignableFrom(bean.getOwner().getClass())){ |
|
221 |
// FIXME open Dialog to warn user about adding an empty fieldUnit to the typeDesignations |
|
222 |
logger.info("Basing all typeDesignations on a new fieldUnit"); |
|
223 |
Session session = getSession(); |
|
224 |
Registration reg = getRepo().getRegistrationService().find(bean.getOwner().getId()); |
|
225 |
RegistrationDTO regDTO = new RegistrationDTO(reg); |
|
226 |
|
|
227 |
FieldUnit fieldUnit = FieldUnit.NewInstance(); |
|
228 |
GatheringEvent gatheringEvent = GatheringEvent.NewInstance(); |
|
229 |
fieldUnit.setGatheringEvent(gatheringEvent); |
|
230 |
getRepo().getOccurrenceService().save(fieldUnit); |
|
231 |
|
|
232 |
VersionableEntity baseEntity = bean.getBaseEntity(); |
|
233 |
Set<TypeDesignationBase> typeDesignations = regDTO.getTypeDesignationsInWorkingSet( |
|
234 |
new TypedEntityReference(baseEntity.getClass(), baseEntity.getId(), baseEntity.toString()) |
|
235 |
); |
|
236 |
for(TypeDesignationBase td : typeDesignations){ |
|
237 |
DerivationEvent de = DerivationEvent.NewInstance();// |
|
238 |
de.addOriginal(fieldUnit); |
|
239 |
de.addDerivative(((SpecimenTypeDesignation)td).getTypeSpecimen()); |
|
240 |
de.setType(DerivationEventType.GATHERING_IN_SITU()); |
|
241 |
} |
|
242 |
|
|
243 |
getRepo().getRegistrationService().saveOrUpdate(reg); |
|
244 |
session.flush(); |
|
245 |
session.close(); |
|
246 |
} else { |
Also available in: Unified diff
ref #7059 ref #7046 using kindOfunit for TypeDesisgnations instead of DerivationEvent type and fixing save and LIE problems:
- intoducing EntityCache to allow re-using previously loaded entities
- CdmEntityCache implements EntityCache
- ToOneRelatedEntityReloader to replace entities loaded by the LazySelect
- SpecimenTypeDesignationWorkingsetEditorPresenter implements CachingPresenter so that EnityCache and
ToOneRelatedEntityReloader can interact
- completing init strategies in RegistrationWorkingSetService
- SpecimenTypeDesignationWorkingsetEditorPresenter.saveBean reuses entities stored in entityCache
- introducing SpecimenTypeDesignationWorkingSetService