<commit_before>/**
 * JBoss, Home of Professional Open Source
 * Copyright 2013, Red Hat, Inc. and individual contributors
 * by the @authors tag. See the copyright.txt in the distribution for a
 * full listing of individual contributors.
 *
 * This is free software; you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License as
 * published by the Free Software Foundation; either version 2.1 of
 * the License, or (at your option) any later version.
 *
 * This software is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this software; if not, write to the Free
 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
 * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
 */
package org.jboss.arquillian.graphene.enricher;

import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;

import org.jboss.arquillian.core.spi.LoadableExtension.ExtensionBuilder;
import org.jboss.arquillian.graphene.context.GrapheneContext;
import org.jboss.arquillian.graphene.proxy.GrapheneProxy;
import org.jboss.arquillian.graphene.proxy.GrapheneProxyHandler;
import org.jboss.arquillian.test.api.ArquillianResource;
import org.jboss.arquillian.test.spi.enricher.resource.ResourceProvider;
import org.openqa.selenium.Capabilities;
import org.openqa.selenium.HasCapabilities;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.Rotatable;
import org.openqa.selenium.TakesScreenshot;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.html5.ApplicationCache;
import org.openqa.selenium.html5.BrowserConnection;
import org.openqa.selenium.html5.DatabaseStorage;
import org.openqa.selenium.html5.LocalStorage;
import org.openqa.selenium.html5.LocationContext;
import org.openqa.selenium.html5.SessionStorage;
import org.openqa.selenium.html5.WebStorage;
import org.openqa.selenium.interactions.Actions;
import org.openqa.selenium.interactions.HasInputDevices;
import org.openqa.selenium.interactions.HasTouchScreen;
import org.openqa.selenium.interactions.Keyboard;
import org.openqa.selenium.interactions.Mouse;
import org.openqa.selenium.interactions.TouchScreen;

/**
 * Provides common Selenium objects as Arquillian resources
 *
 * @author <NAME>
 */
public abstract class SeleniumResourceProvider<T> implements ResourceProvider {

    public static class WebDriverProvider extends DirectProvider<WebDriver> {
    }

    public static class JavascriptExecutorProvider extends DirectProvider<JavascriptExecutor> {
    }

    public static class TakesScreenshotProvider extends DirectProvider<TakesScreenshot> {
    }

    public static class RotatableProvider extends DirectProvider<Rotatable> {
    }

    public static class LocationContextProvider extends DirectProvider<LocationContext> {
    }

    public static class ApplicationCacheProvider extends DirectProvider<ApplicationCache> {
    }

    public static class BrowserConnectionProvider extends DirectProvider<BrowserConnection> {
    }

    public static class WebStorageProvider extends DirectProvider<WebStorage> {
    }

    @SuppressWarnings("deprecation")
    public static class DatabaseStorageProvider extends DirectProvider<DatabaseStorage> {
    }

    public static class LocalStorageProvider extends IndirectProvider<LocalStorage, WebStorage> {
        @Override
        public LocalStorage generateProxy(WebStorage base) {
            return base.getLocalStorage();
        }
    }

    public static class SessionStorageProvider extends IndirectProvider<SessionStorage, WebStorage> {
        @Override
        public SessionStorage generateProxy(WebStorage base) {
            return base.getSessionStorage();
        }
    }

    public static class KeyboardProvider extends IndirectProvider<Keyboard, HasInputDevices> {
        @Override
        public Keyboard generateProxy(HasInputDevices base) {
            return base.getKeyboard();
        }
    }

    public static class MouseProvider extends IndirectProvider<Mouse, HasInputDevices> {
        @Override
        public Mouse generateProxy(HasInputDevices base) {
            return base.getMouse();
        }
    }

    public static class CapabilitiesProvider extends IndirectProvider<Capabilities, HasCapabilities> {
        @Override
        public Capabilities generateProxy(HasCapabilities base) {
            return base.getCapabilities();
        }
    }

    public static class TouchScreenProvider extends IndirectProvider<TouchScreen, HasTouchScreen> {
        @Override
        public TouchScreen generateProxy(HasTouchScreen base) {
            return base.getTouch();
        }
    }

    public static class ActionsProvider extends IndirectProvider<Actions, HasInputDevices> {
        @Override
        public Actions generateProxy(HasInputDevices base) {
            Keyboard keyboard = base.getKeyboard();
            Mouse mouse = base.getMouse();
            return new Actions(keyboard, mouse);
        }
    }

    protected Class<?> mediatorType;
    protected Class<?> returnType;

    public SeleniumResourceProvider() {
        this.returnType = getTypeArgument(0);
        this.mediatorType = returnType;
    }

    @Override
    public boolean canProvide(Class<?> type) {
        return type == this.returnType;
    }

    protected <BASE> BASE base(final Annotation[] annotations) {

        GrapheneContext context = GrapheneContext.getContextFor(ReflectionHelper.getQualifier(annotations));
        return (BASE) context.getWebDriver(returnType);
    }

    protected final Class<?> getTypeArgument(int i) {
        ParameterizedType superType = (ParameterizedType) getClass().getGenericSuperclass();
        Type[] typeArguments = superType.getActualTypeArguments();
        return (Class<?>) typeArguments[i];
    }

    /**
     * Provides a given object type directly by casting WebDriver base instance
     *
     * @param <T> type of the returned object
     */
    private static class DirectProvider<T> extends SeleniumResourceProvider<T> {

        @Override
        public T lookup(ArquillianResource resource, Annotation... qualifiers) {
            return base(qualifiers);
        }
    }

    /**
     * This provides must provide a way how to obtain a given provider from provided WebDriver base object
     *
     * @param <T> type of the returned object
     * @param <M> type of the WebDriver base
     */
    private abstract static class IndirectProvider<T, M> extends SeleniumResourceProvider<T> {

        public IndirectProvider() {
            this.mediatorType = getTypeArgument(1);
        }

        @Override
        protected <BASE> BASE base(final Annotation[] annotations) {
            final GrapheneProxy.FutureTarget futureTarget = new GrapheneProxy.FutureTarget() {
                @Override
                public Object getTarget() {
                    GrapheneContext context = GrapheneContext.getContextFor(ReflectionHelper.getQualifier(annotations));
                    return context.getWebDriver(mediatorType);
                }
            };

            GrapheneProxyHandler mediatorHandler = new GrapheneProxyHandler(futureTarget) {
                @Override
                public Object invoke(Object proxy, final Method mediatorMethod, final Object[] mediatorArgs) throws Throwable {

                    GrapheneProxyHandler handler = new GrapheneProxyHandler(futureTarget) {

                        @Override
                        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                            Object mediatorObject = mediatorMethod.invoke(getTarget(), mediatorArgs);
                            return method.invoke(mediatorObject, args);
                        }
                    };

                    return GrapheneProxy.getProxyForHandler(handler, mediatorMethod.getReturnType());
                }
            };

            return (BASE) GrapheneProxy.getProxyForHandler(mediatorHandler, WebDriver.class, mediatorType);
        }

        @Override
        public Object lookup(ArquillianResource resource, Annotation... qualifiers) {
            final M base = base(qualifiers);
            return generateProxy(base);
        }

        public abstract T generateProxy(M mediator);
    }

    /**
     * Register all providers specified in this class
     */
    @SuppressWarnings("unchecked")
    public static void registerAllProviders(ExtensionBuilder builder) {
        for (Class<?> clazz : SeleniumResourceProvider.class.getClasses()) {
            if (SeleniumResourceProvider.class.isAssignableFrom(clazz)) {
                builder.service(ResourceProvider.class, (Class<SeleniumResourceProvider<?>>) clazz);
            }
        }
    }
}<commit_msg>ARQGRA-442: Graphene is not compatible with selenium 2.42.0<commit_after>/**
 * JBoss, Home of Professional Open Source
 * Copyright 2013, Red Hat, Inc. and individual contributors
 * by the @authors tag. See the copyright.txt in the distribution for a
 * full listing of individual contributors.
 *
 * This is free software; you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License as
 * published by the Free Software Foundation; either version 2.1 of
 * the License, or (at your option) any later version.
 *
 * This software is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this software; if not, write to the Free
 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
 * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
 */
package org.jboss.arquillian.graphene.enricher;

import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;

import org.jboss.arquillian.core.spi.LoadableExtension.ExtensionBuilder;
import org.jboss.arquillian.graphene.context.GrapheneContext;
import org.jboss.arquillian.graphene.proxy.GrapheneProxy;
import org.jboss.arquillian.graphene.proxy.GrapheneProxyHandler;
import org.jboss.arquillian.test.api.ArquillianResource;
import org.jboss.arquillian.test.spi.enricher.resource.ResourceProvider;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.HasCapabilities;
import org.openqa.selenium.html5.WebStorage;
import org.openqa.selenium.interactions.Actions;
import org.openqa.selenium.interactions.HasInputDevices;
import org.openqa.selenium.interactions.HasTouchScreen;
import org.openqa.selenium.interactions.Mouse;
import org.openqa.selenium.interactions.Keyboard;

/**
 * Provides common Selenium objects as Arquillian resources
 *
 * @author <NAME>
 */
public abstract class SeleniumResourceProvider implements ResourceProvider {

    /**
     * This is a resource provider for WebDriver interface.
     * It is used in an internal code.
     */
    public static class WebDriverProvider extends DirectProvider {
        @Override
        protected String getReturnType() {
            return WebDriver.class.getName();
        }
    }

    /**
     * This is a resource provider for JavascriptExecutor interface.
     * It is used in an internal code.
     */
    public static class JavascriptExecutorProvider extends DirectProvider {
        @Override
        protected String getReturnType() {
            return JavascriptExecutor.class.getName();
        }
    }

    public static class TakesScreenshotProvider extends DirectProvider {
        @Override
        protected String getReturnType() {
            return "org.openqa.selenium.TakesScreenshot";
        }
    }

    public static class RotatableProvider extends DirectProvider {
        @Override
        protected String getReturnType() {
            return "org.openqa.selenium.Rotatable";
        }
    }

    public static class LocationContextProvider extends DirectProvider {
        @Override
        protected String getReturnType() {
            return "org.openqa.selenium.html5.LocationContext";
        }
    }

    public static class ApplicationCacheProvider extends DirectProvider {
        @Override
        protected String getReturnType() {
            return "org.openqa.selenium.html5.ApplicationCache";
        }
    }

    public static class BrowserConnectionProvider extends DirectProvider {
        @Override
        protected String getReturnType() {
            return "org.openqa.selenium.html5.BrowserConnection";
        }
    }

    public static class WebStorageProvider extends DirectProvider {
        @Override
        protected String getReturnType() {
            return "org.openqa.selenium.html5.WebStorage";
        }
    }

    public static class DatabaseStorageProvider extends DirectProvider {
        @Override
        protected String getReturnType() {
            return "org.openqa.selenium.html5.DatabaseStorage";
        }
    }

    public static class LocalStorageProvider extends IndirectProvider<WebStorage> {
        @Override
        public Object generateProxy(WebStorage base) {
            return base.getLocalStorage();
        }

        @Override
        protected String getReturnType() {
            return "org.openqa.selenium.html5.LocalStorage";
        }
    }

    public static class SessionStorageProvider extends IndirectProvider<WebStorage> {
        @Override
        public Object generateProxy(WebStorage base) {
            return base.getSessionStorage();
        }

        @Override
        protected String getReturnType() {
            return "org.openqa.selenium.html5.SessionStorage";
        }
    }

    public static class KeyboardProvider extends IndirectProvider<HasInputDevices> {
        @Override
        public Object generateProxy(HasInputDevices base) {
            return base.getKeyboard();
        }

        @Override
        protected String getReturnType() {
            return Keyboard.class.getName();
        }
    }

    /**
     * This is a resource provider for Mouse interface.
     * It is used in an internal code.
     */
    public static class MouseProvider extends IndirectProvider<HasInputDevices> {
        @Override
        public Object generateProxy(HasInputDevices base) {
            return base.getMouse();
        }

        @Override
        protected String getReturnType() {
            return Mouse.class.getName();
        }
    }

    public static class CapabilitiesProvider extends IndirectProvider<HasCapabilities> {
        @Override
        public Object generateProxy(HasCapabilities base) {
            return base.getCapabilities();
        }

        @Override
        protected String getReturnType() {
            return "org.openqa.selenium.Capabilities";
        }
    }

    public static class TouchScreenProvider extends IndirectProvider<HasTouchScreen> {
        @Override
        public Object generateProxy(HasTouchScreen base) {
            return base.getTouch();
        }

        @Override
        protected String getReturnType() {
            return "org.openqa.selenium.interactions.TouchScreen";
        }
    }

    /**
     * This is a resource provider for Action interface.
     * It is used in an internal code.
     */
    public static class ActionsProvider extends IndirectProvider<HasInputDevices> {
        @Override
        public Object generateProxy(HasInputDevices base) {
            return new Actions (base.getKeyboard(), base.getMouse());
        }

        @Override
        protected String getReturnType() {
            return Actions.class.getName();
        }
    }

    protected abstract String getReturnType();

    @Override
    public boolean canProvide(Class<?> type) {
        return type.getName().equals(getReturnType());
    }

    protected final Class<?> getTypeArgument(int i) {
        ParameterizedType superType = (ParameterizedType) getClass().getGenericSuperclass();
        Type[] typeArguments = superType.getActualTypeArguments();
        return (Class<?>) typeArguments[i];
    }

    /**
     * Provides a given object type directly by casting WebDriver base instance
     *
     * @param <T> type of the returned object
     */
    private abstract static class DirectProvider extends SeleniumResourceProvider {
        @Override
        public Object lookup(ArquillianResource resource, Annotation... qualifiers) {
            GrapheneContext context = GrapheneContext.getContextFor(ReflectionHelper.getQualifier(qualifiers));
            try {
                return context.getWebDriver(Class.forName(getReturnType()));
            } catch (ClassNotFoundException ex) {
                //the external users:
                //  - does not have any chance to build a test with classes which are not added on classpath
                //the intern usage of Providers:
                //  - the class path may contain a different version of Selenium
                //  - problem with internal use of Actions, Javascript, Mouse
                throw new IllegalStateException("The class of the provider is not on the class path.", ex);
            }
        }
    }

    /**
     * This provides must provide a way how to obtain a given provider from provided WebDriver base object
     *
     * @param <T> type of the returned object
     * @param <M> type of the WebDriver base
     */
    private abstract static class IndirectProvider<M> extends SeleniumResourceProvider {

        protected Class<?> mediatorType;

        public IndirectProvider() {
            this.mediatorType = getTypeArgument(0);
        }

        protected <BASE> BASE base(final Annotation[] annotations) {
            final GrapheneProxy.FutureTarget futureTarget = new GrapheneProxy.FutureTarget() {
                @Override
                public Object getTarget() {
                    GrapheneContext context = GrapheneContext.getContextFor(ReflectionHelper.getQualifier(annotations));
                    return context.getWebDriver(mediatorType);
                }
            };

            GrapheneProxyHandler mediatorHandler = new GrapheneProxyHandler(futureTarget) {
                @Override
                public Object invoke(Object proxy, final Method mediatorMethod, final Object[] mediatorArgs) throws Throwable {

                    GrapheneProxyHandler handler = new GrapheneProxyHandler(futureTarget) {

                        @Override
                        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                            Object mediatorObject = mediatorMethod.invoke(getTarget(), mediatorArgs);
                            return method.invoke(mediatorObject, args);
                        }
                    };

                    return GrapheneProxy.getProxyForHandler(handler, mediatorMethod.getReturnType());
                }
            };

            return (BASE) GrapheneProxy.getProxyForHandler(mediatorHandler, WebDriver.class, mediatorType);
        }

        @Override
        public Object lookup(ArquillianResource resource, Annotation... qualifiers) {
            final M base = base(qualifiers);
            return generateProxy(base);
        }

        public abstract Object generateProxy(M mediator);
    }

    /**
     * Register all providers specified in this class
     */
    @SuppressWarnings("unchecked")
    public static void registerAllProviders(ExtensionBuilder builder) {
        for (Class<?> clazz : SeleniumResourceProvider.class.getClasses()) {
            if (SeleniumResourceProvider.class.isAssignableFrom(clazz)) {
                builder.service(ResourceProvider.class, (Class<SeleniumResourceProvider>) clazz);
            }
        }
    }
}
{'fraction_non_alphanumeric': 0.07429530532655379, 'fraction_numerical': 0.0029125734314064274, 'mean_word_length': 2.7493984823246342, 'pattern_counts': {'":': 0, '<': 57, '<?xml version=': 0, '>': 57, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5111131', 'n_tokens_mistral': 5210, 'n_tokens_neox': 4911, 'n_words': 1415}