All Downloads are FREE. Search and download functionalities are using the official Maven repository.

geb.ConfigurationLoader.groovy Maven / Gradle / Ivy

/* 
 * Copyright 2011 the original author or authors.
 *
 * 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 geb

import geb.buildadapter.BuildAdapterFactory

/**
 * Manages the process of creating {@link geb.Configuration} objects, which control the runtime behaviour of Geb.
 * 

* Typically usage of this class is hidden from the user as the {@link geb.Browser} uses this class internally * to load configuration based on its construction. If however custom configuration loading mechanics are necessary, * users can use this class or a subclass of to create a {@link geb.Configuration} object and construct the {@link geb.Browser} * with that. *

* Another avenue for custom configuration is usage of the {@link geb.BuildAdapter build adapter}. The build adapter that * will be used with any loaded configurations will be what is provided by {@link #createBuildAdapter()} * * @see geb.Configuration * @see geb.Browser */ class ConfigurationLoader { final String environment final Properties properties final BuildAdapter buildAdapter final GroovyClassLoader specialClassLoader /** * Configures the loader using the defaults. * * @see ConfigurationLoader(ClassLoader, String, Properties) */ ConfigurationLoader() { this(null, null, null) } /** * Configures the loader with the given environment for parsing config scripts, and defaults for everything else. * * @see ConfigurationLoader(String, Properties, ClassLoader) */ ConfigurationLoader(String environment) { this(environment, null, null) } /** * Sets the loader environment. *

* If any of the parameters are {@code null}, the appropriate {@code getDefault«something»()} method will be used to supply the value. * * @param classLoader The loader to use to find classpath resources and to {@link #createBuildAdapter() load the build adapter} * @param environment If loading a config script, the environment to load it with * @param properties The properties given to created {@link geb.Configuration} objects * @see #getDefaultEnvironment() * @see #getDefaultProperties() */ ConfigurationLoader(String environment, Properties properties, GroovyClassLoader classLoader) { this.environment = environment ?: getDefaultEnvironment() this.properties = properties ?: getDefaultProperties() this.specialClassLoader = classLoader ?: getDefaultSpecialClassLoader() } /** * Result of this method is used as the default configuration when there is no configuration script or class. * This implementation returns a configuration as if the loaded configuration script/class was empty. */ protected Configuration getDefaultConf() { createConf(new ConfigObject(), new GroovyClassLoader(getClass().classLoader)) } /** * Creates a config using the default path for the config script and the default config class name. It loads the * configuration from class only if the configuration script was not found. *

* Uses {@link #getDefaultConfigScriptResourcePath()} for the path and {@link #getDefaultConfigClassName()} for the class name. * * @throws geb.ConfigurationLoader.UnableToLoadException if the config script or class exists but could not be read or parsed. * @see #getConf(String) * @see #getConfFromClass(String) */ Configuration getConf() throws UnableToLoadException { doGetConf(null) ?: doGetConfFromClass(null) ?: getDefaultConf() } /** *

Creates a config backed by the classpath config script resource at the given path.

* *

The resource is first searched for using the special class loader (thread context loader by default), and then the class loader of this class if it wasn't found. * If no classpath resource can be found at the given path, an empty config object will be used with the class loader of this class.

* *

The class loader that is used is then propagated to the created configuration object. This means that if it is the special loader it must have * the same copy of the Geb classes as this class loader and any other classes Geb depends on.

* * @param configFileResourcePath the classpath relative path to the config script to use (if {@code null}, {@link #getDefaultConfigScriptResourcePath() default} will be used). * @throws geb.ConfigurationLoader.UnableToLoadException if the config script exists but could not be read or parsed. * @see #getConf(URL, GroovyClassLoader) * @see #getConfFromClass(String) */ Configuration getConf(String configFileResourcePath) throws UnableToLoadException { if (configFileResourcePath == null) { getConf() } else { doGetConf(configFileResourcePath) ?: getDefaultConf() } } /** *

Creates a config backed by the classpath config script resource at the given path. This method is used by {@link #getConf(String)}.

* *

The resource is first searched for using the special class loader (thread context loader by default), and then the class loader of this class if it wasn't found. * If no classpath resource can be found at the given path null is returned.

* *

The class loader that is used is then propagated to the created configuration object. This means that if it is the special loader it must have * the same copy of the Geb classes as this class loader and any other classes Geb depends on.

* * @param configFileResourcePath the classpath relative path to the config script to use (if {@code null}, {@link #getDefaultConfigScriptResourcePath() default} will be used). * @throws geb.ConfigurationLoader.UnableToLoadException if the config script exists but could not be read or parsed. * @see #getConf(URL, GroovyClassLoader) * @see #getConf(String) */ protected Configuration doGetConf(String configFileResourcePath) throws UnableToLoadException { configFileResourcePath = configFileResourcePath ?: getDefaultConfigScriptResourcePath() def specialLoaderResource = specialClassLoader.getResource(configFileResourcePath) if (specialLoaderResource) { getConf(specialLoaderResource, specialClassLoader) } else { def thisClassLoader = new GroovyClassLoader(getClass().classLoader) def thisLoaderResource = thisClassLoader.getResource(configFileResourcePath) thisLoaderResource ? getConf(thisLoaderResource, thisClassLoader) : null } } /** * Creates a config backed by the config script at the given URL. *

* If URL is {@code null} or doesn't exist, an exception will be thrown. * * @param configLocation The absolute URL to the config script to use for the config (cannot be {@code null}) * @param classLoader The class loader to load the config script with (must be the same or a child of the class loader of this class) * @throws geb.ConfigurationLoader.UnableToLoadException if the config script exists but could not be read or parsed. */ Configuration getConf(URL configLocation, GroovyClassLoader classLoader) throws UnableToLoadException { if (configLocation == null) { throw new IllegalArgumentException("configLocation cannot be null") } createConf(loadRawConfig(configLocation, classLoader), classLoader) } /** *

Creates a config backed by the config class with a given name.

* *

The class is first searched for using the special class loader (thread context loader by default), and then the class loader of this class if it wasn't found. * If no such class can be found, an empty config object will be used with the class loader of this class.

* *

The class loader that is used is then propagated to the created configuration object. This means that if it is the special loader it must have * the same copy of the Geb classes as this class loader and any other classes Geb depends on.

* * @param configFileResourcePath the classpath relative path to the config script to use (if {@code null}, {@link #getDefaultConfigScriptResourcePath() default} will be used). * @throws geb.ConfigurationLoader.UnableToLoadException if the config script exists but could not be read or parsed. * @see #getConf(Class, GroovyClassLoader) * @see #getConf(String) */ Configuration getConfFromClass(String className) throws UnableToLoadException { doGetConfFromClass(className) ?: getDefaultConf() } /** *

Creates a config backed by the config class with a given name. This method is used by {@link #getConfFromClass(String)}.

* *

The class is first searched for using the special class loader (thread context loader by default), and then the class loader of this class if it wasn't found. * If no such class can be found, null is returned.

* *

The class loader that is used is then propagated to the created configuration object. This means that if it is the special loader it must have * the same copy of the Geb classes as this class loader and any other classes Geb depends on.

* * @param configFileResourcePath the classpath relative path to the config script to use (if {@code null}, {@link #getDefaultConfigScriptResourcePath() default} will be used). * @throws geb.ConfigurationLoader.UnableToLoadException if the config script exists but could not be read or parsed. * @see #getConfFromClass(String) * @see #getConf(Class, GroovyClassLoader) */ protected Configuration doGetConfFromClass(String className) { className = className ?: getDefaultConfigClassName() def configClass = tryToLoadClass(className, specialClassLoader) if (configClass) { getConf(configClass, specialClassLoader) } else { def thisLoader = new GroovyClassLoader(getClass().classLoader) configClass = tryToLoadClass(className, thisLoader) configClass ? getConf(configClass, thisLoader) : null } } protected Class tryToLoadClass(String className, ClassLoader loader) { def loaded try { loaded = loader.loadClass(className) } catch (ClassNotFoundException cnfe) { //just return null if the class could not be found } return loaded } /** * Creates a config backed by a given class. * * @param configClass Class that contains configuration * @param classLoader The class loader to load the config script with (must be the same or a child of the class loader of this class) * @throws geb.ConfigurationLoader.UnableToLoadException when config class cannot be read */ Configuration getConf(Class configClass, GroovyClassLoader classLoader) throws UnableToLoadException { createConf(loadRawConfig(configClass), classLoader) } /** * This implementation returns a new {@link groovy.lang.GroovyClassLoader} which uses the * {@code Thread.currentThread().contextClassLoader} as the parent. */ protected GroovyClassLoader getDefaultSpecialClassLoader() { new GroovyClassLoader() } /** * This implementation returns {@code System.properties["geb.env"]} */ protected String getDefaultEnvironment() { System.properties["geb.env"] } /** * This implementation returns {@code System.properties} */ protected Properties getDefaultProperties() { System.properties } /** * This implementation returns {@code "GebConfig.groovy"} */ String getDefaultConfigScriptResourcePath() { "GebConfig.groovy" } /** * This implementation returns {@code "GebConfig"} */ String getDefaultConfigClassName() { 'GebConfig' } static class UnableToLoadException extends geb.error.GebException { UnableToLoadException(URL configLocation, String environment, Throwable cause) { super("Unable to load configuration @ '$configLocation' (with environment: $environment)", cause) } UnableToLoadException(Class configClass, String environment, Throwable cause) { super("Unable to load configuration from class '$configClass' (with environment: $environment)", cause) } } /** * Reads the config scripts at {@code configLocation} with the {@link #createSlurper()} * * @throws geb.ConfigurationLoader.UnableToLoadException if the config script could not be read. */ protected ConfigObject loadRawConfig(URL configLocation, GroovyClassLoader classLoader) throws UnableToLoadException { loadRawConfig(createSlurper(classLoader), configLocation) } /** * Reads the config class with the {@link #createSlurper()} * * @throws geb.ConfigurationLoader.UnableToLoadException if the config class could not be read. */ protected ConfigObject loadRawConfig(Class configClass) throws UnableToLoadException { loadRawConfig(createSlurper(), configClass) } protected ConfigObject loadRawConfig(ConfigSlurper slurper, source) { try { slurper.parse(source) } catch (Throwable e) { throw new UnableToLoadException(source, slurper.environment, e) } } /** * Creates a config slurper with environment we were constructed with (if any) and sets * the slurpers classloader to the classloader we were constructed with. */ protected ConfigSlurper createSlurper(GroovyClassLoader classLoader) { def slurper = createSlurper() slurper.classLoader = classLoader slurper } /** * Creates a config slurper with environment we were constructed with (if any). */ protected ConfigSlurper createSlurper() { environment ? new ConfigSlurper(environment) : new ConfigSlurper() } /** * Creates a new {@link geb.Configuration} backed by {@code rawConfig} with the {@code properties} and {@code classLoader} * we were constructed with, and a {@link geb.BuildAdapter build adapter}. * * @see geb.Configuration#Configuration */ protected createConf(ConfigObject rawConfig, GroovyClassLoader classLoader) { new Configuration(rawConfig, properties, createBuildAdapter(classLoader), classLoader) } /** * Uses the {@link geb.buildadapter.BuildAdapterFactory#getBuildAdapter(ClassLoader) build adapter factory} to load * a build adapter with the {@code classLoader} we were constructed with. */ protected BuildAdapter createBuildAdapter(GroovyClassLoader classLoader) { BuildAdapterFactory.getBuildAdapter(classLoader) } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy