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

org.jboss.arquillian.graphene.enricher.AbstractSearchContextEnricher Maven / Gradle / Ivy

The newest version!
/**
 * 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.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Modifier;
import java.lang.reflect.Type;
import java.lang.reflect.TypeVariable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;

import org.jboss.arquillian.core.api.Instance;
import org.jboss.arquillian.core.api.annotation.Inject;
import org.jboss.arquillian.core.spi.ServiceLoader;
import org.jboss.arquillian.graphene.enricher.exception.GrapheneTestEnricherException;
import org.jboss.arquillian.graphene.spi.TypeResolver;
import org.jboss.arquillian.graphene.spi.enricher.SearchContextTestEnricher;
import org.jboss.arquillian.test.spi.TestEnricher;
import org.openqa.selenium.SearchContext;

/**
 * This class should help you to implement {@link SearchContextTestEnricher}.
 *
 * @author Juraj Huska
 * @author Jan Papousek
 */
public abstract class AbstractSearchContextEnricher implements SearchContextTestEnricher {

    /**
     * Constant containing new line separator dependent on the environment.
     */
    protected static final String NEW_LINE = System.getProperty("line.separator");
    @Inject
    private static Instance serviceLoader;

    /**
     * Performs further enrichment on the given instance with the given search context. That means all instances
     * {@link TestEnricher} and {@link SearchContextTestEnricher} are invoked.
     *
     * @param searchContext
     * @param target
     */
    protected static void enrichRecursively(SearchContext searchContext, Object target) {
        for (TestEnricher enricher : serviceLoader.get().all(TestEnricher.class)) {
            if (!enricher.getClass().equals(GrapheneEnricher.class)) {
                enricher.enrich(target);
            }
        }
        for (SearchContextTestEnricher enricher : getSortedSearchContextEnrichers(serviceLoader)) {
            enricher.enrich(searchContext, target);
        }
    }

    public static Collection getSortedSearchContextEnrichers(Instance serviceLoader) {
        List allSearchContextErichers = new ArrayList(serviceLoader.get()
            .all(SearchContextTestEnricher.class));
        Collections.sort(allSearchContextErichers, new SearchContextTestEnricherPrecedenceComparator());
        return allSearchContextErichers;
    }

    /**
     * It loads a real type of a field defined by parametric type. It searches in declaring class and super class. E. g. if a
     * field is declared as 'A fieldName', It tries to find type parameter called 'A' in super class declaration and its
     * evaluation in the class declaring the given field.
     *
     * @param field
     * @param testCase
     * @return type of the given field
     */
    protected final Class getActualType(Field field, Object testCase) {

        // e.g. TestPage, HomePage
        Type[] superClassActualTypeArguments = GenericTypeInspector.getTypeArguments(testCase);
        // e.g. T, E
        TypeVariable[] superClassTypeParameters = GenericTypeInspector.getTypeParameters(testCase);

        // the type parameter has the same index as the actual type
        String fieldParameterTypeName = field.getGenericType().toString();

        int index;
        for (index = 0; index < superClassTypeParameters.length; index++) {
            String superClassTypeParameterName = superClassTypeParameters[index].getName();
            if (fieldParameterTypeName.equals(superClassTypeParameterName)) {
                break;
            }
        }

        return (Class) superClassActualTypeArguments[index];
    }

    /**
     * It loads the concrete type of list items. E.g. for List, String is returned.
     *
     * @param listField
     * @return
     * @throws ClassNotFoundException
     */
    protected final Class getListType(Field listField) throws ClassNotFoundException {
        return Class.forName(listField.getGenericType().toString().split("<")[1].split(">")[0].split("<")[0]);
    }

    /**
     * Initialize given class.
     *
     * @param clazz to be initialized
     * @throws IllegalAccessException
     * @throws InstantiationException
     * @throws InvocationTargetException
     * @throws IllegalArgumentException
     * @throws SecurityException
     * @throws NoSuchMethodException
     */
    protected static  T instantiate(Class type, Object... args) throws NoSuchMethodException, SecurityException,
        InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {

        Class clazz = TypeResolver.resolveType(type);
        Class outerClass = clazz.getDeclaringClass();

        // load constructor and rea; arguments
        // check whether declared page object is not nested class
        Class[] argTypes;
        Object[] realArgs;
        if (outerClass == null || Modifier.isStatic(clazz.getModifiers())) {
            argTypes = new Class[args.length];
            realArgs = args;
            for (int i = 0; i < args.length; i++) {
                argTypes[i] = args[i].getClass();
            }
        } else {
            argTypes = new Class[args.length + 1];
            realArgs = new Object[args.length + 1];
            argTypes[0] = outerClass;
            realArgs[0] = instantiate(outerClass);
            for (int i = 0; i < args.length; i++) {
                argTypes[i + 1] = args[i].getClass();
                realArgs[i + 1] = args[i];
            }
        }
        Constructor construtor;
        if (ReflectionHelper.hasConstructor(clazz, argTypes)) {
            construtor = clazz.getDeclaredConstructor(argTypes);
        } else {
            construtor = ReflectionHelper.getAssignableConstructor(clazz, argTypes);
        }
        // instantiate
        if (!construtor.isAccessible()) {
            construtor.setAccessible(true);
        }

        return construtor.newInstance(realArgs);
    }

    protected static void setValue(Field field, Object target, Object value) {

        boolean accessible = field.isAccessible();
        if (!accessible) {
            field.setAccessible(true);
        }
        try {
            field.set(target, value);
        } catch (Exception ex) {
            throw new GrapheneTestEnricherException("During enriching of " + NEW_LINE + target.getClass() + NEW_LINE
                + " the field " + NEW_LINE + field + " was not able to be set! Check the cause!", ex);
        }
        if (!accessible) {
            field.setAccessible(false);
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy