selenium.server/src/org/netbeans/modules/selenium/server/SeleniumServerRunner.java
author Martin Fousek <marfous@netbeans.org>
Thu, 01 Nov 2012 09:53:16 +0100
branchrelease72
changeset 17894 7ceebbb201a7
parent 17795 ed07e23ee4d1
child 17940 c5cac35f0ad7
permissions -rw-r--r--
#217956 - UI Element / User-extensions are not configurable via Selenium Server Configuartion
     1 /*
     2  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
     3  *
     4  * Copyright 1997-2008 Sun Microsystems, Inc. All rights reserved.
     5  *
     6  * The contents of this file are subject to the terms of either the GNU
     7  * General Public License Version 2 only ("GPL") or the Common
     8  * Development and Distribution License("CDDL") (collectively, the
     9  * "License"). You may not use this file except in compliance with the
    10  * License. You can obtain a copy of the License at
    11  * http://www.netbeans.org/cddl-gplv2.html
    12  * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
    13  * specific language governing permissions and limitations under the
    14  * License.  When distributing the software, include this License Header
    15  * Notice in each file and include the License file at
    16  * nbbuild/licenses/CDDL-GPL-2-CP.  Sun designates this
    17  * particular file as subject to the "Classpath" exception as provided
    18  * by Sun in the GPL Version 2 section of the License file that
    19  * accompanied this code. If applicable, add the following below the
    20  * License Header, with the fields enclosed by brackets [] replaced by
    21  * your own identifying information:
    22  * "Portions Copyrighted [year] [name of copyright owner]"
    23  *
    24  * Contributor(s):
    25  *
    26  * The Original Software is NetBeans. The Initial Developer of the Original
    27  * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
    28  * Microsystems, Inc. All Rights Reserved.
    29  *
    30  * If you wish your version of this file to be governed by only the CDDL
    31  * or only the GPL Version 2, indicate your decision by adding
    32  * "[Contributor] elects to include this software in this distribution
    33  * under the [CDDL or GPL Version 2] license." If you do not indicate a
    34  * single choice of license, a recipient has the option to distribute
    35  * your version of this file under either the CDDL, the GPL Version 2 or
    36  * to extend the choice of license to its licensees as provided above.
    37  * However, if you add GPL Version 2 code and therefore, elected the GPL
    38  * Version 2 license, then the option applies only if the new code is
    39  * made subject to such option by the copyright holder.
    40  */
    41 package org.netbeans.modules.selenium.server;
    42 
    43 import java.beans.PropertyChangeEvent;
    44 import java.beans.PropertyChangeListener;
    45 import java.io.File;
    46 import java.lang.reflect.InvocationTargetException;
    47 import java.net.BindException;
    48 import java.net.MalformedURLException;
    49 import java.net.URL;
    50 import java.net.URLClassLoader;
    51 import java.util.logging.Level;
    52 import java.util.logging.Logger;
    53 import org.netbeans.api.server.properties.InstanceProperties;
    54 import org.openide.modules.InstalledFileLocator;
    55 import org.openide.util.RequestProcessor;
    56 import org.openide.util.Task;
    57 
    58 /**
    59  *
    60  * @author Jindrich Sedek
    61  * @author Martin Fousek
    62  */
    63 class SeleniumServerRunner implements Runnable, PropertyChangeListener {
    64 
    65     private static final Logger LOGGER = Logger.getLogger(SeleniumServerRunner.class.getName());
    66 
    67     private static final SeleniumServerRunner instance = new SeleniumServerRunner();
    68     private static Object server = null;
    69     private boolean isRunning = false;
    70     private static Action action = null;
    71     private static Task latestTask = null;
    72 
    73     private SeleniumServerRunner() {
    74     }
    75 
    76     static Task startServer() {
    77         if (isRunning()) {
    78             return Task.EMPTY;
    79         }
    80         action = Action.START;
    81         return postTask();
    82     }
    83 
    84     static Task stopServer() {
    85         if (!isRunning()) {
    86             return Task.EMPTY;
    87         }
    88         action = Action.STOP;
    89         return postTask();
    90     }
    91 
    92     static Task restartServer() {
    93         if (!isRunning()) {
    94             return startServer();
    95         } else {
    96             action = Action.RESTART;
    97             return postTask();
    98         }
    99     }
   100 
   101     static boolean isRunning() {
   102         return instance.isRunning;
   103     }
   104 
   105     private static Task postTask(){
   106         Task t = RequestProcessor.getDefault().post(instance);
   107         latestTask = t;
   108         return t;
   109     }
   110 
   111     @Override
   112     public void run() {
   113         try {
   114             if (server == null) {
   115                 initializeServer();
   116             }
   117             switch (action) {
   118                 case START:
   119                     callSeleniumServerMethod("boot");
   120                     callSeleniumServerMethod("start");
   121                     break;
   122                 case STOP:
   123                     callSeleniumServerMethod("stop");
   124                     break;
   125                 case RESTART:
   126                     callSeleniumServerMethod("stop");
   127                     callSeleniumServerMethod("boot");
   128                     callSeleniumServerMethod("start");
   129                     break;
   130                 case RELOAD:
   131                     callSeleniumServerMethod("stop");
   132                     server = null;
   133                     initializeServer();
   134                     callSeleniumServerMethod("boot");
   135                     callSeleniumServerMethod("start");
   136                     break;
   137                 default:
   138                     assert false : "Invalid option";
   139             }
   140             if (action == null) {
   141                 return;
   142             }
   143             isRunning = (!action.equals(Action.STOP));
   144             action = null;
   145         } catch (BindException bi) {
   146             LOGGER.log(Level.INFO, "Port already in use - the server is probably already running.", bi); //NOI18N
   147         } catch (Exception exc) {
   148             LOGGER.log(Level.INFO, null, exc);
   149         }
   150     }
   151 
   152     protected static URLClassLoader getSeleniumServerClassLoader() {
   153         URL url = null;
   154         try {
   155             url = InstalledFileLocator.getDefault().locate(
   156                         "modules/ext/selenium/selenium-server-2.16.1.jar", //NOI18N
   157                         null, //NOI18N
   158                         false).toURI().toURL();
   159         } catch (MalformedURLException ex) {
   160             LOGGER.log(Level.SEVERE, null, ex);
   161         }
   162         return URLClassLoader.newInstance(new URL[] {url}); //NOI18N
   163     }
   164 
   165     private void callSeleniumServerMethod(String method) {
   166         ClassLoader original = Thread.currentThread().getContextClassLoader();
   167         try {
   168             ClassLoader curr = server.getClass().getClassLoader();
   169             Thread.currentThread().setContextClassLoader(curr);
   170             server.getClass().getMethod(method).invoke(server);
   171         } catch (IllegalAccessException ex) {
   172             LOGGER.log(Level.WARNING, null, ex);
   173         } catch (IllegalArgumentException ex) {
   174             LOGGER.log(Level.WARNING, null, ex);
   175         } catch (NoSuchMethodException ex) {
   176             LOGGER.log(Level.WARNING, null, ex);
   177         } catch (SecurityException ex) {
   178             LOGGER.log(Level.WARNING, null, ex);
   179         } catch (InvocationTargetException ex) {
   180             LOGGER.log(Level.WARNING, null, ex);
   181         } finally {
   182             Thread.currentThread().setContextClassLoader(original);
   183         }
   184     }
   185 
   186     private static void initializeServer() throws Exception {
   187         URLClassLoader urlClassLoader = getSeleniumServerClassLoader();
   188         Class seleniumServer = urlClassLoader.loadClass("org.openqa.selenium.server.SeleniumServer"); //NOI18N
   189         Class remoteControlConfiguration = urlClassLoader.loadClass(
   190                 "org.openqa.selenium.server.RemoteControlConfiguration"); //NOI18N
   191 
   192         InstanceProperties ip = SeleniumProperties.getInstanceProperties();
   193         Object remoteControlConfigurationInstance = remoteControlConfiguration.newInstance();
   194         int port = ip.getInt(SeleniumProperties.PORT, SeleniumProperties.getSeleniumDefaultPort());
   195         remoteControlConfiguration.getMethod("setPort", int.class).invoke(
   196             remoteControlConfigurationInstance, port); //NOI18N
   197         boolean runInSingleWindow = ip.getBoolean(SeleniumProperties.SINGLE_WINDOW, false);
   198         remoteControlConfiguration.getMethod("setSingleWindow", Boolean.TYPE).invoke( //NOI18N
   199                 remoteControlConfigurationInstance, runInSingleWindow);
   200 		String firefoxProfileDir = ip.getString(SeleniumProperties.FIREFOX_PROFILE, ""); //NOI18N
   201 		if (!firefoxProfileDir.isEmpty()) {
   202 				File ffProfileDir = new File(firefoxProfileDir);
   203 				if (ffProfileDir.exists()) {
   204 					remoteControlConfiguration.getMethod("setFirefoxProfileTemplate", File.class).invoke( //NOI18N
   205 						remoteControlConfigurationInstance, ffProfileDir);
   206 				}
   207 		}
   208         String userExtensionsString = ip.getString(SeleniumProperties.USER_EXTENSIONS, ""); //NOI18N
   209         if (!userExtensionsString.isEmpty()) {
   210             File userExtensionFile = new File(userExtensionsString);
   211             if (userExtensionFile.exists()) {
   212                 remoteControlConfiguration.getMethod("setUserExtensions", File.class).invoke( //NOI18N
   213                         remoteControlConfigurationInstance, userExtensionFile);
   214             }
   215         }
   216         
   217         server = seleniumServer.getConstructor(remoteControlConfiguration).
   218                 newInstance(remoteControlConfigurationInstance);
   219     }
   220 
   221     @Override
   222     public void propertyChange(PropertyChangeEvent evt) {
   223         if (SeleniumProperties.PORT.equals(evt.getPropertyName())){
   224             action = Action.RELOAD;
   225             RequestProcessor.getDefault().post(instance);
   226         }
   227     }
   228 
   229     // listen on SeleniumProperties
   230     static PropertyChangeListener getPropertyChangeListener() {
   231         return instance;
   232     }
   233 
   234     private static enum Action {
   235 
   236         START, STOP, RESTART, RELOAD
   237     }
   238 
   239     static void waitAllTasksFinished(){
   240         if (latestTask == null){
   241             return;
   242         }
   243         while (!latestTask.isFinished()){
   244             latestTask.waitFinished();
   245         }
   246     }
   247 }