ref #7046 completely removing open session per view implementation and adding init...
authorAndreas Kohlbecker <a.kohlbecker@bgbm.org>
Thu, 2 Nov 2017 11:42:21 +0000 (12:42 +0100)
committerAndreas Kohlbecker <a.kohlbecker@bgbm.org>
Thu, 2 Nov 2017 11:42:21 +0000 (12:42 +0100)
15 files changed:
src/main/java/eu/etaxonomy/cdm/service/CdmFilterablePagingProvider.java
src/main/java/eu/etaxonomy/cdm/service/CdmStore.java
src/main/java/eu/etaxonomy/cdm/service/CdmUserHelper.java
src/main/java/eu/etaxonomy/cdm/service/IRegistrationWorkingSetService.java
src/main/java/eu/etaxonomy/cdm/service/RegistrationWorkingSetService.java
src/main/java/eu/etaxonomy/cdm/vaadin/session/ViewScopeConversationHolder.java [deleted file]
src/main/java/eu/etaxonomy/cdm/vaadin/view/LoginPresenter.java
src/main/java/eu/etaxonomy/cdm/vaadin/view/name/SpecimenTypeDesignationWorkingsetEditorPresenter.java
src/main/java/eu/etaxonomy/cdm/vaadin/view/name/TaxonNameEditorPresenter.java
src/main/java/eu/etaxonomy/cdm/vaadin/view/registration/ListPresenter.java
src/main/java/eu/etaxonomy/cdm/vaadin/view/registration/RegistrationWorkingsetPresenter.java
src/main/java/eu/etaxonomy/cdm/vaadin/view/registration/StartRegistrationPresenter.java
src/main/java/eu/etaxonomy/vaadin/mvp/AbstractEditorPresenter.java
src/main/java/eu/etaxonomy/vaadin/mvp/AbstractPresenter.java
src/main/java/eu/etaxonomy/vaadin/ui/view/PopupEditorFactory.java

index 5bc8da9a5b7d9c1a7414fcd6809bafa418d70a2a..b7174a4a40c5b9db65f9c62765522c8585edca44 100644 (file)
@@ -19,7 +19,6 @@ import eu.etaxonomy.cdm.api.service.pager.Pager;
 import eu.etaxonomy.cdm.model.common.IdentifiableEntity;
 import eu.etaxonomy.cdm.persistence.query.MatchMode;
 import eu.etaxonomy.cdm.persistence.query.OrderHint;
-import eu.etaxonomy.cdm.vaadin.session.ConversationDirector;
 
 /**
  * @author a.kohlbecker
@@ -36,8 +35,6 @@ public class CdmFilterablePagingProvider<T extends IdentifiableEntity> implement
 
     private List<OrderHint> orderHints = OrderHint.ORDER_BY_TITLE_CACHE.asList();
 
-    private ConversationDirector conversationDirector;
-
 
     /**
      * @return the matchMode
@@ -72,10 +69,9 @@ public class CdmFilterablePagingProvider<T extends IdentifiableEntity> implement
      *
      * @param service
      */
-    public CdmFilterablePagingProvider(IIdentifiableEntityService<T> service, ConversationDirector conversationDirector) {
+    public CdmFilterablePagingProvider(IIdentifiableEntityService<T> service) {
         super();
         this.service = service;
-        this.conversationDirector = conversationDirector;
     }
 
     /**
@@ -83,12 +79,11 @@ public class CdmFilterablePagingProvider<T extends IdentifiableEntity> implement
      * @param matchMode
      * @param orderHints
      */
-    public CdmFilterablePagingProvider(IIdentifiableEntityService<T> service, MatchMode matchMode, List<OrderHint> orderHints, ConversationDirector conversationDirector) {
+    public CdmFilterablePagingProvider(IIdentifiableEntityService<T> service, MatchMode matchMode, List<OrderHint> orderHints) {
         super();
         this.service = service;
         this.matchMode = matchMode;
         this.orderHints = orderHints;
-        this.conversationDirector = conversationDirector;
     }
 
     /**
@@ -97,7 +92,6 @@ public class CdmFilterablePagingProvider<T extends IdentifiableEntity> implement
     @Override
     public List<T> findEntities(int firstRow, String filter) {
 
-        conversationDirector.ensureBoundConversation();
         Pager<T> page = service.findByTitle(
                 null,
                 filter,
@@ -117,7 +111,6 @@ public class CdmFilterablePagingProvider<T extends IdentifiableEntity> implement
     @Override
     public int size(String filter) {
 
-        conversationDirector.ensureBoundConversation();
         Pager<T> page = service.findByTitle(
                 null,
                 filter,
index ef267158a99b9ce5894e94489f36f0e00ffab3c5..460b3e00c933d6d90eeed6c911d1a2fd08335f1e 100644 (file)
@@ -18,7 +18,6 @@ import com.vaadin.ui.Notification;
 import com.vaadin.ui.UI;
 
 import eu.etaxonomy.cdm.api.application.CdmRepository;
-import eu.etaxonomy.cdm.api.conversation.ConversationHolder;
 import eu.etaxonomy.cdm.api.service.DeleteResult;
 import eu.etaxonomy.cdm.api.service.IService;
 import eu.etaxonomy.cdm.model.common.CdmBase;
@@ -41,16 +40,16 @@ public class CdmStore<T extends CdmBase, S extends IService<T>> {
 
     private S service;
 
-    TransactionStatus txNonConversational = null;
+    TransactionStatus txStatus = null;
 
-    ConversationHolder conversationHolder = null;
-
-    /**
-     * @return the conversationHolder
-     */
-    public ConversationHolder getConversationHolder() {
-        return conversationHolder;
-    }
+//    ConversationHolder conversationHolder = null;
+//
+//    /**
+//     * @return the conversationHolder
+//     */
+//    public ConversationHolder getConversationHolder() {
+//        return conversationHolder;
+//    }
 
     protected DefaultTransactionDefinition txDefinition = null;
 
@@ -68,43 +67,43 @@ public class CdmStore<T extends CdmBase, S extends IService<T>> {
 
     }
 
-    /**
-     * constructor which takes a ConversationHolder. The supplying class of the conversationHolder needs
-     * to care for <code>bind()</code>, <code>unbind()</code> and <code>close()</code> since the store is
-     * only responsible for starting and committing of transactions.
-     *
-     * @param repo
-     * @param service
-     * @param conversationHolder
-     */
-    public CdmStore(CdmRepository repo, S service, ConversationHolder conversationHolder) {
-
-        this.repo = repo;
-        this.service = service;
-        this.conversationHolder = conversationHolder;
-
-    }
+//    /**
+//     * constructor which takes a ConversationHolder. The supplying class of the conversationHolder needs
+//     * to care for <code>bind()</code>, <code>unbind()</code> and <code>close()</code> since the store is
+//     * only responsible for starting and committing of transactions.
+//     *
+//     * @param repo
+//     * @param service
+//     * @param conversationHolder
+//     */
+//    public CdmStore(CdmRepository repo, S service, ConversationHolder conversationHolder) {
+//
+//        this.repo = repo;
+//        this.service = service;
+//        this.conversationHolder = conversationHolder;
+//
+//    }
 
     /**
      * @return
      *
      */
     public TransactionStatus startTransaction() {
-        if(conversationHolder != null && !conversationHolder.isTransactionActive()){
-            //conversationHolder.setDefinition(getTransactionDefinition());
-            return conversationHolder.startTransaction();
-        } else {
+//        if(conversationHolder != null && !conversationHolder.isTransactionActive()){
+//            //conversationHolder.setDefinition(getTransactionDefinition());
+//            return conversationHolder.startTransaction();
+//        } else {
             checkExistingTransaction();
-            txNonConversational = repo.startTransaction();
-            return txNonConversational;
-        }
+            txStatus = repo.startTransaction();
+            return txStatus;
+//        }
     }
 
     /**
      *
      */
     protected void checkExistingTransaction() {
-        if (txNonConversational != null) {
+        if (txStatus != null) {
             // @formatter:off
             // holding the TransactionStatus as state is not good design. we
             // should change the save operation
@@ -159,11 +158,11 @@ public class CdmStore<T extends CdmBase, S extends IService<T>> {
     private Session getSession() {
 
         Session session;
-        if(conversationHolder != null){
-            session = conversationHolder.getSession();
-        } else {
+//        if(conversationHolder != null){
+//            session = conversationHolder.getSession();
+//        } else {
             session = repo.getSession();
-        }
+//        }
         logger.trace(this._toString() + ".getSession() - session:" + session.hashCode() + ", persistenceContext: "
                 + ((SessionImplementor) session).getPersistenceContext() + " - " + session.toString());
 
@@ -193,7 +192,9 @@ public class CdmStore<T extends CdmBase, S extends IService<T>> {
         Session session = getSession();
         logger.trace(this._toString() + ".onEditorSaveEvent - session: " + session.hashCode());
 
-        if(txNonConversational == null || (conversationHolder != null && !conversationHolder.isTransactionActive())){
+        if(txStatus == null
+//                || (conversationHolder != null && !conversationHolder.isTransactionActive())
+                ){
             // no running transaction, start one ...
             startTransaction();
         }
@@ -259,7 +260,7 @@ public class CdmStore<T extends CdmBase, S extends IService<T>> {
             Notification notification = new Notification(notificationTitle, messageBody.toString(),
                     com.vaadin.ui.Notification.Type.ERROR_MESSAGE, true);
             notification.show(UI.getCurrent().getPage());
-            txNonConversational = null;
+            txStatus = null;
         }
         return null;
     }
@@ -267,19 +268,19 @@ public class CdmStore<T extends CdmBase, S extends IService<T>> {
 
     protected void commitTransction() {
 
-        if(conversationHolder != null){
-            conversationHolder.commit();
-        } else {
-            repo.commitTransaction(txNonConversational);
-            txNonConversational = null;
-        }
+//        if(conversationHolder != null){
+//            conversationHolder.commit();
+//        } else {
+            repo.commitTransaction(txStatus);
+            txStatus = null;
+//        }
     }
 
     /**
      * @param entityId
      */
     public T loadBean(int entityId) {
-        conversationHolder.startTransaction();
+//        conversationHolder.startTransaction();
         return service.find(entityId);
     }
 
index d57b6a59ecd3e2f9eafabb39c4d25c3321ecb6e4..9c9d376529cd988c40f4c474d4edbe4025b13a5e 100644 (file)
@@ -20,6 +20,7 @@ import org.springframework.security.core.context.SecurityContext;
 import org.springframework.security.core.context.SecurityContextHolder;
 import org.springframework.security.core.userdetails.UserDetails;
 import org.springframework.security.web.authentication.preauth.PreAuthenticatedAuthenticationToken;
+import org.springframework.transaction.TransactionStatus;
 
 import com.vaadin.spring.annotation.SpringComponent;
 import com.vaadin.spring.annotation.UIScope;
@@ -194,6 +195,8 @@ public class CdmUserHelper extends VaadinUserHelper {
      */
     @Override
     public CdmAuthority createAuthorityFor(String username, CdmBase cdmEntity, EnumSet<CRUD> crud, String property) {
+
+        TransactionStatus txStatus = repo.startTransaction();
         UserDetails userDetails = repo.getUserService().loadUserByUsername(username);
         boolean newAuthorityAdded = false;
         CdmAuthority authority = null;
@@ -213,6 +216,7 @@ public class CdmUserHelper extends VaadinUserHelper {
             SecurityContextHolder.getContext().setAuthentication(authentication);
             logger.debug("security context refreshed with user " + username);
         }
+        repo.commitTransaction(txStatus);
         return newAuthorityAdded ? authority : null;
 
     }
@@ -228,7 +232,7 @@ public class CdmUserHelper extends VaadinUserHelper {
     public CdmAuthority createAuthorityFor(String username, Class<? extends CdmBase> cdmType, Integer entitiyId, EnumSet<CRUD> crud, String property) {
 
         CdmBase cdmEntity = repo.getCommonService().find(cdmType, entitiyId);
-        return createAuthorityFor(username,cdmEntity, crud, property);
+        return createAuthorityFor(username, cdmEntity, crud, property);
     }
 
     /**
index 9a8844e56f3e947a51ac384c6438edea5f550d0e..f0e93e099bf77e4654c8bb70702824ce398f36a0 100644 (file)
@@ -34,15 +34,6 @@ public interface IRegistrationWorkingSetService {
 
     public Collection<RegistrationDTO> listDTOs(User submitter, Collection<RegistrationStatus> includedStatus);
 
-    /**
-     * @param  id the CDM Entity id
-     * @return
-     * @throws RegistrationValidationException
-     * @deprecated Use {@link  #loadWorkingSetByReferenceID(Integer) instead
-     */
-    @Deprecated
-    public RegistrationWorkingSet loadWorkingSetByCitationID(Integer id) throws RegistrationValidationException;
-
     /**
      * @param referenceID
      * @return
index 9ba732f3e8a1aceac99b018c121fbbfe5a1f4841..db357b6ba0f9936e81995c8325de25c8f1bb2501 100644 (file)
@@ -9,9 +9,12 @@
 package eu.etaxonomy.cdm.service;
 
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.Collection;
+import java.util.HashSet;
 import java.util.List;
 import java.util.Optional;
+import java.util.Set;
 
 import org.apache.log4j.Logger;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -24,7 +27,13 @@ import eu.etaxonomy.cdm.api.service.pager.Pager;
 import eu.etaxonomy.cdm.model.common.User;
 import eu.etaxonomy.cdm.model.name.Registration;
 import eu.etaxonomy.cdm.model.name.RegistrationStatus;
+import eu.etaxonomy.cdm.model.name.SpecimenTypeDesignation;
+import eu.etaxonomy.cdm.model.name.TypeDesignationBase;
+import eu.etaxonomy.cdm.model.occurrence.DerivedUnit;
+import eu.etaxonomy.cdm.model.occurrence.FieldUnit;
+import eu.etaxonomy.cdm.model.occurrence.SpecimenOrObservationBase;
 import eu.etaxonomy.cdm.model.reference.Reference;
+import eu.etaxonomy.cdm.persistence.dao.initializer.IBeanInitializer;
 import eu.etaxonomy.cdm.vaadin.model.registration.RegistrationWorkingSet;
 import eu.etaxonomy.cdm.vaadin.view.registration.RegistrationDTO;
 import eu.etaxonomy.cdm.vaadin.view.registration.RegistrationValidationException;
@@ -51,6 +60,25 @@ import eu.etaxonomy.cdm.vaadin.view.registration.RegistrationValidationException
 @Transactional(readOnly=true)
 public class RegistrationWorkingSetService implements IRegistrationWorkingSetService {
 
+    public static final List<String> REGISTRATION_INIT_STRATEGY = Arrays.asList(new String []{
+            // typeDesignation
+            "typeDesignations.typeStatus.representations",
+            "typeDesignations.typifiedNames",
+            "typeDesignations.typeSpecimen",
+            "typeDesignations.typeName",
+            "typeDesignations.citation",
+            "typeDesignations.citation.authorship.$",
+            // name
+            "name.$",
+            "name.nomenclaturalReference.authorship",
+            "name.nomenclaturalReference.inReference",
+            "name.rank.representations",
+            "name.status.type.representations",
+            // institution
+            "institution",
+            }
+    );
+
     /**
      *
      */
@@ -62,18 +90,22 @@ public class RegistrationWorkingSetService implements IRegistrationWorkingSetSer
     @Qualifier("cdmRepository")
     private CdmRepository repo;
 
+    @Autowired
+    protected IBeanInitializer defaultBeanInitializer;
+
     public RegistrationWorkingSetService() {
 
     }
 
 
     /**
-     * @param id the CDM Entity id
+     * @param id the Registration entity id
      * @return
      */
     @Override
     public RegistrationDTO loadDtoById(Integer id) {
         Registration reg = repo.getRegistrationService().find(id);
+        inititializeSpecimen(reg);
         return new RegistrationDTO(reg);
     }
 
@@ -81,7 +113,7 @@ public class RegistrationWorkingSetService implements IRegistrationWorkingSetSer
     @Override
     public Collection<RegistrationDTO> listDTOs() {
 
-        List<Registration> regs = repo.getRegistrationService().list(null, PAGE_SIZE, 0, null, null);
+        List<Registration> regs = repo.getRegistrationService().list(null, PAGE_SIZE, 0, null, REGISTRATION_INIT_STRATEGY);
 
         List<RegistrationDTO> dtos = makeDTOs(regs);
         return dtos;
@@ -93,8 +125,9 @@ public class RegistrationWorkingSetService implements IRegistrationWorkingSetSer
     @Override
     public Collection<RegistrationDTO> listDTOs(User submitter, Collection<RegistrationStatus> includedStatus) {
 
-        Pager<Registration> pager = repo.getRegistrationService().page(submitter, includedStatus, PAGE_SIZE, 0, null, null);
-        return makeDTOs(pager.getRecords());
+        Pager<Registration> pager = repo.getRegistrationService().page(submitter, includedStatus, PAGE_SIZE, 0, null, REGISTRATION_INIT_STRATEGY);
+        List<Registration> registrations = pager.getRecords();
+        return makeDTOs(registrations);
     }
 
     /**
@@ -102,34 +135,78 @@ public class RegistrationWorkingSetService implements IRegistrationWorkingSetSer
      * @throws RegistrationValidationException
      */
     @Override
-    @Deprecated
     public RegistrationWorkingSet loadWorkingSetByReferenceID(Integer referenceID) throws RegistrationValidationException {
 
         Reference reference = repo.getReferenceService().find(referenceID);
-        Pager<Registration> pager = repo.getRegistrationService().page(Optional.of(reference), null, null, null, null);
+        Pager<Registration> pager = repo.getRegistrationService().page(Optional.of(reference), null, null, null, REGISTRATION_INIT_STRATEGY);
         return new RegistrationWorkingSet(makeDTOs(pager.getRecords()));
     }
 
-    @Override
-    public RegistrationWorkingSet loadWorkingSetByCitationID(Integer id) throws RegistrationValidationException {
-
-        Reference ref = repo.getReferenceService().find(id);
-        Pager<Registration> pager = repo.getRegistrationService().page(Optional.of(ref), null, null, null, null);
-        return new RegistrationWorkingSet(makeDTOs(pager.getRecords()));
-    }
-
-
     /**
      * @param regs
      * @return
      */
     private List<RegistrationDTO> makeDTOs(List<Registration> regs) {
+        initializeSpecimens(regs);
         List<RegistrationDTO> dtos = new ArrayList<>(regs.size());
         regs.forEach(reg -> {dtos.add(new RegistrationDTO(reg));});
         return dtos;
     }
 
 
+    /**
+     * @param regs
+     */
+    private void initializeSpecimens(List<Registration> regs) {
+        for(Registration reg : regs){
+            inititializeSpecimen(reg);
+        }
+
+    }
+
+
+    /**
+     * @param reg
+     */
+    protected void inititializeSpecimen(Registration reg) {
+        for(TypeDesignationBase<?> td : reg.getTypeDesignations()){
+            if(td instanceof SpecimenTypeDesignation){
+
+                DerivedUnit derivedUnit = ((SpecimenTypeDesignation) td).getTypeSpecimen();
+                @SuppressWarnings("rawtypes")
+                Set<SpecimenOrObservationBase> sobs = new HashSet<>();
+                sobs.add(derivedUnit);
+
+                while(sobs != null && !sobs.isEmpty()){
+                    @SuppressWarnings("rawtypes")
+                    Set<SpecimenOrObservationBase> nextSobs = null;
+                    for(@SuppressWarnings("rawtypes") SpecimenOrObservationBase sob : sobs){
+                        if(sob instanceof DerivedUnit) {
+                            defaultBeanInitializer.initialize(sob, Arrays.asList(new String[]{
+                                    "$",
+                                    "derivedFrom.$",
+                                    "derivedFrom.type"
+                            }));
+                            nextSobs = ((DerivedUnit)sob).getOriginals();
+                        }
+                        if(sob instanceof FieldUnit){
+                            defaultBeanInitializer.initialize(sob, Arrays.asList(new String[]{
+                                    "$",
+                                    "gatheringEvent.$",
+                                    "gatheringEvent.country.representations",
+                                    "gatheringEvent.collectingAreas.representations",
+                                    "gatheringEvent.actor"
+                            }));
+                            int i = 0;
+                        }
+                    }
+                    sobs = nextSobs;
+                }
+            }
+        }
+    }
+
+
 
 
 
diff --git a/src/main/java/eu/etaxonomy/cdm/vaadin/session/ViewScopeConversationHolder.java b/src/main/java/eu/etaxonomy/cdm/vaadin/session/ViewScopeConversationHolder.java
deleted file mode 100644 (file)
index 8c3fc9b..0000000
+++ /dev/null
@@ -1,86 +0,0 @@
-/**
-* Copyright (C) 2017 EDIT
-* European Distributed Institute of Taxonomy
-* http://www.e-taxonomy.eu
-*
-* The contents of this file are subject to the Mozilla Public License Version 1.1
-* See LICENSE.TXT at the top of this package for the full license terms.
-*/
-package eu.etaxonomy.cdm.vaadin.session;
-
-import java.io.Serializable;
-
-import javax.sql.DataSource;
-
-import org.hibernate.FlushMode;
-import org.hibernate.SessionFactory;
-import org.springframework.orm.hibernate5.support.OpenSessionInViewFilter;
-import org.springframework.transaction.PlatformTransactionManager;
-import org.springframework.transaction.TransactionDefinition;
-import org.springframework.transaction.support.DefaultTransactionDefinition;
-
-import com.vaadin.spring.annotation.SpringComponent;
-import com.vaadin.spring.annotation.ViewScope;
-
-import eu.etaxonomy.cdm.api.conversation.ConversationHolder;
-import eu.etaxonomy.vaadin.mvp.AbstractEditorPresenter;
-
-/**
- * The ViewScopeConversationHolder allows to span conversations over all request threads
- * that are involved in the creation, interaction and ending of a View.
- *
- * <p><b>NOTE</b>: Hibernate sessions created in the conversation created by this holder
- * will not fluish automatically. The flush mode is initially
- * set to {@code FlushMode.MANUAL}. It assumes to be used
- * in combination with service layer transactions that care for the flushing: The
- * active transaction manager will temporarily change the flush mode to
- * {@code FlushMode.AUTO} during a read-write transaction, with the flush
- * mode reset to {@code FlushMode.NEVER} at the end of each transaction.
- * This behavior is implemented consistently in the {@link {@link AbstractEditorPresenter} methods
- * {@link AbstractEditorPresenter#onEditorPreSaveEvent(eu.etaxonomy.vaadin.mvp.event.EditorPreSaveEvent) onEditorPreSaveEvent},
- * {@link AbstractEditorPresenter#onEditorSaveEvent(eu.etaxonomy.vaadin.mvp.event.EditorSaveEvent) onEditorSaveEvent} and
- * {@link AbstractEditorPresenter#onEditorDeleteEvent(eu.etaxonomy.vaadin.mvp.event.EditorDeleteEvent) onEditorDeleteEvent}
- * In this whole strategy this class follows the ideas of the {@link OpenSessionInViewFilter}.
- *
- * @author a.kohlbecker
- * @since Jun 30, 2017
- *
- */
-@SpringComponent
-@ViewScope
-public class ViewScopeConversationHolder extends ConversationHolder implements Serializable {
-
-
-    private static final long serialVersionUID = 1001768184000981106L;
-
-    /**
-     *
-     */
-    public ViewScopeConversationHolder() {
-        super();
-        applyDefaultSettings();
-
-    }
-
-    /**
-     * @param dataSource
-     * @param sessionFactory
-     * @param transactionManager
-     */
-    public ViewScopeConversationHolder(DataSource dataSource, SessionFactory sessionFactory,
-            PlatformTransactionManager transactionManager) {
-        super(dataSource, sessionFactory, transactionManager, false);
-        applyDefaultSettings();
-    }
-
-    private void applyDefaultSettings(){
-
-        setDefaultFlushMode(FlushMode.MANUAL);
-        TransactionDefinition definition = new DefaultTransactionDefinition(TransactionDefinition.PROPAGATION_NESTED);
-        setDefinition(definition );
-    }
-
-
-
-
-}
index 898a03dfd6eda0462fafc8dddbd29f2ce7e314e7..215f3f3b17ca88f14e8649bdcbfd72ff11c55022 100644 (file)
@@ -81,8 +81,6 @@ public class LoginPresenter extends AbstractPresenter<LoginView> {
             }
         } catch (AuthenticationException e){
             getView().showErrorMessage("Login failed! Please check your username and password.");
-        } finally {
-            unbindConversation();
         }
         return false;
     }
index 3624b62909327405ba38d630e7d9fccb4bedd333..1937f5e110bd8707936e63caffd44d7c0d1b3100 100644 (file)
@@ -8,13 +8,14 @@
 */
 package eu.etaxonomy.cdm.vaadin.view.name;
 
-import java.util.Arrays;
 import java.util.EnumSet;
 import java.util.HashSet;
 import java.util.Iterator;
 import java.util.Set;
 
 import org.hibernate.Session;
+import org.springframework.beans.factory.BeanFactory;
+import org.springframework.beans.factory.annotation.Autowired;
 import org.vaadin.viritin.fields.AbstractElementCollection;
 
 import eu.etaxonomy.cdm.api.service.IRegistrationService;
@@ -35,6 +36,8 @@ import eu.etaxonomy.cdm.model.reference.Reference;
 import eu.etaxonomy.cdm.persistence.hibernate.permission.CRUD;
 import eu.etaxonomy.cdm.service.CdmFilterablePagingProvider;
 import eu.etaxonomy.cdm.service.CdmStore;
+import eu.etaxonomy.cdm.service.IRegistrationWorkingSetService;
+import eu.etaxonomy.cdm.service.RegistrationWorkingSetService;
 import eu.etaxonomy.cdm.vaadin.component.CdmBeanItemContainerFactory;
 import eu.etaxonomy.cdm.vaadin.event.ToOneRelatedEntityButtonUpdater;
 import eu.etaxonomy.cdm.vaadin.model.TypedEntityReference;
@@ -47,6 +50,7 @@ import eu.etaxonomy.cdm.vaadin.util.CdmTitleCacheCaptionGenerator;
 import eu.etaxonomy.cdm.vaadin.util.converter.TypeDesignationSetManager.TypeDesignationWorkingSet;
 import eu.etaxonomy.cdm.vaadin.view.registration.RegistrationDTO;
 import eu.etaxonomy.vaadin.mvp.AbstractEditorPresenter;
+import eu.etaxonomy.vaadin.ui.view.PopupEditorFactory;
 /**
  * SpecimenTypeDesignationWorkingsetPopupEditorView implementation must override the showInEditor() method,
  * see {@link #prepareAsFieldGroupDataSource()} for details.
@@ -66,6 +70,13 @@ public class SpecimenTypeDesignationWorkingsetEditorPresenter
 
     private TaxonName typifiedName;
 
+    /**
+     * This object for this field will either be injected by the {@link PopupEditorFactory} or by a Spring
+     * {@link BeanFactory}
+     */
+    @Autowired
+    private IRegistrationWorkingSetService registrationWorkingSetService;
+
     /**
      * if not null, this CRUD set is to be used to create a CdmAuthoritiy for the base entitiy which will be
      * granted to the current use as long this grant is not assigned yet.
@@ -98,10 +109,9 @@ public class SpecimenTypeDesignationWorkingsetEditorPresenter
         if(identifier != null){
 
             TypeDesignationWorkingsetEditorIdSet idset = (TypeDesignationWorkingsetEditorIdSet)identifier;
-            Registration reg = getRepo().getRegistrationService().loadByIds(Arrays.asList(idset.registrationId), null).get(0);
 
             if(idset.workingsetId != null){
-                RegistrationDTO regDTO = new RegistrationDTO(reg);
+                RegistrationDTO regDTO = registrationWorkingSetService.loadDtoById(idset.registrationId);
                 // find the working set
                 TypeDesignationWorkingSet typeDesignationWorkingSet = regDTO.getTypeDesignationWorkingSet(idset.workingsetId);
                 workingSetDto = regDTO.getSpecimenTypeDesignationWorkingSetDTO(typeDesignationWorkingSet.getBaseEntityReference());
@@ -109,6 +119,9 @@ public class SpecimenTypeDesignationWorkingsetEditorPresenter
             } else {
                 // create a new workingset, for a new fieldunit which is the base for the workingset
                 FieldUnit newfieldUnit = FieldUnit.NewInstance();
+                Registration reg = getRepo().getRegistrationService().load(idset.registrationId,
+                        RegistrationWorkingSetService.REGISTRATION_INIT_STRATEGY);
+                //TODO checkif passing reg as owner parameter is needed at all
                 workingSetDto = new SpecimenTypeDesignationWorkingSetDTO(reg, newfieldUnit, null);
                 citation = getRepo().getReferenceService().find(idset.publicationId);
                 typifiedName = getRepo().getNameService().find(idset.typifiedNameId);
@@ -133,9 +146,9 @@ public class SpecimenTypeDesignationWorkingsetEditorPresenter
 
         getView().getTypeDesignationsCollectionField().setEditorInstantiator(new AbstractElementCollection.Instantiator<SpecimenTypeDesignationDTORow>() {
 
-            CdmFilterablePagingProvider<Collection> collectionPagingProvider = new CdmFilterablePagingProvider<Collection>(getRepo().getCollectionService(), SpecimenTypeDesignationWorkingsetEditorPresenter.this);
+            CdmFilterablePagingProvider<Collection> collectionPagingProvider = new CdmFilterablePagingProvider<Collection>(getRepo().getCollectionService());
 
-            CdmFilterablePagingProvider<Reference> referencePagingProvider = new CdmFilterablePagingProvider<Reference>(getRepo().getReferenceService(), SpecimenTypeDesignationWorkingsetEditorPresenter.this);
+            CdmFilterablePagingProvider<Reference> referencePagingProvider = new CdmFilterablePagingProvider<Reference>(getRepo().getReferenceService());
 
             @Override
             public SpecimenTypeDesignationDTORow create() {
index c67b477fa190a9240e25cc20b7623a0e58584058..775a838ca6f0f3ede49becbd8812b1dd1956144f 100644 (file)
@@ -8,6 +8,7 @@
 */
 package eu.etaxonomy.cdm.vaadin.view.name;
 
+import java.util.Arrays;
 import java.util.List;
 import java.util.Set;
 
@@ -50,13 +51,13 @@ public class TaxonNameEditorPresenter extends AbstractCdmEditorPresenter<TaxonNa
         getView().getRankSelect().setItemCaptionPropertyId("label");
 
         getView().getNomReferenceCombobox().getSelect().setCaptionGenerator(new CdmTitleCacheCaptionGenerator<Reference>());
-        CdmFilterablePagingProvider<Reference> referencePagingProvider = new CdmFilterablePagingProvider<Reference>(getRepo().getReferenceService(), TaxonNameEditorPresenter.this);
+        CdmFilterablePagingProvider<Reference> referencePagingProvider = new CdmFilterablePagingProvider<Reference>(getRepo().getReferenceService());
         getView().getNomReferenceCombobox().loadFrom(referencePagingProvider, referencePagingProvider, referencePagingProvider.getPageSize());
         getView().getNomReferenceCombobox().getSelect().addValueChangeListener(new ToOneRelatedEntityButtonUpdater<Reference>(getView().getNomReferenceCombobox()));
 
 
         getView().getBasionymCombobox().setCaptionGenerator(new CdmTitleCacheCaptionGenerator<TaxonName>());
-        CdmFilterablePagingProvider<TaxonName> namePagingProvider = new CdmFilterablePagingProvider<TaxonName>(getRepo().getNameService(), TaxonNameEditorPresenter.this);
+        CdmFilterablePagingProvider<TaxonName> namePagingProvider = new CdmFilterablePagingProvider<TaxonName>(getRepo().getNameService());
         getView().getBasionymCombobox().setPagingProviders(namePagingProvider, namePagingProvider, namePagingProvider.getPageSize());
 
     }
@@ -67,9 +68,31 @@ public class TaxonNameEditorPresenter extends AbstractCdmEditorPresenter<TaxonNa
     @Override
     protected TaxonName loadCdmEntityById(Integer identifier) {
 
+        List<String> initStrategy = Arrays.asList(new String []{
+
+                "$",
+                "rank.representations",
+
+                "nomenclaturalReference.authorship",
+                "nomenclaturalReference.inReference",
+
+                "status.type.representations",
+
+                "combinationAuthorship",
+                "exCombinationAuthorship",
+                "basionymAuthorship",
+                "exBasionymAuthorship",
+
+                "basionyms.rank.representations",
+                "basionyms.nomenclaturalReference.authorship",
+                "basionyms.nomenclaturalReference.inReference",
+
+                }
+        );
+
         TaxonName bean;
         if(identifier != null){
-            bean = getRepo().getNameService().find(identifier);
+            bean = getRepo().getNameService().load(identifier, initStrategy);
         } else {
             bean = TaxonNameFactory.NewBotanicalInstance(Rank.SPECIES());
         }
index 7fae0174c9456fc4508a12c595842bd39b6b1b28..2adc5c56beb3eadcf8beea3ed37be3d550d30ba5 100644 (file)
@@ -52,7 +52,6 @@ public class ListPresenter extends AbstractPresenter<ListView> {
      * @return the workingSetService
      */
     public IRegistrationWorkingSetService getWorkingSetService() {
-        ensureBoundConversation();
         return workingSetService;
     }
 
index be872f6a8ab31f7efa6cc8237145896c3e0c8daa..7273ac800faa3328de0dd325a96ae44d1982d27f 100644 (file)
@@ -15,6 +15,7 @@ import java.util.List;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.context.event.EventListener;
 import org.springframework.security.core.Authentication;
+import org.springframework.transaction.TransactionStatus;
 
 import com.vaadin.spring.annotation.SpringComponent;
 import com.vaadin.spring.annotation.ViewScope;
@@ -76,7 +77,6 @@ public class RegistrationWorkingsetPresenter extends AbstractPresenter<Registrat
      * @return the workingSetService
      */
     public IRegistrationWorkingSetService getWorkingSetService() {
-        ensureBoundConversation();
         return workingSetService;
     }
 
@@ -120,6 +120,7 @@ public class RegistrationWorkingsetPresenter extends AbstractPresenter<Registrat
     protected Registration createNewRegistrationForName(Integer taxonNameId) {
         // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
         // move into RegistrationWorkflowStateMachine
+        TransactionStatus txStatus = getRepo().startTransaction();
         long identifier = System.currentTimeMillis();
         Registration reg = Registration.NewInstance(
                 "http://phycobank.org/" + identifier,
@@ -130,17 +131,21 @@ public class RegistrationWorkingsetPresenter extends AbstractPresenter<Registrat
         reg.setSubmitter((User)authentication.getPrincipal());
         EntityChangeEvent event = getRegistrationStore().saveBean(reg);
         UserHelper.fromSession().createAuthorityForCurrentUser(Registration.class, event.getEntityId(), Operation.UPDATE, RegistrationStatus.PREPARATION.name());
+        getRepo().commitTransaction(txStatus);
         // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
         return getRepo().getRegistrationService().find(event.getEntityId());
     }
 
 
     /**
+     * @param doReload TODO
      *
      */
-    protected void refreshView() {
-        getConversationHolder().getSession().clear();
-        presentWorkingSet(workingset.getCitationId());
+    protected void refreshView(boolean doReload) {
+        if(doReload){
+            loadWorkingSet(workingset.getCitationId());
+        }
+        getView().setWorkingset(workingset);
     }
 
 
@@ -152,21 +157,21 @@ public class RegistrationWorkingsetPresenter extends AbstractPresenter<Registrat
 
         super.handleViewEntered();
 
-        presentWorkingSet(getView().getCitationID());
+        loadWorkingSet(getView().getCitationID());
+        getView().setWorkingset(workingset);
 
         CdmFilterablePagingProvider<TaxonName> pagingProvider = new CdmFilterablePagingProvider<TaxonName>(
-                getRepo().getNameService(), this);
+                getRepo().getNameService());
         CdmTitleCacheCaptionGenerator<TaxonName> titleCacheGenrator = new CdmTitleCacheCaptionGenerator<TaxonName>();
         getView().getAddExistingNameCombobox().setCaptionGenerator(titleCacheGenrator);
         getView().getAddExistingNameCombobox().loadFrom(pagingProvider, pagingProvider, pagingProvider.getPageSize());
     }
 
+
     /**
-     * Loads the WorkingSet from the data base and passes it to the view.
-     *
-     * @param registrationID
+     * @param referenceID
      */
-    private void presentWorkingSet(Integer referenceID) {
+    protected void loadWorkingSet(Integer referenceID) {
         try {
             workingset = getWorkingSetService().loadWorkingSetByReferenceID(referenceID);
         } catch (RegistrationValidationException error) {
@@ -183,8 +188,6 @@ public class RegistrationWorkingsetPresenter extends AbstractPresenter<Registrat
             Reference citation = getRepo().getReferenceService().find(referenceID);
             workingset = new RegistrationWorkingSet(citation);
         }
-        // getView().setHeaderText("Registrations for " + workingset.getCitation());
-        getView().setWorkingset(workingset);
     }
 
     @EventListener(condition = "#event.type == T(eu.etaxonomy.cdm.vaadin.event.AbstractEditorAction.Action).ADD && #event.sourceComponent == null")
@@ -247,18 +250,22 @@ public class RegistrationWorkingsetPresenter extends AbstractPresenter<Registrat
     @EventListener
     public void onDoneWithTaxonnameEditor(DoneWithPopupEvent event) throws RegistrationValidationException{
         if(event.getPopup() instanceof TaxonNamePopupEditor){
+            TransactionStatus txStatus = getRepo().startTransaction();
             if(event.getReason().equals(Reason.SAVE)){
                 if(newTaxonNameForRegistration != null){
                     int taxonNameId = newTaxonNameForRegistration.getId();
                     getRepo().getSession().refresh(newTaxonNameForRegistration);
                     Registration reg = createNewRegistrationForName(taxonNameId);
+                    // reload workingset into current session
+                    loadWorkingSet(workingset.getCitationId());
                     workingset.add(reg);
                 }
-                refreshView();
+                refreshView(false);
             } else if(event.getReason().equals(Reason.CANCEL)){
                 // clean up
                 getTaxonNameStore().deleteBean(newTaxonNameForRegistration);
             }
+            getRepo().commitTransaction(txStatus);
             newTaxonNameForRegistration = null;
         }
     }
@@ -354,7 +361,7 @@ public class RegistrationWorkingsetPresenter extends AbstractPresenter<Registrat
     public void onDoneWithTypeDesignationEditor(DoneWithPopupEvent event) throws RegistrationValidationException{
         if(event.getPopup() instanceof SpecimenTypeDesignationWorkingsetPopupEditor){
             if(event.getReason().equals(Reason.SAVE)){
-                refreshView();
+                refreshView(true);
             } else if(event.getReason().equals(Reason.CANCEL)){
                 // clean up
                 if(newRegistrationDTOWithExistingName != null){
@@ -395,19 +402,19 @@ public class RegistrationWorkingsetPresenter extends AbstractPresenter<Registrat
         }
         if(Reference.class.isAssignableFrom(event.getEntityType())){
             if(workingset.getCitationId().equals(event.getEntityId())){
-                refreshView();
+                refreshView(true);
             }
         } else
         if(Registration.class.isAssignableFrom(event.getEntityType())){
             if(workingset.getRegistrations().stream().anyMatch(reg -> reg.getId() == event.getEntityId())){
-                refreshView();
+                refreshView(true);
             }
         } else
         if(TaxonName.class.isAssignableFrom(event.getEntityType())){
             if(workingset.getRegistrationDTOs().stream().anyMatch(reg ->
                 reg.getTypifiedName() != null
                 && reg.getTypifiedName().getId() == event.getEntityId())){
-                    refreshView();
+                    refreshView(true);
             }
         } else
         if(TypeDesignationBase.class.isAssignableFrom(event.getEntityType())){
@@ -417,7 +424,7 @@ public class RegistrationWorkingsetPresenter extends AbstractPresenter<Registrat
                             )
                         )
                     ){
-                refreshView();
+                refreshView(true);
             }
         }
 
index de7dbc9d4f71d8f6d0acf5f9a8880fcf1c5fcb81..774e344fc6ddcf5cb8e9cf82ddf029face181dfe 100644 (file)
@@ -58,7 +58,7 @@ public class StartRegistrationPresenter extends AbstractEditorPresenter<Registra
         super.onPresenterReady();
 
         CdmFilterablePagingProvider<Reference> pagingProvider = new CdmFilterablePagingProvider<Reference>(
-                getRepo().getReferenceService(), this);
+                getRepo().getReferenceService());
         CdmTitleCacheCaptionGenerator<Reference> titleCacheGenrator = new CdmTitleCacheCaptionGenerator<Reference>();
         getView().getReferenceCombobox().setCaptionGenerator(titleCacheGenrator);
         getView().getReferenceCombobox().loadFrom(pagingProvider, pagingProvider, pagingProvider.getPageSize());
index 8c60310d05471aa47196ff5db35b9c777b0f9656..c08f371efe1c0c125db46d140a874865acd849b3 100644 (file)
@@ -12,10 +12,17 @@ import org.hibernate.FlushMode;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.context.ApplicationEventPublisher;
 import org.springframework.context.event.EventListener;
-import org.springframework.transaction.TransactionDefinition;
+
+import com.vaadin.server.ServletPortletHelper;
+import com.vaadin.server.VaadinRequest;
+import com.vaadin.server.VaadinService;
+import com.vaadin.server.VaadinSession;
+import com.vaadin.ui.UI;
 
 import eu.etaxonomy.cdm.vaadin.event.AbstractEditorAction;
-import eu.etaxonomy.cdm.vaadin.session.ViewScopeConversationHolder;
+import eu.etaxonomy.cdm.vaadin.server.CdmSpringVaadinServletService;
+import eu.etaxonomy.cdm.vaadin.server.RequestEndListener;
+import eu.etaxonomy.cdm.vaadin.server.RequestStartListener;
 import eu.etaxonomy.vaadin.mvp.event.EditorDeleteEvent;
 import eu.etaxonomy.vaadin.mvp.event.EditorPreSaveEvent;
 import eu.etaxonomy.vaadin.mvp.event.EditorSaveEvent;
@@ -27,7 +34,8 @@ import eu.etaxonomy.vaadin.mvp.event.EditorViewEvent;
  * @since Apr 5, 2017
  *
  */
-public abstract class AbstractEditorPresenter<DTO extends Object, V extends ApplicationView<?>> extends AbstractPresenter<V> {
+public abstract class AbstractEditorPresenter<DTO extends Object, V extends ApplicationView<?>> extends AbstractPresenter<V>
+implements RequestEndListener, RequestStartListener {
 
 
     private static final long serialVersionUID = -6677074110764145236L;
@@ -61,14 +69,14 @@ public abstract class AbstractEditorPresenter<DTO extends Object, V extends Appl
         return bean;
     }
 
-    @Override
-    protected TransactionDefinition getTransactionDefinition(){
-        super.getTransactionDefinition();
-        if(definition.isReadOnly()){
-            definition.setReadOnly(false);
-        }
-        return definition;
-    }
+//    @Override
+//    protected TransactionDefinition getTransactionDefinition(){
+//        super.getTransactionDefinition();
+//        if(definition.isReadOnly()){
+//            definition.setReadOnly(false);
+//        }
+//        return definition;
+//    }
 
     /**
      * Regarding changing the Flush mode see see also {@link ViewScopeConversationHolder}
@@ -80,9 +88,7 @@ public abstract class AbstractEditorPresenter<DTO extends Object, V extends Appl
         if(!isFromOwnView(preSaveEvent)){
             return;
         }
-        ensureBoundConversation();
-        previousPreSaveEvenFlushMode = getConversationHolder().getSession().getFlushMode();
-        getConversationHolder().getSession().setFlushMode(FlushMode.AUTO);
+        getSession().setFlushMode(FlushMode.AUTO);
 
     }
 
@@ -98,7 +104,7 @@ public abstract class AbstractEditorPresenter<DTO extends Object, V extends Appl
         }
         DTO bean = saveEvent.getBean();
         saveBean(bean);
-        getConversationHolder().getSession().setFlushMode(previousPreSaveEvenFlushMode);
+        getSession().setFlushMode(previousPreSaveEvenFlushMode);
         previousPreSaveEvenFlushMode = null;
     }
 
@@ -112,13 +118,10 @@ public abstract class AbstractEditorPresenter<DTO extends Object, V extends Appl
        if(!isFromOwnView(deleteEvent)){
            return;
        }
-       if(!conversationBound){
-           bindConversation();
-       }
        FlushMode previousFlushMode = getSession().getFlushMode();
-       getConversationHolder().getSession().setFlushMode(FlushMode.AUTO);
+       getSession().setFlushMode(FlushMode.AUTO);
        deleteBean(deleteEvent.getBean());
-       getConversationHolder().getSession().setFlushMode(previousFlushMode);
+       getSession().setFlushMode(previousFlushMode);
    }
 
     /**
@@ -137,6 +140,115 @@ public abstract class AbstractEditorPresenter<DTO extends Object, V extends Appl
         return action.getSourceView() != null && getView().equals(action.getSourceView());
     }
 
+    @Override
+    protected void init(V view) {
+        super.init(view);
+        registerListeners();
+    }
+
+    @Override
+    public void onViewExit() {
+        super.onViewExit();
+        unregisterListeners();
+    }
+
+
+    // -------------------------------------------------------------------------
+
+    protected void registerListeners() {
+     // register as request start and end listener
+        VaadinService service = UI.getCurrent().getSession().getService();
+        if(service instanceof CdmSpringVaadinServletService){
+            logger.trace(String.format("~~~~~ %s register as request listener", _toString()));
+            ((CdmSpringVaadinServletService)service).addRequestEndListener(this);
+            if(logger.isTraceEnabled()){
+                ((CdmSpringVaadinServletService)service).addRequestStartListener(this);
+            }
+        } else {
+            throw new RuntimeException("Using the CdmSpringVaadinServletService is required for proper per view conversation handling");
+        }
+    }
+
+    /**
+    *
+    */
+   protected void unregisterListeners() {
+       VaadinService service = UI.getCurrent().getSession().getService();
+       if(service instanceof CdmSpringVaadinServletService){
+           logger.trace(String.format("~~~~~ %s un-register as request listener", _toString()));
+           ((CdmSpringVaadinServletService)service).removeRequestEndListener(this);
+           if(logger.isTraceEnabled()){
+               ((CdmSpringVaadinServletService)service).removeRequestStartListener(this);
+           }
+       } else {
+           throw new RuntimeException("Using the CdmSpringVaadinServletService is required for proper per view conversation handling");
+       }
+   }
+
+    /**
+     * <b>ONLY USED FOR LOGGING</b> when Level==TRACE
+     * {@inheritDoc}
+     */
+    @Override
+    public void onRequestStart(VaadinRequest request){
+
+        if(requestNeedsSession(request) ){
+
+            if(getView() instanceof AbstractPopupEditor){
+                Object bean = ((AbstractPopupEditor)getView()).getBean();
+                getSession().merge(bean);
+            }
+
+        } else {
+            // ignore hartbeat, fileupload, push etc
+            logger.trace("ignoring request:" + request.getPathInfo());
+        }
+    }
+
+    /**
+     * Returns <code>true</code> for:
+     * <ul>
+     *   <li>..</li>
+     * <ul>
+     *
+     * Return <code>false</code> for:
+     *
+     * <ul>
+     *   <li>UILD request in a existing view, like clicking on a button</li>
+     * <ul>
+     *
+     * @return
+    protected boolean isActiveView(){
+        return UI.getCurrent() != null && getView() != null && getView() == navigationManager.getCurrentView();
+    }
+     */
+
+    @Override
+    public void onRequestEnd(VaadinRequest request, VaadinSession session){
+
+        if(requestNeedsSession(request) ){
+            logger.trace("onRequestEnd() " + request.getPathInfo() + " " + _toString());
+
+        } else {
+            // ignore hartbeat, fileupload, push etc
+            logger.trace("ignoring request:" + request.getPathInfo());
+        }
+
+    }
+
+    /**
+     * @param request
+     * @return
+     */
+    protected boolean requestNeedsSession(VaadinRequest request) {
+        return !(
+                ServletPortletHelper.isAppRequest(request) // includes published file request
+             || ServletPortletHelper.isFileUploadRequest(request)
+             || ServletPortletHelper.isHeartbeatRequest(request)
+             || ServletPortletHelper.isPushRequest(request)
+             );
+    }
+
     protected abstract void saveBean(DTO bean);
 
     /**
index 9d28761e68f6ba7995812ac948471af0f44a5749..7cd91be164d81c01b4298b25010b652125bc2595 100644 (file)
@@ -4,26 +4,14 @@ import java.io.Serializable;
 
 import org.apache.log4j.Logger;
 import org.hibernate.Session;
+import org.hibernate.engine.internal.StatefulPersistenceContext;
 import org.hibernate.engine.spi.SessionImplementor;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Qualifier;
 import org.springframework.security.core.context.SecurityContext;
 import org.springframework.security.core.context.SecurityContextHolder;
-import org.springframework.transaction.IllegalTransactionStateException;
-import org.springframework.transaction.TransactionDefinition;
-import org.springframework.transaction.support.DefaultTransactionDefinition;
-
-import com.vaadin.server.ServletPortletHelper;
-import com.vaadin.server.VaadinRequest;
-import com.vaadin.server.VaadinService;
-import com.vaadin.server.VaadinSession;
-import com.vaadin.ui.UI;
 
 import eu.etaxonomy.cdm.api.application.CdmRepository;
-import eu.etaxonomy.cdm.vaadin.server.CdmSpringVaadinServletService;
-import eu.etaxonomy.cdm.vaadin.server.RequestStartListener;
-import eu.etaxonomy.cdm.vaadin.session.IntraViewConversationDirector;
-import eu.etaxonomy.cdm.vaadin.session.ViewScopeConversationHolder;
 import eu.etaxonomy.vaadin.ui.navigation.NavigationManager;
 import eu.etaxonomy.vaadin.ui.navigation.NavigationManagerBean;
 
@@ -37,7 +25,7 @@ import eu.etaxonomy.vaadin.ui.navigation.NavigationManagerBean;
  * @param <V>
  *            type of the view this presenter governs
  */
-public abstract class AbstractPresenter<V extends ApplicationView> implements Serializable, IntraViewConversationDirector, RequestStartListener {
+public abstract class AbstractPresenter<V extends ApplicationView> implements Serializable {
 
 
     private static final long serialVersionUID = 5260910510283481832L;
@@ -61,39 +49,22 @@ public abstract class AbstractPresenter<V extends ApplicationView> implements Se
        @Autowired
        private NavigationManager navigationManager;
 
-       private ViewScopeConversationHolder conversationHolder;
-
-       protected DefaultTransactionDefinition definition = null;
-
-    protected boolean conversationBound;
-
-       @Autowired
-       private void setConversationHolder(ViewScopeConversationHolder conversationHolder){
-           this.conversationHolder = conversationHolder;
-           this.conversationHolder.setDefinition(getTransactionDefinition());
-       }
-
-       protected TransactionDefinition getTransactionDefinition(){
-           if(definition == null){
-           definition = new DefaultTransactionDefinition();
-           definition.setReadOnly(true);
-           }
-           return definition;
-       }
 
+       //      protected DefaultTransactionDefinition definition = null;
 
+    // protected TransactionDefinition getTransactionDefinition(){
+    //     if(definition == null){
+    //             definition = new DefaultTransactionDefinition();
+    //             definition.setReadOnly(true);
+    //     }
+    //     return definition;
+    // }
 
 
        /**
         * @return the repo
         */
        public CdmRepository getRepo() {
-           if(!conversationBound){
-               // this is the central access point for getting access to the service layer.
-               // In case the presenter needs access to the repository, it most probably will use
-               // a service, so it is a good idea to bind the conversation at this point.
-               bindConversation();
-           }
            return repo;
        }
 
@@ -110,7 +81,7 @@ public abstract class AbstractPresenter<V extends ApplicationView> implements Se
      * @return
      */
     protected Session getSession() {
-        Session session = conversationHolder.getSession();
+        Session session = getRepo().getSession();
         logger.trace(this._toString() + ".getSession() - session:" + session.hashCode() +", persistenceContext: " + ((SessionImplementor)session).getPersistenceContext() + " - " + session.toString());
         return session;
     }
@@ -125,85 +96,12 @@ public abstract class AbstractPresenter<V extends ApplicationView> implements Se
         *
         * @param view
         */
-       protected final void init(V view) {
+       protected void init(V view) {
            logger.trace(String.format("Presenter %s init()", _toString()));
                this.view = view;
-               // bind the conversation to the thread of the first request send to the according View
-               // all other requests are handled in onRequestStart()
-               // logger.trace(String.format(">>>>> %s init() bind()", _toString()));
-           ensureBoundConversation();
-           // register as request start and end listener
-           VaadinService service = UI.getCurrent().getSession().getService();
-           if(service instanceof CdmSpringVaadinServletService){
-               logger.trace(String.format("~~~~~ %s register as request listener", _toString()));
-               ((CdmSpringVaadinServletService)service).addRequestEndListener(this);
-               if(logger.isTraceEnabled()){
-                   ((CdmSpringVaadinServletService)service).addRequestStartListener(this);
-               }
-           } else {
-               throw new RuntimeException("Using the CdmSpringVaadinServletService is required for proper per view conversation handling");
-           }
                onPresenterReady();
        }
 
-       /**
-        * Returns <code>true</code> for:
-        * <ul>
-        *   <li>..</li>
-        * <ul>
-        *
-        * Return <code>false</code> for:
-        *
-        * <ul>
-     *   <li>UILD request in a existing view, like clicking on a button</li>
-     * <ul>
-     *
-        * @return
-       protected boolean isActiveView(){
-        return UI.getCurrent() != null && getView() != null && getView() == navigationManager.getCurrentView();
-    }
-        */
-
-    /**
-     *
-     */
-       protected void bindConversation() {
-        logger.trace(String.format(">>>>> %s bind()", _toString()));
-        conversationHolder.bind();
-        conversationBound = true;
-    }
-
-    @Override
-    public void ensureBoundConversation() {
-        if(!conversationBound){
-            bindConversation();
-        }
-        if(!conversationHolder.isTransactionActive()){
-            logger.trace(String.format(">>   %s starting transaction ", _toString()));
-            conversationHolder.startTransaction();
-        }
-    }
-
-    /**
-     *
-     */
-    protected void unbindConversation() {
-        logger.trace(String.format("<<<<< %s unbind()", _toString()));
-        conversationHolder.unbind();
-        // FIXME conversationHolder.isTransactionActive() always returns true
-        // see https://dev.e-taxonomy.eu/redmine/issues/6780
-        if(false && conversationHolder.isTransactionActive()){
-            logger.trace(String.format("<<    %s comitting transaction ", _toString()));
-            try{
-                conversationHolder.commit(false);
-            } catch (IllegalTransactionStateException | IllegalStateException e){
-                // log this exception, but stop from propagating
-                // FIXME remove this catch once https://dev.e-taxonomy.eu/redmine/issues/6780 is fixed
-                logger.error(e.getMessage());
-            }
-        }
-        conversationBound = false;
-    }
 
     /**
         * Extending classes should overwrite this method in order to perform logic
@@ -217,50 +115,10 @@ public abstract class AbstractPresenter<V extends ApplicationView> implements Se
        }
 
     /**
-     * <b>ONLY USED FOR LOGGING</b> when Level==TRACE
-     * {@inheritDoc}
-     */
-    @Override
-    public void onRequestStart(VaadinRequest request){
-
-        if( ! requestNeedsConversation(request) ){
-            // ignore hartbeat, fileupload, push etc
-            logger.trace("ignoring request:" + request.getPathInfo());
-            return;
-        }
-        logger.trace("onRequestStart() " + request.getPathInfo() + " " + _toString());
-    }
-
-    /**
-     * @param request
      * @return
      */
-    protected boolean requestNeedsConversation(VaadinRequest request) {
-        return !(
-                ServletPortletHelper.isAppRequest(request) // includes published file request
-             || ServletPortletHelper.isFileUploadRequest(request)
-             || ServletPortletHelper.isHeartbeatRequest(request)
-             || ServletPortletHelper.isPushRequest(request)
-             );
-    }
-
-    @Override
-    public void onRequestEnd(VaadinRequest request, VaadinSession session){
-
-        if( ! requestNeedsConversation(request) ){
-            // ignore hartbeat, fileupload, push etc
-            logger.trace("ignoring request:" + request.getPathInfo());
-            return;
-        }
-
-        // always unbind at the end of a request to clean up the threadLocal variables in the
-        // TransactionManager. This is crucial since applications containers manage threads in a pool
-        // and the recycled threads may still have a reference to a SessionHolder from the processing
-        // of a former request
-        logger.trace("onRequestEnd() " + request.getPathInfo() + " " + _toString());
-        if(conversationBound){
-            unbindConversation();
-        }
+    private StatefulPersistenceContext getPersitenceContext() {
+        return (StatefulPersistenceContext)((SessionImplementor)getSession()).getPersistenceContext();
     }
 
     public final void onViewEnter() {
@@ -268,27 +126,9 @@ public abstract class AbstractPresenter<V extends ApplicationView> implements Se
            handleViewEntered();
        }
 
-       public final void onViewExit() {
+       public void onViewExit() {
            logger.trace(String.format("%s onViewExit()", _toString()));
            handleViewExit();
-           // un-register as request start and end listener
-           if(conversationBound){
-           logger.trace(String.format("<<<<< %s onViewExit() unbind()", _toString()));
-            conversationHolder.unbind();
-            conversationBound = false;
-           }
-           logger.trace(String.format("<<<<< %s onViewExit() close()", _toString()));
-           conversationHolder.close();
-        VaadinService service = UI.getCurrent().getSession().getService();
-        if(service instanceof CdmSpringVaadinServletService){
-            logger.trace(String.format("~~~~~ %s un-register as request listener", _toString()));
-            ((CdmSpringVaadinServletService)service).removeRequestEndListener(this);
-            if(logger.isTraceEnabled()){
-                ((CdmSpringVaadinServletService)service).removeRequestStartListener(this);
-            }
-        } else {
-            throw new RuntimeException("Using the CdmSpringVaadinServletService is required for proper per view conversation handling");
-        }
        }
 
        /**
@@ -317,10 +157,6 @@ public abstract class AbstractPresenter<V extends ApplicationView> implements Se
         return navigationManager;
     }
 
-    protected ViewScopeConversationHolder getConversationHolder(){
-        return conversationHolder;
-    }
-
     /**
      * @param repo the repo to set
      */
@@ -335,6 +171,4 @@ public abstract class AbstractPresenter<V extends ApplicationView> implements Se
         this.navigationManager = navigationManager;
     }
 
-
-
 }
index 2d6031593855165d595f79a6997000b06605dae2..efef6eeac4570569392c86de357c12cdce1ed941 100644 (file)
@@ -27,7 +27,8 @@ import com.vaadin.spring.annotation.SpringComponent;
 import com.vaadin.spring.annotation.UIScope;
 
 import eu.etaxonomy.cdm.api.application.CdmRepository;
-import eu.etaxonomy.cdm.vaadin.session.ViewScopeConversationHolder;
+import eu.etaxonomy.cdm.service.IRegistrationWorkingSetService;
+import eu.etaxonomy.cdm.vaadin.view.name.SpecimenTypeDesignationWorkingsetEditorPresenter;
 import eu.etaxonomy.vaadin.mvp.AbstractEditorPresenter;
 import eu.etaxonomy.vaadin.mvp.AbstractPopupEditor;
 import eu.etaxonomy.vaadin.mvp.AbstractPresenter;
@@ -60,22 +61,23 @@ public class PopupEditorFactory {
     @Autowired
     private PlatformTransactionManager transactionManager;
 
+    @Autowired
+    private IRegistrationWorkingSetService registrationWorkingSetService;
+
     @Autowired
     @Lazy
     private NavigationManager navigationManager;
 
-
     private Field presenterRepoField;
     private Field presenterNavigationManagerField;
     private Field presenterEventBusField;
 
     private Field viewEventBusField;
+    private Field registrationWorkingSetServiceField;
     private Method viewInjectPresenterMethod;
 
     private Method viewInitMethod;
 
-    private Method conversationHolderMethod;
-
     public PopupEditorFactory(){
         initFieldsAccess();
     }
@@ -96,9 +98,6 @@ public class PopupEditorFactory {
             presenterEventBusField = AbstractEditorPresenter.class.getDeclaredField("eventBus");
             presenterEventBusField.setAccessible(true);
 
-            conversationHolderMethod = AbstractPresenter.class.getDeclaredMethod("setConversationHolder", ViewScopeConversationHolder.class);
-            conversationHolderMethod.setAccessible(true);
-
             viewEventBusField = AbstractView.class.getDeclaredField("eventBus");
             viewEventBusField.setAccessible(true);
 
@@ -108,6 +107,9 @@ public class PopupEditorFactory {
             viewInitMethod = AbstractView.class.getDeclaredMethod("init");
             viewInitMethod.setAccessible(true);
 
+            registrationWorkingSetServiceField = SpecimenTypeDesignationWorkingsetEditorPresenter.class.getDeclaredField("registrationWorkingSetService");
+            registrationWorkingSetServiceField.setAccessible(true);
+
         } catch (NoSuchFieldException | SecurityException | NoSuchMethodException  e) {
             throw new RuntimeException("Severe error during initialization. Please check the classes AbstractPresenter, AbstractEditorPresenter, AbstractView for modificactions.", e);
         }
@@ -155,11 +157,13 @@ public class PopupEditorFactory {
             Class<? extends AbstractPresenter<?>> presenterClass, P presenter) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException {
         presenterRepoField.set(presenter, repo);
         presenterNavigationManagerField.set(presenter, navigationManager);
-        conversationHolderMethod.invoke(presenter, new ViewScopeConversationHolder(dataSource, sessionFactory, transactionManager));
 
         if(AbstractEditorPresenter.class.isAssignableFrom(presenterClass)){
             presenterEventBusField.set(presenter, eventBus);
         }
+        if(SpecimenTypeDesignationWorkingsetEditorPresenter.class.equals(presenterClass)){
+            registrationWorkingSetServiceField.set(presenter, registrationWorkingSetService);
+        }
     }
 
     /**