Mercurial > hg > release > thermostat-2.0
changeset 2496:50b5d89f6e25
Refactor Platform State Machine
reviewed-by: aazores
review-thread: http://icedtea.classpath.org/pipermail/thermostat/2016-October/021373.html
line wrap: on
line diff
--- a/platform/core/pom.xml Tue Oct 25 18:12:39 2016 -0400 +++ b/platform/core/pom.xml Wed Oct 26 17:22:43 2016 +0200 @@ -146,7 +146,7 @@ com.redhat.thermostat.platform.internal.command, com.redhat.thermostat.platform.internal.mvc, com.redhat.thermostat.platform.internal.mvc.lifecycle, - com.redhat.thermostat.platform.internal.mvc.lifecycle.handlers, + com.redhat.thermostat.platform.internal.mvc.lifecycle.state, com.redhat.thermostat.platform.internal.locale, </Private-Package> <!--Do not autogenerate uses clauses in Manifests -->
--- a/platform/core/src/main/java/com/redhat/thermostat/platform/internal/mvc/lifecycle/ControllerLifeCycleState.java Tue Oct 25 18:12:39 2016 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,45 +0,0 @@ -/* - * Copyright 2012-2016 Red Hat, Inc. - * - * This file is part of Thermostat. - * - * Thermostat is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published - * by the Free Software Foundation; either version 2, or (at your - * option) any later version. - * - * Thermostat is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Thermostat; see the file COPYING. If not see - * <http://www.gnu.org/licenses/>. - * - * Linking this code with other modules is making a combined work - * based on this code. Thus, the terms and conditions of the GNU - * General Public License cover the whole combination. - * - * As a special exception, the copyright holders of this code give - * you permission to link this code with independent modules to - * produce an executable, regardless of the license terms of these - * independent modules, and to copy and distribute the resulting - * executable under terms of your choice, provided that you also - * meet, for each linked independent module, the terms and conditions - * of the license of that module. An independent module is a module - * which is not derived from or based on this code. If you modify - * this code, you may extend this exception to your version of the - * library, but you are not obligated to do so. If you do not wish - * to do so, delete this exception statement from your version. - */ - -package com.redhat.thermostat.platform.internal.mvc.lifecycle; - -/** - */ -public enum ControllerLifeCycleState { - PRE_INIT, - STARTED, - STOPPED, -}
--- a/platform/core/src/main/java/com/redhat/thermostat/platform/internal/mvc/lifecycle/LifeCycle.java Tue Oct 25 18:12:39 2016 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,64 +0,0 @@ -/* - * Copyright 2012-2016 Red Hat, Inc. - * - * This file is part of Thermostat. - * - * Thermostat is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published - * by the Free Software Foundation; either version 2, or (at your - * option) any later version. - * - * Thermostat is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Thermostat; see the file COPYING. If not see - * <http://www.gnu.org/licenses/>. - * - * Linking this code with other modules is making a combined work - * based on this code. Thus, the terms and conditions of the GNU - * General Public License cover the whole combination. - * - * As a special exception, the copyright holders of this code give - * you permission to link this code with independent modules to - * produce an executable, regardless of the license terms of these - * independent modules, and to copy and distribute the resulting - * executable under terms of your choice, provided that you also - * meet, for each linked independent module, the terms and conditions - * of the license of that module. An independent module is a module - * which is not derived from or based on this code. If you modify - * this code, you may extend this exception to your version of the - * library, but you are not obligated to do so. If you do not wish - * to do so, delete this exception statement from your version. - */ - -package com.redhat.thermostat.platform.internal.mvc.lifecycle; - -/** - */ -public enum LifeCycle { - - PRE_CREATE, - - CREATE_VIEW, - VIEW_CREATED, - - INIT_VIEW, - VIEW_INITIALIZED, - - REGISTER_MVC, - - START_CONTROLLER, - START_VIEW, - STARTED, - - STOP_VIEW, - STOP_CONTROLLER, - STOPPED, - - DESTROY_VIEW, - DESTROY, - DESTROYED, -}
--- a/platform/core/src/main/java/com/redhat/thermostat/platform/internal/mvc/lifecycle/MVCLifeCycleManager.java Tue Oct 25 18:12:39 2016 -0400 +++ b/platform/core/src/main/java/com/redhat/thermostat/platform/internal/mvc/lifecycle/MVCLifeCycleManager.java Wed Oct 26 17:22:43 2016 +0200 @@ -37,8 +37,6 @@ package com.redhat.thermostat.platform.internal.mvc.lifecycle; import com.redhat.thermostat.beans.property.BooleanProperty; -import com.redhat.thermostat.beans.property.ChangeListener; -import com.redhat.thermostat.beans.property.ObservableValue; import com.redhat.thermostat.common.ActionEvent; import com.redhat.thermostat.common.ActionListener; import com.redhat.thermostat.common.ThermostatExtensionRegistry; @@ -46,11 +44,9 @@ import com.redhat.thermostat.platform.MDIService; import com.redhat.thermostat.platform.Platform; import com.redhat.thermostat.platform.event.EventQueue; -import com.redhat.thermostat.platform.internal.mvc.lifecycle.handlers.LifeCycleStateHandler; -import com.redhat.thermostat.platform.internal.mvc.lifecycle.handlers.LifeCycleTransitionDispatcher; -import com.redhat.thermostat.platform.internal.mvc.lifecycle.handlers.PlatformServiceRegistrar; +import com.redhat.thermostat.platform.internal.mvc.lifecycle.state.PlatformServiceRegistrar; +import com.redhat.thermostat.platform.internal.mvc.lifecycle.state.StateMachine; import com.redhat.thermostat.platform.mvc.MVCProvider; -import com.redhat.thermostat.platform.mvc.Workbench; import java.util.Deque; import java.util.concurrent.ConcurrentLinkedDeque; @@ -62,15 +58,11 @@ private MVCRegistry registry; private EventQueue eventQueue; - private Deque<LifeCycleStateHandler> handlers; - - private LifeCycleStateHandler workbench; + private Deque<StateMachine> providers; private Platform platform; private PlatformServiceRegistrar serviceRegistrar; - private volatile boolean shutdown; - public MVCLifeCycleManager() { this(new MVCRegistry()); } @@ -82,7 +74,7 @@ this.registry = registry; - handlers = new ConcurrentLinkedDeque<>(); + providers = new ConcurrentLinkedDeque<>(); MVCListener listener = new MVCListener(); registry.addMVCRegistryListener(listener); @@ -105,24 +97,17 @@ } public void stop() { - shutdown = true; - registry.stop(); - for (LifeCycleStateHandler handler : handlers) { - handler.destroy(); + for (StateMachine stateMachine : providers) { + stateMachine.stop(); } doShutdown(); } private void doShutdown() { - - if (handlers.isEmpty()) { - if (workbench != null) { - workbench.destroy(); - } - } + // TODO } public BooleanProperty shutdownProperty() { @@ -133,45 +118,11 @@ public void startLifeCycle(final MVCProvider provider) { - LifeCycleStateHandler handler = - new LifeCycleStateHandler(provider, platform, serviceRegistrar); - LifeCycleTransitionDispatcher dispatcher = - new LifeCycleTransitionDispatcher(eventQueue); - handler.setDispatcher(dispatcher); - dispatcher.addLifeCycleListener(handler); - - if (provider instanceof Workbench) { - workbench = handler; - shutdownProperty.bind(workbench.shutdownProperty()); - } else { - handlers.add(handler); - - ShutdownListener listener = new ShutdownListener(handler); - handler.shutdownProperty().addListener(listener); - } - - dispatcher.requestLifeCycleTransition(LifeCycle.CREATE_VIEW); - } - - class ShutdownListener implements ChangeListener<Boolean> { - private LifeCycleStateHandler handler; - - public ShutdownListener(LifeCycleStateHandler handler) { - this.handler = handler; - } - - @Override - public void changed(ObservableValue<? extends Boolean> observable, Boolean oldValue, Boolean newValue) { - handler.getDispatcher().removeLifeCycleListener(handler); - handler.setDispatcher(null); - handler.shutdownProperty().removeListener(this); - - handlers.remove(handler); - - if (shutdown) { - doShutdown(); - } - } + StateMachine stateMachine = new StateMachine(provider, platform, + serviceRegistrar, + eventQueue); + providers.add(stateMachine); + stateMachine.start(); } public void setPlatform(Platform platform) {
--- a/platform/core/src/main/java/com/redhat/thermostat/platform/internal/mvc/lifecycle/handlers/LifeCycleStateHandler.java Tue Oct 25 18:12:39 2016 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,292 +0,0 @@ -/* - * Copyright 2012-2016 Red Hat, Inc. - * - * This file is part of Thermostat. - * - * Thermostat is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published - * by the Free Software Foundation; either version 2, or (at your - * option) any later version. - * - * Thermostat is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Thermostat; see the file COPYING. If not see - * <http://www.gnu.org/licenses/>. - * - * Linking this code with other modules is making a combined work - * based on this code. Thus, the terms and conditions of the GNU - * General Public License cover the whole combination. - * - * As a special exception, the copyright holders of this code give - * you permission to link this code with independent modules to - * produce an executable, regardless of the license terms of these - * independent modules, and to copy and distribute the resulting - * executable under terms of your choice, provided that you also - * meet, for each linked independent module, the terms and conditions - * of the license of that module. An independent module is a module - * which is not derived from or based on this code. If you modify - * this code, you may extend this exception to your version of the - * library, but you are not obligated to do so. If you do not wish - * to do so, delete this exception statement from your version. - */ - -package com.redhat.thermostat.platform.internal.mvc.lifecycle.handlers; - -import com.redhat.thermostat.beans.property.BooleanProperty; -import com.redhat.thermostat.beans.property.ChangeListener; -import com.redhat.thermostat.beans.property.ObservableValue; -import com.redhat.thermostat.common.ActionEvent; -import com.redhat.thermostat.common.ActionListener; -import com.redhat.thermostat.platform.Platform; -import com.redhat.thermostat.platform.internal.mvc.lifecycle.ControllerLifeCycleState; -import com.redhat.thermostat.platform.internal.mvc.lifecycle.LifeCycle; -import com.redhat.thermostat.platform.mvc.MVCProvider; -import com.redhat.thermostat.platform.mvc.Workbench; - -public class LifeCycleStateHandler implements ActionListener<LifeCycle> { - - private volatile boolean shutdown; - - private BooleanProperty shutdownProperty; - - private MVCProvider provider; - private Platform platform; - - private LifeCycleTransitionDispatcher dispatcher; - private PlatformServiceRegistrar serviceRegistrar; - - private volatile ControllerLifeCycleState currentControllerState; - - public LifeCycleStateHandler(MVCProvider provider, Platform platform, - PlatformServiceRegistrar serviceRegistrar) - { - this.provider = provider; - this.platform = platform; - shutdownProperty = new BooleanProperty(false); - this.serviceRegistrar = serviceRegistrar; - currentControllerState = ControllerLifeCycleState.PRE_INIT; - } - - public MVCProvider getProvider() { - return provider; - } - - @Override - public void actionPerformed(ActionEvent<LifeCycle> actionEvent) { - switch (actionEvent.getActionId()) { - case CREATE_VIEW: { - platform.queueOnViewThread(new Runnable() { - @Override - public void run() { - provider.getView().create(); - dispatcher.requestLifeCycleTransition(LifeCycle.VIEW_CREATED); - } - }); - } - break; - - case VIEW_CREATED: { - platform.queueOnApplicationThread(new Runnable() { - @Override - public void run() { - provider.getModel().create(); - provider.getController().create(); - dispatcher.requestLifeCycleTransition(LifeCycle.INIT_VIEW); - } - }); - } - break; - - case INIT_VIEW: { - platform.queueOnViewThread(new Runnable() { - @Override - public void run() { - provider.getView().init(platform); - provider.getView().showingProperty().addListener(new ChangeListener<Boolean>() { - @Override - public void changed(ObservableValue<? extends Boolean> observable, Boolean oldValue, Boolean newValue) { - if (currentControllerState.equals(ControllerLifeCycleState.PRE_INIT)) { - return; - } - - if (newValue.booleanValue() && currentControllerState.equals(ControllerLifeCycleState.STOPPED)) { - dispatcher.requestLifeCycleTransition(LifeCycle.START_CONTROLLER); - - } else if (!newValue.booleanValue() && currentControllerState.equals(ControllerLifeCycleState.STARTED)) { - dispatcher.requestLifeCycleTransition(LifeCycle.STOP_CONTROLLER); - } - } - }); - dispatcher.requestLifeCycleTransition(LifeCycle.VIEW_INITIALIZED); - } - }); - } - break; - - case VIEW_INITIALIZED: { - platform.queueOnApplicationThread(new Runnable() { - @Override - public void run() { - provider.getModel().init(platform); - provider.getController().init(platform, provider.getModel(), provider.getView()); - currentControllerState = ControllerLifeCycleState.STOPPED; - dispatcher.requestLifeCycleTransition(LifeCycle.REGISTER_MVC); - } - }); - } - break; - - case REGISTER_MVC: { - serviceRegistrar.checkAndRegister(provider); - if (provider instanceof Workbench) { - dispatcher.requestLifeCycleTransition(LifeCycle.START_CONTROLLER); - } - platform.queueOnApplicationThread(new Runnable() { - @Override - public void run() { - if (provider.getView().showingProperty().get()) { - dispatcher.requestLifeCycleTransition(LifeCycle.START_CONTROLLER); - } - } - }); - } - break; - - case START_CONTROLLER: { - platform.queueOnApplicationThread(new Runnable() { - @Override - public void run() { - provider.getController().start(); - currentControllerState = ControllerLifeCycleState.STARTED; - dispatcher.requestLifeCycleTransition(LifeCycle.START_VIEW); - } - }); - } - break; - - case START_VIEW: { - platform.queueOnViewThread(new Runnable() { - @Override - public void run() { - provider.getView().start(); - dispatcher.requestLifeCycleTransition(LifeCycle.STARTED); - } - }); - } - break; - - case STARTED: { - platform.queueOnApplicationThread(new Runnable() { - @Override - public void run() { - provider.getController().viewStarted(); - } - }); - } - break; - - case STOP_CONTROLLER: { - platform.queueOnApplicationThread(new Runnable() { - @Override - public void run() { - provider.getController().stop(); - currentControllerState = ControllerLifeCycleState.STOPPED; - dispatcher.requestLifeCycleTransition(LifeCycle.STOP_VIEW); - } - }); - } - break; - - case STOP_VIEW: { - platform.queueOnViewThread(new Runnable() { - @Override - public void run() { - provider.getView().stop(); - dispatcher.requestLifeCycleTransition(LifeCycle.STOPPED); - } - }); - } - break; - - case STOPPED: { - platform.queueOnApplicationThread(new Runnable() { - @Override - public void run() { - provider.getController().viewStopped(); - if (shutdown) { - dispatcher.requestLifeCycleTransition(LifeCycle.DESTROY_VIEW); - } - } - }); - } - break; - - case DESTROY_VIEW: { - platform.queueOnViewThread(new Runnable() { - @Override - public void run() { - provider.getView().destroy(); - dispatcher.requestLifeCycleTransition(LifeCycle.DESTROY); - } - }); - } - break; - - case DESTROY: { - platform.queueOnApplicationThread(new Runnable() { - @Override - public void run() { - provider.getController().destroy(); - provider.getModel().destroy(); - dispatcher.requestLifeCycleTransition(LifeCycle.DESTROYED); - } - }); - } - break; - - case DESTROYED: { - shutdownProperty.set(true); - } - break; - - // not handled cases - case PRE_CREATE: - break; - } - } - - public BooleanProperty shutdownProperty() { - return shutdownProperty; - } - - public void destroy() { - if (currentControllerState == ControllerLifeCycleState.STARTED) { - shutdown = true; - dispatcher.requestLifeCycleTransition(LifeCycle.STOP_CONTROLLER); - } else { - dispatcher.requestLifeCycleTransition(LifeCycle.DESTROY_VIEW); - } - } - - public void setDispatcher(LifeCycleTransitionDispatcher dispatcher) { - this.dispatcher = dispatcher; - } - - public LifeCycleTransitionDispatcher getDispatcher() { - return dispatcher; - } - - @Override - public String toString() { - return "[LifeCycleStateHandler: " + provider.getClass() + "]"; - } - - // Test hook - ControllerLifeCycleState getCurrentControllerState() { - return currentControllerState; - } -}
--- a/platform/core/src/main/java/com/redhat/thermostat/platform/internal/mvc/lifecycle/handlers/LifeCycleTransitionDispatcher.java Tue Oct 25 18:12:39 2016 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,92 +0,0 @@ -/* - * Copyright 2012-2016 Red Hat, Inc. - * - * This file is part of Thermostat. - * - * Thermostat is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published - * by the Free Software Foundation; either version 2, or (at your - * option) any later version. - * - * Thermostat is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Thermostat; see the file COPYING. If not see - * <http://www.gnu.org/licenses/>. - * - * Linking this code with other modules is making a combined work - * based on this code. Thus, the terms and conditions of the GNU - * General Public License cover the whole combination. - * - * As a special exception, the copyright holders of this code give - * you permission to link this code with independent modules to - * produce an executable, regardless of the license terms of these - * independent modules, and to copy and distribute the resulting - * executable under terms of your choice, provided that you also - * meet, for each linked independent module, the terms and conditions - * of the license of that module. An independent module is a module - * which is not derived from or based on this code. If you modify - * this code, you may extend this exception to your version of the - * library, but you are not obligated to do so. If you do not wish - * to do so, delete this exception statement from your version. - */ - -package com.redhat.thermostat.platform.internal.mvc.lifecycle.handlers; - -import com.redhat.thermostat.common.ActionListener; -import com.redhat.thermostat.common.ActionNotifier; -import com.redhat.thermostat.platform.internal.mvc.lifecycle.LifeCycle; -import com.redhat.thermostat.platform.event.EventQueue; - -public class LifeCycleTransitionDispatcher { - private ActionNotifier<LifeCycle> notifier; - private LifeCycle currentState; - private EventQueue eventQueue; - - // Testing hook - LifeCycleTransitionDispatcher(ActionNotifier<LifeCycle> notifier, - EventQueue eventQueue) { - init(notifier, eventQueue); - } - - public LifeCycleTransitionDispatcher(EventQueue eventQueue) { - init(new ActionNotifier<LifeCycle>(this), eventQueue); - } - - private void init(ActionNotifier<LifeCycle> notifier, EventQueue eventQueue) - { - this.notifier = notifier; - this.eventQueue = eventQueue; - currentState = LifeCycle.PRE_CREATE; - } - - public void requestLifeCycleTransition(final LifeCycle newState) { - if (currentState != null && currentState.equals(newState)) { - return; - } - - final Object oldState = this.currentState; - this.currentState = newState; - eventQueue.runLater(new Runnable() { - @Override - public void run() { - notifier.fireAction(newState, oldState); - } - }); - } - - public LifeCycle getCurrentLifeCycleState() { - return currentState; - } - - public void addLifeCycleListener(ActionListener<LifeCycle> listener) { - notifier.addActionListener(listener); - } - - public void removeLifeCycleListener(ActionListener<LifeCycle> listener) { - notifier.removeActionListener(listener); - } -}
--- a/platform/core/src/main/java/com/redhat/thermostat/platform/internal/mvc/lifecycle/handlers/PlatformServiceRegistrar.java Tue Oct 25 18:12:39 2016 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,127 +0,0 @@ -/* - * Copyright 2012-2016 Red Hat, Inc. - * - * This file is part of Thermostat. - * - * Thermostat is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published - * by the Free Software Foundation; either version 2, or (at your - * option) any later version. - * - * Thermostat is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Thermostat; see the file COPYING. If not see - * <http://www.gnu.org/licenses/>. - * - * Linking this code with other modules is making a combined work - * based on this code. Thus, the terms and conditions of the GNU - * General Public License cover the whole combination. - * - * As a special exception, the copyright holders of this code give - * you permission to link this code with independent modules to - * produce an executable, regardless of the license terms of these - * independent modules, and to copy and distribute the resulting - * executable under terms of your choice, provided that you also - * meet, for each linked independent module, the terms and conditions - * of the license of that module. An independent module is a module - * which is not derived from or based on this code. If you modify - * this code, you may extend this exception to your version of the - * library, but you are not obligated to do so. If you do not wish - * to do so, delete this exception statement from your version. - */ - -package com.redhat.thermostat.platform.internal.mvc.lifecycle.handlers; - -import com.redhat.thermostat.common.Constants; -import com.redhat.thermostat.platform.annotations.PlatformService; -import com.redhat.thermostat.platform.mvc.MVCComponent; -import com.redhat.thermostat.platform.mvc.MVCProvider; -import org.osgi.framework.BundleContext; -import org.osgi.framework.FrameworkUtil; - -import java.util.ArrayList; -import java.util.Dictionary; -import java.util.Hashtable; -import java.util.List; -import java.util.concurrent.ExecutorService; - -public class PlatformServiceRegistrar { - private ExecutorService executor; - private BundleContext context; - - public PlatformServiceRegistrar(ExecutorService executor) { - this(executor, FrameworkUtil.getBundle(PlatformServiceRegistrar.class). - getBundleContext()); - } - - // Testing hook - PlatformServiceRegistrar(ExecutorService executor, BundleContext context) { - this.executor = executor; - this.context = context; - } - - public void checkAndRegister(MVCProvider provider) { - checkAndRegisterImpl(provider.getModel()); - checkAndRegisterImpl(provider.getController()); - checkAndRegisterImpl(provider.getView()); - } - - // Testing hook - void checkAndRegisterImpl(MVCComponent component) { - List<String> serviceIds = - getPlatformServiceIDs(component.getClass()); - if (!serviceIds.isEmpty()) { - registerComponent(component, serviceIds); - } - } - - // Testing hook - void registerComponent(final MVCComponent component, - final List<String> serviceIds) - { - Runnable runnable = new Runnable() { - @Override - public void run() { - - Class<? extends MVCComponent> clazz = component.getClass(); - Dictionary<String, String> properties = new Hashtable<>(); - properties.put(Constants.GENERIC_SERVICE_CLASSNAME, clazz.getName()); - - for (String serviceId : serviceIds) { - context.registerService(serviceId, component, properties); - } - } - }; - executor.execute(runnable); - } - - // Testing hook - List<String> getPlatformServiceIDs(Class<? extends MVCComponent> clazz) { - - List<String> services = new ArrayList<>(); - - boolean isService = clazz.isAnnotationPresent(PlatformService.class); - if (isService) { - PlatformService service = clazz.getAnnotation(PlatformService.class); - Class<? extends MVCComponent>[] components = service.service(); - for (Class<? extends MVCComponent> component : components) { - services.add(component.getName()); - } - - String value = service.value(); - if (services.isEmpty() && !value.isEmpty()) { - services.add(value); - } - - if (services.isEmpty()) { - services.add(clazz.getName()); - } - } - - return services; - } -}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/platform/core/src/main/java/com/redhat/thermostat/platform/internal/mvc/lifecycle/state/Context.java Wed Oct 26 17:22:43 2016 +0200 @@ -0,0 +1,49 @@ +/* + * Copyright 2012-2016 Red Hat, Inc. + * + * This file is part of Thermostat. + * + * Thermostat is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published + * by the Free Software Foundation; either version 2, or (at your + * option) any later version. + * + * Thermostat is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Thermostat; see the file COPYING. If not see + * <http://www.gnu.org/licenses/>. + * + * Linking this code with other modules is making a combined work + * based on this code. Thus, the terms and conditions of the GNU + * General Public License cover the whole combination. + * + * As a special exception, the copyright holders of this code give + * you permission to link this code with independent modules to + * produce an executable, regardless of the license terms of these + * independent modules, and to copy and distribute the resulting + * executable under terms of your choice, provided that you also + * meet, for each linked independent module, the terms and conditions + * of the license of that module. An independent module is a module + * which is not derived from or based on this code. If you modify + * this code, you may extend this exception to your version of the + * library, but you are not obligated to do so. If you do not wish + * to do so, delete this exception statement from your version. + */ + +package com.redhat.thermostat.platform.internal.mvc.lifecycle.state; + +import com.redhat.thermostat.platform.Platform; +import com.redhat.thermostat.platform.mvc.MVCProvider; + +/** + */ +public class Context { + Platform platform; + MVCProvider provider; + StateMachineTransitionDispatcher dispatcher; + PlatformServiceRegistrar registrar; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/platform/core/src/main/java/com/redhat/thermostat/platform/internal/mvc/lifecycle/state/Create.java Wed Oct 26 17:22:43 2016 +0200 @@ -0,0 +1,60 @@ +/* + * Copyright 2012-2016 Red Hat, Inc. + * + * This file is part of Thermostat. + * + * Thermostat is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published + * by the Free Software Foundation; either version 2, or (at your + * option) any later version. + * + * Thermostat is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Thermostat; see the file COPYING. If not see + * <http://www.gnu.org/licenses/>. + * + * Linking this code with other modules is making a combined work + * based on this code. Thus, the terms and conditions of the GNU + * General Public License cover the whole combination. + * + * As a special exception, the copyright holders of this code give + * you permission to link this code with independent modules to + * produce an executable, regardless of the license terms of these + * independent modules, and to copy and distribute the resulting + * executable under terms of your choice, provided that you also + * meet, for each linked independent module, the terms and conditions + * of the license of that module. An independent module is a module + * which is not derived from or based on this code. If you modify + * this code, you may extend this exception to your version of the + * library, but you are not obligated to do so. If you do not wish + * to do so, delete this exception statement from your version. + */ + +package com.redhat.thermostat.platform.internal.mvc.lifecycle.state; + +/** + */ +public class Create implements StateAction { + @Override + public void execute(final Context context) { + context.platform.queueOnViewThread(new Runnable() { + @Override + public void run() { + context.provider.getView().create(); + context.platform.queueOnApplicationThread(new Runnable() { + @Override + public void run() { + context.provider.getModel().create(); + context.provider.getController().create(); + + context.dispatcher.dispatch(State.INIT); + } + }); + } + }); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/platform/core/src/main/java/com/redhat/thermostat/platform/internal/mvc/lifecycle/state/Destroy.java Wed Oct 26 17:22:43 2016 +0200 @@ -0,0 +1,61 @@ +/* + * Copyright 2012-2016 Red Hat, Inc. + * + * This file is part of Thermostat. + * + * Thermostat is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published + * by the Free Software Foundation; either version 2, or (at your + * option) any later version. + * + * Thermostat is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Thermostat; see the file COPYING. If not see + * <http://www.gnu.org/licenses/>. + * + * Linking this code with other modules is making a combined work + * based on this code. Thus, the terms and conditions of the GNU + * General Public License cover the whole combination. + * + * As a special exception, the copyright holders of this code give + * you permission to link this code with independent modules to + * produce an executable, regardless of the license terms of these + * independent modules, and to copy and distribute the resulting + * executable under terms of your choice, provided that you also + * meet, for each linked independent module, the terms and conditions + * of the license of that module. An independent module is a module + * which is not derived from or based on this code. If you modify + * this code, you may extend this exception to your version of the + * library, but you are not obligated to do so. If you do not wish + * to do so, delete this exception statement from your version. + */ + +package com.redhat.thermostat.platform.internal.mvc.lifecycle.state; + +import com.redhat.thermostat.platform.Platform; +import com.redhat.thermostat.platform.mvc.MVCProvider; + +/** + */ +public class Destroy implements StateAction { + @Override + public void execute(final Context context) { + context.platform.queueOnApplicationThread(new Runnable() { + @Override + public void run() { + context.provider.getController().destroy(); + context.provider.getModel().destroy(); + context.platform.queueOnViewThread(new Runnable() { + @Override + public void run() { + context.provider.getView().destroy(); + } + }); + } + }); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/platform/core/src/main/java/com/redhat/thermostat/platform/internal/mvc/lifecycle/state/Init.java Wed Oct 26 17:22:43 2016 +0200 @@ -0,0 +1,80 @@ +/* + * Copyright 2012-2016 Red Hat, Inc. + * + * This file is part of Thermostat. + * + * Thermostat is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published + * by the Free Software Foundation; either version 2, or (at your + * option) any later version. + * + * Thermostat is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Thermostat; see the file COPYING. If not see + * <http://www.gnu.org/licenses/>. + * + * Linking this code with other modules is making a combined work + * based on this code. Thus, the terms and conditions of the GNU + * General Public License cover the whole combination. + * + * As a special exception, the copyright holders of this code give + * you permission to link this code with independent modules to + * produce an executable, regardless of the license terms of these + * independent modules, and to copy and distribute the resulting + * executable under terms of your choice, provided that you also + * meet, for each linked independent module, the terms and conditions + * of the license of that module. An independent module is a module + * which is not derived from or based on this code. If you modify + * this code, you may extend this exception to your version of the + * library, but you are not obligated to do so. If you do not wish + * to do so, delete this exception statement from your version. + */ + +package com.redhat.thermostat.platform.internal.mvc.lifecycle.state; + +import com.redhat.thermostat.beans.property.ChangeListener; +import com.redhat.thermostat.beans.property.ObservableValue; +import com.redhat.thermostat.platform.mvc.Workbench; + +/** + */ +public class Init implements StateAction { + @Override + public void execute(final Context context) { + context.platform.queueOnViewThread(new Runnable() { + @Override + public void run() { + context.provider.getView().init(context.platform); + registerListenerOnVisibleProperty(context); + + context.platform.queueOnApplicationThread(new Runnable() { + @Override + public void run() { + context.provider.getModel().init(context.platform); + context.provider.getController().init(context.platform, + context.provider.getModel(), + context.provider.getView()); + context.registrar.checkAndRegister(context.provider); + if (context.provider instanceof Workbench) { + context.dispatcher.dispatch(State.START); + } + } + }); + } + }); + } + + private void registerListenerOnVisibleProperty(final Context context) { + context.provider.getView().showingProperty().addListener(new ChangeListener<Boolean>() { + @Override + public void changed(ObservableValue<? extends Boolean> observable, Boolean oldValue, Boolean newValue) { + State state = newValue ? State.START : State.STOP; + context.dispatcher.dispatch(state); + } + }); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/platform/core/src/main/java/com/redhat/thermostat/platform/internal/mvc/lifecycle/state/Invalid.java Wed Oct 26 17:22:43 2016 +0200 @@ -0,0 +1,49 @@ +/* + * Copyright 2012-2016 Red Hat, Inc. + * + * This file is part of Thermostat. + * + * Thermostat is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published + * by the Free Software Foundation; either version 2, or (at your + * option) any later version. + * + * Thermostat is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Thermostat; see the file COPYING. If not see + * <http://www.gnu.org/licenses/>. + * + * Linking this code with other modules is making a combined work + * based on this code. Thus, the terms and conditions of the GNU + * General Public License cover the whole combination. + * + * As a special exception, the copyright holders of this code give + * you permission to link this code with independent modules to + * produce an executable, regardless of the license terms of these + * independent modules, and to copy and distribute the resulting + * executable under terms of your choice, provided that you also + * meet, for each linked independent module, the terms and conditions + * of the license of that module. An independent module is a module + * which is not derived from or based on this code. If you modify + * this code, you may extend this exception to your version of the + * library, but you are not obligated to do so. If you do not wish + * to do so, delete this exception statement from your version. + */ + +package com.redhat.thermostat.platform.internal.mvc.lifecycle.state; + +import com.redhat.thermostat.platform.Platform; +import com.redhat.thermostat.platform.mvc.MVCProvider; + +/** + */ +public class Invalid implements StateAction { + @Override + public void execute(Context context) { + + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/platform/core/src/main/java/com/redhat/thermostat/platform/internal/mvc/lifecycle/state/PlatformServiceRegistrar.java Wed Oct 26 17:22:43 2016 +0200 @@ -0,0 +1,127 @@ +/* + * Copyright 2012-2016 Red Hat, Inc. + * + * This file is part of Thermostat. + * + * Thermostat is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published + * by the Free Software Foundation; either version 2, or (at your + * option) any later version. + * + * Thermostat is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Thermostat; see the file COPYING. If not see + * <http://www.gnu.org/licenses/>. + * + * Linking this code with other modules is making a combined work + * based on this code. Thus, the terms and conditions of the GNU + * General Public License cover the whole combination. + * + * As a special exception, the copyright holders of this code give + * you permission to link this code with independent modules to + * produce an executable, regardless of the license terms of these + * independent modules, and to copy and distribute the resulting + * executable under terms of your choice, provided that you also + * meet, for each linked independent module, the terms and conditions + * of the license of that module. An independent module is a module + * which is not derived from or based on this code. If you modify + * this code, you may extend this exception to your version of the + * library, but you are not obligated to do so. If you do not wish + * to do so, delete this exception statement from your version. + */ + +package com.redhat.thermostat.platform.internal.mvc.lifecycle.state; + +import com.redhat.thermostat.common.Constants; +import com.redhat.thermostat.platform.annotations.PlatformService; +import com.redhat.thermostat.platform.mvc.MVCComponent; +import com.redhat.thermostat.platform.mvc.MVCProvider; +import org.osgi.framework.BundleContext; +import org.osgi.framework.FrameworkUtil; + +import java.util.ArrayList; +import java.util.Dictionary; +import java.util.Hashtable; +import java.util.List; +import java.util.concurrent.ExecutorService; + +public class PlatformServiceRegistrar { + private ExecutorService executor; + private BundleContext context; + + public PlatformServiceRegistrar(ExecutorService executor) { + this(executor, FrameworkUtil.getBundle(PlatformServiceRegistrar.class). + getBundleContext()); + } + + // Testing hook + PlatformServiceRegistrar(ExecutorService executor, BundleContext context) { + this.executor = executor; + this.context = context; + } + + public void checkAndRegister(MVCProvider provider) { + checkAndRegisterImpl(provider.getModel()); + checkAndRegisterImpl(provider.getController()); + checkAndRegisterImpl(provider.getView()); + } + + // Testing hook + void checkAndRegisterImpl(MVCComponent component) { + List<String> serviceIds = + getPlatformServiceIDs(component.getClass()); + if (!serviceIds.isEmpty()) { + registerComponent(component, serviceIds); + } + } + + // Testing hook + void registerComponent(final MVCComponent component, + final List<String> serviceIds) + { + Runnable runnable = new Runnable() { + @Override + public void run() { + + Class<? extends MVCComponent> clazz = component.getClass(); + Dictionary<String, String> properties = new Hashtable<>(); + properties.put(Constants.GENERIC_SERVICE_CLASSNAME, clazz.getName()); + + for (String serviceId : serviceIds) { + context.registerService(serviceId, component, properties); + } + } + }; + executor.execute(runnable); + } + + // Testing hook + List<String> getPlatformServiceIDs(Class<? extends MVCComponent> clazz) { + + List<String> services = new ArrayList<>(); + + boolean isService = clazz.isAnnotationPresent(PlatformService.class); + if (isService) { + PlatformService service = clazz.getAnnotation(PlatformService.class); + Class<? extends MVCComponent>[] components = service.service(); + for (Class<? extends MVCComponent> component : components) { + services.add(component.getName()); + } + + String value = service.value(); + if (services.isEmpty() && !value.isEmpty()) { + services.add(value); + } + + if (services.isEmpty()) { + services.add(clazz.getName()); + } + } + + return services; + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/platform/core/src/main/java/com/redhat/thermostat/platform/internal/mvc/lifecycle/state/Start.java Wed Oct 26 17:22:43 2016 +0200 @@ -0,0 +1,66 @@ +/* + * Copyright 2012-2016 Red Hat, Inc. + * + * This file is part of Thermostat. + * + * Thermostat is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published + * by the Free Software Foundation; either version 2, or (at your + * option) any later version. + * + * Thermostat is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Thermostat; see the file COPYING. If not see + * <http://www.gnu.org/licenses/>. + * + * Linking this code with other modules is making a combined work + * based on this code. Thus, the terms and conditions of the GNU + * General Public License cover the whole combination. + * + * As a special exception, the copyright holders of this code give + * you permission to link this code with independent modules to + * produce an executable, regardless of the license terms of these + * independent modules, and to copy and distribute the resulting + * executable under terms of your choice, provided that you also + * meet, for each linked independent module, the terms and conditions + * of the license of that module. An independent module is a module + * which is not derived from or based on this code. If you modify + * this code, you may extend this exception to your version of the + * library, but you are not obligated to do so. If you do not wish + * to do so, delete this exception statement from your version. + */ + +package com.redhat.thermostat.platform.internal.mvc.lifecycle.state; + +import com.redhat.thermostat.platform.Platform; +import com.redhat.thermostat.platform.mvc.MVCProvider; + +/** + */ +public class Start implements StateAction { + @Override + public void execute(final Context context) { + context.platform.queueOnApplicationThread(new Runnable() { + @Override + public void run() { + context.provider.getController().start(); + context.platform.queueOnViewThread(new Runnable() { + @Override + public void run() { + context.provider.getView().start(); + context.platform.queueOnApplicationThread(new Runnable() { + @Override + public void run() { + context.provider.getController().viewStarted(); + } + }); + } + }); + } + }); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/platform/core/src/main/java/com/redhat/thermostat/platform/internal/mvc/lifecycle/state/State.java Wed Oct 26 17:22:43 2016 +0200 @@ -0,0 +1,80 @@ +/* + * Copyright 2012-2016 Red Hat, Inc. + * + * This file is part of Thermostat. + * + * Thermostat is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published + * by the Free Software Foundation; either version 2, or (at your + * option) any later version. + * + * Thermostat is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Thermostat; see the file COPYING. If not see + * <http://www.gnu.org/licenses/>. + * + * Linking this code with other modules is making a combined work + * based on this code. Thus, the terms and conditions of the GNU + * General Public License cover the whole combination. + * + * As a special exception, the copyright holders of this code give + * you permission to link this code with independent modules to + * produce an executable, regardless of the license terms of these + * independent modules, and to copy and distribute the resulting + * executable under terms of your choice, provided that you also + * meet, for each linked independent module, the terms and conditions + * of the license of that module. An independent module is a module + * which is not derived from or based on this code. If you modify + * this code, you may extend this exception to your version of the + * library, but you are not obligated to do so. If you do not wish + * to do so, delete this exception statement from your version. + */ + +package com.redhat.thermostat.platform.internal.mvc.lifecycle.state; + +import java.util.EnumSet; +import java.util.Set; + +/** + * List of possible states + */ +public enum State { + INVALID(new Invalid()), + CREATE(new Create()), + INIT(new Init()), + START(new Start()), + STOP(new Stop()), + DESTROY(new Destroy()), + + ; + + /** + * Accepted transitions between each state, + */ + Set<State> transitions; + static { + INVALID.transitions = EnumSet.of(CREATE); + CREATE.transitions = EnumSet.of(INIT, DESTROY); + INIT.transitions = EnumSet.of(START, DESTROY); + START.transitions = EnumSet.of(STOP); + STOP.transitions = EnumSet.of(START, DESTROY); + DESTROY.transitions = EnumSet.of(INVALID); + } + + StateAction action; + State(StateAction action) { + this.action = action; + } + + public void execute(Context context) { + action.execute(context); + } + + boolean canGoToState(State other) { + return transitions.contains(other); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/platform/core/src/main/java/com/redhat/thermostat/platform/internal/mvc/lifecycle/state/StateAction.java Wed Oct 26 17:22:43 2016 +0200 @@ -0,0 +1,43 @@ +/* + * Copyright 2012-2016 Red Hat, Inc. + * + * This file is part of Thermostat. + * + * Thermostat is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published + * by the Free Software Foundation; either version 2, or (at your + * option) any later version. + * + * Thermostat is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Thermostat; see the file COPYING. If not see + * <http://www.gnu.org/licenses/>. + * + * Linking this code with other modules is making a combined work + * based on this code. Thus, the terms and conditions of the GNU + * General Public License cover the whole combination. + * + * As a special exception, the copyright holders of this code give + * you permission to link this code with independent modules to + * produce an executable, regardless of the license terms of these + * independent modules, and to copy and distribute the resulting + * executable under terms of your choice, provided that you also + * meet, for each linked independent module, the terms and conditions + * of the license of that module. An independent module is a module + * which is not derived from or based on this code. If you modify + * this code, you may extend this exception to your version of the + * library, but you are not obligated to do so. If you do not wish + * to do so, delete this exception statement from your version. + */ + +package com.redhat.thermostat.platform.internal.mvc.lifecycle.state; + +/** + */ +public interface StateAction { + void execute(Context context); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/platform/core/src/main/java/com/redhat/thermostat/platform/internal/mvc/lifecycle/state/StateMachine.java Wed Oct 26 17:22:43 2016 +0200 @@ -0,0 +1,102 @@ +/* + * Copyright 2012-2016 Red Hat, Inc. + * + * This file is part of Thermostat. + * + * Thermostat is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published + * by the Free Software Foundation; either version 2, or (at your + * option) any later version. + * + * Thermostat is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Thermostat; see the file COPYING. If not see + * <http://www.gnu.org/licenses/>. + * + * Linking this code with other modules is making a combined work + * based on this code. Thus, the terms and conditions of the GNU + * General Public License cover the whole combination. + * + * As a special exception, the copyright holders of this code give + * you permission to link this code with independent modules to + * produce an executable, regardless of the license terms of these + * independent modules, and to copy and distribute the resulting + * executable under terms of your choice, provided that you also + * meet, for each linked independent module, the terms and conditions + * of the license of that module. An independent module is a module + * which is not derived from or based on this code. If you modify + * this code, you may extend this exception to your version of the + * library, but you are not obligated to do so. If you do not wish + * to do so, delete this exception statement from your version. + */ + +package com.redhat.thermostat.platform.internal.mvc.lifecycle.state; + +import com.redhat.thermostat.beans.property.ObjectProperty; +import com.redhat.thermostat.platform.Platform; +import com.redhat.thermostat.platform.event.EventQueue; +import com.redhat.thermostat.platform.mvc.MVCProvider; + +/** + */ +public class StateMachine { + + private Context context; + private ObjectProperty<State> stateProperty; + + public StateMachine(MVCProvider provider, Platform platform, + PlatformServiceRegistrar registrar, + EventQueue eventQueue) { + + context = new Context(); + context.platform = platform; + context.provider = provider; + context.dispatcher = new StateMachineTransitionDispatcher(eventQueue, this); + context.registrar = registrar; + stateProperty = new ObjectProperty<>(State.INVALID); + } + + public void start() { + setState(State.CREATE); + } + + public ObjectProperty<State> stateProperty() { + return stateProperty; + } + + boolean canGoToState(State state) { + return stateProperty.get().canGoToState(state); + } + + void setStateInternal(State newState) { + stateProperty.set(newState); + } + + public void setState(State newState) { + if (canGoToState(newState)) { + setStateInternal(newState); + stateProperty.get().execute(context); + } + } + + public void stop() { + State currentState = stateProperty.get(); + + if (currentState.equals(State.INVALID) || currentState.equals(State.DESTROY)) { + // do nothing + return; + } + + if (canGoToState(State.DESTROY)) { + setState(State.DESTROY); + + } else if (stateProperty.get().equals(State.START)) { + setState(State.STOP); + setState(State.DESTROY); + } + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/platform/core/src/main/java/com/redhat/thermostat/platform/internal/mvc/lifecycle/state/StateMachineTransitionDispatcher.java Wed Oct 26 17:22:43 2016 +0200 @@ -0,0 +1,61 @@ +/* + * Copyright 2012-2016 Red Hat, Inc. + * + * This file is part of Thermostat. + * + * Thermostat is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published + * by the Free Software Foundation; either version 2, or (at your + * option) any later version. + * + * Thermostat is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Thermostat; see the file COPYING. If not see + * <http://www.gnu.org/licenses/>. + * + * Linking this code with other modules is making a combined work + * based on this code. Thus, the terms and conditions of the GNU + * General Public License cover the whole combination. + * + * As a special exception, the copyright holders of this code give + * you permission to link this code with independent modules to + * produce an executable, regardless of the license terms of these + * independent modules, and to copy and distribute the resulting + * executable under terms of your choice, provided that you also + * meet, for each linked independent module, the terms and conditions + * of the license of that module. An independent module is a module + * which is not derived from or based on this code. If you modify + * this code, you may extend this exception to your version of the + * library, but you are not obligated to do so. If you do not wish + * to do so, delete this exception statement from your version. + */ + +package com.redhat.thermostat.platform.internal.mvc.lifecycle.state; + +import com.redhat.thermostat.platform.event.EventQueue; + +class StateMachineTransitionDispatcher { + private EventQueue eventQueue; + private StateMachine stateMachine; + + StateMachineTransitionDispatcher(EventQueue eventQueue, + StateMachine stateMachine) + { + this.eventQueue = eventQueue; + this.stateMachine = stateMachine; + } + + public void dispatch(final State newState) { + + eventQueue.runLater(new Runnable() { + @Override + public void run() { + stateMachine.setState(newState); + } + }); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/platform/core/src/main/java/com/redhat/thermostat/platform/internal/mvc/lifecycle/state/Stop.java Wed Oct 26 17:22:43 2016 +0200 @@ -0,0 +1,66 @@ +/* + * Copyright 2012-2016 Red Hat, Inc. + * + * This file is part of Thermostat. + * + * Thermostat is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published + * by the Free Software Foundation; either version 2, or (at your + * option) any later version. + * + * Thermostat is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Thermostat; see the file COPYING. If not see + * <http://www.gnu.org/licenses/>. + * + * Linking this code with other modules is making a combined work + * based on this code. Thus, the terms and conditions of the GNU + * General Public License cover the whole combination. + * + * As a special exception, the copyright holders of this code give + * you permission to link this code with independent modules to + * produce an executable, regardless of the license terms of these + * independent modules, and to copy and distribute the resulting + * executable under terms of your choice, provided that you also + * meet, for each linked independent module, the terms and conditions + * of the license of that module. An independent module is a module + * which is not derived from or based on this code. If you modify + * this code, you may extend this exception to your version of the + * library, but you are not obligated to do so. If you do not wish + * to do so, delete this exception statement from your version. + */ + +package com.redhat.thermostat.platform.internal.mvc.lifecycle.state; + +import com.redhat.thermostat.platform.Platform; +import com.redhat.thermostat.platform.mvc.MVCProvider; + +/** + */ +public class Stop implements StateAction { + @Override + public void execute(final Context context) { + context.platform.queueOnApplicationThread(new Runnable() { + @Override + public void run() { + context.provider.getController().stop(); + context.platform.queueOnViewThread(new Runnable() { + @Override + public void run() { + context.provider.getView().stop(); + context.platform.queueOnApplicationThread(new Runnable() { + @Override + public void run() { + context.provider.getController().viewStopped(); + } + }); + } + }); + } + }); + } +}
--- a/platform/core/src/test/java/com/redhat/thermostat/platform/internal/mvc/lifecycle/handlers/LifeCycleStateHandlerTest.java Tue Oct 25 18:12:39 2016 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,380 +0,0 @@ -/* - * Copyright 2012-2016 Red Hat, Inc. - * - * This file is part of Thermostat. - * - * Thermostat is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published - * by the Free Software Foundation; either version 2, or (at your - * option) any later version. - * - * Thermostat is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Thermostat; see the file COPYING. If not see - * <http://www.gnu.org/licenses/>. - * - * Linking this code with other modules is making a combined work - * based on this code. Thus, the terms and conditions of the GNU - * General Public License cover the whole combination. - * - * As a special exception, the copyright holders of this code give - * you permission to link this code with independent modules to - * produce an executable, regardless of the license terms of these - * independent modules, and to copy and distribute the resulting - * executable under terms of your choice, provided that you also - * meet, for each linked independent module, the terms and conditions - * of the license of that module. An independent module is a module - * which is not derived from or based on this code. If you modify - * this code, you may extend this exception to your version of the - * library, but you are not obligated to do so. If you do not wish - * to do so, delete this exception statement from your version. - */ - -package com.redhat.thermostat.platform.internal.mvc.lifecycle.handlers; - -import com.redhat.thermostat.beans.property.BooleanProperty; -import com.redhat.thermostat.common.ActionEvent; -import com.redhat.thermostat.common.ApplicationService; -import com.redhat.thermostat.platform.Platform; -import com.redhat.thermostat.platform.internal.mvc.lifecycle.ControllerLifeCycleState; -import com.redhat.thermostat.platform.internal.mvc.lifecycle.LifeCycle; -import com.redhat.thermostat.platform.mvc.Controller; -import com.redhat.thermostat.platform.mvc.MVCProvider; -import com.redhat.thermostat.platform.mvc.Model; -import com.redhat.thermostat.platform.mvc.View; -import com.redhat.thermostat.platform.mvc.Workbench; -import org.junit.Before; -import org.junit.Test; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertTrue; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.verifyNoMoreInteractions; -import static org.mockito.Mockito.when; - -/** - */ -public class LifeCycleStateHandlerTest { - - private BooleanProperty showing; - - private TestPlatform platform; - private PlatformServiceRegistrar serviceRegistrar; - private LifeCycleTransitionDispatcher dispatcher; - - private Workbench workbenchProvider; - private MVCProvider provider; - private View view; - private Model model; - private Controller controller; - - private ActionEvent<LifeCycle> actionEvent; - - @Before - public void setUp() { - provider = mock(MVCProvider.class); - workbenchProvider = mock(Workbench.class); - - view = mock(View.class); - when(provider.getView()).thenReturn(view); - when(workbenchProvider.getView()).thenReturn(view); - - showing = mock(BooleanProperty.class); - when(view.showingProperty()).thenReturn(showing); - - model = mock(Model.class); - when(provider.getModel()).thenReturn(model); - when(workbenchProvider.getModel()).thenReturn(model); - - controller = mock(Controller.class); - when(provider.getController()).thenReturn(controller); - when(workbenchProvider.getController()).thenReturn(controller); - - platform = new TestPlatform(); - serviceRegistrar = mock(PlatformServiceRegistrar.class); - actionEvent = mock(ActionEvent.class); - dispatcher = mock(LifeCycleTransitionDispatcher.class); - } - - private LifeCycleStateHandler createHandler(MVCProvider provider) { - LifeCycleStateHandler handler = - new LifeCycleStateHandler(provider, platform, serviceRegistrar); - handler.setDispatcher(dispatcher); - return handler; - } - - @Test - public void test_CREATE_VIEW() { - when(actionEvent.getActionId()).thenReturn(LifeCycle.CREATE_VIEW); - - LifeCycleStateHandler handler = createHandler(provider); - handler.actionPerformed(actionEvent); - - platform.viewRunnable.run(); - verify(view).create(); - verify(dispatcher).requestLifeCycleTransition(LifeCycle.VIEW_CREATED); - } - - @Test - public void test_VIEW_CREATED() { - when(actionEvent.getActionId()).thenReturn(LifeCycle.VIEW_CREATED); - - LifeCycleStateHandler handler = createHandler(provider); - handler.actionPerformed(actionEvent); - - platform.applicationRunnable.run(); - verify(model).create(); - verify(controller).create(); - verify(dispatcher).requestLifeCycleTransition(LifeCycle.INIT_VIEW); - } - - @Test - public void test_INIT_VIEW() { - when(actionEvent.getActionId()).thenReturn(LifeCycle.INIT_VIEW); - - LifeCycleStateHandler handler = createHandler(provider); - handler.actionPerformed(actionEvent); - - platform.viewRunnable.run(); - verify(view).init(platform); - - verify(dispatcher).requestLifeCycleTransition(LifeCycle.VIEW_INITIALIZED); - } - - @Test - public void test_VIEW_INITIALIZED() { - when(actionEvent.getActionId()).thenReturn(LifeCycle.VIEW_INITIALIZED); - - LifeCycleStateHandler handler = createHandler(provider); - - handler.actionPerformed(actionEvent); - - assertEquals(ControllerLifeCycleState.PRE_INIT, handler.getCurrentControllerState()); - - platform.applicationRunnable.run(); - verify(model).init(platform); - verify(controller).init(platform, model, view); - - assertEquals(ControllerLifeCycleState.STOPPED, handler.getCurrentControllerState()); - - verify(dispatcher).requestLifeCycleTransition(LifeCycle.REGISTER_MVC); - } - - @Test - public void test_REGISTER_MVC() { - when(actionEvent.getActionId()).thenReturn(LifeCycle.REGISTER_MVC); - - LifeCycleStateHandler handler = createHandler(provider); - handler.actionPerformed(actionEvent); - - platform.applicationRunnable.run(); - verify(serviceRegistrar).checkAndRegister(provider); - - // this is not true for a Workbench provider, it is tested later - verifyNoMoreInteractions(dispatcher); - } - - @Test - public void test_REGISTER_MVC_Workbench() { - when(actionEvent.getActionId()).thenReturn(LifeCycle.REGISTER_MVC); - - LifeCycleStateHandler handler = createHandler(workbenchProvider); - handler.actionPerformed(actionEvent); - - platform.applicationRunnable.run(); - verify(serviceRegistrar).checkAndRegister(workbenchProvider); - - verify(dispatcher).requestLifeCycleTransition(LifeCycle.START_CONTROLLER); - } - - @Test - public void test_REGISTER_MVC_StartOnVisible() { - when(actionEvent.getActionId()).thenReturn(LifeCycle.REGISTER_MVC); - when(showing.get()).thenReturn(true); - - LifeCycleStateHandler handler = createHandler(provider); - handler.actionPerformed(actionEvent); - - platform.applicationRunnable.run(); - - verify(dispatcher).requestLifeCycleTransition(LifeCycle.START_CONTROLLER); - } - - @Test - public void test_START_CONTROLLER() { - when(actionEvent.getActionId()).thenReturn(LifeCycle.START_CONTROLLER); - - LifeCycleStateHandler handler = createHandler(provider); - - handler.actionPerformed(actionEvent); - - assertFalse(handler.getCurrentControllerState().equals(ControllerLifeCycleState.STARTED)); - - platform.applicationRunnable.run(); - verify(controller).start(); - - assertEquals(ControllerLifeCycleState.STARTED, handler.getCurrentControllerState()); - - verify(dispatcher).requestLifeCycleTransition(LifeCycle.START_VIEW); - } - - @Test - public void test_START_VIEW() { - when(actionEvent.getActionId()).thenReturn(LifeCycle.START_VIEW); - - LifeCycleStateHandler handler = createHandler(provider); - - handler.actionPerformed(actionEvent); - - platform.viewRunnable.run(); - verify(view).start(); - - verify(dispatcher).requestLifeCycleTransition(LifeCycle.STARTED); - } - - @Test - public void test_STARTED() { - when(actionEvent.getActionId()).thenReturn(LifeCycle.STARTED); - - LifeCycleStateHandler handler = createHandler(provider); - - handler.actionPerformed(actionEvent); - - platform.applicationRunnable.run(); - verify(controller).viewStarted(); - - verifyNoMoreInteractions(dispatcher); - } - - @Test - public void test_STOP_CONTROLLER() { - when(actionEvent.getActionId()).thenReturn(LifeCycle.STOP_CONTROLLER); - - LifeCycleStateHandler handler = createHandler(provider); - - handler.actionPerformed(actionEvent); - - // in a real lifecycle this should not be PRE_INIT but STARTED - assertEquals(ControllerLifeCycleState.PRE_INIT, handler.getCurrentControllerState()); - - platform.applicationRunnable.run(); - verify(controller).stop(); - - assertEquals(ControllerLifeCycleState.STOPPED, handler.getCurrentControllerState()); - - verify(dispatcher).requestLifeCycleTransition(LifeCycle.STOP_VIEW); - } - - @Test - public void test_STOP_VIEW() { - when(actionEvent.getActionId()).thenReturn(LifeCycle.STOP_VIEW); - - LifeCycleStateHandler handler = createHandler(provider); - - handler.actionPerformed(actionEvent); - - platform.viewRunnable.run(); - verify(view).stop(); - - verify(dispatcher).requestLifeCycleTransition(LifeCycle.STOPPED); - } - - @Test - public void test_STOPPED() { - when(actionEvent.getActionId()).thenReturn(LifeCycle.STOPPED); - - LifeCycleStateHandler handler = createHandler(provider); - - handler.actionPerformed(actionEvent); - - platform.applicationRunnable.run(); - verify(controller).viewStopped(); - - verifyNoMoreInteractions(dispatcher); - } - - @Test - public void test_DESTROY_VIEW() { - when(actionEvent.getActionId()).thenReturn(LifeCycle.DESTROY_VIEW); - - LifeCycleStateHandler handler = createHandler(provider); - - handler.actionPerformed(actionEvent); - - platform.viewRunnable.run(); - verify(view).destroy(); - - verify(dispatcher).requestLifeCycleTransition(LifeCycle.DESTROY); - } - - @Test - public void test_DESTROY() { - when(actionEvent.getActionId()).thenReturn(LifeCycle.DESTROY); - - LifeCycleStateHandler handler = createHandler(provider); - - handler.actionPerformed(actionEvent); - - platform.applicationRunnable.run(); - verify(controller).destroy(); - verify(model).destroy(); - - verify(dispatcher).requestLifeCycleTransition(LifeCycle.DESTROYED); - } - - @Test - public void test_DESTROYED() { - when(actionEvent.getActionId()).thenReturn(LifeCycle.DESTROYED); - - LifeCycleStateHandler handler = createHandler(provider); - - assertFalse(handler.shutdownProperty().get()); - - handler.actionPerformed(actionEvent); - - assertNull(platform.applicationRunnable); - assertNull(platform.viewRunnable); - - assertTrue(handler.shutdownProperty().get()); - - verifyNoMoreInteractions(dispatcher); - } - - private class TestPlatform implements Platform { - - Runnable applicationRunnable; - Runnable viewRunnable; - - @Override - public void queueOnApplicationThread(Runnable runnable) { - applicationRunnable = runnable; - } - - @Override - public void queueOnViewThread(Runnable runnable) { - viewRunnable = runnable; - } - - @Override - public boolean isViewThread() { - return true; - } - - @Override - public boolean isApplicationThread() { - return true; - } - - @Override - public ApplicationService getAppService() { - return null; - } - } -}
--- a/platform/core/src/test/java/com/redhat/thermostat/platform/internal/mvc/lifecycle/handlers/PlatformServiceRegistrarTest.java Tue Oct 25 18:12:39 2016 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,121 +0,0 @@ -/* - * Copyright 2012-2016 Red Hat, Inc. - * - * This file is part of Thermostat. - * - * Thermostat is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published - * by the Free Software Foundation; either version 2, or (at your - * option) any later version. - * - * Thermostat is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Thermostat; see the file COPYING. If not see - * <http://www.gnu.org/licenses/>. - * - * Linking this code with other modules is making a combined work - * based on this code. Thus, the terms and conditions of the GNU - * General Public License cover the whole combination. - * - * As a special exception, the copyright holders of this code give - * you permission to link this code with independent modules to - * produce an executable, regardless of the license terms of these - * independent modules, and to copy and distribute the resulting - * executable under terms of your choice, provided that you also - * meet, for each linked independent module, the terms and conditions - * of the license of that module. An independent module is a module - * which is not derived from or based on this code. If you modify - * this code, you may extend this exception to your version of the - * library, but you are not obligated to do so. If you do not wish - * to do so, delete this exception statement from your version. - */ - -package com.redhat.thermostat.platform.internal.mvc.lifecycle.handlers; - -import com.redhat.thermostat.platform.annotations.PlatformService; -import com.redhat.thermostat.platform.mvc.Model; -import org.junit.Before; -import org.junit.Test; -import org.osgi.framework.BundleContext; - -import java.util.List; -import java.util.concurrent.ExecutorService; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; -import static org.mockito.Mockito.mock; - -/** - */ -public class PlatformServiceRegistrarTest { - - @PlatformService - private class TestClassEmptyNames extends Model {} - - @PlatformService("TestClass") - private class TestClassWithValue extends TestClassEmptyNames {} - - @PlatformService(service = { Model.class, TestClassWithServices.class }) - private class TestClassWithServices extends TestClassWithValue {} - - @PlatformService( - service = { Model.class, TestClassWithServices.class }, - value = "ThisShouldNotAppearInTheList" - ) - private class TestClassWithServices2 extends Model {} - - private ExecutorService executorService; - private BundleContext context; - - @Before - public void setUp() { - executorService = mock(ExecutorService.class); - context = mock(BundleContext.class); - } - - @Test - public void testAnnotationParserEmpty() throws Exception { - PlatformServiceRegistrar registrar = - new PlatformServiceRegistrar(executorService, context); - - List<String> results = registrar.getPlatformServiceIDs(TestClassEmptyNames.class); - assertEquals(1, results.size()); - assertEquals(TestClassEmptyNames.class.getName(), results.get(0)); - } - - @Test - public void testAnnotationParserOnlyValue() throws Exception { - PlatformServiceRegistrar registrar = - new PlatformServiceRegistrar(executorService, context); - - List<String> results = registrar.getPlatformServiceIDs(TestClassWithValue.class); - assertEquals(1, results.size()); - assertEquals("TestClass", results.get(0)); - } - - @Test - public void testAnnotationParserWithServices() throws Exception { - PlatformServiceRegistrar registrar = - new PlatformServiceRegistrar(executorService, context); - - List<String> results = registrar.getPlatformServiceIDs(TestClassWithServices.class); - assertEquals(2, results.size()); - assertTrue(results.contains(TestClassWithServices.class.getName())); - assertTrue(results.contains(Model.class.getName())); - } - - @Test - public void testAnnotationParserWithServices2() throws Exception { - PlatformServiceRegistrar registrar = - new PlatformServiceRegistrar(executorService, context); - - List<String> results = registrar.getPlatformServiceIDs(TestClassWithServices.class); - assertEquals(2, results.size()); - assertTrue(results.contains(TestClassWithServices.class.getName())); - assertTrue(results.contains(Model.class.getName())); - } -}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/platform/core/src/test/java/com/redhat/thermostat/platform/internal/mvc/lifecycle/state/CreateTest.java Wed Oct 26 17:22:43 2016 +0200 @@ -0,0 +1,109 @@ +/* + * Copyright 2012-2016 Red Hat, Inc. + * + * This file is part of Thermostat. + * + * Thermostat is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published + * by the Free Software Foundation; either version 2, or (at your + * option) any later version. + * + * Thermostat is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Thermostat; see the file COPYING. If not see + * <http://www.gnu.org/licenses/>. + * + * Linking this code with other modules is making a combined work + * based on this code. Thus, the terms and conditions of the GNU + * General Public License cover the whole combination. + * + * As a special exception, the copyright holders of this code give + * you permission to link this code with independent modules to + * produce an executable, regardless of the license terms of these + * independent modules, and to copy and distribute the resulting + * executable under terms of your choice, provided that you also + * meet, for each linked independent module, the terms and conditions + * of the license of that module. An independent module is a module + * which is not derived from or based on this code. If you modify + * this code, you may extend this exception to your version of the + * library, but you are not obligated to do so. If you do not wish + * to do so, delete this exception statement from your version. + */ + +package com.redhat.thermostat.platform.internal.mvc.lifecycle.state; + +import com.redhat.thermostat.platform.Platform; +import com.redhat.thermostat.platform.mvc.Controller; +import com.redhat.thermostat.platform.mvc.MVCProvider; +import com.redhat.thermostat.platform.mvc.Model; +import com.redhat.thermostat.platform.mvc.View; +import org.junit.Before; +import org.junit.Test; +import org.mockito.ArgumentCaptor; + +import static org.mockito.Mockito.doNothing; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.verifyZeroInteractions; +import static org.mockito.Mockito.when; + +/** + */ +public class CreateTest { + private MVCProvider provider; + private Platform platform; + private StateMachineTransitionDispatcher dispatcher; + private Context context; + private View view; + private Controller controller; + private Model model; + + @Before + public void setUp() { + provider = mock(MVCProvider.class); + platform = mock(Platform.class); + dispatcher = mock(StateMachineTransitionDispatcher.class); + + view = mock(View.class); + model = mock(Model.class); + controller = mock(Controller.class); + + when(provider.getView()).thenReturn(view); + when(provider.getController()).thenReturn(controller); + when(provider.getModel()).thenReturn(model); + + context = new Context(); + context.dispatcher = dispatcher; + context.provider = provider; + context.platform = platform; + } + + @Test + public void execute() throws Exception { + + ArgumentCaptor<Runnable> captor0 = ArgumentCaptor.forClass(Runnable.class); + ArgumentCaptor<Runnable> captor1 = ArgumentCaptor.forClass(Runnable.class); + + doNothing().when(platform).queueOnApplicationThread(captor0.capture()); + doNothing().when(platform).queueOnViewThread(captor1.capture()); + + Create create = new Create(); + create.execute(context); + + captor1.getValue().run(); + verify(view).create(); + + verifyZeroInteractions(dispatcher); + + captor0.getValue().run(); + verify(model).create(); + verify(controller).create(); + + verify(dispatcher, times(1)).dispatch(State.INIT); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/platform/core/src/test/java/com/redhat/thermostat/platform/internal/mvc/lifecycle/state/DestroyTest.java Wed Oct 26 17:22:43 2016 +0200 @@ -0,0 +1,103 @@ +/* + * Copyright 2012-2016 Red Hat, Inc. + * + * This file is part of Thermostat. + * + * Thermostat is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published + * by the Free Software Foundation; either version 2, or (at your + * option) any later version. + * + * Thermostat is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Thermostat; see the file COPYING. If not see + * <http://www.gnu.org/licenses/>. + * + * Linking this code with other modules is making a combined work + * based on this code. Thus, the terms and conditions of the GNU + * General Public License cover the whole combination. + * + * As a special exception, the copyright holders of this code give + * you permission to link this code with independent modules to + * produce an executable, regardless of the license terms of these + * independent modules, and to copy and distribute the resulting + * executable under terms of your choice, provided that you also + * meet, for each linked independent module, the terms and conditions + * of the license of that module. An independent module is a module + * which is not derived from or based on this code. If you modify + * this code, you may extend this exception to your version of the + * library, but you are not obligated to do so. If you do not wish + * to do so, delete this exception statement from your version. + */ + +package com.redhat.thermostat.platform.internal.mvc.lifecycle.state; + +import com.redhat.thermostat.platform.Platform; +import com.redhat.thermostat.platform.mvc.Controller; +import com.redhat.thermostat.platform.mvc.MVCProvider; +import com.redhat.thermostat.platform.mvc.Model; +import com.redhat.thermostat.platform.mvc.View; +import org.junit.Before; +import org.junit.Test; +import org.mockito.ArgumentCaptor; + +import static org.mockito.Mockito.doNothing; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +/** + */ +public class DestroyTest { + private MVCProvider provider; + private Platform platform; + private StateMachineTransitionDispatcher dispatcher; + private Context context; + private View view; + private Controller controller; + private Model model; + + @Before + public void setUp() { + provider = mock(MVCProvider.class); + platform = mock(Platform.class); + dispatcher = mock(StateMachineTransitionDispatcher.class); + + view = mock(View.class); + model = mock(Model.class); + controller = mock(Controller.class); + + when(provider.getView()).thenReturn(view); + when(provider.getController()).thenReturn(controller); + when(provider.getModel()).thenReturn(model); + + context = new Context(); + context.dispatcher = dispatcher; + context.provider = provider; + context.platform = platform; + } + + @Test + public void execute() throws Exception { + + ArgumentCaptor<Runnable> captor0 = ArgumentCaptor.forClass(Runnable.class); + ArgumentCaptor<Runnable> captor1 = ArgumentCaptor.forClass(Runnable.class); + + doNothing().when(platform).queueOnApplicationThread(captor0.capture()); + doNothing().when(platform).queueOnViewThread(captor1.capture()); + + Destroy destroy = new Destroy(); + destroy.execute(context); + + captor0.getValue().run(); + verify(controller).destroy(); + verify(model).destroy(); + + captor1.getValue().run(); + verify(view).destroy(); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/platform/core/src/test/java/com/redhat/thermostat/platform/internal/mvc/lifecycle/state/InitTest.java Wed Oct 26 17:22:43 2016 +0200 @@ -0,0 +1,138 @@ +/* + * Copyright 2012-2016 Red Hat, Inc. + * + * This file is part of Thermostat. + * + * Thermostat is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published + * by the Free Software Foundation; either version 2, or (at your + * option) any later version. + * + * Thermostat is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Thermostat; see the file COPYING. If not see + * <http://www.gnu.org/licenses/>. + * + * Linking this code with other modules is making a combined work + * based on this code. Thus, the terms and conditions of the GNU + * General Public License cover the whole combination. + * + * As a special exception, the copyright holders of this code give + * you permission to link this code with independent modules to + * produce an executable, regardless of the license terms of these + * independent modules, and to copy and distribute the resulting + * executable under terms of your choice, provided that you also + * meet, for each linked independent module, the terms and conditions + * of the license of that module. An independent module is a module + * which is not derived from or based on this code. If you modify + * this code, you may extend this exception to your version of the + * library, but you are not obligated to do so. If you do not wish + * to do so, delete this exception statement from your version. + */ + +package com.redhat.thermostat.platform.internal.mvc.lifecycle.state; + +import com.redhat.thermostat.beans.property.BooleanProperty; +import com.redhat.thermostat.beans.property.ChangeListener; +import com.redhat.thermostat.platform.Platform; +import com.redhat.thermostat.platform.mvc.Controller; +import com.redhat.thermostat.platform.mvc.MVCProvider; +import com.redhat.thermostat.platform.mvc.Model; +import com.redhat.thermostat.platform.mvc.View; +import org.junit.Before; +import org.junit.Test; +import org.mockito.ArgumentCaptor; + +import static org.mockito.Matchers.any; +import static org.mockito.Mockito.doNothing; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +/** + */ +public class InitTest { + + private MVCProvider provider; + private Platform platform; + private StateMachineTransitionDispatcher dispatcher; + private Context context; + private View view; + private Controller controller; + private Model model; + private PlatformServiceRegistrar registrar; + private BooleanProperty visible; + + @Before + public void setUp() { + provider = mock(MVCProvider.class); + platform = mock(Platform.class); + dispatcher = mock(StateMachineTransitionDispatcher.class); + visible = mock(BooleanProperty.class); + registrar = mock(PlatformServiceRegistrar.class); + + view = mock(View.class); + when(view.showingProperty()).thenReturn(visible); + + model = mock(Model.class); + controller = mock(Controller.class); + + when(provider.getView()).thenReturn(view); + when(provider.getController()).thenReturn(controller); + when(provider.getModel()).thenReturn(model); + + context = new Context(); + context.dispatcher = dispatcher; + context.provider = provider; + context.platform = platform; + context.registrar = registrar; + } + + @Test + public void execute() throws Exception { + ArgumentCaptor<Runnable> captor0 = ArgumentCaptor.forClass(Runnable.class); + ArgumentCaptor<Runnable> captor1 = ArgumentCaptor.forClass(Runnable.class); + + doNothing().when(platform).queueOnApplicationThread(captor0.capture()); + doNothing().when(platform).queueOnViewThread(captor1.capture()); + + Init init = new Init(); + init.execute(context); + + captor1.getValue().run(); + + verify(view).init(platform); + verify(visible).addListener(any(ChangeListener.class)); + + captor0.getValue().run(); + + verify(model).init(platform); + verify(controller).init(platform, model, view); + verify(context.registrar).checkAndRegister(context.provider); + } + + @Test + public void reactToVisibilityChange() throws Exception { + + ArgumentCaptor<Runnable> captor1 = ArgumentCaptor.forClass(Runnable.class); + ArgumentCaptor<ChangeListener> captor2 = ArgumentCaptor.forClass(ChangeListener.class); + + doNothing().when(platform).queueOnViewThread(captor1.capture()); + doNothing().when(visible).addListener(captor2.capture()); + + Init init = new Init(); + init.execute(context); + + captor1.getValue().run(); + + captor2.getValue().changed(visible, true, false); + verify(context.dispatcher).dispatch(State.STOP); + + captor2.getValue().changed(visible, false, true); + verify(context.dispatcher).dispatch(State.START); + } +} \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/platform/core/src/test/java/com/redhat/thermostat/platform/internal/mvc/lifecycle/state/PlatformServiceRegistrarTest.java Wed Oct 26 17:22:43 2016 +0200 @@ -0,0 +1,121 @@ +/* + * Copyright 2012-2016 Red Hat, Inc. + * + * This file is part of Thermostat. + * + * Thermostat is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published + * by the Free Software Foundation; either version 2, or (at your + * option) any later version. + * + * Thermostat is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Thermostat; see the file COPYING. If not see + * <http://www.gnu.org/licenses/>. + * + * Linking this code with other modules is making a combined work + * based on this code. Thus, the terms and conditions of the GNU + * General Public License cover the whole combination. + * + * As a special exception, the copyright holders of this code give + * you permission to link this code with independent modules to + * produce an executable, regardless of the license terms of these + * independent modules, and to copy and distribute the resulting + * executable under terms of your choice, provided that you also + * meet, for each linked independent module, the terms and conditions + * of the license of that module. An independent module is a module + * which is not derived from or based on this code. If you modify + * this code, you may extend this exception to your version of the + * library, but you are not obligated to do so. If you do not wish + * to do so, delete this exception statement from your version. + */ + +package com.redhat.thermostat.platform.internal.mvc.lifecycle.state; + +import com.redhat.thermostat.platform.annotations.PlatformService; +import com.redhat.thermostat.platform.mvc.Model; +import org.junit.Before; +import org.junit.Test; +import org.osgi.framework.BundleContext; + +import java.util.List; +import java.util.concurrent.ExecutorService; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; +import static org.mockito.Mockito.mock; + +/** + */ +public class PlatformServiceRegistrarTest { + + @PlatformService + private class TestClassEmptyNames extends Model {} + + @PlatformService("TestClass") + private class TestClassWithValue extends TestClassEmptyNames {} + + @PlatformService(service = { Model.class, TestClassWithServices.class }) + private class TestClassWithServices extends TestClassWithValue {} + + @PlatformService( + service = { Model.class, TestClassWithServices.class }, + value = "ThisShouldNotAppearInTheList" + ) + private class TestClassWithServices2 extends Model {} + + private ExecutorService executorService; + private BundleContext context; + + @Before + public void setUp() { + executorService = mock(ExecutorService.class); + context = mock(BundleContext.class); + } + + @Test + public void testAnnotationParserEmpty() throws Exception { + PlatformServiceRegistrar registrar = + new PlatformServiceRegistrar(executorService, context); + + List<String> results = registrar.getPlatformServiceIDs(TestClassEmptyNames.class); + assertEquals(1, results.size()); + assertEquals(TestClassEmptyNames.class.getName(), results.get(0)); + } + + @Test + public void testAnnotationParserOnlyValue() throws Exception { + PlatformServiceRegistrar registrar = + new PlatformServiceRegistrar(executorService, context); + + List<String> results = registrar.getPlatformServiceIDs(TestClassWithValue.class); + assertEquals(1, results.size()); + assertEquals("TestClass", results.get(0)); + } + + @Test + public void testAnnotationParserWithServices() throws Exception { + PlatformServiceRegistrar registrar = + new PlatformServiceRegistrar(executorService, context); + + List<String> results = registrar.getPlatformServiceIDs(TestClassWithServices.class); + assertEquals(2, results.size()); + assertTrue(results.contains(TestClassWithServices.class.getName())); + assertTrue(results.contains(Model.class.getName())); + } + + @Test + public void testAnnotationParserWithServices2() throws Exception { + PlatformServiceRegistrar registrar = + new PlatformServiceRegistrar(executorService, context); + + List<String> results = registrar.getPlatformServiceIDs(TestClassWithServices.class); + assertEquals(2, results.size()); + assertTrue(results.contains(TestClassWithServices.class.getName())); + assertTrue(results.contains(Model.class.getName())); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/platform/core/src/test/java/com/redhat/thermostat/platform/internal/mvc/lifecycle/state/StartTest.java Wed Oct 26 17:22:43 2016 +0200 @@ -0,0 +1,106 @@ +/* + * Copyright 2012-2016 Red Hat, Inc. + * + * This file is part of Thermostat. + * + * Thermostat is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published + * by the Free Software Foundation; either version 2, or (at your + * option) any later version. + * + * Thermostat is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Thermostat; see the file COPYING. If not see + * <http://www.gnu.org/licenses/>. + * + * Linking this code with other modules is making a combined work + * based on this code. Thus, the terms and conditions of the GNU + * General Public License cover the whole combination. + * + * As a special exception, the copyright holders of this code give + * you permission to link this code with independent modules to + * produce an executable, regardless of the license terms of these + * independent modules, and to copy and distribute the resulting + * executable under terms of your choice, provided that you also + * meet, for each linked independent module, the terms and conditions + * of the license of that module. An independent module is a module + * which is not derived from or based on this code. If you modify + * this code, you may extend this exception to your version of the + * library, but you are not obligated to do so. If you do not wish + * to do so, delete this exception statement from your version. + */ + +package com.redhat.thermostat.platform.internal.mvc.lifecycle.state; + +import com.redhat.thermostat.platform.Platform; +import com.redhat.thermostat.platform.mvc.Controller; +import com.redhat.thermostat.platform.mvc.MVCProvider; +import com.redhat.thermostat.platform.mvc.Model; +import com.redhat.thermostat.platform.mvc.View; +import org.junit.Before; +import org.junit.Test; +import org.mockito.ArgumentCaptor; + +import static org.mockito.Mockito.doNothing; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +/** + */ +public class StartTest { + + private MVCProvider provider; + private Platform platform; + private StateMachineTransitionDispatcher dispatcher; + private Context context; + private View view; + private Controller controller; + private Model model; + + @Before + public void setUp() { + provider = mock(MVCProvider.class); + platform = mock(Platform.class); + dispatcher = mock(StateMachineTransitionDispatcher.class); + + view = mock(View.class); + model = mock(Model.class); + controller = mock(Controller.class); + + when(provider.getView()).thenReturn(view); + when(provider.getController()).thenReturn(controller); + when(provider.getModel()).thenReturn(model); + + context = new Context(); + context.dispatcher = dispatcher; + context.provider = provider; + context.platform = platform; + } + + @Test + public void execute() throws Exception { + + ArgumentCaptor<Runnable> captor0 = ArgumentCaptor.forClass(Runnable.class); + ArgumentCaptor<Runnable> captor1 = ArgumentCaptor.forClass(Runnable.class); + + doNothing().when(platform).queueOnApplicationThread(captor0.capture()); + doNothing().when(platform).queueOnViewThread(captor1.capture()); + + Start start = new Start(); + start.execute(context); + + captor0.getValue().run(); + verify(controller).start(); + + captor1.getValue().run(); + verify(view).start(); + + captor0.getValue().run(); + verify(controller).viewStarted(); + } +} \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/platform/core/src/test/java/com/redhat/thermostat/platform/internal/mvc/lifecycle/state/StateMachineTest.java Wed Oct 26 17:22:43 2016 +0200 @@ -0,0 +1,125 @@ +/* + * Copyright 2012-2016 Red Hat, Inc. + * + * This file is part of Thermostat. + * + * Thermostat is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published + * by the Free Software Foundation; either version 2, or (at your + * option) any later version. + * + * Thermostat is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Thermostat; see the file COPYING. If not see + * <http://www.gnu.org/licenses/>. + * + * Linking this code with other modules is making a combined work + * based on this code. Thus, the terms and conditions of the GNU + * General Public License cover the whole combination. + * + * As a special exception, the copyright holders of this code give + * you permission to link this code with independent modules to + * produce an executable, regardless of the license terms of these + * independent modules, and to copy and distribute the resulting + * executable under terms of your choice, provided that you also + * meet, for each linked independent module, the terms and conditions + * of the license of that module. An independent module is a module + * which is not derived from or based on this code. If you modify + * this code, you may extend this exception to your version of the + * library, but you are not obligated to do so. If you do not wish + * to do so, delete this exception statement from your version. + */ + +package com.redhat.thermostat.platform.internal.mvc.lifecycle.state; + +import com.redhat.thermostat.platform.Platform; +import com.redhat.thermostat.platform.event.EventQueue; +import com.redhat.thermostat.platform.mvc.MVCProvider; +import org.junit.Test; + +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.assertFalse; + +import static org.mockito.Mockito.mock; + +/** + */ +public class StateMachineTest { + + @Test + public void stateMachine_canGoToState() { + MVCProvider provider = mock(MVCProvider.class); + Platform platform = mock(Platform.class); + EventQueue eventQueue = mock(EventQueue.class); + PlatformServiceRegistrar registrar = mock(PlatformServiceRegistrar.class); + + StateMachine stateMachine = + new StateMachine(provider, platform, registrar, eventQueue); + + assertTrue(stateMachine.canGoToState(State.CREATE)); + + assertFalse(stateMachine.canGoToState(State.INVALID)); + assertFalse(stateMachine.canGoToState(State.INIT)); + assertFalse(stateMachine.canGoToState(State.START)); + assertFalse(stateMachine.canGoToState(State.STOP)); + assertFalse(stateMachine.canGoToState(State.DESTROY)); + + stateMachine.setStateInternal(State.CREATE); + assertTrue(stateMachine.canGoToState(State.INIT)); + assertTrue(stateMachine.canGoToState(State.DESTROY)); + + assertFalse(stateMachine.canGoToState(State.CREATE)); + assertFalse(stateMachine.canGoToState(State.START)); + assertFalse(stateMachine.canGoToState(State.STOP)); + assertFalse(stateMachine.canGoToState(State.INVALID)); + + stateMachine.setStateInternal(State.INIT); + assertTrue(stateMachine.canGoToState(State.START)); + assertTrue(stateMachine.canGoToState(State.DESTROY)); + + assertFalse(stateMachine.canGoToState(State.CREATE)); + assertFalse(stateMachine.canGoToState(State.INIT)); + assertFalse(stateMachine.canGoToState(State.STOP)); + assertFalse(stateMachine.canGoToState(State.INVALID)); + + stateMachine.setStateInternal(State.START); + assertTrue(stateMachine.canGoToState(State.STOP)); + + assertFalse(stateMachine.canGoToState(State.START)); + assertFalse(stateMachine.canGoToState(State.DESTROY)); + assertFalse(stateMachine.canGoToState(State.CREATE)); + assertFalse(stateMachine.canGoToState(State.INIT)); + assertFalse(stateMachine.canGoToState(State.INVALID)); + + stateMachine.setStateInternal(State.STOP); + assertTrue(stateMachine.canGoToState(State.START)); + assertTrue(stateMachine.canGoToState(State.DESTROY)); + + assertFalse(stateMachine.canGoToState(State.STOP)); + assertFalse(stateMachine.canGoToState(State.CREATE)); + assertFalse(stateMachine.canGoToState(State.INIT)); + assertFalse(stateMachine.canGoToState(State.INVALID)); + + stateMachine.setStateInternal(State.STOP); + assertTrue(stateMachine.canGoToState(State.START)); + assertTrue(stateMachine.canGoToState(State.DESTROY)); + + assertFalse(stateMachine.canGoToState(State.STOP)); + assertFalse(stateMachine.canGoToState(State.CREATE)); + assertFalse(stateMachine.canGoToState(State.INIT)); + assertFalse(stateMachine.canGoToState(State.INVALID)); + + stateMachine.setStateInternal(State.DESTROY); + assertTrue(stateMachine.canGoToState(State.INVALID)); + + assertFalse(stateMachine.canGoToState(State.START)); + assertFalse(stateMachine.canGoToState(State.STOP)); + assertFalse(stateMachine.canGoToState(State.CREATE)); + assertFalse(stateMachine.canGoToState(State.INIT)); + assertFalse(stateMachine.canGoToState(State.DESTROY)); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/platform/core/src/test/java/com/redhat/thermostat/platform/internal/mvc/lifecycle/state/StateTest.java Wed Oct 26 17:22:43 2016 +0200 @@ -0,0 +1,134 @@ +/* + * Copyright 2012-2016 Red Hat, Inc. + * + * This file is part of Thermostat. + * + * Thermostat is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published + * by the Free Software Foundation; either version 2, or (at your + * option) any later version. + * + * Thermostat is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Thermostat; see the file COPYING. If not see + * <http://www.gnu.org/licenses/>. + * + * Linking this code with other modules is making a combined work + * based on this code. Thus, the terms and conditions of the GNU + * General Public License cover the whole combination. + * + * As a special exception, the copyright holders of this code give + * you permission to link this code with independent modules to + * produce an executable, regardless of the license terms of these + * independent modules, and to copy and distribute the resulting + * executable under terms of your choice, provided that you also + * meet, for each linked independent module, the terms and conditions + * of the license of that module. An independent module is a module + * which is not derived from or based on this code. If you modify + * this code, you may extend this exception to your version of the + * library, but you are not obligated to do so. If you do not wish + * to do so, delete this exception statement from your version. + */ + +package com.redhat.thermostat.platform.internal.mvc.lifecycle.state; + +import junit.framework.Assert; +import org.junit.Test; + +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertEquals; + +/** + */ +public class StateTest { + + @Test + public void testCorrectDispatchers() { + assertTrue(State.INVALID.action instanceof Invalid); + assertTrue(State.CREATE.action instanceof Create); + assertTrue(State.INIT.action instanceof Init); + assertTrue(State.START.action instanceof Start); + assertTrue(State.STOP.action instanceof Stop); + assertTrue(State.DESTROY.action instanceof Destroy); + + // so we know that we should re-check this test if we add a new state + assertEquals(6, State.values().length); + } + + @Test + public void testCanGoToState_INVALID() { + + assertTrue(State.INVALID.canGoToState(State.CREATE)); + + assertFalse(State.INVALID.canGoToState(State.INVALID)); + assertFalse(State.INVALID.canGoToState(State.INIT)); + assertFalse(State.INVALID.canGoToState(State.START)); + assertFalse(State.INVALID.canGoToState(State.STOP)); + assertFalse(State.INVALID.canGoToState(State.DESTROY)); + } + + @Test + public void testCanGoToState_CREATE() { + + assertTrue(State.CREATE.canGoToState(State.INIT)); + assertTrue(State.CREATE.canGoToState(State.DESTROY)); + + assertFalse(State.CREATE.canGoToState(State.CREATE)); + assertFalse(State.CREATE.canGoToState(State.START)); + assertFalse(State.CREATE.canGoToState(State.STOP)); + assertFalse(State.CREATE.canGoToState(State.INVALID)); + } + + @Test + public void testCanGoToState_INIT() { + + assertTrue(State.INIT.canGoToState(State.START)); + assertTrue(State.INIT.canGoToState(State.DESTROY)); + + assertFalse(State.INIT.canGoToState(State.CREATE)); + assertFalse(State.INIT.canGoToState(State.INIT)); + assertFalse(State.INIT.canGoToState(State.STOP)); + assertFalse(State.INIT.canGoToState(State.INVALID)); + } + + @Test + public void testCanGoToState_START() { + + assertTrue(State.START.canGoToState(State.STOP)); + + assertFalse(State.START.canGoToState(State.START)); + assertFalse(State.START.canGoToState(State.DESTROY)); + assertFalse(State.START.canGoToState(State.CREATE)); + assertFalse(State.START.canGoToState(State.INIT)); + assertFalse(State.START.canGoToState(State.INVALID)); + } + + @Test + public void testCanGoToState_STOP() { + + assertTrue(State.STOP.canGoToState(State.START)); + assertTrue(State.STOP.canGoToState(State.DESTROY)); + + assertFalse(State.STOP.canGoToState(State.STOP)); + assertFalse(State.STOP.canGoToState(State.CREATE)); + assertFalse(State.STOP.canGoToState(State.INIT)); + assertFalse(State.STOP.canGoToState(State.INVALID)); + } + + @Test + public void testCanGoToState_DESTROY() { + + assertTrue(State.DESTROY.canGoToState(State.INVALID)); + + assertFalse(State.DESTROY.canGoToState(State.START)); + assertFalse(State.DESTROY.canGoToState(State.STOP)); + assertFalse(State.DESTROY.canGoToState(State.CREATE)); + assertFalse(State.DESTROY.canGoToState(State.INIT)); + assertFalse(State.DESTROY.canGoToState(State.DESTROY)); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/platform/core/src/test/java/com/redhat/thermostat/platform/internal/mvc/lifecycle/state/StopTest.java Wed Oct 26 17:22:43 2016 +0200 @@ -0,0 +1,106 @@ +/* + * Copyright 2012-2016 Red Hat, Inc. + * + * This file is part of Thermostat. + * + * Thermostat is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published + * by the Free Software Foundation; either version 2, or (at your + * option) any later version. + * + * Thermostat is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Thermostat; see the file COPYING. If not see + * <http://www.gnu.org/licenses/>. + * + * Linking this code with other modules is making a combined work + * based on this code. Thus, the terms and conditions of the GNU + * General Public License cover the whole combination. + * + * As a special exception, the copyright holders of this code give + * you permission to link this code with independent modules to + * produce an executable, regardless of the license terms of these + * independent modules, and to copy and distribute the resulting + * executable under terms of your choice, provided that you also + * meet, for each linked independent module, the terms and conditions + * of the license of that module. An independent module is a module + * which is not derived from or based on this code. If you modify + * this code, you may extend this exception to your version of the + * library, but you are not obligated to do so. If you do not wish + * to do so, delete this exception statement from your version. + */ + +package com.redhat.thermostat.platform.internal.mvc.lifecycle.state; + +import com.redhat.thermostat.platform.Platform; +import com.redhat.thermostat.platform.mvc.Controller; +import com.redhat.thermostat.platform.mvc.MVCProvider; +import com.redhat.thermostat.platform.mvc.Model; +import com.redhat.thermostat.platform.mvc.View; +import org.junit.Before; +import org.junit.Test; +import org.mockito.ArgumentCaptor; + +import static org.mockito.Mockito.doNothing; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +/** + */ +public class StopTest { + + private MVCProvider provider; + private Platform platform; + private StateMachineTransitionDispatcher dispatcher; + private Context context; + private View view; + private Controller controller; + private Model model; + + @Before + public void setUp() { + provider = mock(MVCProvider.class); + platform = mock(Platform.class); + dispatcher = mock(StateMachineTransitionDispatcher.class); + + view = mock(View.class); + model = mock(Model.class); + controller = mock(Controller.class); + + when(provider.getView()).thenReturn(view); + when(provider.getController()).thenReturn(controller); + when(provider.getModel()).thenReturn(model); + + context = new Context(); + context.dispatcher = dispatcher; + context.provider = provider; + context.platform = platform; + } + + @Test + public void execute() throws Exception { + + ArgumentCaptor<Runnable> captor0 = ArgumentCaptor.forClass(Runnable.class); + ArgumentCaptor<Runnable> captor1 = ArgumentCaptor.forClass(Runnable.class); + + doNothing().when(platform).queueOnApplicationThread(captor0.capture()); + doNothing().when(platform).queueOnViewThread(captor1.capture()); + + Stop stop = new Stop(); + stop.execute(context); + + captor0.getValue().run(); + verify(controller).stop(); + + captor1.getValue().run(); + verify(view).stop(); + + captor0.getValue().run(); + verify(controller).viewStopped(); + } +} \ No newline at end of file