| /** |
| * |
| * 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: |
| * Christophe Loetz (Loetz GmbH&Co.KG) - initial implementation |
| */ |
| package org.eclipse.osbp.osgi.hybrid.api; |
| |
| import java.util.Collection; |
| import java.util.List; |
| import java.util.Map; |
| import java.util.Set; |
| |
| import javax.annotation.PostConstruct; |
| import javax.annotation.PreDestroy; |
| import javax.inject.Inject; |
| |
| import org.eclipse.e4.core.contexts.IEclipseContext; |
| import org.eclipse.e4.core.services.events.IEventBroker; |
| import org.eclipse.e4.ui.model.application.MApplication; |
| import org.eclipse.e4.ui.model.application.ui.MUIElement; |
| import org.eclipse.e4.ui.model.application.ui.advanced.MPerspective; |
| import org.eclipse.e4.ui.model.application.ui.basic.MPart; |
| import org.eclipse.e4.ui.workbench.modeling.EPartService; |
| import org.eclipse.e4.ui.workbench.modeling.IPartListener; |
| import org.eclipse.osbp.bpm.api.IBlipBPMConstants; |
| import org.eclipse.osbp.core.api.persistence.IPersistenceService; |
| import org.eclipse.osbp.dsl.common.datatypes.IDto; |
| import org.eclipse.osbp.runtime.web.vaadin.databinding.VaadinObservables; |
| import org.eclipse.osbp.ui.api.themes.IThemeResourceService; |
| import org.eclipse.osbp.ui.api.themes.IThemeResourceService.ThemeResourceType; |
| import org.eclipse.osbp.ui.api.useraccess.AbstractAuthorization; |
| import org.eclipse.osbp.ui.api.useraccess.AbstractPosition; |
| import org.eclipse.osbp.webserver.messagequeue.ECXMqMessageAttribute; |
| import org.eclipse.osbp.webserver.messagequeue.ECXMqMessageEvent; |
| import org.slf4j.Logger; |
| import org.slf4j.LoggerFactory; |
| |
| import com.vaadin.server.VaadinRequest; |
| import com.vaadin.ui.AbstractOrderedLayout; |
| import com.vaadin.ui.FormLayout; |
| import com.vaadin.ui.Label; |
| import com.vaadin.ui.UI; |
| import com.vaadin.ui.VerticalLayout; |
| |
| public abstract class AbstractHybridVaaclipseView implements IHybridVaadinVaaclipseListener, IPartListener { |
| |
| @Inject |
| IEventBroker eventBroker; |
| |
| @Inject |
| protected IPersistenceService persistenceService; |
| |
| private static final Logger LOGGER = LoggerFactory.getLogger(AbstractHybridVaaclipseView.class); |
| |
| public enum RenderMode { |
| SYNCHRONOUSLY, ASYNCHRONOUSLY |
| } |
| |
| private IEclipseContext fEclipseContext; |
| private MApplication fE4App; |
| private VerticalLayout fParent; |
| private boolean fViewInitialized; |
| |
| private RenderMode renderMode = RenderMode.SYNCHRONOUSLY; |
| private boolean firstTime = true; |
| private int pollingInterval = 2000; |
| |
| private RecursiveFocusBlurListener fRecursiveFocusBlurListener; |
| |
| public AbstractHybridVaaclipseView() {} |
| /** |
| * <b><i><u>Warning:</u> never use initializing class attributes in the definition!<br> |
| * Due to Java specific internals the overriden method createView() will be called before that initializing will be done!<br> |
| * Instead put any initializing inside the overriden method createView()!</i></b> |
| * |
| * @param parent |
| * @param context |
| * @param app |
| */ |
| public AbstractHybridVaaclipseView(final VerticalLayout parent, final IEclipseContext context, final MApplication app) { |
| fE4App = app; |
| fEclipseContext = context; |
| fViewInitialized = false; |
| fParent = parent; |
| fRecursiveFocusBlurListener = RecursiveFocusBlurListener.attachFor(fParent); |
| } |
| |
| @PostConstruct |
| public void initView() { |
| preInit(); |
| VaadinObservables.getRealm(UI.getCurrent()); |
| UI.getCurrent().setPollInterval(pollingInterval); |
| createView(fParent); |
| postInit(null); |
| renderData(true); |
| } |
| |
| public void promptSecurityMessage(String message, AbstractOrderedLayout layout) { |
| layout.removeAllComponents(); |
| FormLayout area = new FormLayout(); |
| layout.addComponent(area); |
| |
| Label msg = new Label(message); |
| msg.setPrimaryStyleName("osbp"); |
| msg.setStyleName("osbpSecurityPrompt"); |
| if (getThemeResourceService() != null) { |
| msg.setIcon(getThemeResourceService().getThemeResource("locksview.gif", ThemeResourceType.IMAGE)); |
| } |
| else { |
| LOGGER.error("themeResourceService not set!"); |
| } |
| area.addComponent(msg); |
| } |
| |
| public final MApplication getApplication() { |
| return fE4App; |
| } |
| |
| public final VerticalLayout getParent() { |
| return fParent; |
| } |
| |
| public final IEclipseContext getContext() { |
| return fEclipseContext; |
| } |
| |
| public final MPart getPart() { |
| return fEclipseContext.get(MPart.class); |
| } |
| |
| public final String getProcessWorkloadDtoFqn() { |
| return (String) getTransientDataVariable(IBlipBPMConstants.VARIABLE_PROCESS_WORKLOAD_DTO_FQN); |
| } |
| |
| public final IDto getProcessInitialWorkloadDto() { |
| return (IDto) getTransientDataVariable(IBlipBPMConstants.VARIABLE_PROCESS_WORKLOAD_DTO); |
| } |
| |
| public final Class<?> getTaskOperativeDtoClass() { |
| return (Class<?>) getTransientDataVariable(IBlipBPMConstants.VARIABLE_TASK_OPERATIVE_DTO_CLASS); |
| } |
| |
| public final String getTaskOperativeDtoFqn() { |
| return (String) getTransientDataVariable(IBlipBPMConstants.VARIABLE_TASK_OPERATIVE_DTO_FQN); |
| } |
| |
| @SuppressWarnings("unchecked") |
| public final List<IDto> getTaskInitialOperativeDtos() { |
| return (List<IDto>) getTransientDataVariable(IBlipBPMConstants.VARIABLE_TASK_OPERATIVE_DTOS); |
| } |
| |
| public final Object getTransientDataVariable(String variable) { |
| MPerspective perspective = getPerspective(); |
| if (perspective != null) { |
| Map<String, Object> data = perspective.getTransientData(); |
| if (data != null) { |
| return data.get(variable); |
| } |
| } |
| return null; |
| } |
| |
| public final MPerspective getPerspective() { |
| MUIElement step = getPart(); |
| while ((step != null) && !(step instanceof MPerspective)) { |
| step = step.getParent(); |
| } |
| return (MPerspective) step; |
| } |
| |
| public final IPersistenceService getPersistenceService() { |
| return fEclipseContext.get(IPersistenceService.class); |
| } |
| |
| protected final boolean isViewInitialized() { |
| return fViewInitialized; |
| } |
| |
| /** |
| * <b><i><u>Warning:</u> put any initializing inside the your overriden method createView()!<br> |
| * Due to Java specific internals the overriden method createView() will be called before that initializing will be done!</i></b> |
| * |
| * @param parent |
| */ |
| protected abstract void createView(final VerticalLayout parent); |
| |
| protected abstract void createComponents(); |
| |
| // renderData is used for components that are not fully embedded in vaadin's connector structure |
| // and must be repainted when parent window resizes |
| // but can also be used to make component rendering asynchronously from view creation |
| public void renderData() { |
| LOGGER.debug("renderData not firsttime"); |
| renderData(false); |
| } |
| |
| public void renderData(boolean firstTime) { |
| // the first time we only want to be triggered by the initial createView process, not by changeLocale |
| if (this.firstTime) { |
| if (!firstTime) { |
| LOGGER.debug("renderData ignored because not firsttime"); |
| return; |
| } else { |
| this.firstTime = false; |
| } |
| } |
| if (UI.getCurrent() == null) { |
| LOGGER.debug("renderData has no current ui"); |
| return; |
| } |
| if (renderMode == RenderMode.SYNCHRONOUSLY) { |
| LOGGER.debug("render synchronously"); |
| UI.getCurrent().accessSynchronously(new Runnable() { |
| @Override |
| public void run() { |
| createComponents(); |
| } |
| }); |
| } else { |
| LOGGER.debug("render asynchronously"); |
| UI.getCurrent().access(new Runnable() { |
| @Override |
| public void run() { |
| createComponents(); |
| } |
| }); |
| } |
| } |
| |
| public IThemeResourceService getThemeResourceService() { |
| if (fEclipseContext.containsKey(IThemeResourceService.class)) { |
| return fEclipseContext.get(IThemeResourceService.class); |
| } |
| return null; |
| } |
| |
| public EPartService getPartService() { |
| if (fEclipseContext.containsKey(EPartService.class)) { |
| return fEclipseContext.get(EPartService.class); |
| } |
| return null; |
| } |
| |
| protected void preInit() { |
| EPartService partService = getPartService(); |
| if(partService != null) { |
| partService.addPartListener(this); |
| HybridVaadinVaaclipseConnector.instance(fEclipseContext).addListener(this); |
| HybridVaadinVaaclipseConnector.instance(fEclipseContext).setE4Application(fE4App); |
| } |
| } |
| |
| @PreDestroy |
| public void preDestroy() { |
| fRecursiveFocusBlurListener.detach(); |
| HybridVaadinVaaclipseConnector.instance(fEclipseContext).removeListener(this); |
| } |
| |
| /** |
| * You <b>must call this at the end of the overridden init()</b> |
| */ |
| protected final void postInit(VaadinRequest request) { |
| HybridVaadinVaaclipseConnector.instance(fEclipseContext).postInit(request); |
| fViewInitialized = true; |
| if (isAuthenticated()) { |
| setAuthenticated(isAuthenticated()); |
| } |
| } |
| |
| /** |
| * React in the application according to <code>authenticated</code> |
| * |
| * @param authenticated |
| * true if the user is authenticated now! |
| */ |
| @Override |
| public void setAuthenticated(boolean authenticated) { |
| // now send the list of perspectives |
| HybridVaadinVaaclipseConnector.instance(fEclipseContext).updatePerspectiveList(); |
| } |
| |
| protected final boolean isAuthenticated() { |
| return HybridVaadinVaaclipseConnector.instance(fEclipseContext).isAuthenticated(); |
| } |
| |
| protected final IDto getAuthenticatedUser() { |
| return HybridVaadinVaaclipseConnector.instance(fEclipseContext).getUser(); |
| } |
| |
| protected final AbstractPosition getAuthenticatedPosition() { |
| return HybridVaadinVaaclipseConnector.instance(fEclipseContext).getPosition(); |
| } |
| |
| protected final Collection<String> getAuthenticatedRoles() { |
| return HybridVaadinVaaclipseConnector.instance(fEclipseContext).getRoles(); |
| } |
| |
| protected final AbstractAuthorization getAuthenticatedPermissions() { |
| return HybridVaadinVaaclipseConnector.instance(fEclipseContext).getAuthorization(); |
| } |
| |
| protected final Set<String> getAllUsers() { |
| return HybridVaadinVaaclipseConnector.instance(fEclipseContext).getAllUsers(); |
| } |
| |
| /** |
| * Try to authenticate with the credentials given!<br> |
| * {@link #setAuthenticated(boolean)} will explicit be called! |
| * |
| * @param portalId |
| * @param userName |
| * @param password |
| * @return true if the user was authenticated successful |
| */ |
| // protected boolean tryToAuthenticate(String portalId, String userName, String password) { |
| // return HybridVaadinVaaclipseConnector.instance().tryToAuthenticate(portalId, userName, password); |
| // } |
| |
| /** |
| * Logout from the Shiro API and send a LOGOUT event via ActiveMQ |
| */ |
| protected void logout() { |
| HybridVaadinVaaclipseConnector.instance(fEclipseContext).logout(); |
| } |
| |
| /** |
| * handle any message received via ActiveMQ |
| * |
| * @param event |
| * @param body |
| */ |
| @Override |
| public final boolean onMessage(ECXMqMessageEvent event, Map<ECXMqMessageAttribute, Object> body) { |
| boolean retcode = false; |
| switch (event) { |
| case FOCUS_PERSPECTIVE: |
| retcode = HybridVaadinVaaclipseConnector.instance(fEclipseContext).onFocusPerspective(body.get(ECXMqMessageAttribute.PERSPECTIVE_ID).toString()); |
| break; |
| case REQUEST_ICON: |
| retcode = HybridVaadinVaaclipseConnector.instance(fEclipseContext).requestIcon(body.get(ECXMqMessageAttribute.PERSPECTIVE_ID).toString()); |
| break; |
| case TRY_AUTHENTICATE: |
| case DISPOSE: |
| case LOGOUT: |
| default: |
| break; |
| } |
| return retcode; |
| } |
| |
| @Override |
| public void partActivated(MPart part) { |
| HybridVaadinVaaclipseConnector.instance(fEclipseContext).activatePartStateRefresher(part); |
| MPerspective active = HybridVaadinVaaclipseConnector.findCurrentPerspectiveFor(part == null ? getPartService().getActivePart() : part); |
| if (active instanceof MPerspective) { |
| HybridVaadinVaaclipseConnector.instance(fEclipseContext).updatePerspectiveList(); |
| HybridVaadinVaaclipseConnector.instance(fEclipseContext).updateFocusPerspective(active.getElementId()); |
| } else if (part != null || getPartService().getActivePart() != null) { |
| LOGGER.debug("part activated:" + (part == null ? "<null>" : part.getElementId() + " '" + part.getLabel() + "'")); |
| List<MPerspective> existing = HybridVaadinVaaclipseConnector.instance(fEclipseContext).findPerspectives(); |
| for (MPerspective perspective : existing) { |
| LOGGER.debug(" perspective:" + perspective.getElementId() + " '" + perspective.getLabel() + "'"); |
| } |
| LOGGER.debug(" COULD NOT find the corresponding perspective :-("); |
| } |
| } |
| |
| @Override |
| public void partBroughtToTop(MPart part) { |
| HybridVaadinVaaclipseConnector.instance(fEclipseContext).activatePartStateRefresher(part); |
| } |
| |
| @Override |
| public void partDeactivated(MPart part) { |
| } // NOP |
| |
| @Override |
| public void partHidden(MPart part) { |
| } // NOP |
| |
| @Override |
| public void partVisible(MPart part) { |
| } // NOP |
| |
| /** |
| * Try to authenticate with the credentials given!<br> |
| * {@link #setAuthenticated(boolean)} will explicit be called! |
| * |
| * @param portalId |
| * @param userName |
| * @param password |
| * @return true if the user was authenticated successful |
| */ |
| protected boolean tryToAuthenticate(String portalId, String userName, String password) { |
| return HybridVaadinVaaclipseConnector.instance(fEclipseContext).tryToAuthenticate(portalId, userName, password); |
| } |
| |
| public RenderMode getRenderMode() { |
| return renderMode; |
| } |
| |
| public void setRenderMode(RenderMode renderMode) { |
| this.renderMode = renderMode; |
| } |
| |
| public int getPollingInterval() { |
| return pollingInterval; |
| } |
| |
| public void setPollingInterval(int pollingInterval) { |
| this.pollingInterval = pollingInterval; |
| } |
| |
| } |