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
private List<OrderHint> orderHints = OrderHint.ORDER_BY_TITLE_CACHE.asList();
- private ConversationDirector conversationDirector;
-
/**
* @return the matchMode
*
* @param service
*/
- public CdmFilterablePagingProvider(IIdentifiableEntityService<T> service, ConversationDirector conversationDirector) {
+ public CdmFilterablePagingProvider(IIdentifiableEntityService<T> service) {
super();
this.service = service;
- this.conversationDirector = conversationDirector;
}
/**
* @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;
}
/**
@Override
public List<T> findEntities(int firstRow, String filter) {
- conversationDirector.ensureBoundConversation();
Pager<T> page = service.findByTitle(
null,
filter,
@Override
public int size(String filter) {
- conversationDirector.ensureBoundConversation();
Pager<T> page = service.findByTitle(
null,
filter,
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;
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;
}
- /**
- * 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
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());
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();
}
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;
}
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);
}
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;
*/
@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;
SecurityContextHolder.getContext().setAuthentication(authentication);
logger.debug("security context refreshed with user " + username);
}
+ repo.commitTransaction(txStatus);
return newAuthorityAdded ? authority : null;
}
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);
}
/**
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
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;
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;
@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",
+ }
+ );
+
/**
*
*/
@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);
}
@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;
@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);
}
/**
* @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;
+ }
+ }
+ }
+ }
+
+
+++ /dev/null
-/**
-* 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 );
- }
-
-
-
-
-}
}
} catch (AuthenticationException e){
getView().showErrorMessage("Login failed! Please check your username and password.");
- } finally {
- unbindConversation();
}
return false;
}
*/
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;
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;
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.
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.
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());
} 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);
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() {
*/
package eu.etaxonomy.cdm.vaadin.view.name;
+import java.util.Arrays;
import java.util.List;
import java.util.Set;
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());
}
@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());
}
* @return the workingSetService
*/
public IRegistrationWorkingSetService getWorkingSetService() {
- ensureBoundConversation();
return workingSetService;
}
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;
* @return the workingSetService
*/
public IRegistrationWorkingSetService getWorkingSetService() {
- ensureBoundConversation();
return workingSetService;
}
protected Registration createNewRegistrationForName(Integer taxonNameId) {
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// move into RegistrationWorkflowStateMachine
+ TransactionStatus txStatus = getRepo().startTransaction();
long identifier = System.currentTimeMillis();
Registration reg = Registration.NewInstance(
"http://phycobank.org/" + identifier,
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);
}
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) {
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")
@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;
}
}
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){
}
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())){
)
)
){
- refreshView();
+ refreshView(true);
}
}
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());
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;
* @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;
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}
if(!isFromOwnView(preSaveEvent)){
return;
}
- ensureBoundConversation();
- previousPreSaveEvenFlushMode = getConversationHolder().getSession().getFlushMode();
- getConversationHolder().getSession().setFlushMode(FlushMode.AUTO);
+ getSession().setFlushMode(FlushMode.AUTO);
}
}
DTO bean = saveEvent.getBean();
saveBean(bean);
- getConversationHolder().getSession().setFlushMode(previousPreSaveEvenFlushMode);
+ getSession().setFlushMode(previousPreSaveEvenFlushMode);
previousPreSaveEvenFlushMode = null;
}
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);
}
/**
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);
/**
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;
* @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;
@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;
}
* @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;
}
*
* @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
}
/**
- * <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() {
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");
- }
}
/**
return navigationManager;
}
- protected ViewScopeConversationHolder getConversationHolder(){
- return conversationHolder;
- }
-
/**
* @param repo the repo to set
*/
this.navigationManager = navigationManager;
}
-
-
}
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;
@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();
}
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);
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);
}
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);
+ }
}
/**