| /** |
| * |
| * 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.common; |
| |
| import java.util.HashMap; |
| import java.util.Map; |
| |
| import org.eclipse.osbp.ecview.core.common.context.ContextException; |
| import org.eclipse.osbp.ecview.core.common.context.IViewContext; |
| import org.eclipse.osbp.ecview.core.common.extender.IECViewProviderService; |
| import org.eclipse.osbp.ecview.core.common.model.core.YView; |
| import org.eclipse.osbp.runtime.web.ecview.presentation.vaadin.VaadinRenderer; |
| import org.osgi.framework.BundleContext; |
| import org.osgi.framework.FrameworkUtil; |
| import org.osgi.framework.ServiceReference; |
| import org.slf4j.Logger; |
| import org.slf4j.LoggerFactory; |
| |
| import com.vaadin.ui.CustomComponent; |
| import com.vaadin.ui.Notification; |
| import com.vaadin.ui.Notification.Type; |
| import com.vaadin.ui.VerticalLayout; |
| |
| /** |
| * This component shows an rendered ECView component for the given DTO instance. |
| * <p> |
| * Attention: This component needs to be {@link #dispose() disposed} if not used |
| * anymore. |
| */ |
| @SuppressWarnings("serial") |
| public class ECViewComponent extends CustomComponent { |
| |
| /** The Constant LOGGER. */ |
| private static final Logger LOGGER = LoggerFactory |
| .getLogger(ECViewComponent.class); |
| |
| /** |
| * Use this property to pass the beanSlot that should be used for the dto. |
| * See properties map in {@link #render(Object, Map)} |
| */ |
| public static final String PROP_SLOT = "beanSlot"; |
| |
| /** The cache. */ |
| private Map<String, IViewContext> cache = new HashMap<>(); |
| |
| /** The layout. */ |
| private VerticalLayout layout; |
| |
| /** The current view context. */ |
| private IViewContext currentViewContext; |
| |
| /** The callback. */ |
| private ViewProviderCallback callback; |
| |
| /** |
| * Instantiates a new EC view component. |
| */ |
| public ECViewComponent() { |
| this(null); |
| } |
| |
| /** |
| * Instantiates a new EC view component. |
| * |
| * @param callback |
| * the callback |
| */ |
| public ECViewComponent(ViewProviderCallback callback) { |
| this.callback = callback; |
| |
| setSizeFull(); |
| |
| layout = new VerticalLayout(); |
| layout.setSizeFull(); |
| setCompositionRoot(layout); |
| |
| } |
| |
| /** |
| * Will render and show a bound view instance for the given dto. |
| * |
| * @param viewId |
| * the id of the view |
| * @param dto |
| * the dto instance to be displayed |
| * @param properties |
| * render properties |
| * @return the rendered view context or <code>null</code>. |
| */ |
| public IViewContext setValue(String viewId, Object dto, |
| Map<String, Object> properties) { |
| // if the type of dto did not change, we only need to set the new dto |
| // instance |
| String currentId = null; |
| if (currentViewContext != null) { |
| currentId = currentViewContext.getViewEditpart().getName(); |
| } |
| |
| if (viewId.equals(currentId)) { |
| currentViewContext.setBean(getBeanSlotName(properties), dto); |
| } else { |
| // remove all components |
| layout.removeAllComponents(); |
| |
| // determine the resulting ui content |
| IViewContext context = cache.get(viewId); |
| if (context == null) { |
| context = createNewContext(viewId, properties); |
| } |
| |
| if (context != null) { |
| if (!context.isRendered()) { |
| try { |
| new VaadinRenderer() |
| .render(context, layout, properties); |
| } catch (ContextException e) { |
| LOGGER.error("{}", e); |
| Notification.show( |
| viewId + " caused " + e.getLocalizedMessage() |
| + "!", Type.ERROR_MESSAGE); |
| } |
| } |
| |
| // set data to the view |
| if (dto != null) { |
| context.setBean(getBeanSlotName(properties), dto); |
| } |
| } |
| currentViewContext = context; |
| } |
| return currentViewContext; |
| } |
| |
| /** |
| * Gets the bean slot name. |
| * |
| * @param properties |
| * the properties |
| * @return the bean slot name |
| */ |
| protected String getBeanSlotName(Map<String, Object> properties) { |
| return (String) properties.get(PROP_SLOT); |
| } |
| |
| /** |
| * Creates a new context for the given dto using the properties. |
| * |
| * @param viewId |
| * the view id |
| * @param properties |
| * the properties |
| * @return the i view context |
| */ |
| protected IViewContext createNewContext(String viewId, |
| Map<String, Object> properties) { |
| |
| IViewContext context = null; |
| BundleContext bc = FrameworkUtil.getBundle(getClass()) |
| .getBundleContext(); |
| ServiceReference<IECViewProviderService> ref = bc |
| .getServiceReference(IECViewProviderService.class); |
| if (ref != null) { |
| IECViewProviderService service = bc.getService(ref); |
| |
| YView yView = null; |
| // check whether the owner wants to contribute a view model |
| if (callback != null) { |
| yView = callback.getView(viewId, properties); |
| } |
| |
| if (yView != null) { |
| // create a context for the provided view model |
| context = service.getViewContext(yView); |
| } else { |
| // else check the service for a proper view model |
| context = service.getViewContext(viewId); |
| } |
| if (context != null) { |
| cache.put(viewId, context); |
| } |
| |
| bc.ungetService(ref); |
| } else { |
| LOGGER.error("No view available for " + viewId); |
| } |
| |
| return context; |
| } |
| |
| /** |
| * Disposes the component. |
| */ |
| public void dispose() { |
| cache.values().forEach(it -> { |
| try { |
| it.dispose(); |
| } catch (Exception e) { |
| LOGGER.error("{}", e); |
| } |
| }); |
| cache.clear(); |
| cache = null; |
| |
| layout = null; |
| currentViewContext = null; |
| } |
| |
| /** |
| * A callback class to allow owners of this class to create context specifix |
| * views. |
| */ |
| public interface ViewProviderCallback { |
| |
| /** |
| * Returns a custom view for the given id and properties. Or |
| * <code>null</code> if a default view should be used. |
| * |
| * @param viewId |
| * the view id |
| * @param properties |
| * the properties |
| * @return the view |
| */ |
| YView getView(String viewId, Map<String, Object> properties); |
| } |
| } |