Project

General

Profile

Download (7.32 KB) Statistics
| Branch: | Tag: | Revision:
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 org.apache.log4j.Logger;
12
import org.hibernate.Session;
13
import org.springframework.beans.factory.annotation.Autowired;
14
import org.springframework.beans.factory.annotation.Qualifier;
15
import org.springframework.transaction.TransactionStatus;
16

    
17
import com.vaadin.spring.annotation.SpringComponent;
18
import com.vaadin.spring.annotation.ViewScope;
19
import com.vaadin.ui.Notification;
20
import com.vaadin.ui.UI;
21

    
22
import eu.etaxonomy.cdm.api.application.CdmRepository;
23
import eu.etaxonomy.cdm.api.service.DeleteResult;
24
import eu.etaxonomy.cdm.api.service.IService;
25
import eu.etaxonomy.cdm.model.agent.AgentBase;
26
import eu.etaxonomy.cdm.model.common.CdmBase;
27
import eu.etaxonomy.cdm.model.common.IdentifiableEntity;
28
import eu.etaxonomy.cdm.model.name.NameTypeDesignation;
29
import eu.etaxonomy.cdm.model.name.Registration;
30
import eu.etaxonomy.cdm.model.name.TaxonName;
31
import eu.etaxonomy.cdm.model.occurrence.Collection;
32
import eu.etaxonomy.cdm.model.occurrence.SpecimenOrObservationBase;
33
import eu.etaxonomy.cdm.model.reference.Reference;
34
import eu.etaxonomy.cdm.vaadin.event.EntityChangeEvent;
35
import eu.etaxonomy.cdm.vaadin.event.EntityChangeEvent.Type;
36
import eu.etaxonomy.vaadin.mvp.AbstractView;
37

    
38
/**
39
 * @author a.kohlbecker
40
 * @since Jun 26, 2017
41
 *
42
 * TODO better naming of this class, ServiceWrapper, ServiceOperator, ...?
43
 *
44
 */
45
@SpringComponent
46
@ViewScope
47
public class CdmStore {
48

    
49
    private static final Logger logger = Logger.getLogger(CdmStore.class);
50

    
51
    @Autowired
52
    @Qualifier("cdmRepository")
53
    private CdmRepository repo;
54

    
55
    protected String _toString() {
56
        return this.getClass().getSimpleName() + "@" + this.hashCode();
57
    }
58

    
59
    /**
60
     *
61
     * @param bean
62
     *
63
     * @return the merged bean, this bean is <b>not reloaded</b> from the
64
     *         persistent storage.
65
     */
66
    public <T extends CdmBase> EntityChangeEvent saveBean(T bean, AbstractView view) {
67

    
68
        Type changeEventType;
69
        if(bean.isPersited()){
70
            changeEventType = Type.MODIFIED;
71
        } else {
72
            changeEventType = Type.CREATED;
73
        }
74

    
75
        try{
76
            TransactionStatus txStatus = repo.startTransaction();
77
            Session session = repo.getSession();
78
            try {
79
                logger.trace(this._toString() + ".onEditorSaveEvent - merging bean into session");
80
                // merge the changes into the session, ...
81
                if (session.contains(bean)) {
82
                    // evict bean before merge to avoid duplicate beans in same session
83
                    logger.trace(this._toString() + ".mergedBean() - evict " + bean.toString());
84
                    session.evict(bean);
85
                }
86
                logger.trace(this._toString() + ".mergedBean() - doing merge of" + bean.toString());
87
                @SuppressWarnings("unchecked")
88
                T mergedBean = (T) session.merge(bean);
89
                repo.commitTransaction(txStatus);
90
                return new EntityChangeEvent(mergedBean, changeEventType, view);
91
            } catch(Exception e){
92
                transactionRollbackIfNotCompleted(txStatus);
93
                throw e;
94
            }
95
        } finally {
96
            repo.clearSession(); // #7559
97
        }
98

    
99
    }
100

    
101

    
102
    /**
103
     * @param txStatus
104
     */
105
    public void transactionRollbackIfNotCompleted(TransactionStatus txStatus) {
106
        if(!txStatus.isCompleted()){
107
            repo.getTransactionManager().rollback(txStatus);
108
        }
109
    }
110

    
111
    /**
112
     *
113
     * @param bean
114
     * @return a EntityChangeEvent in case the deletion was successful otherwise <code>null</code>.
115
     */
116
    public final <T extends CdmBase> EntityChangeEvent deleteBean(T bean, AbstractView view) {
117

    
118
        IService<T> typeSpecificService = serviceFor(bean);
119

    
120
        try{
121
            logger.trace(this._toString() + ".deleteBean - deleting" + bean.toString());
122
            DeleteResult result = typeSpecificService.delete(bean);
123
            if (result.isOk()) {
124
                return new EntityChangeEvent(bean, Type.REMOVED, view);
125
            } else {
126
                handleDeleteresultInError(result);
127
            }
128
        } finally {
129
            repo.clearSession(); // #7559
130
        }
131

    
132
        return null;
133
    }
134

    
135
    /**
136
     * @param result
137
     */
138
    public static void handleDeleteresultInError(DeleteResult result) {
139
        String notificationTitle;
140
        StringBuffer messageBody = new StringBuffer();
141
        if (result.isAbort()) {
142
            notificationTitle = "The delete operation as abborded by the system.";
143
        } else {
144
            notificationTitle = "An error occured during the delete operation.";
145
        }
146
        if (!result.getExceptions().isEmpty()) {
147
            messageBody.append("<h3>").append("Exceptions:").append("</h3>").append("<ul>");
148
            result.getExceptions().forEach(e -> messageBody.append("<li>").append(e.getMessage()).append("</li>"));
149
            messageBody.append("</ul>");
150
        }
151
        if (!result.getRelatedObjects().isEmpty()) {
152
            messageBody.append("<h3>").append("Related objects exist:").append("</h3>").append("<ul>");
153
            result.getRelatedObjects().forEach(e -> {
154
                messageBody.append("<li>");
155
                if (IdentifiableEntity.class.isAssignableFrom(e.getClass())) {
156
                    messageBody.append(((IdentifiableEntity) e).getTitleCache());
157
                } else {
158
                    messageBody.append(e.toString());
159
                }
160
                messageBody.append("</li>");
161
            });
162

    
163
            messageBody.append("</ul>");
164
        }
165
        Notification notification = new Notification(notificationTitle, messageBody.toString(),
166
                com.vaadin.ui.Notification.Type.ERROR_MESSAGE, true);
167
        notification.show(UI.getCurrent().getPage());
168
    }
169

    
170
    @SuppressWarnings("unchecked")
171
    protected <T extends CdmBase> IService<T> serviceFor(T bean){
172
         Class<? extends CdmBase> cdmType = bean.getClass();
173

    
174
         if(Registration.class.isAssignableFrom(cdmType)){
175
             return (IService<T>) repo.getRegistrationService();
176
         } else if(TaxonName.class.isAssignableFrom(cdmType)){
177
             return (IService<T>) repo.getNameService();
178
         } else if(Reference.class.isAssignableFrom(cdmType)){
179
             return (IService<T>) repo.getReferenceService();
180
         } else if (NameTypeDesignation.class.isAssignableFrom(cdmType)){
181
             throw new RuntimeException("no generic sercvice for NameTypeDesignation, use dedicated methods of NameService");
182
         } else if (SpecimenOrObservationBase.class.isAssignableFrom(cdmType)){
183
             return (IService<T>) repo.getOccurrenceService();
184
         } else if (AgentBase.class.isAssignableFrom(cdmType)){
185
             return (IService<T>) repo.getAgentService();
186
         } else if (Collection.class.isAssignableFrom(cdmType)){
187
             return (IService<T>) repo.getCollectionService();
188
         } else if (Collection.class.isAssignableFrom(cdmType)){
189
             return (IService<T>) repo.getCollectionService();
190
         } else {
191
             throw new RuntimeException("Implementation to find service for " + cdmType + " still missing.");
192
         }
193
    }
194

    
195
}
(4-4/11)