/******************************************************************************* * Copyright (c) 2004, 2010 BREDEX GmbH. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * BREDEX GmbH - initial API and implementation and/or initial documentation *******************************************************************************/ package org.eclipse.jubula.rc.swt; import java.lang.reflect.InvocationTargetException; import org.eclipse.jubula.rc.common.AUTServer; import org.eclipse.jubula.rc.common.AUTServerConfiguration; import org.eclipse.jubula.rc.common.driver.IRobot; import org.eclipse.jubula.rc.common.exception.ComponentNotFoundException; import org.eclipse.jubula.rc.common.listener.BaseAUTListener; import org.eclipse.jubula.rc.swt.driver.RobotFactoryConfig; import org.eclipse.jubula.rc.swt.driver.RobotFactorySwtImpl; import org.eclipse.jubula.rc.swt.driver.RobotSwtImpl; import org.eclipse.jubula.rc.swt.listener.AbstractAutSwtEventListener; import org.eclipse.jubula.rc.swt.listener.CheckListener; import org.eclipse.jubula.rc.swt.listener.ComponentHandler; import org.eclipse.jubula.rc.swt.listener.FocusTracker; import org.eclipse.jubula.rc.swt.listener.MappingListener; import org.eclipse.jubula.rc.swt.listener.RecordListener; import org.eclipse.jubula.rc.swt.listener.TableSelectionTracker; import org.eclipse.jubula.rc.swt.utils.KeyConverter; import org.eclipse.jubula.tools.internal.constants.AUTServerExitConstants; import org.eclipse.jubula.tools.internal.objects.IComponentIdentifier; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Listener; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * The AutServer controlling the AUT. <br> * A quasi singleton: the instance is created from main(). <br> * Expected arguments to main are, see also * StartAUTServerCommand.createCmdArray(): * <ul> * <li>The name of host the Client is running on, must be InetAddress conform.</li> * <li>The port the Client is listening to.</li> * <li>The main class of the AUT.</li> * <li>Any further arguments are interpreted as arguments to the AUT.</li> * <ul> * When a connection to the JubulaClient could made, any errors will send as a * message to the JubulaClient. * * Changing the mode to OBJECT_MAPPING results in installing an AWTEventListener * (an instance of <code>MappingListener</code>). For simplification the virtual * machine is closed without sending a message to the client when an error * occurs during the installation of the SWTEventListener. The exit-code is the * appropriate EXIT_* constant * * Changing the mode to TESTING removes the installed MappingListener. * * @author BREDEX GmbH * @created 20.04.2006 */ public class SwtAUTServer extends AUTServer { /** the logger */ private static final Logger LOG = LoggerFactory.getLogger(SwtAUTServer.class); /** the aut display */ private Display m_display = null; /** the robot */ private RobotSwtImpl m_robot = null; /** * private constructor * instantiates the listeners */ public SwtAUTServer() { super(new MappingListener(), new RecordListener(), new CheckListener()); } /** * Starts the AUTServer in its own Thread with its own ClassLoader. */ public void startAUT() { if (isRcpAccessible()) { return; } super.startAUT(); // wait until aut is started getAutDisplay(); if (!isAgentSet()) { //already done in AutServer if Agent is in use super.addToolKitEventListenerToAUT(); } } /** * @return the aut display. */ public Display getAutDisplay() { if (isRcpAccessible()) { while (m_display == null) { m_display = Display.findDisplay(Thread.currentThread()); try { Thread.sleep(50); } catch (InterruptedException e) { // OK here! } } } else { return getSwtAutDisplay(); } return m_display; } /** * @return Display in case of SWT-Application */ private Display getSwtAutDisplay() { final ClassLoader oldCL = Thread.currentThread() .getContextClassLoader(); try { Thread.currentThread().setContextClassLoader(getAutThread() .getContextClassLoader()); while (m_display == null) { m_display = Display.findDisplay(getAutThread()); try { Thread.sleep(50); } catch (InterruptedException e) { // OK here! } } return m_display; } finally { if (m_display == null) { LOG.error("SWT Display not found"); //$NON-NLS-1$ } Thread.currentThread().setContextClassLoader(oldCL); } } /** * {@inheritDoc} */ protected void addToolkitEventListeners() { // install the component handler addToolkitEventListener(new ComponentHandler()); // install the focus tracker addToolkitEventListener(new FocusTracker()); // install the table selection tracker addToolkitEventListener(TableSelectionTracker.getInstance()); } /** * {@inheritDoc} * @param listener */ protected void addToolkitEventListener(final BaseAUTListener listener) { try { getAutDisplay().syncExec(new Runnable() { public void run() { long[] mask = listener.getEventMask(); for (int i = 0; i < mask.length; i++) { getAutDisplay().addFilter((int)mask[i], (Listener)listener); } if (LOG.isInfoEnabled()) { LOG.info("installing SWTEventListener " //$NON-NLS-1$ + listener.toString()); } } }); } catch (NullPointerException se) { // no permission to remove an SWTEventListener, // should not occur, because addSWTEventListener() should be called // first. But just in case, close the VM LOG.error(se.getLocalizedMessage(), se); System.exit(AUTServerExitConstants .EXIT_SECURITY_VIOLATION_AWT_EVENT_LISTENER); } } /** * {@inheritDoc} * @param listener */ protected void removeToolkitEventListener(final BaseAUTListener listener) { try { getAutDisplay().syncExec(new Runnable() { public void run() { for (int i = 0; i < ((AbstractAutSwtEventListener)listener) .getEventMask().length; i++) { getAutDisplay().removeFilter( (int)((AbstractAutSwtEventListener) listener).getEventMask()[i], (AbstractAutSwtEventListener)listener); if (LOG.isInfoEnabled()) { LOG.info("uninstalling SWTEventListener " //$NON-NLS-1$ + listener.toString()); } } } }); } catch (NullPointerException se) { // no permission to remove an SWTEventListener, // should not occur, because addSWTEventListener() should be called // first. But just in case, close the vm LOG.error(se.getLocalizedMessage(), se); System.exit(AUTServerExitConstants .EXIT_SECURITY_VIOLATION_AWT_EVENT_LISTENER); } } /** * {@inheritDoc} */ protected void startTasks() throws ExceptionInInitializerError, InvocationTargetException, NoSuchMethodException { super.invokeAUT(); if (getCommunicator() != null) { getCommunicator().close(); } } /** * {@inheritDoc} */ public synchronized IRobot getRobot() { if (m_robot == null) { RobotFactorySwtImpl robotFactory = new RobotFactoryConfig().getRobotFactory(); m_robot = (RobotSwtImpl) robotFactory.getRobot(); } return m_robot; } /** * <HR NOSHADE><CENTER><FONT color="#FF0000"><b>ONLY TO USE FOR SWT-JUNIT TESTS<br> * AND<br>FOR "RcpAccessor" PLUG-IN !!!</b></FONT></CENTER><HR NOSHADE> * @param display the display to set */ public void setDisplay(Display display) { m_display = display; } /** * {@inheritDoc} */ public Object findComponent(final IComponentIdentifier ci, final int timeout) throws ComponentNotFoundException, IllegalArgumentException { return ComponentHandler.findComponent(ci, true, timeout); } /** * {@inheritDoc} */ @Override public boolean isComponentDisappeared(IComponentIdentifier ci, int timeout) throws ComponentNotFoundException, IllegalArgumentException { return ComponentHandler.isComponentDisappeared(ci, timeout); } /** {@inheritDoc} */ public void setMode(int newMode) { convertMappingKeys(); super.setMode(newMode); } /** * This methods converts the mapping keys from swing to SWT */ private void convertMappingKeys() { /* for mapping mode */ AUTServerConfiguration config = AUTServerConfiguration.getInstance(); int mappingKey = config.getMappingKey(); config.setMappingKey(KeyConverter.convertSwingToSwt(mappingKey)); int mappingMod = config.getMappingKeyMod(); config.setMappingKeyMod(KeyConverter.convertSwingStateMask(mappingMod)); /* for observation mode */ int checkModeKey = config.getCheckModeKey(); config.setCheckModeKey(KeyConverter.convertSwingToSwt(checkModeKey)); int checkModeMod = config.getCheckModeKeyMod(); config.setCheckModeKeyMod( KeyConverter.convertSwingStateMask(checkModeMod)); int checkCompKey = config.getCheckCompKey(); config.setCheckCompKey(KeyConverter.convertSwingToSwt(checkCompKey)); int checkCompKeyMod = config.getCheckCompKeyMod(); config.setCheckModeKeyMod( KeyConverter.convertSwingStateMask(checkCompKeyMod)); } }