Project

General

Profile

Download (7.36 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.logging.log4j.LogManager;
12
import org.apache.logging.log4j.Logger;
13
import org.hibernate.Session;
14
import org.springframework.beans.factory.annotation.Autowired;
15
import org.springframework.beans.factory.annotation.Qualifier;
16
import org.springframework.transaction.TransactionStatus;
17

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

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

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

    
50
    private final static Logger logger = LogManager.getLogger();
51

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

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

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

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

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

    
100
    }
101

    
102

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

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

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

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

    
133
        return null;
134
    }
135

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

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

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

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

    
196
}
(5-5/13)