blob: b1c33560e955707ec540ee9035248ad40c61dc0c [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.ecview.core.common.editpart.emf;
import java.util.ArrayList;
import java.util.List;
import org.eclipse.emf.common.notify.Notification;
import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.osbp.ecview.core.common.context.IViewContext;
import org.eclipse.osbp.ecview.core.common.editpart.IEmbeddableEditpart;
import org.eclipse.osbp.ecview.core.common.editpart.IEmbeddableParent;
import org.eclipse.osbp.ecview.core.common.editpart.IViewEditpart;
import org.eclipse.osbp.ecview.core.common.editpart.datatypes.IDatatypeEditpart;
import org.eclipse.osbp.ecview.core.common.editpart.datatypes.IDatatypeEditpart.DatatypeBridge;
import org.eclipse.osbp.ecview.core.common.editpart.datatypes.IDatatypeEditpart.DatatypeChangeEvent;
import org.eclipse.osbp.ecview.core.common.editpart.validation.IValidatorEditpart;
import org.eclipse.osbp.ecview.core.common.editpart.visibility.IUiElementAccess;
import org.eclipse.osbp.ecview.core.common.memento.IECViewMementoManager;
import org.eclipse.osbp.ecview.core.common.model.core.YEmbeddable;
import org.eclipse.osbp.ecview.core.common.model.core.YLayout;
import org.eclipse.osbp.ecview.core.common.model.core.YMemento;
import org.eclipse.osbp.ecview.core.common.model.core.YView;
import org.eclipse.osbp.ecview.core.common.model.datatypes.YDatatype;
import org.eclipse.osbp.ecview.core.common.presentation.DelegatingPresenterFactory;
import org.eclipse.osbp.ecview.core.common.presentation.IWidgetPresentation;
import org.eclipse.osbp.ecview.core.common.visibility.IVisibilityHandler;
import org.eclipse.osbp.runtime.common.memento.IMementoHandler;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
// TODO: Auto-generated Javadoc
/**
* See {@link ElementEditpart}.
*
* @param <M>
* the generic type
*/
public abstract class EmbeddableEditpart<M extends YEmbeddable> extends
ElementEditpart<M> implements IEmbeddableEditpart, DatatypeBridge,
IUiElementAccess {
/** The Constant LOGGER. */
private static final Logger LOGGER = LoggerFactory
.getLogger(EmbeddableEditpart.class);
/** The presentation. */
private IWidgetPresentation<?> presentation;
/** The datatype feature. */
private EStructuralFeature datatypeFeature;
/**
* The default constructor.
*/
protected EmbeddableEditpart() {
}
/**
* A constructor that becomes passed the datatype feature.
*
* @param datatypeFeature
* the datatype feature
*/
public EmbeddableEditpart(EStructuralFeature datatypeFeature) {
this.datatypeFeature = datatypeFeature;
}
/**
* {@inheritDoc}
*/
@Override
public IEmbeddableParent getParent() {
YLayout yParentLayout = getModel().getParent();
if (yParentLayout != null) {
return getEditpart(viewContext, yParentLayout);
} else {
YView yView = getModel().getView();
if (yView != null && yView.getContent() == getModel()) {
return (IViewEditpart) getEditpart(viewContext, yView);
}
}
return null;
}
/* (non-Javadoc)
* @see org.eclipse.osbp.ecview.core.common.editpart.IEmbeddableEditpart#getView()
*/
@Override
public IViewEditpart getView() {
return viewContext.getViewEditpart();
}
/**
* Returns the instance of the presentation, but does not load it.
*
* @param <A>
* An instance of {@link IWidgetPresentation}
* @return presentation
*/
@SuppressWarnings("unchecked")
protected <A extends IWidgetPresentation<?>> A internalGetPresentation() {
return (A) presentation;
}
/* (non-Javadoc)
* @see org.eclipse.osbp.ecview.core.common.editpart.IEmbeddableEditpart#getPresentation()
*/
@SuppressWarnings("unchecked")
@Override
public <A extends IWidgetPresentation<?>> A getPresentation() {
if (presentation == null) {
presentation = createPresenter();
doInitPresentation(presentation);
}
return (A) presentation;
}
/**
* A hook method to initialize the presentation after creation.
*
* @param presentation
* the presentation
*/
protected void doInitPresentation(IWidgetPresentation<?> presentation) {
}
/* (non-Javadoc)
* @see org.eclipse.osbp.ecview.core.common.editpart.visibility.IVisibilityProcessable#apply(org.eclipse.osbp.ecview.core.common.visibility.IVisibilityHandler)
*/
@Override
public void apply(IVisibilityHandler handler) {
IWidgetPresentation<?> presentation = getPresentation();
if (presentation != null) {
presentation.apply(handler);
}
}
/* (non-Javadoc)
* @see org.eclipse.osbp.ecview.core.common.editpart.visibility.IVisibilityProcessable#resetVisibilityProperties()
*/
@Override
public void resetVisibilityProperties() {
IWidgetPresentation<?> presentation = getPresentation();
if (presentation != null) {
presentation.resetVisibilityProperties();
}
}
/* (non-Javadoc)
* @see org.eclipse.osbp.ecview.core.common.editpart.IEmbeddableEditpart#restoreMemento()
*/
@Override
public void restoreMemento() {
if (isRendered()) {
if (!(getPresentation() instanceof IMementoHandler)) {
throw new UnsupportedOperationException(
"Memento not supported by element.");
}
YMemento yMemento = loadMemento(getModel().getMementoId());
if (yMemento != null) {
((IMementoHandler) getPresentation()).applyMemento(yMemento);
} else {
LOGGER.debug("Memento is null. No apply to presentation. mementoId: "
+ getModel().getMementoId());
}
}
}
/* (non-Javadoc)
* @see org.eclipse.osbp.ecview.core.common.editpart.IEmbeddableEditpart#saveMemento(java.lang.Object)
*/
@Override
public void saveMemento(Object memento) {
if (isRendered()) {
if (!(getPresentation() instanceof IMementoHandler)) {
throw new UnsupportedOperationException(
"Memento not supported by element.");
}
YMemento yMemento = (YMemento) memento;
if (yMemento != null) {
IECViewMementoManager manager = getView().getContext()
.getService(IECViewMementoManager.class.getName());
if (manager != null) {
manager.saveMemento(yMemento.getId(), yMemento);
} else {
LOGGER.warn("IMementoManager is not available.");
}
} else {
LOGGER.warn("Memento is null. No save done. mementoId: "
+ memento);
}
}
}
/**
* Load memento.
*
* @param mementoId
* the memento id
* @return the y memento
*/
protected YMemento loadMemento(String mementoId) {
IECViewMementoManager manager = getView().getContext().getService(
IECViewMementoManager.class.getName());
if (manager == null) {
LOGGER.error("IMementoManager is not available.");
return null;
}
return (YMemento) manager.loadMemento(mementoId);
}
/**
* Returns the datatype of the model. Or <code>null</code> if no datatype is
* available.
*
* @return the y datatype
*/
protected YDatatype internalGetDatatype() {
if (datatypeFeature == null) {
return null;
}
return (YDatatype) getModel().eGet(datatypeFeature);
}
/**
* Is called to created the presenter for this edit part.
*
* @param <A>
* the generic type
* @return the a
*/
protected <A extends IWidgetPresentation<?>> A createPresenter() {
IViewEditpart viewEditPart = getView();
if (viewEditPart == null) {
LOGGER.info("View is null");
return null;
}
return DelegatingPresenterFactory.getInstance().createPresentation(
viewEditPart.getContext(), this);
}
/* (non-Javadoc)
* @see org.eclipse.osbp.ecview.core.common.editpart.emf.ElementEditpart#initialize(org.eclipse.osbp.ecview.core.common.model.core.YElement)
*/
@Override
public void initialize(IViewContext context, M model) {
super.initialize(context, model);
// directly after initialization the embeddable needs to become
// registered at the datatype editpart. No lazy loading can be used
// here.
registerAtDatatype();
}
/* (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();
if (notification.getFeature() == datatypeFeature) {
YDatatype oldYDatatype = (YDatatype) notification.getOldValue();
if (oldYDatatype != null) {
// unregister the element from the old datatype
unregisterFromDatatype(oldYDatatype);
}
// an register the field to the new datatype if available
YDatatype newYDatatype = (YDatatype) notification.getNewValue();
if (newYDatatype != null) {
registerAtDatatype();
}
} else {
super.handleModelSet(featureId, notification);
}
}
/**
* Registers the element at the datatype. Changes on the datatype will
* update the embeddable.
*/
protected void registerAtDatatype() {
// unregisters the datatype editpart
YDatatype yDatatype = internalGetDatatype();
if (yDatatype != null) {
IDatatypeEditpart datatypeEditpart = getEditpart(viewContext, yDatatype);
datatypeEditpart.addBridge(this);
notifyDatatypeChanged(datatypeEditpart.getCurrentState());
}
}
/**
* Unregisters the element from the datatype. So changes on the datatype do
* not update the embeddable anymore.
*
* @param yDatatype
* the y datatype
*/
protected void unregisterFromDatatype(YDatatype yDatatype) {
// unregisters the datatype editpart
if (yDatatype != null) {
IDatatypeEditpart datatypeEditpart = getEditpart(viewContext, yDatatype);
datatypeEditpart.removeBridge(this);
notifyDatatypeChanged(createDatatypeUnsetEvent(datatypeEditpart));
}
}
/**
* Create an internal event that resets the datatype information.
*
* @param datatypeEditpart
* the datatype editpart
* @return the datatype change event
*/
private DatatypeChangeEvent createDatatypeUnsetEvent(
IDatatypeEditpart datatypeEditpart) {
List<IValidatorEditpart> toRemove = new ArrayList<>(
getDatatypeValidators());
DatatypeChangeEvent event = new DatatypeChangeEvent(true,
datatypeEditpart, null, null, toRemove);
return event;
}
/* (non-Javadoc)
* @see org.eclipse.osbp.ecview.core.common.editpart.datatypes.IDatatypeEditpart.DatatypeBridge#notifyDatatypeChanged(org.eclipse.osbp.ecview.core.common.editpart.datatypes.IDatatypeEditpart.DatatypeChangeEvent)
*/
@Override
public void notifyDatatypeChanged(DatatypeChangeEvent event) {
IWidgetPresentation<?> presentation = getPresentation();
if (presentation != null) {
presentation.notifyDatatypeChanged(event);
} else {
LOGGER.warn("Presentation is null for " + getModel());
}
}
/**
* {@inheritDoc}
*/
@Override
protected void internalDispose() {
try {
// unregister the element from the datatype
YDatatype yDatatype = internalGetDatatype();
if (yDatatype != null) {
unregisterFromDatatype(yDatatype);
}
// dispose the presenter
//
if (presentation != null) {
presentation.dispose();
presentation = null;
}
} finally {
super.internalDispose();
}
}
/* (non-Javadoc)
* @see org.eclipse.osbp.ecview.core.common.editpart.IEmbeddableEditpart#requestRender()
*/
@Override
public void requestRender() {
if (getParent() != null) {
getParent().renderChild(this);
} else {
unrender();
}
}
/* (non-Javadoc)
* @see org.eclipse.osbp.ecview.core.common.editpart.IEmbeddableEditpart#render(java.lang.Object)
*/
@Override
public Object render(Object parentWidget) {
if (getPresentation() == null) {
throw new IllegalStateException("No presentation for " + getModel());
}
return getPresentation().createWidget(parentWidget);
}
/* (non-Javadoc)
* @see org.eclipse.osbp.ecview.core.common.editpart.IEmbeddableEditpart#requestUnrender()
*/
@Override
public void requestUnrender() {
if (getParent() != null) {
getParent().unrenderChild(this);
} else {
unrender();
}
}
/* (non-Javadoc)
* @see org.eclipse.osbp.ecview.core.common.editpart.IEmbeddableEditpart#unrender()
*/
@Override
public void unrender() {
IWidgetPresentation<?> presentation = getPresentation();
if (presentation != null) {
presentation.unrender();
}
}
/* (non-Javadoc)
* @see org.eclipse.osbp.ecview.core.common.editpart.IEmbeddableEditpart#isRendered()
*/
@Override
public boolean isRendered() {
return internalGetPresentation() != null
&& internalGetPresentation().isRendered();
}
/* (non-Javadoc)
* @see org.eclipse.osbp.ecview.core.common.editpart.IEmbeddableEditpart#getWidget()
*/
@Override
public Object getWidget() {
IWidgetPresentation<?> presentation = getPresentation();
if (presentation != null) {
return presentation.getWidget();
}
return null;
}
/* (non-Javadoc)
* @see org.eclipse.osbp.ecview.core.common.editpart.emf.ElementEditpart#requestDispose()
*/
@Override
public void requestDispose() {
if (getParent() != null) {
getParent().disposeChild(this);
} else {
// in case where the embeddable is not added to a layout
dispose();
}
}
}