org.cybercat.automation.annotations.AnnotationBuilder.java Source code

Java tutorial

Introduction

Here is the source code for org.cybercat.automation.annotations.AnnotationBuilder.java

Source

/**Copyright 2013 The Cybercat project
 * 
 * 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.cybercat.automation.annotations;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.util.Set;

import org.apache.log4j.Logger;
import org.cybercat.automation.AutomationFrameworkException;
import org.cybercat.automation.PageFactory;
import org.cybercat.automation.PageObjectException;
import org.cybercat.automation.components.AbstractPageObject;
import org.cybercat.automation.core.AutomationMain;
import org.cybercat.automation.core.TestStepAspect;
import org.cybercat.automation.core.integration.IIntegrationService;
import org.cybercat.automation.core.integration.IntegrationServiceAspect;
import org.cybercat.automation.test.AbstractFeature;
import org.cybercat.automation.test.AbstractTestCase;
import org.cybercat.automation.test.IFeature;
import org.cybercat.automation.test.IVersionControl;
import org.reflections.Reflections;
import org.springframework.aop.aspectj.annotation.AspectJProxyFactory;

/**
 * @author Ubegun
 *
 */
public class AnnotationBuilder {

    private static Logger log = Logger.getLogger(AnnotationBuilder.class);

    public static final <T extends IFeature> void processCCPageObject(T entity)
            throws AutomationFrameworkException {
        for (Field field : entity.getClass().getDeclaredFields()) {
            field.setAccessible(true);
            if (field.getAnnotation(CCPageObject.class) != null) {
                createPageObjectField(entity, field);
            } else if (field.getAnnotation(CCProperty.class) != null) {
                processPropertyField(entity, field);
            }
        }
    }

    private static Reflections reflections;

    private static Reflections getReflections(String sourcePakage) throws AutomationFrameworkException {
        if (reflections != null)
            return reflections;
        String rootPackage = AutomationMain.getProperty("version.control.root.package");
        if (rootPackage == null)
            rootPackage = sourcePakage;
        reflections = new Reflections(rootPackage);
        return reflections;
    }

    @SuppressWarnings("unchecked")
    private final static <T extends IVersionControl> Class<T> versionControlPreprocessor(Class<T> providerzz)
            throws AutomationFrameworkException {
        Reflections refSearch;
        int version = 0;
        try {
            refSearch = getReflections(providerzz.getPackage().getName());
            version = (int) AutomationMain.getPropertyLong("app.version");
            if (refSearch == null || version < 0)
                return providerzz;
        } catch (Exception e) {
            return providerzz;
        }
        Set<Class<? extends T>> providers = refSearch.getSubTypesOf(providerzz);
        if (providers == null || providers.size() == 0)
            return providerzz;
        T candidate, caught = null;
        for (Class<? extends T> classProvider : providers) {
            try {
                Constructor<T> c = (Constructor<T>) classProvider.getConstructor();
                candidate = c.newInstance();
                if (candidate.getVersion() == version)
                    return (Class<T>) candidate.getClass();
                if (caught == null
                        || (candidate.getVersion() < version && caught.getVersion() < candidate.getVersion())) {
                    caught = candidate;
                }

            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return (Class<T>) caught.getClass();
    }

    public static final <T extends AbstractTestCase> void processCCFeature(T entity)
            throws AutomationFrameworkException {
        processCCFeatureForObject(entity);
    }

    public static final <T extends IFeature> void processCCFeature(T entity) throws AutomationFrameworkException {
        processCCFeatureForObject(entity);
    }

    private static <T extends Object> void processCCFeatureForObject(T entity) throws AutomationFrameworkException {
        processCCFeatureForObject(entity, entity.getClass());
    }

    private static <T extends Object> void processCCFeatureForObject(T entity, Class<? extends Object> clazz)
            throws AutomationFrameworkException {
        if (clazz == null)
            return;
        for (Field field : clazz.getDeclaredFields()) {
            field.setAccessible(true);
            if (field.getAnnotation(CCFeature.class) != null) {
                processCCFeatureField(entity, field);
            } else if (field.getAnnotation(CCIntegrationService.class) != null) {
                createIntegrationService(field, entity);
            } else if (field.getAnnotation(CCProperty.class) != null) {
                processPropertyField(entity, field);
            }
        }
        processCCFeatureForObject(entity, (Class<? extends Object>) clazz.getSuperclass());
    }

    public static final <T extends AbstractPageObject> void processCCPageFragment(T entity)
            throws AutomationFrameworkException {
        processCCPageFragment(entity, entity.getClass());
    }

    @SuppressWarnings("unchecked")
    private static final <T extends AbstractPageObject> void processCCPageFragment(T entity,
            Class<? extends AbstractPageObject> clazz) throws AutomationFrameworkException {
        if (clazz == null)
            return;
        Field[] fields = clazz.getDeclaredFields();

        for (int i = 0; i < fields.length; i++) {
            fields[i].setAccessible(true);
            if (fields[i].getAnnotation(CCPageFragment.class) != null) {
                entity.addPageFragment(createPageObjectField(entity, fields[i]));
            }
        }
        processCCPageFragment(entity, (Class<? extends AbstractPageObject>) clazz.getSuperclass());
    }

    /**
     * @param targetObject
     * @param fields
     * @return
     * @throws AutomationFrameworkException
     * @throws PageObjectException
     */
    @SuppressWarnings("unchecked")
    private static <T extends AbstractPageObject> T createPageObjectField(Object targetObject, Field field)
            throws AutomationFrameworkException, PageObjectException {
        AutomationMain mainFactory = AutomationMain.getMainFactory();
        PageFactory pageFactory = mainFactory.getPageFactory();
        Class<AbstractPageObject> clazz;
        try {
            clazz = (Class<AbstractPageObject>) field.getType();
        } catch (Exception e) {
            throw new AutomationFrameworkException("Unexpected field type :" + field.getType().getSimpleName()
                    + " field name: " + field.getName() + " class: " + targetObject.getClass().getSimpleName()
                    + " Thread ID:" + Thread.currentThread().getId()
                    + " \n\tThis field must be of the type that extends AbstractPageObject class.", e);
        }
        try {
            T po = (T) pageFactory.createPage(clazz);
            po.setPageFactory(pageFactory);
            field.set(targetObject, po);
            return po;
        } catch (Exception e) {
            throw new AutomationFrameworkException(
                    "Set filed exception. Please, save this log and contact the Cybercat project support."
                            + " field name: " + field.getName() + " class: "
                            + targetObject.getClass().getSimpleName() + " Thread ID:"
                            + Thread.currentThread().getId(),
                    e);
        }
    }

    /**
     * @param entity
     * @param fields
     * @param i
     * @return
     * @throws AutomationFrameworkException
     */
    @SuppressWarnings("unchecked")
    private static <T> Class<AbstractFeature> processCCFeatureField(T entity, Field field)
            throws AutomationFrameworkException {
        Class<AbstractFeature> clazz;
        try {
            clazz = (Class<AbstractFeature>) field.getType();
        } catch (Exception e) {
            throw new AutomationFrameworkException("Unexpected field type :" + field.getType().getSimpleName()
                    + " field name: " + field.getName() + " class: " + entity.getClass().getSimpleName()
                    + " Thread ID:" + Thread.currentThread().getId()
                    + " \n\tThis field must be of the type that extends AbstractPageObject class.", e);
        }
        try {
            field.set(entity, createFeature(versionControlPreprocessor(clazz)));
        } catch (Exception e) {
            throw new AutomationFrameworkException(
                    "Set filed exception. Please, save this log and contact the Cybercat project support."
                            + " field name: " + field.getName() + " class: " + entity.getClass().getSimpleName()
                            + " Thread ID:" + Thread.currentThread().getId(),
                    e);
        }
        return clazz;
    }

    @SuppressWarnings("unchecked")
    private final static <T extends IFeature> T createFeature(Class<T> eType) throws AutomationFrameworkException {
        try {
            Constructor<T> cons = eType.getDeclaredConstructor();
            T result = cons.newInstance();
            AnnotationBuilder.processCCFeature(result);
            AnnotationBuilder.processCCPageObject(result);
            AspectJProxyFactory proxyFactory = new AspectJProxyFactory(result);
            proxyFactory.addAspect(TestStepAspect.class);
            result = (T) proxyFactory.getProxy();
            log.info(eType.getSimpleName() + " feature has been created.");
            return result;
        } catch (Exception e) {
            // handle test fail
            throw new AutomationFrameworkException("Feature factoring exception. ", e);
        }
    }

    @SuppressWarnings("unchecked")
    private static final void createIntegrationService(Field field, Object targetObject)
            throws AutomationFrameworkException {
        Class<IIntegrationService> clazz;
        try {
            clazz = (Class<IIntegrationService>) field.getType();
        } catch (Exception e) {
            throw new AutomationFrameworkException("Unexpected field type :" + field.getType().getSimpleName()
                    + " field name: " + field.getName() + " class: " + targetObject.getClass().getSimpleName()
                    + " Thread ID:" + Thread.currentThread().getId()
                    + " \n\tThis field must be of the type that extends AbstractPageObject class.", e);
        }
        try {

            field.set(targetObject,
                    createIntegrationService(clazz, field.getAnnotation(CCIntegrationService.class)));
        } catch (Exception e) {
            throw new AutomationFrameworkException(
                    "Set filed exception. Please, save this log and contact the Cybercat project support."
                            + " field name: " + field.getName() + " class: "
                            + targetObject.getClass().getSimpleName() + " Thread ID:"
                            + Thread.currentThread().getId(),
                    e);
        }

    }

    private static void processIntegrationService(Object targetObject, Class<? extends Object> clazz)
            throws AutomationFrameworkException {
        if (clazz == null)
            return;
        for (Field field : clazz.getDeclaredFields()) {
            field.setAccessible(true);
            if (field.getAnnotation(CCProperty.class) != null) {
                processPropertyField(targetObject, field);
            }
        }
        processIntegrationService(targetObject, clazz.getSuperclass());
    }

    /**
     * @param targetObject
     * @param fields
     * @param i
     * @throws AutomationFrameworkException
     */
    public static void processPropertyField(Object targetObject, Field field) throws AutomationFrameworkException {
        try {
            CCProperty properties = field.getAnnotation(CCProperty.class);
            StringBuffer value = new StringBuffer("");
            for (String prop : properties.value()) {
                value.append(AutomationMain.getProperty(prop));
            }
            field.set(targetObject, value.toString());
        } catch (Exception e) {
            throw new AutomationFrameworkException(
                    "Set filed exception. Please, save this log and contact the Cybercat project support."
                            + " field name: " + field.getName() + " class: "
                            + targetObject.getClass().getSimpleName() + " Thread ID:"
                            + Thread.currentThread().getId(),
                    e);
        }
    }

    @SuppressWarnings("unchecked")
    private static final <T extends IIntegrationService> T createIntegrationService(Class<T> clazz,
            CCIntegrationService aService) throws AutomationFrameworkException {
        Class<T> cService = versionControlPreprocessor(clazz);
        Constructor<T> cons;
        try {
            cons = cService.getConstructor();
            T result = cons.newInstance();
            processIntegrationService(result, result.getClass());
            result.setup();
            AspectJProxyFactory proxyFactory = new AspectJProxyFactory(result);
            proxyFactory.addAspect(new IntegrationServiceAspect(aService.hasSession()));
            result = (T) proxyFactory.getProxy();
            log.info(cService.getSimpleName() + " integration Service has been created.");
            return result;
        } catch (Exception e) {
            throw new AutomationFrameworkException("Integration service creation problem.", e);
        }
    }

}