Package com.indeed.proctor.consumer.gen

Source Code of com.indeed.proctor.consumer.gen.TestGroupsGenerator

package com.indeed.proctor.consumer.gen;


import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Function;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import com.indeed.proctor.common.PayloadType;
import com.indeed.proctor.common.ProctorSpecification;
import com.indeed.proctor.common.ProctorUtils;
import com.indeed.proctor.common.Serializers;
import com.indeed.proctor.common.TestSpecification;
import org.apache.commons.lang.StringEscapeUtils;
import org.codehaus.jackson.map.ObjectMapper;

import javax.annotation.Nullable;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.SortedSet;
import java.util.TreeSet;


public class TestGroupsGenerator extends FreeMarkerCodeGenerator {
    private static final ObjectMapper OBJECT_MAPPER = Serializers.lenient();

    public void generate(final String input, final String target, final String packageName, final String groupsClass, final String groupsManagerClass) throws CodeGenException {
        final String templatePath = "/com/indeed/proctor/consumer/ant/";
        final String groupsTemplateName = "groups.ftl";
        final String groupsManagerTemplateName = "groups-manager.ftl";
        final String payloadTemplateName = "payload.ftl";
        final String payloadClass = groupsClass + "Payload";
        final Map<String, Object> baseContext = Maps.newHashMap();
        baseContext.put("groupsClassName", groupsClass);
        baseContext.put("groupsManagerClassName", groupsManagerClass);
        baseContext.put("payloadClassName",groupsClass + "Payload");
        if (groupsClass != null) {
            generate(input, target, baseContext, packageName, groupsClass, templatePath, groupsTemplateName);
        }
        if (groupsManagerClass != null) {
            generate(input, target, baseContext, packageName, groupsManagerClass, templatePath, groupsManagerTemplateName);
        }
        if (groupsClass != null) {
            generate(input, target, baseContext, packageName, payloadClass, templatePath, payloadTemplateName);
        }

    }
    /*
     * If a folder of split jsons defining a proctor specification is provided, this method iterates over the folder
     * contents, using the individual TestDefinition jsons and a providedcontext.json to create one large
     * temporary ProctorSpecification json to be used for code generation
     */
    public static File makeTotalSpecification(File dir, String targetDir) throws CodeGenException {
        //If no name is provided use the name of the containing folder
        return makeTotalSpecification(dir,targetDir,dir.getPath().substring(dir.getPath().lastIndexOf(File.separator) + 1) + "Groups.json");
    }
    public static File makeTotalSpecification(File dir, String targetDir, String name) throws CodeGenException {
        final File[] dirFiles = dir.listFiles();
        Map<String,TestSpecification> testSpec = new LinkedHashMap<String, TestSpecification>();
        Map<String,String> providedContext = new LinkedHashMap<String,String>();
        for(File child : dirFiles) {
            final String childName = child.getName();
            if(childName.equals("providedcontext.json")){
                try {
                    providedContext = OBJECT_MAPPER.readValue(child,Map.class);
                } catch (IOException e) {
                    throw new CodeGenException("Could not read json correctly " + child.getAbsolutePath(), e);
                }
            }
            else if (childName.endsWith(".json")){
                final TestSpecification spec;
                try {
                    spec = OBJECT_MAPPER.readValue(child,TestSpecification.class);
                } catch (IOException e) {
                    throw new CodeGenException("Could not read json correctly " + child.getAbsolutePath(),e);
                }
                testSpec.put(childName.substring(0, childName.indexOf(".json")),spec);
            }
        }
        final ProctorSpecification proctorSpecification = new ProctorSpecification();
        proctorSpecification.setTests(testSpec);
        proctorSpecification.setProvidedContext(providedContext);

        final File output =  new File(targetDir, name);
        try {
            OBJECT_MAPPER.defaultPrettyPrintingWriter().writeValue(output, proctorSpecification);
        } catch (IOException e) {
            throw new CodeGenException("Could not write to temp file " + output.getAbsolutePath(),e);
        }
        return output;
    }

    @Override
    protected Map<String, Object> populateRootMap(final String input, final Map<String, Object> baseContext, final String packageName, final String className) {
        final File inputFile = new File(input);
        final ProctorSpecification spec = ProctorUtils.readSpecification(inputFile);

        return populateRootMap(spec, baseContext, packageName, className);
    }

    @VisibleForTesting
    static Map<String, Object> populateRootMap(final ProctorSpecification spec, final Map<String, Object> baseContext, final String packageName, final String className) {
        final Map<String, Object> rootMap = Maps.newHashMap(baseContext);

        final Map<String, TestSpecification> tests = spec.getTests();

        final List<Object> testDefs = Lists.newArrayListWithCapacity(tests.size());

        // Sort buckets and test names, to have consistent iterator
        final SortedSet<String> sortedTestNames = new TreeSet<String>(tests.keySet());
        for (String testName : sortedTestNames) {
            final Set<Map<String, ?>> buckets = Sets.newLinkedHashSet();

            final TestSpecification testSpecification = tests.get(testName);
            final Entry<String, Integer>[] sortedBuckets = testSpecification.getBuckets().entrySet().toArray(new Map.Entry[testSpecification.getBuckets().size()]);

            Arrays.sort(sortedBuckets, new Comparator<Entry<String, Integer>>() {
                public int compare(final Entry<String, Integer> e0, final Entry<String, Integer> e1) {
                    if(e0.getValue().intValue() < e1.getValue().intValue()) {
                        return -1;
                    }
                    return e0.getValue() == e1.getValue() ? 0 : 1;
                }
            });

            boolean foundFallbackValue = false;
            for (final Entry<String, Integer> bucket : sortedBuckets) {
                final String bucketName = bucket.getKey();
                final String enumName = toEnumName(bucketName);

                final Map<String, Object> bucketDef = Maps.newHashMap();
                final String normalizedBucketName = toJavaIdentifier(bucketName);
                bucketDef.put("value", bucket.getValue());
                bucketDef.put("name", bucketName);
                bucketDef.put("normalizedName", normalizedBucketName);
                bucketDef.put("enumName", enumName);
                bucketDef.put("javaClassName", uppercaseFirstChar(normalizedBucketName));

                buckets.add(bucketDef);

                foundFallbackValue = foundFallbackValue || (bucket.getValue() == testSpecification.getFallbackValue());
            }

            if (! foundFallbackValue) {
                throw new IllegalArgumentException("Specified fallback value " + testSpecification.getFallbackValue() + " for test " + testName + " is not in the list of standard values: " + Arrays.toString(sortedBuckets));
            }

            final String name = toJavaIdentifier(testName);
            final String enumName = toEnumName(name);

            final Map<String, Object> testDef = Maps.newHashMap();
            testDef.put("name", testName);
            testDef.put("normalizedName", name);
            testDef.put("enumName", enumName);

            testDef.put("javaClassName", uppercaseFirstChar(name));
            testDef.put("buckets", buckets);
            testDef.put("defaultValue", testSpecification.getFallbackValue());
            final List<Map<String, String>> nestedPayloadsList = new ArrayList<Map<String,String>>();
            // Only define testDef.payloadJavaClass if the API user has
            // claimed she expects a payload.
            if (testSpecification.getPayload() != null) {
                final String specifiedPayloadTypeName = testSpecification.getPayload().getType();
                final PayloadType specifiedPayloadType = PayloadType.payloadTypeForName(specifiedPayloadTypeName);
                if(specifiedPayloadType == PayloadType.MAP) {
                    testDef.put("isMap","true");
                    for(Map.Entry<String,String> entry : testSpecification.getPayload().getSchema().entrySet()) {
                        final Map<String,String> nestedPayloadsMap = Maps.newHashMap();
                        nestedPayloadsMap.put("key",entry.getKey());
                        final PayloadType payloadTypeForValue = PayloadType.payloadTypeForName(entry.getValue());
                        if(payloadTypeForValue != PayloadType.MAP) {
                            nestedPayloadsMap.put("value", payloadTypeForValue.javaClassName);
                            nestedPayloadsMap.put("valueWithoutArray",
                                    payloadTypeForValue.javaClassName.substring(0, payloadTypeForValue.javaClassName.length() - 2));
                            if (PayloadType.STRING_ARRAY == payloadTypeForValue) {
                                nestedPayloadsMap.put("notANumber", "true");
                            }
                            nestedPayloadsMap.put("payloadTypeName", payloadTypeForValue.payloadTypeName);
                            nestedPayloadsList.add(nestedPayloadsMap);
                        } else {
                            throw new IllegalArgumentException("Nested Map Payloads are not allowed");
                        }
                    }
                }
                testDef.put("payloadJavaClass", specifiedPayloadType.javaClassName);
                testDef.put("payloadAccessorName", specifiedPayloadType.javaAccessorName);
            }

            if (testSpecification.getDescription() != null) {
                testDef.put("description", StringEscapeUtils.escapeJava(testSpecification.getDescription()));
            }
            testDef.put("nestedPayloadsList",nestedPayloadsList);

            testDefs.add(testDef);
        }

        rootMap.put("contextArguments", spec.getProvidedContext());
        rootMap.put("mainClassName", className);
        rootMap.put("packageName", packageName);
        rootMap.put("testEnumName", "Test");
        rootMap.put("testDefs", testDefs);

        return rootMap;
    }

    public static void main(final String[] args) throws CodeGenException {
        if (args.length != 5) {
            System.err.println("java " + TestGroupsGenerator.class.getCanonicalName() + " input.json outputDirectory packageName groupsClassName");
            System.exit(-4);
        }
        final TestGroupsGenerator generator = new TestGroupsGenerator();
        final String input = args[0];
        final String target = args[1];
        final String packageName = args[2];
        final String groupsClass = args[3];
        final String groupsManagerClass = args[4];
        generator.generate(input, target, packageName, groupsClass, groupsManagerClass);
    }
}
TOP

Related Classes of com.indeed.proctor.consumer.gen.TestGroupsGenerator

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.