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

com.socialbakers.config.generator.GenerateConfig Maven / Gradle / Ivy

Go to download

Maven plugin for small application config support. Allows you to define configuration for your application at one place and generate config files and java class. Configuration can be instantiate by var args, file config or environment variables or combination of all. TODO: - boolean opts -- is/get -- option without value true - make def enum public - static instance to access from everywhere without pass an instance

The newest version!
package com.socialbakers.config.generator;

import java.io.File;
import java.io.FileWriter;
import java.io.Writer;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.apache.commons.lang3.StringUtils;
import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugins.annotations.Mojo;
import org.apache.maven.plugins.annotations.Parameter;
import org.eclipse.jdt.internal.core.Assert;

import com.socialbakers.config.IParamDefinition;

import freemarker.template.Configuration;
import freemarker.template.Template;
import freemarker.template.TemplateExceptionHandler;

/**
 * @author Robert Fišer
 */
@Mojo(name = "generate-config")
public class GenerateConfig extends AbstractMojo {

	private static final String PACKAGE_CLASS_REGEX = "(([a-z_]+\\.)*)([A-Z_][A-Za-z0-9_]*)";

	public static final String HELP = "help";
	public static final String DUMP = "dump";

	@Parameter
	private List params;
	private Map iParams = new LinkedHashMap();

	@Parameter(alias = "outputDir")
	private String outputDirName;

	@Parameter
	private String configClass;

	@Parameter
	private String envFile = ".env";

	@Parameter
	private String configFileDefault = "configuration-default.xml";

	@Parameter
	private String configFileSite = "configuration-site.xml";

	@Parameter
	private String helpName = "";

	@Parameter
	private String helpDescription = "";

	@Parameter(alias = "abstract")
	private boolean abstr;

	@Parameter
	private ParamValueSeparator paramValueSeparator = ParamValueSeparator.NO_SEPARATOR;

	@Parameter
	private boolean alwaysReload;

	@Parameter
	private String confDirEnv = "conf/";

	@Parameter
	private String superClass = "com.socialbakers.config.AbstractConfiguration";

	@Parameter
	private boolean genEnv = false;

	@Parameter
	private boolean genXml = true;

	private String className;
	private String packagePath;
	private File javaConfig;
	private File envConfig;
	private File xmlDefaultConfig;
	private File xmlSiteConfig;
	private File outputDir;

	@Override
	public void execute() throws MojoExecutionException {
		try {

			for (IParamDefinition param : params) {
				iParams.put(param.getName(), param);
			}
			validate();

			Matcher matcher = Pattern.compile(PACKAGE_CLASS_REGEX).matcher(configClass);
			boolean find = matcher.find();
			Assert.isTrue(find);

			packagePath = matcher.group(1);
			className = matcher.group(3);

			if (outputDirName == null) {
				outputDir = new File("target/generated-sources/");
			} else {
				outputDir = new File(outputDirName);
			}

			if (!packagePath.isEmpty()) {
				packagePath = packagePath.substring(0, packagePath.length() - 1);
			}

			Configuration cfg = new Configuration();
			cfg.setTemplateExceptionHandler(TemplateExceptionHandler.RETHROW_HANDLER);
			cfg.setClassForTemplateLoading(getClass(), "templates");

			loadSuperParams();

			validate();

			Map input = new HashMap();
			input.put("params", iParams.values());
			input.put("package", packagePath);
			input.put("className", className);
			input.put("abstract", abstr);
			input.put("configFileDefault", configFileDefault);
			input.put("configFileSite", configFileSite);
			input.put("helpName", helpName);
			input.put("helpDescription", helpDescription);
			input.put("paramValueSeparator", paramValueSeparator);
			input.put("alwaysReload", Boolean.valueOf(alwaysReload).toString());
			input.put("confDirEnv", confDirEnv);
			input.put("superClass", superClass);
			input.put("genXml", genXml);
			input.put("genEnv", genEnv);

			javaConfig = new File(outputDir, packagePath.replaceAll("\\.", "/"));
			javaConfig.mkdirs();
			javaConfig = new File(javaConfig, className + ".java");
			getLog().info("Generating files:");
			getLog().info(javaConfig.getAbsolutePath());
			Template javaConfigTemplate = cfg.getTemplate("java-config.ftl");
			writeFile(javaConfigTemplate, javaConfig, input);

			if (genXml) {
				xmlDefaultConfig = new File(outputDir, configFileDefault);
				xmlSiteConfig = new File(outputDir, configFileSite);
				getLog().info(xmlDefaultConfig.getAbsolutePath());
				getLog().info(xmlSiteConfig.getAbsolutePath());
				Template xmlConfigTemplate = cfg.getTemplate("xml-config.ftl");
				writeFile(xmlConfigTemplate, xmlDefaultConfig, input);
				writeFile(xmlConfigTemplate, xmlSiteConfig, new HashMap());
			}

			if (genEnv) {
				envConfig = new File(outputDir, envFile);
				getLog().info(envConfig.getAbsolutePath());
				Template envConfigTemplate = cfg.getTemplate("env-config.ftl");
				writeFile(envConfigTemplate, envConfig, input);
			}
		} catch (Exception e) {
			throw new MojoExecutionException(e.getMessage(), e);
		}
	}

	private void checkNamesAreSet() {
		for (IParamDefinition p : iParams.values()) {
			if (StringUtils.isBlank(p.getName())) {
				throw new IllegalStateException("Some parameter hasn't set name.");
			}
		}
	}

	private void checkSubsequence(String s1, String s2, String what) {
		if (StringUtils.isBlank(s1) || StringUtils.isBlank(s2)) {
			return;
		}
		if (s1.startsWith(s2)) {
			throw new IllegalStateException(what + " '" + s1 + "' starts with " + what + " '" + s2 + "'.");
		}
	}

	private void checkSubsequences() {
		for (IParamDefinition p1 : iParams.values()) {
			for (IParamDefinition p2 : iParams.values()) {
				if (p1 == p2) {
					continue;
				}
				checkSubsequence(p1.getName(), p2.getName(), "name");
				checkSubsequence(p1.getOption(), p2.getOption(), "option");
				checkSubsequence(p1.getEnv(), p2.getEnv(), "env var");
			}
		}
	}

	private  void checkUnique(T value, String what, Set set) {
		if (value == null) {
			return;
		}
		if (set.contains(value)) {
			throw new IllegalStateException("Multiple usage of " + what + ": " + value);
		}
		if (HELP.equals(value)) {
			throw new IllegalStateException(HELP + " is reserved word and cannot be used for " + what);
		}
		if (DUMP.equals(value)) {
			throw new IllegalStateException(DUMP + " is reserved word and cannot be used for " + what);
		}
		set.add(value);
	}

	private void checkUniqueIdentifiers() {
		Set names = new HashSet();
		Set envVars = new HashSet();
		Set options = new HashSet();
		Set orders = new HashSet();

		for (ParamDefinition p : params) {
			checkUnique(p.getName(), "name", names);
			checkUnique(p.getEnv(), "env. var.", envVars);
			checkUnique(p.getOption(), "option", options);
			checkUnique(p.getOrder(), "order", orders);
		}
	}

	private void loadSuperParams() {
		try {
			recLoadSuperParams(Class.forName(superClass));
		} catch (ClassNotFoundException e) {
			throw new IllegalStateException(e);
		}
	}

	private void recLoadSuperParams(Class configSuperClass) {
		if (com.socialbakers.config.AbstractConfiguration.class == configSuperClass || Object.class == configSuperClass) {
			return;
		}
		for (Class class1 : configSuperClass.getDeclaredClasses()) {
			if (!class1.isEnum()) {
				continue;
			}
			if (!Arrays.asList(class1.getInterfaces()).contains(IParamDefinition.class)) {
				continue;
			}
			getLog().info("Loading params from superClass:" + class1);
			for (Object object : class1.getEnumConstants()) {
				IParamDefinition param = (IParamDefinition) object;
				if (!iParams.containsKey(param.getName())) {
					iParams.put(param.getName(), param);
				}
			}
		}
		recLoadSuperParams(configSuperClass.getSuperclass());
	}

	private void validate() {
		checkNamesAreSet();
		checkUniqueIdentifiers();
		checkSubsequences();
	}

	private void writeFile(Template template, File targetFile, Map input) throws Exception {
		Writer fileWriter = new FileWriter(targetFile);
		try {
			template.process(input, fileWriter);
		} finally {
			fileWriter.close();
		}
	}

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy