bug #6673

Updated by Andreas Kohlbecker about 3 years ago

In a vaadin application it must be possible to open multiple popup editors of the same type. For example to open an editor for the inReference from within the popupeditor of the contained reference.
Therefore implementations of the popup editors are spring prototype beans. Here shown at the example of the ReferencePopupEditor:

public class ReferencePopupEditor extends AbstractCdmPopupEditor<Reference, ReferenceEditorPresenter> implements ReferencePopupEditorView, AccessRestrictedView {

So a new editor bean is created each time a bean is requested. Each editor should have it's own `Presenter`, so it seems logically to also make the implementations of `AbstractEditorPresenter` also prototype beans. But this is not possible since it would break the Event bus. The event bus is build using the `org.springframework.context.ApplicationEventPublisher` and `org.springframework.context.event.EventListener` annotation at presenter classes. The events are delegated to the listening beans by the `SimpleApplicationEventMulticaster` which uses the `AbstractApplicationEventMulticaster.getApplicationListeners()` method to retrieve the listening beans. But in this method the `beanFactory.getBean()` call would cause the creation of new instances of the prototype presenters, which are not responsible for the view from where the event was published, these new presenters actually have no view at all. The presenters that already exist are never found and are thus not receiving the event.

Potential solution:

* Make editor presenters prototype beans and implement a **`PojoEventListenerManager` which manages the presenter beans that have been created already on behalf of Spring**. Presenter beans are created in turn of the calls to `NavigationManagerBean.findPopupView()` (see also #6562). Therefore the `NavigationManagerBean` will hold a reference to the `PojoEventListenerManager` -Bean and will delegate Presenters for registration or removal to the `PojoEventListenerManager`. The `PojoEventListenerManager` creates a `ApplicationListener` instances instance for each method annotated with `@EventListner` and adds add them to the EventMulticaster.
* One caveat is that the `AbstractApplicationEventMulticaster` still will create useless prototype presenter beans. This can be avoided by several optional strategies ...
1. Implement a PopupEditorFactory which is responsible for creating the View and Presenter
1. **Implement a (Popup)PresenterFactory** which is responsible for creating Presenter only. The View uses the factory to create the required Presenter. Presenters must not be annotated as `@SpringComponent` or the like. This factory could be suitable for all types of views.

For now the presenters are having the scope "vaadin-view" (`@ScopeView`) and are thus one presenter is responsible for all editors which can cause last view wins problems. The presenters are always associated with the last view created. This is not causing a problem as long only the last editor is used. **Therefore popup editors should be modal at the moment.**

Due to the above problem the responsibility of a presenter can not be decided by the view instance, this is only possible by the view class, see `AbstractCdmEditorPresenter.isResponsible(EditorViewEvent event)'


Add picture from clipboard (Maximum size: 40 MB)