| /** |
| * 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.ecview.core.common.editpart.emf.binding; |
| |
| import org.eclipse.core.databinding.Binding; |
| import org.eclipse.core.databinding.observable.list.IObservableList; |
| import org.eclipse.emf.common.notify.Notification; |
| import org.eclipse.emf.common.notify.impl.AdapterImpl; |
| import org.eclipse.osbp.ecview.core.common.binding.IECViewBindingManager; |
| import org.eclipse.osbp.ecview.core.common.editpart.DelegatingEditPartManager; |
| import org.eclipse.osbp.ecview.core.common.editpart.binding.IBindableListEndpointEditpart; |
| import org.eclipse.osbp.ecview.core.common.editpart.binding.IBindingSetEditpart; |
| import org.eclipse.osbp.ecview.core.common.editpart.binding.IListBindingEditpart; |
| import org.eclipse.osbp.ecview.core.common.editpart.emf.ElementEditpart; |
| import org.eclipse.osbp.ecview.core.common.model.binding.BindingPackage; |
| import org.eclipse.osbp.ecview.core.common.model.binding.YBindingEndpoint; |
| import org.eclipse.osbp.ecview.core.common.model.binding.YBindingUpdateStrategy; |
| import org.eclipse.osbp.ecview.core.common.model.binding.YListBinding; |
| import org.eclipse.osbp.ecview.core.common.model.binding.YListBindingEndpoint; |
| import org.eclipse.osbp.ecview.core.databinding.emf.common.ECViewUpdateListStrategy; |
| import org.slf4j.Logger; |
| import org.slf4j.LoggerFactory; |
| |
| // TODO: Auto-generated Javadoc |
| /** |
| * Implementation of {@link IBindingSetEditpart}. |
| */ |
| public class ListBindingEditpart extends ElementEditpart<YListBinding> implements IListBindingEditpart { |
| |
| /** The Constant LOGGER. */ |
| private static final Logger LOGGER = LoggerFactory.getLogger(ListBindingEditpart.class); |
| |
| /** The target value. */ |
| private IBindableListEndpointEditpart targetValue; |
| |
| /** The model value. */ |
| private IBindableListEndpointEditpart modelValue; |
| |
| /** The bound. */ |
| private boolean bound; |
| |
| /** The binding. */ |
| private Binding binding; |
| |
| private ActiveAdapter adapter = new ActiveAdapter(); |
| |
| private boolean isBinding; |
| |
| /** |
| * A default constructor. |
| */ |
| public ListBindingEditpart() { |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see org.eclipse.osbp.ecview.core.common.editpart.emf.ElementEditpart# |
| * handleModelSet(int, org.eclipse.emf.common.notify.Notification) |
| */ |
| @Override |
| protected void handleModelSet(int featureId, Notification notification) { |
| checkDisposed(); |
| |
| boolean shouldRebind = false; |
| switch (featureId) { |
| case BindingPackage.YLIST_BINDING__TARGET_ENDPOINT: |
| YBindingEndpoint YBindingEndpoint = (YBindingEndpoint) notification.getNewValue(); |
| |
| IBindableListEndpointEditpart editPart = (IBindableListEndpointEditpart) getEditpart(viewContext, |
| YBindingEndpoint); |
| internalSetTargetValue(editPart); |
| |
| shouldRebind = true; |
| break; |
| case BindingPackage.YLIST_BINDING__MODEL_ENDPOINT: |
| YBindingEndpoint = (YBindingEndpoint) notification.getNewValue(); |
| |
| editPart = (IBindableListEndpointEditpart) getEditpart(viewContext, YBindingEndpoint); |
| internalSetModelValue(editPart); |
| |
| shouldRebind = true; |
| break; |
| default: |
| break; |
| } |
| |
| if (shouldRebind) { |
| unbind(); |
| bind(); |
| } |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see |
| * org.eclipse.osbp.ecview.core.common.editpart.binding.IBindingEditpart |
| * #setTargetEndpoint(org.eclipse.osbp.ecview.core.common.editpart.binding. |
| * IBindableEndpointEditpart) |
| */ |
| public void setTargetEndpoint(IBindableListEndpointEditpart target) { |
| try { |
| checkDisposed(); |
| |
| // set the element by using the model |
| // |
| YListBinding yBinding = getModel(); |
| YListBindingEndpoint yElement = target != null ? (YListBindingEndpoint) target.getModel() : null; |
| yBinding.setTargetEndpoint(yElement); |
| // BEGIN SUPRESS CATCH EXCEPTION |
| } catch (RuntimeException e) { |
| // END SUPRESS CATCH EXCEPTION |
| LOGGER.error("{}", e); |
| throw e; |
| } |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see |
| * org.eclipse.osbp.ecview.core.common.editpart.binding.IBindingEditpart |
| * #getTargetEndpoint() |
| */ |
| public IBindableListEndpointEditpart getTargetEndpoint() { |
| checkDisposed(); |
| |
| if (targetValue == null) { |
| loadTargetValue(); |
| } |
| return targetValue; |
| } |
| |
| /** |
| * Loads the content of the view. |
| */ |
| protected void loadTargetValue() { |
| if (targetValue == null) { |
| YBindingEndpoint yValue = getModel().getTargetEndpoint(); |
| internalSetTargetValue((IBindableListEndpointEditpart) getEditpart(viewContext, yValue)); |
| } |
| } |
| |
| /** |
| * May be invoked by a model change and the content of the edit part should |
| * be set. |
| * |
| * @param targetValue |
| * The content to be set |
| */ |
| protected void internalSetTargetValue(IBindableListEndpointEditpart targetValue) { |
| if (this.targetValue != null) { |
| YBindingEndpoint newEP = (YBindingEndpoint) this.targetValue.getModel(); |
| newEP.eAdapters().remove(adapter); |
| } |
| |
| this.targetValue = targetValue; |
| |
| if (this.targetValue != null) { |
| YBindingEndpoint newEP = (YBindingEndpoint) this.targetValue.getModel(); |
| newEP.eAdapters().add(adapter); |
| } |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see |
| * org.eclipse.osbp.ecview.core.common.editpart.binding.IBindingEditpart |
| * #setModelEndpoint(org.eclipse.osbp.ecview.core.common.editpart.binding. |
| * IBindableEndpointEditpart) |
| */ |
| public void setModelEndpoint(IBindableListEndpointEditpart model) { |
| try { |
| checkDisposed(); |
| |
| // set the element by using the model |
| // |
| YListBinding yBinding = getModel(); |
| YListBindingEndpoint yElement = model != null ? (YListBindingEndpoint) model.getModel() : null; |
| yBinding.setModelEndpoint(yElement); |
| // BEGIN SUPRESS CATCH EXCEPTION |
| } catch (RuntimeException e) { |
| // END SUPRESS CATCH EXCEPTION |
| LOGGER.error("{}", e); |
| throw e; |
| } |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see |
| * org.eclipse.osbp.ecview.core.common.editpart.binding.IBindingEditpart |
| * #getModelEndpoint() |
| */ |
| public IBindableListEndpointEditpart getModelEndpoint() { |
| checkDisposed(); |
| |
| if (modelValue == null) { |
| loadModelValue(); |
| } |
| return modelValue; |
| } |
| |
| /** |
| * Loads the content of the view. |
| */ |
| protected void loadModelValue() { |
| if (modelValue == null) { |
| YBindingEndpoint yValue = getModel().getModelEndpoint(); |
| internalSetModelValue((IBindableListEndpointEditpart) getEditpart(viewContext, yValue)); |
| } |
| } |
| |
| /** |
| * May be invoked by a model change and the content of the edit part should |
| * be set. |
| * |
| * @param modelValue |
| * The content to be set |
| */ |
| protected void internalSetModelValue(IBindableListEndpointEditpart modelValue) { |
| this.modelValue = modelValue; |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see |
| * org.eclipse.osbp.ecview.core.common.editpart.binding.IBindingEditpart |
| * #isBound() |
| */ |
| @Override |
| public boolean isBound() { |
| checkDisposed(); |
| |
| return bound; |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see |
| * org.eclipse.osbp.ecview.core.common.editpart.binding.IBindingEditpart |
| * #bind() |
| */ |
| @Override |
| public void bind() { |
| checkDisposed(); |
| |
| if (bound) { |
| return; |
| } |
| |
| try { |
| isBinding = true; |
| IECViewBindingManager bindingManager = null; |
| if (getBindindSet() != null) { |
| bindingManager = getBindindSet().getBindingManager(); |
| } else { |
| bindingManager = getViewContext(getModel()).getService(IECViewBindingManager.class.getName()); |
| } |
| if (bindingManager != null) { |
| if (getTargetEndpoint() == null || getModelEndpoint() == null) { |
| LOGGER.warn("Endpoints are null"); |
| return; |
| } |
| |
| IObservableList target = getTargetEndpoint().getObservable(); |
| YBindingEndpoint targetEP = (YBindingEndpoint) getTargetEndpoint().getModel(); |
| if (!targetEP.isActive()) { |
| target.dispose(); |
| return; |
| } |
| IObservableList model = getModelEndpoint().getObservable(); |
| |
| if (target == null) { |
| LOGGER.error("TargetValue must never be null! {}", getTargetEndpoint()); |
| return; |
| } |
| |
| if (model == null) { |
| LOGGER.error("ModelValue must never be null! {}", getModelEndpoint()); |
| return; |
| } |
| |
| ECViewUpdateListStrategy modelToTargetStrategy = getValueUpdateStrategy( |
| getModel().getModelToTargetStrategy()); |
| ECViewUpdateListStrategy targetToModelStrategy = getValueUpdateStrategy( |
| getModel().getTargetToModelStrategy()); |
| binding = bindingManager.bindList(target, model, targetToModelStrategy, modelToTargetStrategy); |
| binding.updateModelToTarget(); |
| |
| // set bound to true if everything went fine |
| bound = true; |
| |
| } else { |
| LOGGER.error("BindingManager is null!. No bindings processed!"); |
| } |
| } finally { |
| isBinding = false; |
| } |
| } |
| |
| /** |
| * Gets the value update strategy. |
| * |
| * @param strategy |
| * the strategy |
| * @return the value update strategy |
| */ |
| private ECViewUpdateListStrategy getValueUpdateStrategy(YBindingUpdateStrategy strategy) { |
| ECViewUpdateListStrategy result = null; |
| switch (strategy) { |
| case UPDATE: |
| result = new ECViewUpdateListStrategy(ECViewUpdateListStrategy.POLICY_UPDATE); |
| break; |
| case NEVER: |
| result = new ECViewUpdateListStrategy(ECViewUpdateListStrategy.POLICY_NEVER); |
| break; |
| case ON_REQUEST: |
| result = new ECViewUpdateListStrategy(ECViewUpdateListStrategy.POLICY_ON_REQUEST); |
| break; |
| default: |
| result = new ECViewUpdateListStrategy(ECViewUpdateListStrategy.POLICY_UPDATE); |
| } |
| return result; |
| } |
| |
| /** |
| * Returns the binding set this binding belongs to. |
| * |
| * @return the bindind set |
| */ |
| protected IBindingSetEditpart getBindindSet() { |
| if (getModel().getBindingSet() == null) { |
| return null; |
| } |
| return DelegatingEditPartManager.getInstance().findEditpart(getModel().getBindingSet()); |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see |
| * org.eclipse.osbp.ecview.core.common.editpart.binding.IBindingEditpart |
| * #unbind() |
| */ |
| @Override |
| public void unbind() { |
| |
| if(!isDisposed()) { |
| checkDisposed(); |
| } else { |
| LOGGER.warn("{}", "Why is this list binding already disposed? Seems to be related to StrategyLayout"); |
| return; |
| } |
| |
| if (!bound) { |
| return; |
| } |
| |
| try { |
| if (binding != null) { |
| if (binding.getModel() != null) |
| binding.getModel().dispose(); |
| if (binding.getTarget() != null) |
| binding.getTarget().dispose(); |
| binding.dispose(); |
| binding = null; |
| } |
| } finally { |
| bound = false; |
| } |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see org.eclipse.osbp.ecview.core.common.editpart.emf.ElementEditpart# |
| * internalDispose() |
| */ |
| @Override |
| protected void internalDispose() { |
| try { |
| if (binding != null) { |
| binding.dispose(); |
| binding = null; |
| } |
| if (modelValue != null) { |
| modelValue.dispose(); |
| modelValue = null; |
| } |
| if (targetValue != null) { |
| targetValue.dispose(); |
| targetValue = null; |
| } |
| } finally { |
| super.internalDispose(); |
| } |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see |
| * org.eclipse.osbp.ecview.core.common.editpart.binding.IBindingEditpart |
| * #getBinding() |
| */ |
| @Override |
| public Binding getBinding() { |
| return binding; |
| } |
| |
| class ActiveAdapter extends AdapterImpl { |
| @Override |
| public void notifyChanged(Notification notification) { |
| if (notification.getFeature() == BindingPackage.Literals.YBINDING_ENDPOINT__ACTIVE) { |
| if (isBinding) |
| return; |
| boolean active = notification.getNewBooleanValue(); |
| if (active) { |
| bind(); |
| } else { |
| unbind(); |
| } |
| } |
| } |
| } |
| } |