| /** |
| * |
| * Copyright (c) 2011, 2016 - 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.ecview.extension.presentation.vaadin.components; |
| |
| import java.util.Locale; |
| |
| import org.eclipse.core.databinding.Binding; |
| import org.eclipse.core.databinding.UpdateValueStrategy; |
| import org.eclipse.core.databinding.conversion.Converter; |
| 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.EMFObservables; |
| import org.eclipse.emf.databinding.EMFProperties; |
| import org.eclipse.emf.ecore.EObject; |
| import org.eclipse.emf.ecore.EStructuralFeature; |
| import org.eclipse.osbp.ecview.core.common.editpart.IElementEditpart; |
| 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.databinding.emf.model.ECViewModelBindable; |
| import org.eclipse.osbp.ecview.extension.editparts.components.IPairComboBoxEditpart; |
| import org.eclipse.osbp.ecview.extension.model.YECviewPackage; |
| import org.eclipse.osbp.ecview.extension.model.YPairComboBox; |
| import org.eclipse.osbp.runtime.common.state.ISharedStateContext; |
| import org.eclipse.osbp.runtime.web.ecview.presentation.vaadin.IBindingManager; |
| import org.eclipse.osbp.runtime.web.ecview.presentation.vaadin.common.AbstractFieldWidgetPresenter; |
| import org.eclipse.osbp.runtime.web.ecview.presentation.vaadin.internal.util.Util; |
| import org.eclipse.osbp.runtime.web.vaadin.common.data.BeanServiceLazyLoadingContainer; |
| import org.eclipse.osbp.runtime.web.vaadin.common.data.DeepResolvingBeanItemContainer; |
| import org.eclipse.osbp.runtime.web.vaadin.common.data.IBeanSearchServiceFactory; |
| import org.eclipse.osbp.runtime.web.vaadin.components.widget.LazyLoadingComboBox; |
| import org.eclipse.osbp.runtime.web.vaadin.databinding.VaadinObservables; |
| import org.eclipse.xtext.util.Pair; |
| import org.eclipse.xtext.util.Tuples; |
| import org.slf4j.Logger; |
| import org.slf4j.LoggerFactory; |
| |
| import com.vaadin.data.Container; |
| import com.vaadin.data.Container.Sortable; |
| import com.vaadin.data.Property; |
| import com.vaadin.data.util.ObjectProperty; |
| import com.vaadin.server.Resource; |
| import com.vaadin.server.ThemeResource; |
| import com.vaadin.ui.AbstractSelect.ItemCaptionMode; |
| import com.vaadin.ui.Component; |
| import com.vaadin.ui.ComponentContainer; |
| import com.vaadin.ui.Field; |
| |
| @SuppressWarnings("restriction") |
| public class PairComboBoxPresentation extends AbstractFieldWidgetPresenter<Component> { |
| |
| /** The Constant LOGGER. */ |
| private static final Logger LOGGER = LoggerFactory.getLogger(PairComboBoxPresentation.class); |
| |
| /** The model access. */ |
| private final ModelAccess modelAccess; |
| |
| /** The combo. */ |
| private LazyLoadingComboBox combo; |
| |
| /** The property. */ |
| @SuppressWarnings("rawtypes") |
| private ObjectProperty property; |
| |
| /** |
| * Constructor. |
| * |
| * @param editpart |
| * The editpart of that presenter |
| */ |
| public PairComboBoxPresentation(IElementEditpart editpart) { |
| super((IPairComboBoxEditpart) editpart); |
| this.modelAccess = new ModelAccess((YPairComboBox) editpart.getModel()); |
| } |
| |
| /** |
| * {@inheritDoc} |
| */ |
| @SuppressWarnings({ "unchecked", "rawtypes" }) |
| @Override |
| public Component doCreateWidget(Object parent) { |
| if (combo == null) { |
| |
| combo = new CustomComboBox(); |
| combo.addStyleName(CSS_CLASS_CONTROL); |
| combo.setImmediate(true); |
| setupComponent(combo, getCastedModel()); |
| |
| associateWidget(combo, modelAccess.yField); |
| if (modelAccess.isCssIdValid()) { |
| combo.setId(modelAccess.getCssID()); |
| } else { |
| combo.setId(getEditpart().getId()); |
| } |
| |
| if (modelAccess.isCssClassValid()) { |
| combo.addStyleName(modelAccess.getCssClass()); |
| } |
| |
| try { |
| property = new ObjectProperty(null, modelAccess.yField.getType()); |
| combo.setPropertyDataSource(property); |
| |
| if (modelAccess.yField.getType() != null) { |
| if (!modelAccess.yField.isUseBeanService()) { |
| DeepResolvingBeanItemContainer datasource = new DeepResolvingBeanItemContainer(modelAccess.yField.getType()); |
| combo.setContainerDataSource(datasource); |
| } else { |
| IBeanSearchServiceFactory factory = getViewContext().getService(IBeanSearchServiceFactory.class.getName()); |
| if (factory != null) { |
| ISharedStateContext sharedState = getViewContext().getService(ISharedStateContext.class.getName()); |
| BeanServiceLazyLoadingContainer<?> datasource = new BeanServiceLazyLoadingContainer( |
| factory.createService(modelAccess.yField.getType()), modelAccess.yField.getType(), sharedState); |
| combo.setContainerDataSource(datasource); |
| } |
| } |
| } |
| |
| String itemCaptionProperty = modelAccess.yField.getCaptionProperty(); |
| if (itemCaptionProperty != null && !itemCaptionProperty.equals("")) { |
| combo.setItemCaptionPropertyId(itemCaptionProperty); |
| combo.setItemCaptionMode(ItemCaptionMode.PROPERTY); |
| |
| Container container = combo.getContainerDataSource(); |
| if (container instanceof Container.Sortable) { |
| Container.Sortable sortable = (Sortable) container; |
| sortable.sort(new Object[] { itemCaptionProperty }, new boolean[] { true }); |
| } |
| } else { |
| combo.setItemCaptionMode(ItemCaptionMode.ID); |
| } |
| |
| String itemImageProperty = modelAccess.yField.getImageProperty(); |
| if (itemImageProperty != null && !itemImageProperty.equals("")) { |
| combo.setItemIconPropertyId(itemImageProperty); |
| } |
| |
| // creates the binding for the field |
| createBindings(modelAccess.yField, combo); |
| |
| if (modelAccess.isCssClassValid()) { |
| combo.addStyleName(modelAccess.getCssClass()); |
| } |
| |
| applyCaptions(); |
| |
| initializeField(combo); |
| } catch (Exception e) { |
| LOGGER.error("{}", e); |
| } |
| } |
| return combo; |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see org.eclipse.osbp.runtime.web.ecview.presentation.vaadin.common. |
| * AbstractVaadinWidgetPresenter#doUpdateLocale(java.util.Locale) |
| */ |
| @Override |
| protected void doUpdateLocale(Locale locale) { |
| // no need to set the locale to the ui elements. Is handled by vaadin |
| // internally. |
| |
| // update the captions |
| applyCaptions(); |
| } |
| |
| /** |
| * Applies the labels to the widgets. |
| */ |
| protected void applyCaptions() { |
| Util.applyCaptions(getI18nService(), modelAccess.getLabel(), modelAccess.getLabelI18nKey(), getLocale(), combo); |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see org.eclipse.osbp.runtime.web.ecview.presentation.vaadin.common. |
| * AbstractFieldWidgetPresenter#doGetField() |
| */ |
| @Override |
| protected Field<?> doGetField() { |
| return combo; |
| } |
| |
| /* |
| * (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 IllegalArgumentException("BindableValue must not be null!"); |
| } |
| |
| if (bindableValue instanceof YEmbeddableCollectionEndpoint) { |
| return internalGetCollectionEndpoint(); |
| } else if (bindableValue instanceof YEmbeddableSelectionEndpoint) { |
| return internalGetSelectionEndpoint((YEmbeddableSelectionEndpoint) bindableValue); |
| } |
| throw new IllegalArgumentException("Not a valid input: " + bindableValue); |
| } |
| |
| /** |
| * Returns the observable to observe the collection. |
| * |
| * @return the i observable list |
| */ |
| protected IObservableList internalGetCollectionEndpoint() { |
| // return the observable value for text |
| return EMFProperties.list(YECviewPackage.Literals.YPAIR_COMBO_BOX__COLLECTION).observe(getModel()); |
| } |
| |
| /** |
| * 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(YECviewPackage.Literals.YPAIR_COMBO_BOX__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 Component getWidget() { |
| return combo; |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see |
| * org.eclipse.osbp.ecview.core.common.presentation.IWidgetPresentation# |
| * isRendered() |
| */ |
| @Override |
| public boolean isRendered() { |
| return combo != null; |
| } |
| |
| /** |
| * {@inheritDoc} |
| */ |
| @Override |
| public void doUnrender() { |
| if (combo != null) { |
| |
| // unbind all active bindings |
| unbind(); |
| |
| Component parent = ((Component) combo.getParent()); |
| if (parent != null && parent instanceof ComponentContainer) { |
| ((ComponentContainer) parent).removeComponent(combo); |
| } |
| |
| // remove assocations |
| unassociateWidget(combo); |
| |
| combo = null; |
| } |
| } |
| |
| /** |
| * {@inheritDoc} |
| */ |
| @Override |
| protected void internalDispose() { |
| try { |
| unrender(); |
| } finally { |
| super.internalDispose(); |
| } |
| } |
| |
| /** |
| * A helper class. |
| */ |
| private static class ModelAccess { |
| |
| /** The y field. */ |
| private final YPairComboBox yField; |
| |
| /** |
| * Instantiates a new model access. |
| * |
| * @param yField |
| * the y field |
| */ |
| public ModelAccess(YPairComboBox 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 |
| */ |
| 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; |
| } |
| } |
| |
| /** |
| * Converts the string value of the item icon property to |
| * {@link ThemeResource}. |
| */ |
| @SuppressWarnings("serial") |
| private static class CustomComboBox extends LazyLoadingComboBox { |
| |
| /** The item icon property id. */ |
| private Object itemIconPropertyId; |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see |
| * com.vaadin.ui.AbstractSelect#setItemIconPropertyId(java.lang.Object) |
| */ |
| @Override |
| public void setItemIconPropertyId(Object propertyId) throws IllegalArgumentException { |
| if (propertyId == null) { |
| super.setItemIconPropertyId(propertyId); |
| } else if (!getContainerPropertyIds().contains(propertyId)) { |
| super.setItemIconPropertyId(propertyId); |
| } else if (String.class.isAssignableFrom(getType(propertyId))) { |
| itemIconPropertyId = propertyId; |
| } else { |
| super.setItemIconPropertyId(propertyId); |
| } |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see com.vaadin.ui.AbstractSelect#getItemIconPropertyId() |
| */ |
| public Object getItemIconPropertyId() { |
| return itemIconPropertyId != null ? itemIconPropertyId : super.getItemIconPropertyId(); |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see com.vaadin.ui.AbstractSelect#getItemIcon(java.lang.Object) |
| */ |
| public Resource getItemIcon(Object itemId) { |
| if (itemIconPropertyId == null) { |
| return super.getItemIcon(itemId); |
| } else { |
| final Property<?> ip = getContainerProperty(itemId, getItemIconPropertyId()); |
| if (ip == null) { |
| return null; |
| } |
| final Object icon = ip.getValue(); |
| try { |
| if (icon instanceof String) { |
| return new ThemeResource((String) icon); |
| } |
| } catch (Exception e) { |
| // nothing to do |
| } |
| } |
| return null; |
| } |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see org.eclipse.osbp.runtime.web.ecview.presentation.vaadin.common. |
| * AbstractFieldWidgetPresenter#setConverter(java.lang.Object) |
| */ |
| @Override |
| public void setConverter(Object object) { |
| if (object == null) { |
| |
| } |
| super.setConverter(object); |
| } |
| |
| /** |
| * Creates the bindings for the given values. |
| * |
| * @param yField |
| * the y field |
| * @param field |
| * the field |
| */ |
| protected void createBindings(YPairComboBox yField, LazyLoadingComboBox field) { |
| // create the model binding from ridget to ECView-model |
| // registerBinding(createBindings_ContainerContents(castEObject(getModel()), |
| // YECviewPackage.Literals.YPAIR_COMBO_BOX__COLLECTION, |
| // field)); |
| // create the model binding from ridget to ECView-model |
| registerBinding(createBindings_ContainerContents(castEObject(getModel()), YECviewPackage.Literals.YPAIR_COMBO_BOX__COLLECTION, |
| field, yField.getType())); |
| |
| // create the model binding from ridget to ECView-model |
| // registerBinding(createBindingsPairSelection(castEObject(getModel()), |
| // YECviewPackage.Literals.YPAIR_COMBO_BOX__SELECTION, field, |
| // yField.getType())); |
| registerBinding(createBindingsPairSelection(castEObject(getModel()), YECviewPackage.Literals.YPAIR_COMBO_BOX__SELECTION, field)); |
| |
| super.createBindings(yField, field, null); |
| } |
| |
| /** |
| * Binds the value attribute from the ecview model to the ui element. |
| * |
| * @param model |
| * the model |
| * @param modelFeature |
| * the model feature |
| * @param field |
| * the field |
| * @param targetToModel |
| * the target to model |
| * @param modelToTarget |
| * the model to target |
| * @return Binding - the created binding |
| */ |
| protected Binding createBindingsPairSelection(EObject model, EStructuralFeature modelFeature, Field<?> field) { |
| IBindingManager bindingManager = getViewContext().getService( |
| org.eclipse.osbp.ecview.core.common.binding.IECViewBindingManager.class.getName()); |
| if (bindingManager != null) { |
| |
| UpdateValueStrategy targetToModel = new UpdateValueStrategy(UpdateValueStrategy.POLICY_UPDATE); |
| targetToModel.setConverter(new PairToTextConverter()); |
| UpdateValueStrategy modelToTarget = new UpdateValueStrategy(UpdateValueStrategy.POLICY_UPDATE); |
| modelToTarget.setConverter(new TextToPairConverter()); |
| |
| // bind the value of yText to textRidget |
| IObservableValue modelObservable = EMFObservables.observeValue(model, modelFeature); |
| IObservableValue uiObservable = VaadinObservables.observeValue(field); |
| return bindingManager.bindValue(uiObservable, modelObservable, targetToModel, modelToTarget); |
| } |
| return null; |
| } |
| |
| private static class TextToPairConverter extends Converter { |
| |
| public TextToPairConverter() { |
| super(String.class, Pair.class); |
| } |
| |
| @Override |
| public Object convert(Object fromObject) { |
| if (fromObject == null) { |
| return null; |
| } |
| return Tuples.create(extractSimpleName((String) fromObject), (String) fromObject); |
| // return fromObject; |
| } |
| |
| private String extractSimpleName(String fqn) { |
| String[] splittedFqn = fqn.split("\\."); |
| String name = ""; |
| int length = splittedFqn.length; |
| if (length > 0) { |
| name = splittedFqn[length - 1]; |
| } |
| return name; |
| } |
| } |
| |
| private static class PairToTextConverter extends Converter { |
| |
| public PairToTextConverter() { |
| super(Pair.class, String.class); |
| } |
| |
| @SuppressWarnings("unchecked") |
| @Override |
| public Object convert(Object fromObject) { |
| if (fromObject == null) { |
| return ""; |
| } |
| return ((Pair<String, String>) fromObject).getSecond(); |
| } |
| } |
| |
| } |