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

org.etlunit.maven.FeatureCompilerMojo Maven / Gradle / Ivy

There is a newer version: 1.6.9
Show newest version
package org.etlunit.maven;

import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.project.MavenProject;
import org.codehaus.jackson.JsonNode;
import org.etlunit.io.FileBuilder;
import org.etlunit.json.validator.*;
import org.etlunit.maven.util.JavaProperty;
import org.etlunit.maven.util.JavaSource;
import org.etlunit.util.IOUtils;
import org.etlunit.util.StringUtils;
import org.etlunit.util.maven.regexp.OperationNameExpression;

import java.io.File;
import java.io.FileFilter;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * Goal which touches a timestamp file.
 *
 * @goal generate-gson-proxies
 * @phase generate-sources
 * @requiresDependencyResolution test
 */
public class FeatureCompilerMojo
	extends AbstractMojo
{
	/**
	 * @parameter expression="${project}" default-value="${project}"
	 */
	protected MavenProject mavenProject;

	/**
	 * Location of the file.
	 *
	 * @parameter expression="${basedir}/src/main/resources"
	 * @required
	 */
	private File inputDirectory;

	private final SchemaResolver resolver = new CachingSchemaResolver();

	/**
	 * Location of the file.
	 *
	 * @parameter expression="${outputDirectory}" default-value="${project.build.directory}/generated-sources/etlunit"
	 * @required
	 */
	private File outputDirectory;

	private final List schemaErrors = new ArrayList();

	public void execute()
		throws MojoExecutionException
	{
		File f = outputDirectory;

		if (!f.exists())
		{
			f.mkdirs();
		}

		// recurse, looking for schema's
		scanDir(inputDirectory, null, true);
		scanDir(inputDirectory, null, false);

		if (schemaErrors.size() != 0)
		{
			throw new MojoExecutionException("Errors processing schema files: " + schemaErrors);
		}

		if (mavenProject != null)
		{
			mavenProject.addCompileSourceRoot(outputDirectory.getAbsolutePath());
		}
	}

	private void scan(File file, String packag, boolean scanOnly)
	{
		if (file.isDirectory())
		{
			getLog().info((!scanOnly ? "Processing" : "Prescanning") + " 1-level resource dir: " + file.getAbsolutePath());

			scanDir(file, packag == null ? file.getName() : (packag + "." + file.getName()), scanOnly);
		}
		else if (file.isFile() && file.getName().endsWith(".jsonSchema"))
		{
			scanFile(file, packag, scanOnly);
		}
	}

	private void scanFile(File file, String packag, boolean scanOnly)
	{
		getLog().info((!scanOnly ? "Processing" : "Prescanning") + " schema file: " + file.getName());

		try
		{
			JsonNode schemaNode = JsonUtils.loadJson(file);
			JsonSchema schema = new JsonSchema(schemaNode);

			if (scanOnly)
			{
				String uri = (packag == null ? "" : (packag.replace('.', '/') + "/")) + file.getName();
				getLog().info("Registering schema to uri: " + uri);
				resolver.registerSchemaByLocalId(uri, schema);
				return;
			}

			FileBuilder outputBuilder = new FileBuilder(outputDirectory);

			if (packag != null)
			{
				outputBuilder = outputBuilder.subdir(packag.replace('.', '/'));
			}

			outputBuilder = outputBuilder.mkdirs();

			JsonValidator validator = new JsonValidator(schema, resolver);

			String featureName = getFeatureName(file.getName());

			if (file.getName().endsWith(".configuration.validator.jsonSchema"))
			{
				// process configuration schema
				generateSourceFromSchema(packag, outputBuilder, validator.resolveSchemaReference(schema.getSchemaNode()), StringUtils.makeProperPropertyName(featureName + "Configuration"));
			}
			else if (file.getName().endsWith(".validator.jsonSchema"))
			{
				// process operational schema
				// each of these extends the configuration schema
				generateSourceFromSchema(packag, outputBuilder, validator.resolveSchemaReference(schema.getSchemaNode()), StringUtils.makeProperPropertyName(getOperationName(file.getName()) + "Operation"));
				generateInterfaceForOperation(
					packag,
					StringUtils.makeProperPropertyName(getOperationName(file.getName()) + "Operation"),
					StringUtils.makeProperPropertyName(getOperationName(file.getName()))
				);
			}
		}
		catch (JsonSchemaValidationException e)
		{
			getLog().error(e);
			schemaErrors.add(e);
			throw new IllegalArgumentException(e);
		}
		catch (Exception e)
		{
			getLog().error(e);
			throw new IllegalArgumentException(e);
		}
	}

	private void generateInterfaceForOperation(String packag, String operationClass, String operationName) throws IOException
	{
		String name = operationClass + "Processor";

		FileBuilder outputBuilder = new FileBuilder(outputDirectory);
		if (packag != null)
		{
			outputBuilder = outputBuilder.subdir(packag.replace('.', '/'));
		}

		outputBuilder = outputBuilder.mkdirs();

		File output = outputBuilder.name(name + ".java").file();

		getLog().info("Creating processor interface: " + output);

		IOUtils.writeBufferToFile(output, new StringBuffer("package " + packag + ";\n" +
			"\n" +
			"import org.etlunit.*;\n" +
			"import org.etlunit.context.VariableContext;\n" +
			"import org.etlunit.parser.ETLTestOperation;\n" +
			"import org.etlunit.parser.ETLTestValueObject;\n" +
			"\n" +
			"public interface " + operationClass + "Processor {\n" +
			"\tpublic ClassResponder.action_code process" + operationName + "(" + operationClass + " operation, ETLTestOperation op, ETLTestValueObject obj, VariableContext context, ExecutionContext econtext) throws TestAssertionFailure, TestExecutionError, TestWarning;\n" +
			"}"));
	}

	private String getOperationName(String name)
	{
		OperationNameExpression one = new OperationNameExpression(name);

		if (one.hasNext())
		{
			return one.getOperationName();
		}

		throw new IllegalArgumentException("Invalid schema file name: " + name);
	}

	private void generateSourceFromSchema(String packag, FileBuilder outputBuilder, JsonSchemaObjectNode schema, String className) throws IOException
	{
		File output = outputBuilder.name(className + ".java").file();

		getLog().info("Creating operation request interface: " + output);

		Map properties = schema.getPropertySchemas();

		JavaSource source = new JavaSource(packag, className);

		for (Map.Entry entry : properties.entrySet())
		{
			String key = entry.getKey();
			if (key.startsWith("_"))
			{
				continue;
			}

			JsonSchemaObjectNode propertySchema = entry.getValue();

			JavaProperty property = new JavaProperty(key, propertySchema.getType().get(0), propertySchema.getEnumValues(), propertySchema.isRequired());

			source.addProperty(property);
		}

		IOUtils.writeBufferToFile(output, new StringBuffer(source.toSource()));
	}

	private String getFeatureName(String name)
	{
		int endOfFeatureName = name.indexOf('.');

		return name.substring(0, endOfFeatureName);
	}

	private void scanDir(File file, final String packag, final boolean scanOnly)
	{
		getLog().info((!scanOnly ? "Processing" : "Prescanning") + " resource dir: " + file.getName());

		// skip these common dirs
		if (file.getName().equals("META-INF") || file.getName().equals("WEB-INF") || file.getName().startsWith("."))
		{
			return;
		}

		file.listFiles(new FileFilter()
		{
			public boolean accept(File pathname)
			{
				scan(pathname, packag, scanOnly);

				return false;
			}
		});
	}

	public void setInputDirectory(File inputDirectory)
	{
		this.inputDirectory = inputDirectory;

		if (!inputDirectory.exists())
		{
			throw new IllegalArgumentException("Input directory does not exist: " + inputDirectory);
		}
	}

	public void setOutputDirectory(File outputDirectory)
	{
		this.outputDirectory = outputDirectory;

		outputDirectory.mkdirs();

		if (!outputDirectory.exists())
		{
			throw new IllegalArgumentException("Input directory does not exist: " + outputDirectory);
		}
	}
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy