| /** |
| * 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; |
| } |
| } |
| } |