/*******************************************************************************
* Copyright (c) 2016 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.rcp.e3.accessor;
import java.lang.reflect.Field;
import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.eclipse.jubula.rc.common.AUTServer;
import org.eclipse.jubula.rc.common.adaptable.AdapterFactoryRegistry;
import org.eclipse.jubula.rc.rcp.common.classloader.EclipseUrlLocator;
import org.eclipse.jubula.rc.swt.SwtAUTServer;
import org.eclipse.jubula.tools.internal.constants.AutConfigConstants;
import org.eclipse.jubula.tools.internal.constants.CommandConstants;
import org.eclipse.jubula.tools.internal.constants.StringConstants;
import org.eclipse.jubula.tools.internal.utils.EnvironmentUtils;
import org.eclipse.swt.widgets.Display;
/**
* This is the {@link BundleActivator} for an simple startup.
* This class is activated on startup and is starting a {@link Thread}
* which is waiting for the <code>Default<code> {@link Display} after an
* specified amount of sleep.
* This approach is should only be used if the application has no workbench.
* Naming for parts like the toolbar is not working, as well GEF might not work
*
* The SimpleStartup is only working if the Default Display is used for the ui!
* @author BREDEX GmbH
*/
public class SimpleStartup implements BundleActivator {
/** environment variable */
public static final String JUBULA_ACCESSOR_SIMPLE = "JUBULA_ACCESSOR_SIMPLE"; //$NON-NLS-1$
/** the logger */
private static final Logger LOG =
LoggerFactory.getLogger(SimpleStartup.class);
/** the sleep time before checking the {@link Display} */
private static int sleeptime = 30;
/**
* Thread to wait for the default {@link Display} and start the {@link AUTServer}
*/
private class WaitForDisplay implements Runnable {
/** the timeout for waiting for the default display */
private static final int WAIT_FOR_DISPLAY_TIMEOUT = 30000;
/** {@inheritDoc} */
public void run() {
LOG.info("starting wait for default Display job"); //$NON-NLS-1$
long start = System.currentTimeMillis();
boolean wait = true;
while (wait) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
LOG.debug("Sleep interrupted"); //$NON-NLS-1$
}
if ((System.currentTimeMillis() - start) > sleeptime * 1000) {
wait = false;
}
}
LOG.info("wait for Default display"); //$NON-NLS-1$
try {
start = System.currentTimeMillis();
boolean waitforDisplay = true;
while (waitforDisplay) {
Object obj = getDefaultDisplay();
if (obj != null) {
waitforDisplay = false;
}
if ((System.currentTimeMillis() - start)
> WAIT_FOR_DISPLAY_TIMEOUT) {
return;
}
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
LOG.debug("Sleep interrupted"); //$NON-NLS-1$
}
}
} catch (Exception e) {
LOG.debug("getting the Display via reflection failed", e); //$NON-NLS-1$
}
final Display display = Display.getDefault();
LOG.info("starting AUT server"); //$NON-NLS-1$
AUTServer autServer = initAutServer(display);
AdapterFactoryRegistry.initRegistration(new EclipseUrlLocator());
// // add listener to AUT
autServer.addToolKitEventListenerToAUT();
}
/**
* Initializes the AUT Server for the host application.
*
* @param display
* The Display to use for the AUT Server.
* @return the AUTServer instance
*/
private AUTServer initAutServer(Display display) {
AUTServer instance = AUTServer.getInstance(
CommandConstants.AUT_SWT_SERVER);
((SwtAUTServer) instance).setDisplay(display);
instance.setAutAgentHost(EnvironmentUtils
.getProcessOrSystemProperty(
AutConfigConstants.AUT_AGENT_HOST));
instance.setAutAgentPort(EnvironmentUtils
.getProcessOrSystemProperty(
AutConfigConstants.AUT_AGENT_PORT));
instance.setAutID(EnvironmentUtils
.getProcessOrSystemProperty(AutConfigConstants.AUT_NAME));
instance.start(true);
return instance;
}
}
/**
* {@inheritDoc}
*/
public void start(BundleContext context) throws Exception {
String env = EnvironmentUtils
.getProcessOrSystemProperty(JUBULA_ACCESSOR_SIMPLE);
if (env == null) {
LOG.info("using standard accessor"); //$NON-NLS-1$
return;
}
LOG.warn("Using simple accessor"); //$NON-NLS-1$
if (env.equals(StringConstants.EMPTY)) {
LOG.info("with default " + sleeptime + "s sleeptime"); //$NON-NLS-1$ //$NON-NLS-2$
} else {
try {
sleeptime = Integer.parseInt(env);
LOG.info("with " + env + "s sleeptime"); //$NON-NLS-1$ //$NON-NLS-2$
} catch (NumberFormatException nfe) {
LOG.debug("failed to get number from environment"); //$NON-NLS-1$
LOG.debug("using default " + sleeptime + "s sleeptime"); //$NON-NLS-1$ //$NON-NLS-2$
// ignore using default
}
}
Thread thread = new Thread(new WaitForDisplay());
thread.start();
}
/**
* Getting the value of the Default display without calling
* {@link Display#getDefault()}
*
* @return the value of {@link Display} <code>Default</code> variable
* @throws Exception
*/
private Object getDefaultDisplay() throws Exception {
Class clazz = Display.class;
try {
Field field = clazz.getDeclaredField("Default"); //$NON-NLS-1$
field.setAccessible(true);
Object defaultDisplayValue = field.get(null);
return defaultDisplayValue;
} catch (NoSuchFieldException nsfe) {
throw new Exception(nsfe);
} catch (SecurityException se) {
throw new Exception(se);
} catch (IllegalAccessException e) {
throw new Exception(e);
}
}
/**
* {@inheritDoc}
*/
public void stop(BundleContext context) throws Exception {
// nothing to stop
}
}