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

com.automationrockstars.gir.data.impl.DataLoader Maven / Gradle / Ivy

The newest version!
/*
 * 
 */

package com.automationrockstars.gir.data.impl;

import com.automationrockstars.base.ConfigLoader;
import com.automationrockstars.base.JarUtils;
import com.automationrockstars.gir.data.TestData;
import com.automationrockstars.gir.data.TestDataRecord;
import com.google.common.base.Joiner;
import com.google.common.base.Optional;
import com.google.common.base.Predicate;
import com.google.common.base.Throwables;
import com.google.common.collect.FluentIterable;
import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.gson.Gson;
import org.reflections.util.ConfigurationBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.*;

import static com.automationrockstars.gir.data.TestData.REMOTE_DATA_URL_PROP;


public class DataLoader {


    private static final FluentIterable> AVAILABLE_TYPES = FluentIterable.from(new org.reflections.Reflections(new ConfigurationBuilder().forPackages(TestDataServiceRegistry.packagesToScan())).getSubTypesOf(TestDataRecord.class)).filter(new Predicate>() {
        @Override
        public boolean apply(Class input) {
            return input.isInterface();
        }
    });
    private static final Logger LOG = LoggerFactory.getLogger(DataLoader.class);

    private static Class findTestDataRecordClass(final String name) {
        LOG.debug("Looking for type matching {} among {}", name, AVAILABLE_TYPES);
        Optional> result = AVAILABLE_TYPES.firstMatch(new Predicate>() {
            @Override
            public boolean apply(Class input) {
                return TestDataProxyFactory.separatedWords(input.getSimpleName()).equalsIgnoreCase(name);
            }
        });
        if (result.isPresent()) {
            return result.get();
        } else {
            LOG.warn("Tag {} cannot be matched to any type from available {}", name, Joiner.on("\n").join(AVAILABLE_TYPES));
            return null;
        }

    }


    public static Map, List>> loadFrom(String fileName) throws IOException {
        return loadDataResource(fileName);
    }

    private static Map, List>> loadDataResource(String resourceName) {
        if (ConfigLoader.config().containsKey(REMOTE_DATA_URL_PROP)){
            return loadRemoteDataResource(resourceName);
        } else {
            return loadLocalDataResource(resourceName);
        }
    }


    private static Map, List>> loadLocalDataResource(String resourceName) {
        LOG.info("Loading local data");
        try (InputStream content = JarUtils.findResources(resourceName).first().get().url().openStream()) {
            return loadFrom(content);
        } catch (NoSuchElementException | IOException e) {
            LOG.error("Resource {} cannot be used as data", resourceName, e);
        }
        ;
        return null;

    }

    private static Map, List>> loadRemoteDataResource(String resourceName) {
        try {
            URL remoteUrl = new URL(String.format("%s/%s",ConfigLoader.config().getString(REMOTE_DATA_URL_PROP),resourceName));
            LOG.info("Loading data from URL {}",remoteUrl);
            try (InputStream content = remoteUrl.openStream()) {
                return loadFrom(content);
            } catch (NoSuchElementException | IOException e) {
                LOG.error("Remote resource {} cannot be used as data", resourceName, e);
            }
        } catch (MalformedURLException e) {
            LOG.error("Cannot read data from {}",String.format("%s/%s",ConfigLoader.config().getString(REMOTE_DATA_URL_PROP),resourceName),e);
        }
        return null;
    }

    @SuppressWarnings("unchecked")
    public static Map, List>> loadFrom(InputStream content) throws IOException {
        Map result = Collections.emptyMap();
        try (Reader data = new InputStreamReader(content)) {
            result = new Gson().fromJson(data, HashMap.class);
        } catch (NoSuchElementException | IOException e) {
            LOG.error("Resource cannot be used as data", e);
        }
        return loadFromData(result);
    }

    @SuppressWarnings({"unchecked"})
    private static Map, List>> loadFromData(final Map data) {
        Map, List>> result = Maps.newHashMap();
        for (String dataType : data.keySet()) {
            LOG.debug("Looking for TestDataRecord spec for data marked with {}", dataType);
            Class testDataType = null;
            if (dataType.endsWith(" list")) {
                testDataType = findTestDataRecordClass(dataType.replace(" list", ""));
            } else {
                testDataType = findTestDataRecordClass(dataType);
            }
            if (testDataType != null) {
                LOG.info("Data tagged with {} will be mapped to {}", dataType, testDataType.getName());
                List> bag = result.get(testDataType);
                if (bag == null) {
                    bag = Lists.newArrayList();
                    result.put(testDataType, bag);
                }
                Object listOrMap = data.get(dataType);
                if (List.class.isAssignableFrom(listOrMap.getClass())) {
                    for (Map entry : (List>) listOrMap) {
                        bag.add(entry);
                    }
                } else {
                    bag.add((Map) listOrMap);
                }
                LOG.trace("Mapped {}", callMappings(testDataType, Iterables.getLast(bag)));
            } else {
                LOG.warn("Data marked with {} cannot be matched to any TestDataRecord specification.", dataType);
            }
        }
        return result;

    }

    @SuppressWarnings("unchecked")
    private static String callMappings(Class type, Object o) {
        StringBuilder result = new StringBuilder();
        for (Method m : type.getMethods()) {
            try {
                if (Lists.newArrayList(m.getDeclaringClass().getInterfaces()).contains(TestDataRecord.class)
                        && !m.getDeclaringClass().equals(TestDataRecord.class)
                        && !Lists.newArrayList(m.getReturnType().getInterfaces()).contains(TestDataRecord.class)) {
                    Object tdr = TestDataProxyFactory.createProxy(new MapTestDataRecord((Map) o), (Class) type);
                    result.append("\n").append(m.getName()).append(": ").append(
                            m.invoke(tdr, (Object[]) null)
                    );
                }
            } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
                LOG.error("Cannot call mapped method on {} of {}", o, type, e);
            }
        }
        return result.toString();
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy