/* * Copyright 2005-2010 Ignis Software Tools Ltd. All rights reserved. */ package jsystem.treeui.client; import java.io.File; import java.util.logging.Logger; import jsystem.framework.FrameworkOptions; import jsystem.framework.JSystemProperties; import jsystem.framework.report.RunnerListenersManager; import jsystem.framework.scenario.Scenario; import jsystem.framework.scenario.ScenarioHelpers; import jsystem.framework.scenario.ScenariosManager; import jsystem.runner.ErrorLevel; import jsystem.runner.agent.server.RunnerEngine; import jsystem.runner.agent.server.RunnerEngineExecutionState; import jsystem.runner.agent.server.RunnerEngineImpl; import jsystem.treeui.ExecutionWorker; import jsystem.treeui.TestRunner; import jsystem.treeui.TestTreeView; import jsystem.treeui.error.ErrorPanel; import jsystem.utils.StringUtils; /** * The runner is composed of two modules:<br> * 1. Scenario studio - the module with which the user builds a scenario, sets * its parameters etc'<br> * 2. Execution engine - the engine that runs the scenario.<br> * <br> * The runner application can run with the engine embedded in it ({@link RunnerEngineImpl} * or it can connect to a remote agent {@link RemoteAgentClient}. <br> * In both cases the interface that the runner application works with is * identical - {@link RunnerEngine}.<br> * This factory class creates and manages the engine implementation with which * the runner works with.<br> * * This class also activates a {@link ConnectionListener} which monitors the * connection to the agent in case connection is lost. * * @author goland */ public class RunnerEngineManager { private static Logger log = Logger.getLogger(RunnerEngineManager.class.getName()); private static RunnerEngine agent; private static ConnectionListener connectionListener; final public static String LOCAL_AGNET = "local"; /** * Returns an implementation of {@link RunnerEngine}. * {@link #initRunnerEngine(String))} must be activated before getting * runner engine implementation. */ public static RunnerEngine getRunnerEngine(){ if(agent == null){ throw new IllegalStateException("Agent was not initialized"); } return agent; } /** * Initializes runner's {@link RunnerEngine}.<br> * This method should be invoked before the first time someone calls the * {@link #getRunnerEngine()}.<br> * If the runner is already connected to an engine, the connection to the * engine is closed and a new connection is opened.<br> * * @param agentUrl - * url of remote agent should be in the format host:port.<br> * If the value of this parameter is {@value #LOCAL_AGNET}, the * runner will work with an embedded engine in it ({@link RunnerEngineImpl}) */ public static void initRunnerEngine(String agentUrl) throws Exception { if (agent != null){ agent.close(); log.fine("Agent closed "); } agent = new ApplicationRunnerEngineImpl(); if (!StringUtils.isEmpty(agentUrl) && !LOCAL_AGNET.equals(agentUrl.trim())){ agent = new RemoteAgentClient(agentUrl); JSystemAgentClientsPool.addClient(agentUrl, false); } resetConnectionListener(); updateUI(); AgentList.addToAgentList(agentUrl); } private static void resetConnectionListener() throws Exception{ if (connectionListener == null) { connectionListener = new ConnectionListener(); } connectionListener.stopMonitor(); log.fine("Monitor stopped "); connectionListener.setEngine(agent); log.fine("Engine set "); connectionListener.connect(); log.fine("Connected "); } private static void updateUI() throws Exception{ /** * Set GUI to reflect agent state. */ RunnerEngineExecutionState executionState = agent.getEngineExecutionState(); setExecutionView(executionState); if (!(RunnerEngineExecutionState.idle.equals(executionState) || RunnerEngineExecutionState.idleError.equals(executionState))) { ExecutionWorker runWorker = new ExecutionWorker(TestRunner.treeView); agent.addListener(runWorker); String engineProject = agent.getCurrentProjectName(); boolean isAligned = validateProject(engineProject); if (isAligned) { String currentScenario = agent.getActiveScenario(); syncActiveScenario(currentScenario); } ((RunnerListenersManager) RunnerListenersManager.getInstance()).initReporters(); Scenario scenario = ScenariosManager.getInstance().getCurrentScenario(); scenario.setStatusNotRunning(); } } private static boolean validateProject(String projectName){ File projectFolder = new File(JSystemProperties.getInstance().getPreference(FrameworkOptions.TESTS_CLASS_FOLDER)).getParentFile(); if (!projectFolder.getName().equals(projectName) && !projectFolder.getPath().equals(projectName)){ ErrorPanel.showErrorDialog("Projects Synchronization" , "Engine project and senario studio projects are not aligned. \nPlease note that the JRunner UI will not reflect execution events correctly", ErrorLevel.Warning); return false; } return true; } private static void syncActiveScenario(String currentScenario){ String studioScenario = ScenariosManager.getInstance().getCurrentScenario().getName(); studioScenario = ScenarioHelpers.removeScenarioHeader(studioScenario); currentScenario = ScenarioHelpers.removeScenarioHeader(currentScenario); if (!currentScenario.equals(studioScenario)){ TestRunner.treeView.getTableController().loadScenario(currentScenario, false); } } private static void setExecutionView(RunnerEngineExecutionState executionState){ if (TestRunner.treeView == null){ return; } if (RunnerEngineExecutionState.idle.equals(executionState) || RunnerEngineExecutionState.idleError.equals(executionState)){ TestRunner.treeView.configureView(TestTreeView.VIEW_IDLE); }else if (RunnerEngineExecutionState.running.equals(executionState) || RunnerEngineExecutionState.stopping.equals(executionState)){ TestRunner.treeView.configureView(TestTreeView.VIEW_RUNNING); }else if (RunnerEngineExecutionState.paused.equals(executionState)){ TestRunner.treeView.configureView(TestTreeView.VIEW_PAUSED); }else { throw new IllegalStateException("Illigal engine state"); } } }