blob: eaf548891ed7dee494b1819e66831ab61e0fe426 [file] [log] [blame]
/**
* Copyright (c) 2011, 2015 - Lunifera GmbH (Gross Enzersdorf, Austria), Loetz GmbH&Co.KG (69115 Heidelberg, Germany)
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Florian Pirchner - Initial implementation
*/
package org.eclipse.osbp.runtime.web.ecview.presentation.vaadin.internal;
import java.net.URI;
import java.util.Locale;
import org.eclipse.core.databinding.Binding;
import org.eclipse.core.databinding.observable.IObservable;
import org.eclipse.core.databinding.observable.list.IObservableList;
import org.eclipse.core.databinding.observable.value.IObservableValue;
import org.eclipse.emf.databinding.EMFProperties;
import org.eclipse.osbp.ecview.core.common.binding.observables.ContextObservables;
import org.eclipse.osbp.ecview.core.common.editpart.IElementEditpart;
import org.eclipse.osbp.ecview.core.common.model.core.YCollectionBindable;
import org.eclipse.osbp.ecview.core.common.model.core.YEmbeddable;
import org.eclipse.osbp.ecview.core.common.model.core.YEmbeddableBindingEndpoint;
import org.eclipse.osbp.ecview.core.common.model.core.YEmbeddableCollectionEndpoint;
import org.eclipse.osbp.ecview.core.common.model.core.YEmbeddableSelectionEndpoint;
import org.eclipse.osbp.ecview.core.common.presentation.IWidgetPresentation;
import org.eclipse.osbp.ecview.core.common.uri.URIHelper;
import org.eclipse.osbp.ecview.core.databinding.emf.model.ECViewModelBindable;
import org.eclipse.osbp.ecview.core.extension.model.extension.ExtensionModelPackage;
import org.eclipse.osbp.ecview.core.extension.model.extension.YMasterDetail;
import org.eclipse.osbp.ecview.core.ui.core.editparts.extension.IMasterDetailEditpart;
import org.eclipse.osbp.ecview.core.ui.core.editparts.extension.presentation.IMasterDetailPresentation;
import org.eclipse.osbp.runtime.web.ecview.presentation.vaadin.IConstants;
import org.eclipse.osbp.runtime.web.ecview.presentation.vaadin.common.AbstractVaadinWidgetPresenter;
import org.eclipse.osbp.runtime.web.ecview.presentation.vaadin.internal.util.Util;
import com.vaadin.ui.Component;
import com.vaadin.ui.ComponentContainer;
import com.vaadin.ui.CssLayout;
import com.vaadin.ui.VerticalLayout;
// TODO: Auto-generated Javadoc
/**
* This presenter is responsible to render a text field on the given layout.
*/
@SuppressWarnings("restriction")
public class MasterDetailPresentation extends
AbstractVaadinWidgetPresenter<ComponentContainer> implements
IMasterDetailPresentation<ComponentContainer> {
/** The model access. */
private final ModelAccess modelAccess;
/** The component base. */
private VerticalLayout componentBase;
/** The master base. */
private CssLayout masterBase;
/** The detail base. */
private CssLayout detailBase;
/** The master presentation. */
private IWidgetPresentation<?> masterPresentation;
/** The detail presentation. */
private IWidgetPresentation<?> detailPresentation;
/** The master collection binding. */
private Binding masterCollectionBinding;
/**
* Constructor.
*
* @param editpart
* The editpart of that presenter
*/
public MasterDetailPresentation(IElementEditpart editpart) {
super((IMasterDetailEditpart) editpart);
this.modelAccess = new ModelAccess((YMasterDetail) editpart.getModel());
}
/**
* {@inheritDoc}
*/
@Override
public ComponentContainer doCreateWidget(Object parent) {
if (componentBase == null) {
componentBase = new VerticalLayout();
componentBase.addStyleName(CSS_CLASS_CONTROL_BASE);
if (modelAccess.isCssIdValid()) {
componentBase.setId(modelAccess.getCssID());
} else {
componentBase.setId(getEditpart().getId());
}
associateWidget(componentBase, modelAccess.yField);
// create the container for master an detail
masterBase = new CssLayout();
masterBase.setStyleName(IConstants.CSS_CLASS_MASTER_BASE);
masterBase.setSizeFull();
componentBase.addComponent(masterBase);
associateWidget(masterBase, modelAccess.yField);
detailBase = new CssLayout();
masterBase.setStyleName(IConstants.CSS_CLASS_DETAIL_BASE);
detailBase.setSizeFull();
componentBase.addComponent(detailBase);
associateWidget(detailBase, modelAccess.yField);
// creates the binding for the field
createBindings(modelAccess.yField);
// render master an detail
if (masterPresentation != null) {
createMasterWidget();
}
if (detailPresentation != null) {
Component detailWidget = (Component) detailPresentation
.createWidget(detailBase);
if (detailWidget != null) {
detailBase.removeAllComponents();
detailBase.addComponent(detailWidget);
}
}
}
return componentBase;
}
/**
* Creates the bindings for the given values.
*
* @param yField
* the y field
*/
protected void createBindings(YMasterDetail yField) {
// create the model binding from ECView-Model to the collection bean
// slot
URI uri = URIHelper.view().bean(getCollectionBeanSlot())
.fragment("value").toURI();
IObservableList targetObservableList = ContextObservables.observeList(
getViewContext(), uri, modelAccess.yField.getType());
IObservableList modelObservable = EMFProperties.list(
ExtensionModelPackage.Literals.YMASTER_DETAIL__COLLECTION)
.observe(getModel());
registerBinding(createBindings(targetObservableList, modelObservable));
}
/**
* Creates a bean slot that is the input for the detail fields. It is used
* by the presentation to bind the detail fields to that slot.
*
* @return the selection bean slot
*/
protected String getSelectionBeanSlot() {
return "selection_" + getEditpart().getId();
}
/**
* Create a bean slot which is the input for the master detail. It is used
* by the presentation to bind the table, list,... to that slot.
*
* @return the collection bean slot
*/
protected String getCollectionBeanSlot() {
return "input_" + getEditpart().getId();
}
/* (non-Javadoc)
* @see org.eclipse.osbp.runtime.web.ecview.presentation.vaadin.common.AbstractVaadinWidgetPresenter#doUpdateLocale(java.util.Locale)
*/
@Override
protected void doUpdateLocale(Locale locale) {
// update the captions
applyCaptions();
}
/**
* Applies the labels to the widgets.
*/
protected void applyCaptions() {
Util.applyCaptions(getI18nService(), modelAccess.getLabel(),
modelAccess.getLabelI18nKey(), getLocale(), masterBase);
}
/* (non-Javadoc)
* @see org.eclipse.osbp.runtime.web.ecview.presentation.vaadin.common.AbstractVaadinWidgetPresenter#internalGetObservableEndpoint(org.eclipse.osbp.ecview.core.common.model.core.YEmbeddableBindingEndpoint)
*/
@Override
protected IObservable internalGetObservableEndpoint(
YEmbeddableBindingEndpoint bindableValue) {
if (bindableValue == null) {
throw new NullPointerException("BindableValue must not be null!");
}
if (bindableValue instanceof YEmbeddableSelectionEndpoint) {
return internalGetSelectionEndpoint((YEmbeddableSelectionEndpoint) bindableValue);
} else if (bindableValue instanceof YEmbeddableCollectionEndpoint) {
return internalGetCollectionEndpoint();
}
throw new IllegalArgumentException("Not a valid input: "
+ bindableValue);
}
/**
* Returns the observable to observe value.
*
* @return the i observable list
*/
protected IObservableList internalGetCollectionEndpoint() {
// delegate the binding to the proper bean slot
URI uri = URIHelper.view().bean(getCollectionBeanSlot()).toURI();
IObservableList modelObservableList = ContextObservables.observeList(
getViewContext(), uri, modelAccess.yField.getType());
return modelObservableList;
}
/**
* Returns the observable to observe the selection.
*
* @param yEndpoint
* the y endpoint
* @return the i observable value
*/
protected IObservableValue internalGetSelectionEndpoint(
YEmbeddableSelectionEndpoint yEndpoint) {
String attributePath = ECViewModelBindable.getAttributePath(
ExtensionModelPackage.Literals.YMASTER_DETAIL__SELECTION,
yEndpoint.getAttributePath());
// return the observable value for text
return ECViewModelBindable.observeValue(castEObject(getModel()),
attributePath, modelAccess.yField.getType(),
modelAccess.yField.getEmfNsURI());
}
/* (non-Javadoc)
* @see org.eclipse.osbp.ecview.core.common.presentation.IWidgetPresentation#getWidget()
*/
@Override
public ComponentContainer getWidget() {
return componentBase;
}
/* (non-Javadoc)
* @see org.eclipse.osbp.ecview.core.common.presentation.IWidgetPresentation#isRendered()
*/
@Override
public boolean isRendered() {
return componentBase != null;
}
/**
* {@inheritDoc}
*/
@Override
public void doUnrender() {
if (componentBase != null) {
// unbind all active bindings
unbind();
ComponentContainer parent = ((ComponentContainer) componentBase
.getParent());
if (parent != null) {
parent.removeComponent(componentBase);
}
// remove assocations
unassociateWidget(componentBase);
componentBase = null;
if (masterPresentation != null) {
disposeMasterWidget();
}
if (detailPresentation != null) {
detailPresentation.unrender();
detailBase.removeAllComponents();
}
}
}
/**
* {@inheritDoc}
*/
@Override
protected void internalDispose() {
try {
unrender();
// do NOT dispose. Will be handled by editpart.
masterPresentation = null;
detailPresentation = null;
} finally {
super.internalDispose();
}
}
/* (non-Javadoc)
* @see org.eclipse.osbp.ecview.core.ui.core.editparts.extension.presentation.IMasterDetailPresentation#getMaster()
*/
@Override
public IWidgetPresentation<?> getMaster() {
return masterPresentation;
}
/* (non-Javadoc)
* @see org.eclipse.osbp.ecview.core.ui.core.editparts.extension.presentation.IMasterDetailPresentation#getDetail()
*/
@Override
public IWidgetPresentation<?> getDetail() {
return detailPresentation;
}
/* (non-Javadoc)
* @see org.eclipse.osbp.ecview.core.ui.core.editparts.extension.presentation.IMasterDetailPresentation#setMaster(org.eclipse.osbp.ecview.core.common.presentation.IWidgetPresentation)
*/
@Override
public void setMaster(IWidgetPresentation<?> master) {
if (this.masterPresentation == master) {
return;
}
if (this.masterPresentation != null) {
disposeMasterWidget();
}
this.masterPresentation = master;
if (isRendered()) {
if (this.masterPresentation != null) {
createMasterWidget();
}
}
}
/**
* Creates the master widget and does the databinding.
*/
public void createMasterWidget() {
Component masterWidget = (Component) masterPresentation
.createWidget(masterBase);
if (masterWidget != null) {
masterBase.removeAllComponents();
masterBase.addComponent(masterWidget);
}
YEmbeddable yMaster = (YEmbeddable) masterPresentation.getModel();
if (yMaster instanceof YCollectionBindable) {
createMasterCollectionBinding((YCollectionBindable) yMaster);
}
}
/**
* Disposes the master widget and removes active bindings.
*/
protected void disposeMasterWidget() {
masterPresentation.dispose();
masterBase.removeAllComponents();
if (masterCollectionBinding != null) {
masterCollectionBinding.dispose();
masterCollectionBinding = null;
}
}
/**
* Creates a binding from the master element to the proper bean slot.
*
* @param yMasterCollectionBindable
* the y master collection bindable
*/
protected void createMasterCollectionBinding(
YCollectionBindable yMasterCollectionBindable) {
YEmbeddableCollectionEndpoint yMasterEndpoint = yMasterCollectionBindable
.createCollectionEndpoint();
IObservableList targetObservableList = (IObservableList) this.masterPresentation
.getObservableValue(yMasterEndpoint);
URI uri = URIHelper.view().bean(getCollectionBeanSlot())
.fragment("value").toURI();
IObservableList modelObservableList = ContextObservables.observeList(
getViewContext(), uri, modelAccess.yField.getType());
masterCollectionBinding = createBindings(targetObservableList,
modelObservableList);
}
/* (non-Javadoc)
* @see org.eclipse.osbp.ecview.core.ui.core.editparts.extension.presentation.IMasterDetailPresentation#setDetail(org.eclipse.osbp.ecview.core.common.presentation.IWidgetPresentation)
*/
@Override
public void setDetail(IWidgetPresentation<?> detail) {
if (this.detailPresentation == detail) {
return;
}
if (this.detailPresentation != null) {
this.detailPresentation.dispose();
detailBase.removeAllComponents();
}
this.detailPresentation = detail;
if (isRendered()) {
if (this.detailPresentation != null) {
this.detailPresentation.createWidget(detailBase);
}
}
}
/**
* A helper class.
*/
private static class ModelAccess {
/** The y field. */
private final YMasterDetail yField;
/**
* Instantiates a new model access.
*
* @param yField
* the y field
*/
public ModelAccess(YMasterDetail yField) {
super();
this.yField = yField;
}
/**
* Gets the css class.
*
* @return the css class
* @see org.eclipse.osbp.ecview.core.ui.core.model.core.YCssAble#getCssClass()
*/
public String getCssClass() {
return yField.getCssClass();
}
/**
* Returns true, if the css class is not null and not empty.
*
* @return true, if is css class valid
*/
@SuppressWarnings("unused")
public boolean isCssClassValid() {
return getCssClass() != null && !getCssClass().equals("");
}
/**
* Gets the css id.
*
* @return the css id
* @see org.eclipse.osbp.ecview.core.ui.core.model.core.YCssAble#getCssID()
*/
public String getCssID() {
return yField.getCssID();
}
/**
* Returns true, if the css id is not null and not empty.
*
* @return true, if is css id valid
*/
public boolean isCssIdValid() {
return getCssID() != null && !getCssID().equals("");
}
/**
* Returns the label.
*
* @return the label
*/
public String getLabel() {
return yField.getDatadescription() != null ? yField.getDatadescription().getLabel() : null;
}
/**
* Returns the label.
*
* @return the label i18n key
*/
public String getLabelI18nKey() {
return yField.getDatadescription() != null ? yField.getDatadescription().getLabelI18nKey() : null;
}
}
}