Project

General

Profile

« Previous | Next » 

Revision 02ec8d6b

Added by Andreas Kohlbecker over 6 years ago

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

View differences:

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 {
... This diff was truncated because it exceeds the maximum size that can be displayed.

Also available in: Unified diff