Skip to content

Commit

Permalink
Refactoring the process of driver instances creation to use a new Dri…
Browse files Browse the repository at this point in the history
…verProvider interface. DefaultDriverProvider wraps the current logic -- creating instances using reflection. This is a step to implement ability to load additional providers using ServiceLoader that can add new providers or override existing ones.
  • Loading branch information
barancev committed May 10, 2014
1 parent a0b26dc commit d8eff0c
Show file tree
Hide file tree
Showing 4 changed files with 120 additions and 40 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -20,64 +20,38 @@

import org.openqa.selenium.Capabilities;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebDriverException;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.logging.Logger;

public class DefaultDriverFactory implements DriverFactory {

private static final Logger log = Logger.getLogger(DefaultDriverFactory.class.getName());

private Map<Capabilities, Class<? extends WebDriver>> capabilitiesToDriver =
new ConcurrentHashMap<Capabilities, Class<? extends WebDriver>>();
private Map<Capabilities, DriverProvider> capabilitiesToDriverProvider =
new ConcurrentHashMap<Capabilities, DriverProvider>();

public void registerDriver(Capabilities capabilities, Class<? extends WebDriver> implementation) {
capabilitiesToDriver.put(capabilities, implementation);
capabilitiesToDriverProvider.put(capabilities,
new DefaultDriverProvider(capabilities, implementation));
}

protected Class<? extends WebDriver> getBestMatchFor(Capabilities desired) {
return getProviderMatching(desired).getDriverClass();
}

protected DriverProvider getProviderMatching(Capabilities desired) {
// We won't be able to make a match if no drivers have been registered.
checkState(!capabilitiesToDriver.isEmpty(),
"No drivers have been registered, will be unable to match %s", desired);
checkState(!capabilitiesToDriverProvider.isEmpty(),
"No drivers have been registered, will be unable to match %s", desired);
Capabilities bestMatchingCapabilities =
CapabilitiesComparator.getBestMatch(desired, capabilitiesToDriver.keySet());
return capabilitiesToDriver.get(bestMatchingCapabilities);
CapabilitiesComparator.getBestMatch(desired, capabilitiesToDriverProvider.keySet());
return capabilitiesToDriverProvider.get(bestMatchingCapabilities);
}

public WebDriver newInstance(Capabilities capabilities) {
log.info("Creating a new session for " + capabilities);
Class<? extends WebDriver> clazz = getBestMatchFor(capabilities);

// Try and call the single arg constructor that takes a capabilities first
return callConstructor(clazz, capabilities);
}

private WebDriver callConstructor(Class<? extends WebDriver> from, Capabilities capabilities) {
try {
Constructor<? extends WebDriver> constructor = from.getConstructor(Capabilities.class);
return constructor.newInstance(capabilities);
} catch (NoSuchMethodException e) {
try {
return from.newInstance();
} catch (InstantiationException e1) {
throw new WebDriverException(e);
} catch (IllegalAccessException e1) {
throw new WebDriverException(e);
}
} catch (InvocationTargetException e) {
throw new WebDriverException(e);
} catch (InstantiationException e) {
throw new WebDriverException(e);
} catch (IllegalAccessException e) {
throw new WebDriverException(e);
}
return getProviderMatching(capabilities).newInstance(capabilities);
}

public boolean hasMappingFor(Capabilities capabilities) {
return capabilitiesToDriver.containsKey(capabilities);
return capabilitiesToDriverProvider.containsKey(capabilities);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
/*
Copyright 2014 Selenium committers
Copyright 2014 Software Freedom Conservancy
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package org.openqa.selenium.remote.server;

import org.openqa.selenium.Capabilities;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebDriverException;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.util.logging.Logger;

public class DefaultDriverProvider implements DriverProvider {

private static final Logger log = Logger.getLogger(DefaultDriverProvider.class.getName());

private Capabilities capabilities;
private Class<? extends WebDriver> implementation;

public DefaultDriverProvider(Capabilities capabilities, Class<? extends WebDriver> implementation) {
this.capabilities = capabilities;
this.implementation = implementation;
}

@Override
public Capabilities getProvidedCapabilities() {
return capabilities;
}

@Override
public Class<? extends WebDriver> getDriverClass() {
return implementation;
}

@Override
public WebDriver newInstance(Capabilities capabilities) {
log.info("Creating a new session for " + capabilities);
// Try and call the single arg constructor that takes a capabilities first
return callConstructor(implementation, capabilities);
}

private WebDriver callConstructor(Class<? extends WebDriver> from, Capabilities capabilities) {
try {
Constructor<? extends WebDriver> constructor = from.getConstructor(Capabilities.class);
return constructor.newInstance(capabilities);
} catch (NoSuchMethodException e) {
try {
return from.newInstance();
} catch (InstantiationException e1) {
throw new WebDriverException(e);
} catch (IllegalAccessException e1) {
throw new WebDriverException(e);
}
} catch (InvocationTargetException e) {
throw new WebDriverException(e);
} catch (InstantiationException e) {
throw new WebDriverException(e);
} catch (IllegalAccessException e) {
throw new WebDriverException(e);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/*
Copyright 2014 Selenium committers
Copyright 2014 Software Freedom Conservancy
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package org.openqa.selenium.remote.server;

import org.openqa.selenium.Capabilities;
import org.openqa.selenium.WebDriver;

public interface DriverProvider {
Capabilities getProvidedCapabilities();

Class<? extends WebDriver> getDriverClass();

WebDriver newInstance(Capabilities capabilities);
}
2 changes: 2 additions & 0 deletions java/server/src/org/openqa/selenium/remote/server/build.desc
Original file line number Diff line number Diff line change
Expand Up @@ -60,8 +60,10 @@ java_library(name = "server_very_core",
srcs = [
"CapabilitiesComparator.java",
"DefaultDriverFactory.java",
"DefaultDriverProvider.java",
"DefaultDriverSessions.java",
"DriverFactory.java",
"DriverProvider.java",
"DriverSessions.java",
"KnownElements.java",
"JsonHttpCommandHandler.java",
Expand Down

0 comments on commit d8eff0c

Please sign in to comment.