com.dal.unity.Config.java Source code

Java tutorial

Introduction

Here is the source code for com.dal.unity.Config.java

Source

/*
 * Copyright (C) 1995-2016Dal Solutions, Inc.
 * All Rights Reserved
 * Inquire at License@dal-solutions.com
 */
package com.dal.unity;

import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.Arrays;
import java.util.Collections;
import java.util.EnumSet;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;

import com.dal.unity.test.TestType;
import com.github.javaparser.ast.ImportDeclaration;
import com.github.javaparser.ast.expr.NameExpr;
import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.CommandLineParser;
import org.apache.commons.cli.DefaultParser;
import org.apache.commons.cli.HelpFormatter;
import org.apache.commons.cli.MissingOptionException;
import org.apache.commons.cli.Option;
import org.apache.commons.cli.Options;
import org.apache.commons.cli.ParseException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 *
 * @author Dan Adams
 */
public class Config {
    private static final Logger LOG = LoggerFactory.getLogger(Config.class);
    private final Properties fileProperties = new Properties();
    private File sinkFile;
    private File sourceFile;
    private File targetFile;
    private Map<String, String> javaOptions;
    private String classPath;
    private String methodSuffix;
    private String sink;
    private String source;
    private String target;
    private String testSuffix;
    private boolean compile = false;
    private boolean maxTests = true;
    private boolean minTests = true;
    private boolean nullTests = true;
    private boolean recursive = true;
    private boolean regression = false;
    private static final Config INSTANCE = new Config();
    private static final String DEFAULT_CLASSPATH = ".\\target\\classes";
    private static final String PROPERTIES_FILE = "Unity.properties";
    private static final String DEFAULT_SINK = ".\\src\\test\\java";
    private static final String DEFAULT_SOURCE = ".\\src\\main\\java";
    private static final String DEFAULT_TARGET = ".\\target\\classes";
    private static final String DEFAULT_TEST_FILE_SUFFIX = "UnityTest";
    private static final String DEFAULT_TEST_METHOD_SUFFIX = "UTest";
    private static final String FLAG_CLASSPATH_FILE = "p";
    private static final String FLAG_COMPILE = "c";
    private static final String FLAG_HELP = "h";
    private static final String FLAG_OPTIONS_COMPILER = "D";
    private static final String FLAG_RECURSION = "r";
    private static final String FLAG_REGRESSION = "R";
    private static final String FLAG_SINK = "k";
    private static final String FLAG_SOURCE = "s";
    private static final String FLAG_FILE_SUFFIX = "T";
    private static final String FLAG_METHOD_SUFFIX = "t";
    private static final String FLAG_TARGET = "d";
    private static final String FLAG_TESTS_NULL = "n";
    private static final String FLAG_VALUES_MAX = "M";
    private static final String FLAG_VALUES_MIN = "m";

    private static final String MAJOR_VERSION = "1";
    private static final String MINOR_VERSION = "0";
    private static final String BUG_VERSION = "0";

    private static final ImportDeclaration[] DEFAULT_IMPORTS = new ImportDeclaration[] {
            new ImportDeclaration(new NameExpr("org.junit.After"), false, false),
            new ImportDeclaration(new NameExpr("org.junit.AfterClass"), false, false),
            new ImportDeclaration(new NameExpr("org.junit.Before"), false, false),
            new ImportDeclaration(new NameExpr("org.junit.BeforeClass"), false, false),
            new ImportDeclaration(new NameExpr("org.junit.Test"), false, false),
            new ImportDeclaration(new NameExpr("org.junit.Assert"), true, true) };

    private Config() {
        InputStream propertiesFile = Config.class.getClassLoader().getResourceAsStream(PROPERTIES_FILE);
        try {
            fileProperties.load(propertiesFile);
        } catch (IOException ex) {
            LOG.warn("Unable to read properties file", ex);
        }
    }

    public static Config get() {
        return INSTANCE;
    }

    public String getTestMethodSuffix() {
        return methodSuffix;
    }

    @SuppressWarnings("unchecked")
    void set(String[] args) {
        CommandLineParser parser;
        @SuppressWarnings("UnusedAssignment")
        CommandLine cmd = null;
        try {
            parser = new DefaultParser();
            try {
                cmd = parser.parse(getOptions(), args);
            } catch (MissingOptionException x) {
                System.out.println(x.getMessage());
                HelpFormatter formatter = new HelpFormatter();
                formatter.printHelp("unity", getOptions());
                System.exit(-20);
            }

            if (cmd.hasOption(FLAG_HELP)) {
                // automatically generate the help statement
                HelpFormatter formatter = new HelpFormatter();
                formatter.printHelp("unity", getOptions());
                System.exit(0);
            }

            if (cmd.hasOption(FLAG_CLASSPATH_FILE)) {
                classPath = readClasspath(cmd.getOptionValue(FLAG_CLASSPATH_FILE));
            } else {
                classPath = DEFAULT_CLASSPATH;
            }

            if (cmd.hasOption(FLAG_COMPILE)) {
                compile = true;
            }

            if (cmd.hasOption(FLAG_VALUES_MAX)) {
                maxTests = true;
            }

            if (cmd.hasOption(FLAG_VALUES_MIN)) {
                minTests = true;
            }

            if (cmd.hasOption(FLAG_TESTS_NULL)) {
                nullTests = true;
            }

            if (cmd.hasOption(FLAG_RECURSION)) {
                recursive = true;
            }

            if (cmd.hasOption(FLAG_REGRESSION)) {
                regression = true;
            }

            if (cmd.hasOption(FLAG_SOURCE)) {
                source = cmd.getOptionValue(FLAG_SOURCE);
            } else {
                source = DEFAULT_SOURCE;
            }
            sourceFile = new File(source);

            if (cmd.hasOption(FLAG_TARGET)) {
                target = cmd.getOptionValue(FLAG_TARGET);
            }
            targetFile = new File(target);
            classPath += File.pathSeparator + target + File.pathSeparator + DEFAULT_TARGET;

            if (cmd.hasOption(FLAG_SINK)) {
                sink = cmd.getOptionValue(FLAG_SINK);
            } else {
                sink = DEFAULT_SINK;
            }
            sinkFile = new File(sink);

            if (cmd.hasOption(FLAG_OPTIONS_COMPILER)) {
                Object result = cmd.getParsedOptionValue(FLAG_OPTIONS_COMPILER);
                if (result instanceof Map) {
                    javaOptions = (Map<String, String>) result;
                } else {
                    throw new ParseException("Java Options is not MAP, parsed to " + result.getClass().getName());
                }
            }

            if (cmd.hasOption(FLAG_FILE_SUFFIX)) {
                testSuffix = cmd.getOptionValue(FLAG_FILE_SUFFIX);
            } else {
                testSuffix = DEFAULT_TEST_FILE_SUFFIX;
            }

            if (cmd.hasOption(FLAG_METHOD_SUFFIX)) {
                methodSuffix = cmd.getOptionValue(FLAG_METHOD_SUFFIX);
            } else {
                methodSuffix = DEFAULT_TEST_METHOD_SUFFIX;
            }

        } catch (ParseException x) {
            LOG.error("Parsing failed: {}", x, x);
            System.err.println("Parsing failed.  Reason: " + x.getMessage());
            HelpFormatter formatter = new HelpFormatter();
            formatter.printHelp("ant", getOptions());
            System.exit(-1);
        }
    }

    public Map<String, String> getJavaOptions() {
        return Collections.unmodifiableMap(javaOptions);
    }

    public boolean isRecursive() {
        return recursive;
    }

    public boolean isRegression() {
        return regression;
    }

    public boolean isNullTests() {
        return nullTests;
    }

    public boolean isMaxTests() {
        return maxTests;
    }

    public boolean isMinTests() {
        return minTests;
    }

    public boolean isCompile() {
        return compile;
    }

    public String getSource() {
        return source;
    }

    public String getSink() {
        return sink;
    }

    public String getTarget() {
        return target;
    }

    public String getVersion() {
        return MAJOR_VERSION + "." + MINOR_VERSION + "." + BUG_VERSION;
    }

    public List<ImportDeclaration> getDefaultImports() {
        return Arrays.asList(DEFAULT_IMPORTS);
    }

    public String getClassPath() {
        return classPath;
    }

    public File getSourceFile() {
        return sourceFile;
    }

    public File getSinkFile() {
        return sinkFile;
    }

    public File getTargetFile() {
        return targetFile;
    }

    public String getTestSuffix() {
        return testSuffix;
    }

    public Set<TestType> getTestTypes() {
        Set<TestType> result = EnumSet.allOf(TestType.class);

        if (!maxTests) {
            result.remove(TestType.Max);
        }
        if (!minTests) {
            result.remove(TestType.Min);
        }
        if (!nullTests) {
            result.remove(TestType.Nulls);
        }

        return result;
    }

    private Options getOptions() {
        Options ops = new Options();

        Option compileOpt = new Option(FLAG_COMPILE, "compile", false,
                "Compile source files and ignore any current class files.");
        Option maxOpt = new Option(FLAG_VALUES_MAX, "max", false, "Generate max value tests.");
        Option minOpt = new Option(FLAG_VALUES_MIN, "min", false, "Generate min value tests.");
        Option nullOpt = new Option(FLAG_TESTS_NULL, "null", false, "Generate null tests.");
        Option recurseOpt = new Option(FLAG_RECURSION, "recurse", false,
                "Process files recursively from initial source.");
        Option regressionOpt = new Option(FLAG_REGRESSION, "regress", false,
                "Produce regression tests based on current behavior.");
        Option helpOpt = new Option(FLAG_HELP, "help", false, "Prints this help information.");
        Option classpathOpt = Option.builder(FLAG_CLASSPATH_FILE).longOpt("classpath").hasArg().argName("file")
                .desc("File that contains additional class path entries, used if compiling.  File will have all lines concatonated with a path seperator between each.")
                .build();
        Option javaOpts = Option.builder(FLAG_OPTIONS_COMPILER).hasArgs().valueSeparator().argName("property=value")
                .type((Class<? super Map<String, String>>) Map.class)
                .desc("Additional command line arguments to pass to the compiler.").build();
        Option sourceOpt = Option.builder(FLAG_SOURCE).longOpt("sourcepath").hasArg().argName("source")
                .desc("Source file/directory to process.").build();
        Option sinkOpt = Option.builder(FLAG_SINK).longOpt("sink").hasArg().argName("sink")
                .desc("Location where the generated unit test files are written.").build();
        Option targetOpt = Option.builder(FLAG_TARGET).longOpt("target").hasArg().argName("target")
                .desc("Location where the compiled classes are written, if compile is choosen").build();
        Option suffixOpt = Option.builder(FLAG_FILE_SUFFIX).longOpt("testSuffix").hasArg().argName("suffix")
                .desc("Suffix for the generated test file (text before .java)").build();
        Option methodOpt = Option.builder(FLAG_METHOD_SUFFIX).longOpt("methodSuffix").hasArg().argName("suffix")
                .desc("Suffix added to each test method").build();

        ops.addOption(compileOpt);
        ops.addOption(maxOpt);
        ops.addOption(minOpt);
        ops.addOption(nullOpt);
        ops.addOption(recurseOpt);
        ops.addOption(regressionOpt);
        ops.addOption(classpathOpt);
        ops.addOption(javaOpts);
        ops.addOption(targetOpt);
        ops.addOption(methodOpt);
        ops.addOption(sinkOpt);
        ops.addOption(sourceOpt);
        ops.addOption(suffixOpt);
        ops.addOption(helpOpt);

        return ops;
    }

    private String readClasspath(String classpathFile) {
        StringBuilder result = new StringBuilder(128);
        try (InputStream is = Config.class.getClassLoader().getResourceAsStream(classpathFile);
                InputStreamReader isr = new InputStreamReader(is);
                BufferedReader br = new BufferedReader(isr);) {
            String line;
            while (null != (line = br.readLine())) {
                if (result.length() > 0 && File.pathSeparatorChar != result.charAt(result.length() - 1)) {
                    result.append(File.pathSeparatorChar);
                }
                result.append(line);
            }
        } catch (IOException x) {
            LOG.error("Failure attempting to read classpath file {}", classpathFile, x);
        }

        return result.toString();
    }
}