blob: 6678214281f5cda5bbdc130c02192c426a41bcc6 [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 2.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Florian Pirchner - Initial implementation
*/
package org.eclipse.osbp.runtime.web.ecview.presentation.vaadin.internal;
import java.util.HashSet;
import java.util.Locale;
import java.util.Set;
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.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.core.extension.model.extension.ExtensionModelPackage;
import org.eclipse.osbp.ecview.core.extension.model.extension.YEnumOptionsGroup;
import org.eclipse.osbp.ecview.core.extension.model.extension.YSelectionType;
import org.eclipse.osbp.ecview.core.ui.core.editparts.extension.IEnumOptionsGroupEditpart;
import org.eclipse.osbp.runtime.web.ecview.presentation.vaadin.common.AbstractFieldWidgetPresenter;
import org.eclipse.osbp.runtime.web.ecview.presentation.vaadin.internal.data.EnumConverter;
import org.eclipse.osbp.runtime.web.ecview.presentation.vaadin.internal.data.EnumOptionBean;
import org.eclipse.osbp.runtime.web.ecview.presentation.vaadin.internal.data.EnumOptionBeanHelper;
import org.eclipse.osbp.runtime.web.ecview.presentation.vaadin.internal.data.EnumSetConverter;
import org.eclipse.osbp.runtime.web.ecview.presentation.vaadin.internal.util.Util;
import org.eclipse.osbp.runtime.web.vaadin.common.resource.IResourceProvider;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.vaadin.data.Property;
import com.vaadin.data.util.BeanItemContainer;
import com.vaadin.data.util.ObjectProperty;
import com.vaadin.data.util.converter.Converter;
import com.vaadin.server.ErrorMessage;
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;
import com.vaadin.ui.OptionGroup;
// TODO: Auto-generated Javadoc
/**
* This presenter is responsible to render a list box on the given layout.
*/
@SuppressWarnings("restriction")
public class EnumOptionsGroupPresentation extends
AbstractFieldWidgetPresenter<Component> {
/** The Constant LOGGER. */
private static final Logger LOGGER = LoggerFactory
.getLogger(EnumOptionsGroupPresentation.class);
/** The model access. */
private final ModelAccess modelAccess;
/** The options group. */
private OptionGroup optionsGroup;
/** The property. */
@SuppressWarnings("rawtypes")
private ObjectProperty property;
/**
* Constructor.
*
* @param editpart
* The editpart of that presenter
*/
public EnumOptionsGroupPresentation(IElementEditpart editpart) {
super((IEnumOptionsGroupEditpart) editpart);
this.modelAccess = new ModelAccess(
(YEnumOptionsGroup) editpart.getModel());
}
/**
* {@inheritDoc}
*/
@SuppressWarnings({ "unchecked", "rawtypes" })
@Override
public Component doCreateWidget(Object parent) {
if (optionsGroup == null) {
optionsGroup = new CustomOptionsGroup();
optionsGroup.addStyleName(CSS_CLASS_CONTROL);
optionsGroup.setImmediate(true);
optionsGroup
.setMultiSelect(modelAccess.yField.getSelectionType() == YSelectionType.MULTI);
setupComponent(optionsGroup, getCastedModel());
associateWidget(optionsGroup, modelAccess.yField);
if (modelAccess.isCssIdValid()) {
optionsGroup.setId(modelAccess.getCssID());
} else {
optionsGroup.setId(getEditpart().getId());
}
try {
if (optionsGroup.isMultiSelect()) {
property = new ObjectProperty(new HashSet(), Set.class);
} else {
if (modelAccess.yField.getType() != null) {
property = new ObjectProperty(null,
modelAccess.yField.getType());
} else {
property = new ObjectProperty(null, Object.class);
}
}
optionsGroup.setPropertyDataSource(property);
if (modelAccess.yField.getType() != null) {
BeanItemContainer<EnumOptionBean> datasource = createDatasource((Class<? extends Enum<?>>) modelAccess.yField
.getType());
optionsGroup.setContainerDataSource(datasource);
}
optionsGroup.setConverter(getConverter());
optionsGroup.setItemCaptionPropertyId("description");
optionsGroup.setItemCaptionMode(ItemCaptionMode.PROPERTY);
optionsGroup.setItemIconPropertyId("imagePath");
// creates the binding for the field
createBindings(modelAccess.yField, optionsGroup);
if (modelAccess.isCssClassValid()) {
optionsGroup.addStyleName(modelAccess.getCssClass());
}
applyCaptions();
initializeField(optionsGroup);
} catch (Exception e) {
LOGGER.error("{}", e);
}
}
return optionsGroup;
}
/* (non-Javadoc)
* @see org.eclipse.osbp.runtime.web.ecview.presentation.vaadin.common.AbstractFieldWidgetPresenter#getDefaultConverter()
*/
@SuppressWarnings({ "unchecked", "rawtypes" })
@Override
protected Converter getDefaultConverter() {
if(optionsGroup == null) {
return null;
}
if (modelAccess.yField.getSelectionType() == YSelectionType.MULTI) {
return new EnumSetConverter(
(Class<Enum<?>>) modelAccess.yField.getType(), optionsGroup);
} else {
return new EnumConverter(
(Class<Enum<?>>) modelAccess.yField.getType(), optionsGroup);
}
}
/**
* Creates the datasource used for the enum field.
*
* @param enumClass
* the enum class
* @return the bean item container
*/
protected BeanItemContainer<EnumOptionBean> createDatasource(
Class<? extends Enum<?>> enumClass) {
BeanItemContainer<EnumOptionBean> datasource = new BeanItemContainer<EnumOptionBean>(
EnumOptionBean.class);
datasource.addAll(EnumOptionBeanHelper.getBeans(enumClass,
getI18nService(), getLocale()));
return datasource;
}
/* (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.
*/
@SuppressWarnings("unchecked")
protected void applyCaptions() {
Util.applyCaptions(getI18nService(), modelAccess.getLabel(),
modelAccess.getLabelI18nKey(), getLocale(), optionsGroup);
EnumOptionBeanHelper.updateLocale((BeanItemContainer<EnumOptionBean>) optionsGroup.getContainerDataSource(),
getI18nService(), getLocale());
}
/* (non-Javadoc)
* @see org.eclipse.osbp.runtime.web.ecview.presentation.vaadin.common.AbstractFieldWidgetPresenter#doGetField()
*/
@Override
protected Field<?> doGetField() {
return optionsGroup;
}
/* (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() {
throw new UnsupportedOperationException();
}
/**
* 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.YENUM_OPTIONS_GROUP__SELECTION,
yEndpoint.getAttributePath());
// return the observable value for text
return ECViewModelBindable.observeValue(castEObject(getModel()),
attributePath, modelAccess.yField.getType(),
modelAccess.yField.getEmfNsURI());
}
/**
* Creates the bindings for the given values.
*
* @param yField
* the y field
* @param field
* the field
*/
protected void createBindings(YEnumOptionsGroup yField, OptionGroup field) {
if (modelAccess.yField.getSelectionType() == YSelectionType.MULTI) {
// create the model binding from widget to ECView-model
registerBinding(createBindingsMultiSelection(
castEObject(getModel()),
ExtensionModelPackage.Literals.YENUM_OPTIONS_GROUP__MULTI_SELECTION,
field, yField.getType()));
} else {
// create the model binding from widget to ECView-model
registerBinding(createBindingsSelection(
castEObject(getModel()),
ExtensionModelPackage.Literals.YENUM_OPTIONS_GROUP__SELECTION,
field, yField.getType()));
}
super.createBindings(yField, field, null);
}
/* (non-Javadoc)
* @see org.eclipse.osbp.ecview.core.common.presentation.IWidgetPresentation#getWidget()
*/
@Override
public Component getWidget() {
return optionsGroup;
}
/* (non-Javadoc)
* @see org.eclipse.osbp.ecview.core.common.presentation.IWidgetPresentation#isRendered()
*/
@Override
public boolean isRendered() {
return optionsGroup != null;
}
/**
* {@inheritDoc}
*/
@Override
public void doUnrender() {
if (optionsGroup != null) {
// unbind all active bindings
unbind();
Component parent = ((Component) optionsGroup.getParent());
if (parent != null && parent instanceof ComponentContainer) {
((ComponentContainer) parent).removeComponent(optionsGroup);
}
// remove assocations
unassociateWidget(optionsGroup);
optionsGroup = null;
}
}
/**
* {@inheritDoc}
*/
@Override
protected void internalDispose() {
try {
unrender();
} finally {
super.internalDispose();
}
}
/**
* A helper class.
*/
private static class ModelAccess {
/** The y field. */
private final YEnumOptionsGroup yField;
/**
* Instantiates a new model access.
*
* @param yField
* the y field
*/
public ModelAccess(YEnumOptionsGroup 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 class CustomOptionsGroup extends OptionGroup {
/** The item icon property id. */
private Object itemIconPropertyId;
/**
* Instantiates a new custom options group.
*/
public CustomOptionsGroup() {
}
// @Override
// public Class<?> getType() {
// return EnumOptionBean.class;
// }
/* (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) {
IResourceProvider provider = getViewContext()
.getService(IResourceProvider.class.getName());
return provider.getResource((String) icon);
}
} catch (Exception e) {
}
}
return null;
}
/* (non-Javadoc)
* @see com.vaadin.ui.AbstractField#getErrorMessage()
*/
@Override
public ErrorMessage getErrorMessage() {
if(isDisposed()) {
// after disposal, Vaadin will call this method once.
return null;
}
ErrorMessage message = super.getErrorMessage();
reportValidationError(message);
return message;
}
}
}