2 * Copyright (C) 2017 EDIT
3 * European Distributed Institute of Taxonomy
4 * http://www.e-taxonomy.eu
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.
9 package eu
.etaxonomy
.cdm
.service
;
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
;
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
;
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
;
40 * @author a.kohlbecker
43 * TODO better naming of this class, ServiceWrapper, ServiceOperator, ...?
48 public class CdmStore
{
50 private static final Logger logger
= LogManager
.getLogger();
53 @Qualifier("cdmRepository")
54 private CdmRepository repo
;
56 protected String
_toString() {
57 return this.getClass().getSimpleName() + "@" + this.hashCode();
64 * @return the merged bean, this bean is <b>not reloaded</b> from the
67 public <T
extends CdmBase
> EntityChangeEvent
saveBean(T bean
, AbstractView view
) {
70 if(bean
.isPersited()){
71 changeEventType
= Type
.MODIFIED
;
73 changeEventType
= Type
.CREATED
;
77 TransactionStatus txStatus
= repo
.startTransaction();
78 Session session
= repo
.getSession();
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());
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
);
93 transactionRollbackIfNotCompleted(txStatus
);
97 repo
.clearSession(); // #7559
106 public void transactionRollbackIfNotCompleted(TransactionStatus txStatus
) {
107 if(!txStatus
.isCompleted()){
108 repo
.getTransactionManager().rollback(txStatus
);
115 * @return a EntityChangeEvent in case the deletion was successful otherwise <code>null</code>.
117 public final <T
extends CdmBase
> EntityChangeEvent
deleteBean(T bean
, AbstractView view
) {
119 IService
<T
> typeSpecificService
= serviceFor(bean
);
122 logger
.trace(this._toString() + ".deleteBean - deleting" + bean
.toString());
123 DeleteResult result
= typeSpecificService
.delete(bean
);
125 return new EntityChangeEvent(bean
, Type
.REMOVED
, view
);
127 handleDeleteresultInError(result
);
130 repo
.clearSession(); // #7559
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.";
145 notificationTitle
= "An error occured during the delete operation.";
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>");
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());
159 messageBody
.append(e
.toString());
161 messageBody
.append("</li>");
164 messageBody
.append("</ul>");
166 Notification notification
= new Notification(notificationTitle
, messageBody
.toString(),
167 com
.vaadin
.ui
.Notification
.Type
.ERROR_MESSAGE
, true);
168 notification
.show(UI
.getCurrent().getPage());
171 @SuppressWarnings("unchecked")
172 protected <T
extends CdmBase
> IService
<T
> serviceFor(T bean
){
173 Class
<?
extends CdmBase
> cdmType
= bean
.getClass();
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();
192 throw new RuntimeException("Implementation to find service for " + cdmType
+ " still missing.");