| /* |
| * |
| * 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 |
| * |
| * Initial contribution: |
| * Loetz GmbH & Co. KG |
| * |
| */ |
| package org.eclipse.osbp.abstractstatemachine; |
| |
| import java.io.IOException; |
| import java.net.InetAddress; |
| import java.net.UnknownHostException; |
| import java.nio.channels.SelectableChannel; |
| import java.util.Collection; |
| import java.util.Collections; |
| import java.util.HashMap; |
| import java.util.List; |
| import java.util.Locale; |
| import java.util.Map; |
| import java.util.Set; |
| import java.util.Timer; |
| import java.util.TimerTask; |
| import java.util.concurrent.CopyOnWriteArraySet; |
| |
| import javax.annotation.PreDestroy; |
| |
| import org.eclipse.e4.core.contexts.IEclipseContext; |
| import org.eclipse.osbp.dsl.common.datatypes.IDto; |
| import org.eclipse.osbp.runtime.common.filter.IQuery; |
| import org.eclipse.osbp.runtime.common.session.ISession; |
| import org.eclipse.osbp.ui.api.customfields.IBlobService; |
| import org.eclipse.osbp.ui.api.message.IMessageRequester; |
| import org.eclipse.osbp.ui.api.message.MessageEvent; |
| import org.eclipse.osbp.ui.api.message.MessageEvent.EventType; |
| import org.eclipse.osbp.ui.api.message.MessageRequesterEvent; |
| import org.eclipse.osbp.ui.api.metadata.IDSLMetadataService; |
| import org.eclipse.osbp.ui.api.report.IReportProvider; |
| import org.eclipse.osbp.ui.api.statemachine.IDataProvider; |
| import org.eclipse.osbp.ui.api.statemachine.IEventSource; |
| import org.eclipse.osbp.ui.api.statemachine.IPeripheral; |
| import org.eclipse.osbp.ui.api.statemachine.IStateMachine; |
| import org.eclipse.osbp.ui.api.themes.IThemeResourceService; |
| import org.eclipse.osbp.ui.api.user.IUser; |
| import org.eclipse.osbp.utils.vaadin.MessageDialog; |
| import org.eclipse.osbp.utils.vaadin.YesNoDialog; |
| import org.joda.time.DateTime; |
| import org.joda.time.DateTimeZone; |
| import org.slf4j.Logger; |
| |
| import com.vaadin.server.Page; |
| import com.vaadin.server.WebBrowser; |
| import com.vaadin.ui.UI; |
| |
| public abstract class AbstractStateMachine implements IStateMachine, IMessageRequester.ClickRecipient { |
| private static final String ENABLED = "Enabled"; |
| private static Logger logger = org.slf4j.LoggerFactory.getLogger("statemachine"); |
| protected Collection<IEventSource.Enabler> enablerList = new CopyOnWriteArraySet<>(); |
| protected Collection<IDataProvider.Provider> providerList = new CopyOnWriteArraySet<>(); |
| protected Collection<IPeripheral.Command> peripheralList = new CopyOnWriteArraySet<>(); |
| protected Map<String, MessageDialog> messageDialogs = new HashMap<>(); |
| protected Map<String, YesNoDialog> yesnoDialogs = new HashMap<>(); |
| protected WebBrowser webBrowser = Page.getCurrent().getWebBrowser(); |
| protected Timer timer; |
| protected IUser user; |
| protected Locale locale; |
| protected IDSLMetadataService dslMetadataService; |
| protected IThemeResourceService themeResourceService; |
| protected IReportProvider reportProvider; |
| protected IBlobService blobService; |
| protected Map<String, Map<String, Object>> storage = new HashMap<>(); |
| protected SelectableChannel channel; |
| protected String lastTrigger; |
| protected IEclipseContext eclipseContext; |
| |
| private void addEventProvider(IEventSource.Enabler listener) { |
| enablerList.add(listener); |
| } |
| |
| private void removeEventProvider(IEventSource.Enabler listener) { |
| enablerList.remove(listener); |
| } |
| |
| @Override |
| public void registerEnabler(IEventSource.Enabler listener) { |
| addEventProvider(listener); |
| } |
| |
| @Override |
| public void unregisterEnabler(IEventSource.Enabler listener) { |
| removeEventProvider(listener); |
| } |
| |
| @Override |
| public void setUser(IUser user) { |
| this.user = user; |
| } |
| |
| @Override |
| public IUser getUser() { |
| return user; |
| } |
| |
| @Override |
| public String getUserName() { |
| return user.getUserName(); |
| } |
| |
| @Override |
| public String getUserPassword() { |
| return user.getExtraPassword(); |
| } |
| |
| @Override |
| public String getUserEmail() { |
| return user.getEmail(); |
| } |
| |
| @Override |
| public String getUserPosition() { |
| return user.getPosition(); |
| } |
| |
| @Override |
| public String getUserPrintService() { |
| return user.getPrintService(); |
| } |
| |
| @Override |
| public void setLocale(Locale locale) { |
| this.locale = locale; |
| } |
| |
| @Override |
| public Locale getLocale() { |
| return locale; |
| } |
| |
| @Override |
| public void setDslMetadataService(IDSLMetadataService dslMetadataService) { |
| this.dslMetadataService = dslMetadataService; |
| } |
| |
| @Override |
| public IDSLMetadataService getDslMetadataService() { |
| return dslMetadataService; |
| } |
| |
| @Override |
| public IThemeResourceService getThemeResourceService() { |
| return themeResourceService; |
| } |
| |
| @Override |
| public void setThemeResourceService(IThemeResourceService themeResourceService) { |
| this.themeResourceService = themeResourceService; |
| } |
| |
| @Override |
| public void setReportProvider(IReportProvider reportprovider) { |
| this.reportProvider = reportprovider; |
| } |
| |
| @Override |
| public IReportProvider getReportProvider() { |
| return reportProvider; |
| } |
| |
| @Override |
| public IBlobService getBlobService() { |
| return blobService; |
| } |
| |
| @Override |
| public void setBlobService(IBlobService blobService) { |
| this.blobService = blobService; |
| } |
| |
| @Override |
| public void enable(String id, Boolean enable) { |
| for (IEventSource.Enabler listener : enablerList) { |
| listener.enable(listener, id, enable); |
| } |
| } |
| |
| @Override |
| public void toggle(String id) { |
| for (IEventSource.Enabler listener : enablerList) { |
| listener.toggle(listener, id + ENABLED); |
| } |
| for (IDataProvider.Provider listener : providerList) { |
| listener.toggle(listener, id + ENABLED); |
| } |
| for (IPeripheral.Command listener : peripheralList) { |
| listener.toggle(listener, id + ENABLED); |
| } |
| } |
| |
| @Override |
| public Object get(String id) { |
| Object value; |
| for (IEventSource.Enabler listener : enablerList) { |
| value = listener.get(listener, id); |
| if (value != null) { |
| return value; |
| } |
| } |
| for (IDataProvider.Provider listener : providerList) { |
| value = listener.get(listener, id); |
| if (value != null) { |
| return value; |
| } |
| } |
| for (IPeripheral.Command listener : peripheralList) { |
| value = listener.get(listener, id); |
| if (value != null) { |
| return value; |
| } |
| } |
| return null; |
| } |
| |
| @Override |
| public void set(String id, Object content) { |
| for (IEventSource.Enabler listener : enablerList) { |
| listener.set(listener, id, content); |
| } |
| for (IDataProvider.Provider listener : providerList) { |
| listener.set(listener, id, content); |
| } |
| for (IPeripheral.Command listener : peripheralList) { |
| listener.set(listener, id, content); |
| } |
| } |
| |
| @Override |
| public void set(String id, String device, Object content) { |
| for (IPeripheral.Command listener : peripheralList) { |
| listener.set(listener, id, device, content); |
| } |
| } |
| |
| @Override |
| public void clear(String id) { |
| for (IEventSource.Enabler listener : enablerList) { |
| listener.clear(listener, id); |
| } |
| for (IDataProvider.Provider listener : providerList) { |
| listener.clear(listener, id); |
| } |
| for (IPeripheral.Command listener : peripheralList) { |
| listener.clear(listener, id); |
| } |
| } |
| |
| @Override |
| public void append(String id, String key) { |
| for (IEventSource.Enabler listener : enablerList) { |
| listener.append(listener, id, key); |
| } |
| } |
| |
| @Override |
| public void remove(String id, int pos) { |
| for (IEventSource.Enabler listener : enablerList) { |
| listener.remove(listener, id, pos); |
| } |
| } |
| |
| @Override |
| public void caption(String id, String value) { |
| for (IEventSource.Enabler listener : enablerList) { |
| listener.caption(listener, id, value); |
| } |
| } |
| |
| @Override |
| public void image(String id, String imageName) { |
| for (IEventSource.Enabler listener : enablerList) { |
| listener.image(listener, id, imageName); |
| } |
| } |
| |
| @Override |
| public void addDataProvider(IDataProvider.Provider listener) { |
| providerList.add(listener); |
| } |
| |
| @Override |
| public void removeDataProvider(IDataProvider.Provider listener) { |
| providerList.remove(listener); |
| } |
| |
| @Override |
| public void registerDataProvider(IDataProvider.Provider listener) { |
| addDataProvider(listener); |
| } |
| |
| @Override |
| public void unregisterDataProvider(IDataProvider.Provider listener) { |
| removeDataProvider(listener); |
| } |
| |
| public void addPeripheral(IPeripheral.Command listener) { |
| peripheralList.add(listener); |
| } |
| |
| public void removePeripheral(IPeripheral.Command listener) { |
| peripheralList.remove(listener); |
| } |
| |
| @Override |
| public void registerPeripheral(IPeripheral.Command listener) { |
| addPeripheral(listener); |
| } |
| |
| @Override |
| public void unregisterPeripheral(IPeripheral.Command listener) { |
| removePeripheral(listener); |
| } |
| |
| @Override |
| public Boolean find(String dtoName, IQuery query) { |
| Boolean retVal; |
| for (IDataProvider.Provider listener : providerList) { |
| retVal = listener.find(listener, dtoName, query); |
| if (retVal != null) { |
| return retVal; |
| } |
| } |
| return false; |
| } |
| |
| @Override |
| public Boolean find(String dtoName, String fieldName, Object search) { |
| Boolean retVal; |
| for (IDataProvider.Provider listener : providerList) { |
| retVal = listener.find(listener, dtoName, fieldName, search); |
| if (retVal != null) { |
| return retVal; |
| } |
| } |
| return false; |
| } |
| |
| @Override |
| public Collection<? extends IDto> findAll(String dtoName, IQuery query) { |
| Collection<? extends IDto> retVal; |
| for (IDataProvider.Provider listener : providerList) { |
| retVal = listener.findAll(dtoName, query); |
| if (retVal != null) { |
| return retVal; |
| } |
| } |
| return Collections.emptyList(); |
| } |
| |
| @Override |
| public Collection<? extends IDto> findAll(String dtoName, String fieldName, Object search) { |
| Collection<? extends IDto> retVal; |
| for (IDataProvider.Provider listener : providerList) { |
| retVal = listener.findAll(dtoName, fieldName, search); |
| if (retVal != null) { |
| return retVal; |
| } |
| } |
| return Collections.emptyList(); |
| } |
| |
| @Override |
| public void addTo(String dtoName, String listName, IDto dto) { |
| for (IDataProvider.Provider listener : providerList) { |
| listener.addTo(listener, dtoName, listName, dto); |
| } |
| } |
| |
| @Override |
| public void removeFrom(String dtoName, String listName, IDto dto) { |
| for (IDataProvider.Provider listener : providerList) { |
| listener.removeFrom(listener, dtoName, listName, dto); |
| } |
| } |
| |
| @Override |
| public void update(String dtoName) { |
| for (IDataProvider.Provider listener : providerList) { |
| listener.update(listener, dtoName, (IDto) listener.get(listener, dtoName)); |
| } |
| } |
| |
| @Override |
| public void reload(String dtoName) { |
| for (IDataProvider.Provider listener : providerList) { |
| listener.reload(listener, dtoName, (IDto) listener.get(listener, dtoName)); |
| } |
| } |
| |
| @Override |
| public void delete(String dtoName) { |
| for (IDataProvider.Provider listener : providerList) { |
| listener.delete(listener, dtoName, (IDto) listener.get(listener, dtoName)); |
| } |
| } |
| |
| @Override |
| public String getIPAddress() { |
| // must define -Djava.net.preferIPv4Stack=true to always get IPv4 in |
| // dual stack environments |
| return webBrowser.getAddress(); // May be null, especially if running in |
| // a Portlet. |
| } |
| |
| @Override |
| public String getHostName() { |
| String hostName = null; |
| try { |
| InetAddress netAddress = InetAddress.getByName(webBrowser.getAddress()); |
| hostName = netAddress.getHostName(); |
| } catch (UnknownHostException e) { |
| logger.error("{}", e); |
| } |
| return hostName; |
| } |
| |
| @Override |
| public boolean isItMe(String hostName) { |
| String hostAddress; |
| try { |
| InetAddress netAddress = InetAddress.getByName(hostName); |
| hostAddress = netAddress.getHostAddress(); |
| } catch (UnknownHostException e) { |
| logger.error("{}", e); |
| return false; |
| } |
| return getIPAddress().equals(hostAddress); |
| } |
| |
| @Override |
| public DateTime getNow() { |
| return DateTime.now(DateTimeZone.UTC); |
| } |
| |
| @Override |
| public String getUserAgentInfo() { |
| return webBrowser.getBrowserApplication(); |
| } |
| |
| @Override |
| public Boolean isTouchDevice() { |
| return webBrowser.isTouchDevice(); |
| } |
| |
| @Override |
| public int getSceenWidth() { |
| return webBrowser.getScreenWidth(); |
| } |
| |
| @Override |
| public int getScreenHeight() { |
| return webBrowser.getScreenHeight(); |
| } |
| |
| @PreDestroy |
| void destroy() { |
| timer.cancel(); |
| timer = null; |
| } |
| |
| @Override |
| public Locale getBrowserLocale() { |
| return webBrowser.getLocale(); |
| } |
| |
| @Override |
| public Boolean isHttps() { |
| return webBrowser.isSecureConnection(); |
| } |
| |
| @Override |
| public void schedule(IStateMachine statemachine, long milliseconds, MessageEvent event) { |
| if (timer == null) { |
| timer = new Timer(); |
| } else { |
| timer.cancel(); |
| timer.purge(); |
| timer = new Timer(); |
| } |
| timer.schedule(new EventSourceTask(statemachine, event), milliseconds); |
| } |
| |
| class EventSourceTask extends TimerTask { |
| private IStateMachine statemachine; |
| private MessageEvent event; |
| |
| public EventSourceTask(IStateMachine statemachine, MessageEvent event) { |
| this.statemachine = statemachine; |
| this.event = event; |
| } |
| |
| @Override |
| public void run() { |
| if (UI.getCurrent().isAttached()) |
| statemachine.processEvent(statemachine, event); |
| } |
| } |
| |
| /** |
| * @param doubleStr |
| * @return Double independent of locale |
| */ |
| @Override |
| public Double parseDouble(String doubleStr) { |
| String doubleStrIn = doubleStr.replaceAll("[^\\d,\\.]++", ""); |
| if (doubleStrIn.length() == 0) { |
| return 0.0; |
| } |
| if (doubleStrIn.matches(".+\\.\\d+,\\d+$")) |
| return Double.parseDouble(doubleStrIn.replaceAll("\\.", "").replaceAll(",", ".")); |
| if (doubleStrIn.matches(".+,\\d+\\.\\d+$")) |
| return Double.parseDouble(doubleStrIn.replaceAll(",", "")); |
| return Double.parseDouble(doubleStrIn.replaceAll(",", ".")); |
| } |
| |
| /** |
| * Format a double. |
| * |
| * @param value |
| * the value |
| * @param length |
| * the total length of the resulting string |
| * @param precision |
| * the precision after decimal separator |
| * @return the string |
| */ |
| @Override |
| public String formatDouble(Double value, int length, int precision) { |
| String format = String.format("%% %d.%df", length, precision); |
| return String.format(locale, format, value); |
| } |
| |
| @Override |
| public String getTranslation(String token) { |
| if (dslMetadataService != null && locale != null) { |
| return dslMetadataService.translate(locale.toLanguageTag(), token); |
| } |
| return token; |
| } |
| |
| @Override |
| public void closeMessage(String messageId) { |
| if (messageDialogs.containsKey(messageId)) { |
| MessageDialog messageDialog = messageDialogs.get(messageId); |
| messageDialog.close(); |
| UI.getCurrent().removeWindow(messageDialog); |
| messageDialogs.remove(messageId); |
| } |
| } |
| |
| @Override |
| public void openMessage(String messageId) { |
| openMessage(messageId, false); |
| } |
| |
| @Override |
| public void openMessage(String messageId, boolean okButton) { |
| MessageDialog messageDialog = new MessageDialog(messageId, getTranslation(messageId)); |
| if (okButton) { |
| messageDialog.addButton(getTranslation("ok"), new MessageEvent(EventType.MESSAGECLOSE, messageId)); |
| messageDialog.addButtonListener(this); |
| } |
| messageDialogs.put(messageId, messageDialog); |
| UI.getCurrent().addWindow(messageDialog); |
| } |
| |
| @Override |
| public void openQuestion(String messageId, EventType type, String yesEvent, String noEvent, String cancelEvent) { |
| MessageDialog messageDialog = new MessageDialog(messageId, getTranslation(messageId)); |
| messageDialog.addButton(getTranslation("yes"), new MessageEvent(type, yesEvent)); |
| messageDialog.addButton(getTranslation("no"), new MessageEvent(type, noEvent)); |
| messageDialog.addButton(getTranslation("cancel"), new MessageEvent(type, cancelEvent)); |
| messageDialog.addButtonListener(this); |
| messageDialogs.put(messageId, messageDialog); |
| UI.getCurrent().addWindow(messageDialog); |
| } |
| |
| @Override |
| public void messageButtonPressed(MessageRequesterEvent e) { |
| MessageDialog messageDialog = messageDialogs.get(e.getId()); |
| messageDialog.close(); |
| UI.getCurrent().removeWindow(messageDialog); |
| messageDialogs.remove(e.getId()); |
| this.processEvent(this, e.getEventData()); |
| } |
| |
| @Override |
| public void dispatchMessages(MessageEvent event) { |
| if (event.getType() == MessageEvent.EventType.TRIGGER) { |
| lastTrigger = event.getId(); |
| } |
| switch (event.getType()) { |
| case ERROR: |
| openMessage(event.getId(), true); |
| break; |
| case MESSAGEOPEN: |
| openMessage(event.getId()); |
| break; |
| case MESSAGECLOSE: |
| closeMessage(event.getId()); |
| break; |
| case STATUSOPEN: |
| case STATUSCLOSE: |
| default: |
| break; |
| } |
| } |
| |
| @Override |
| public Object getStorage(String key, String attribute) { |
| if (storage.containsKey(key) && storage.get(key).containsKey(attribute)) { |
| return storage.get(key).get(attribute); |
| } |
| return null; |
| } |
| |
| @Override |
| public Set<String> getStorageAttributes(String key) { |
| if (storage.containsKey(key)) { |
| return storage.get(key).keySet(); |
| } |
| return Collections.emptySet(); |
| } |
| |
| @Override |
| public void putStorage(String key, String attribute, Object content) { |
| if (!storage.containsKey(key)) { |
| storage.put(key, new HashMap<String, Object>()); |
| } |
| storage.get(key).put(attribute, content); |
| } |
| |
| @Override |
| public void openChannel(SelectableChannel channel) { |
| this.channel = channel; |
| } |
| |
| @Override |
| public SelectableChannel getChannel() { |
| return channel; |
| } |
| |
| @Override |
| public void closeChannel() { |
| if (channel != null) { |
| try { |
| channel.close(); |
| } catch (IOException e) { // NOSONAR |
| // do nothing |
| } |
| } |
| } |
| |
| @Override |
| public String getLastTrigger() { |
| return lastTrigger; |
| } |
| |
| @Override |
| public void setEclipseContext(IEclipseContext eclipseContext) { |
| this.eclipseContext = eclipseContext; |
| } |
| |
| @Override |
| public IEclipseContext getEclipseContext() { |
| return eclipseContext; |
| } |
| |
| @Override |
| public void sendSlaveData(Map<String, Object> data) { |
| String currentInstanceId = (String) getEclipseContext().get("e4ApplicationInstanceId"); |
| List<ISession> sessions = POSServiceBinder.getSessionManager() |
| .getSessions((s) -> s.get("e4ApplicationInstanceId").equals(currentInstanceId)); |
| if (!sessions.isEmpty()) { |
| List<ISession> slaves = sessions.get(0).getSlaves(); |
| for (ISession slave : slaves) { |
| slave.async(e -> { |
| slave.sendData(data); |
| return true; |
| }, null); |
| } |
| } |
| } |
| } |