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

com.casualsuperman.portent.PortentMojo Maven / Gradle / Ivy

There is a newer version: 0.3.1
Show newest version
package com.casualsuperman.portent;

import lombok.extern.slf4j.Slf4j;
import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugin.MojoFailureException;
import org.apache.maven.plugins.annotations.LifecyclePhase;
import org.apache.maven.plugins.annotations.Mojo;
import org.apache.maven.plugins.annotations.Parameter;
import org.apache.maven.project.MavenProject;

import java.io.File;
import java.nio.charset.Charset;
import java.nio.file.Path;
import java.util.*;
import java.util.stream.Collectors;

@Slf4j
@Mojo(name = "render", defaultPhase = LifecyclePhase.GENERATE_SOURCES, threadSafe = true)
public class PortentMojo extends AbstractMojo {
	@Parameter(defaultValue = "${project.compileSourceRoots}", required = true)
	private List compileSourceRoots;

	@Parameter(property = "templateDirectory", defaultValue = "src/main/templates")
	private File templateDir;

	@Parameter(defaultValue = "${project.build.directory}/generated-sources/portent")
	private File generatedSourcesDirectory;

	@Parameter(property = "sourceEncoding", defaultValue = "${project.build.sourceEncoding}")
	private String encoding;

	/**
	 * Should Portent fail execution if no templates are found. Defaults to true.
	 */
	@Parameter(property = "failIfNoTemplates", defaultValue = "true")
	private boolean failIfNoTemplates;

	/**
	 * Should Portent fail execution if no instances of a template are found. Defaults to true.
	 */
	@Parameter(property = "failIfNoInstances", defaultValue = "true")
	private boolean failIfNoInstances;

	/**
	 * Should Portent overwrite existing files. Possible values are ALWAYS, NEVER,
	 * and NON_SOURCE_FILES. Defaults to NON_SOURCE_FILES.
	 */
	@Parameter(property = "overwriteExisting", defaultValue = "NON_SOURCE_FILES")
	private OverwriteBehavior overwriteExisting;

	@Parameter(readonly = true, required = true, defaultValue = "${project}")
	private MavenProject project;

	public void execute() throws MojoFailureException {
		Charset charset = Charset.forName(encoding);

		Map archetypes = getArchetypes();
		if (archetypes.isEmpty()) {
			log.warn("No template definitions found in {}, nothing to do.", templateDir);
			if (failIfNoTemplates) {
				throw new MojoFailureException("No template definitions found");
			}
			return;
		}

		Map> instances = getInstances(archetypes);
		if (instances.isEmpty()) {
			log.warn("No template instances found, nothing to do");
			if (failIfNoInstances) {
				throw new MojoFailureException("no instances to render found");
			}
			return;
		}

		boolean overwrite;
		switch (overwriteExisting) {
			case NEVER:
				overwrite = false;
				break;
			case ALWAYS:
				overwrite = true;
				break;
			case NON_SOURCE_FILES:
				overwrite = !isSourceRoot(generatedSourcesDirectory);
				break;
			default:
				throw new IllegalArgumentException("unable to determine overwrite behavior");
		}

		TemplateEngine engine = getTemplateEngine();
		ContextFactory contextFactory = new ContextFactory(getGlobalVars());
		instances.entrySet().parallelStream().forEach(instanceGroup -> {
			Archetype archetype = archetypes.get(instanceGroup.getKey());
			ArchetypeTemplater templater = new ArchetypeTemplater(archetype, engine, contextFactory,
			                                                      charset);
			instanceGroup.getValue().parallelStream().forEach(instance ->
					templater.constructArchetype(generatedSourcesDirectory, instance, overwrite));
		});
		String relDest = project.getBasedir().toPath().relativize(generatedSourcesDirectory.toPath()).toString();
		project.addCompileSourceRoot(relDest);
	}

	private boolean isSourceRoot(File dir) {
		Path basePath = project.getBasedir().toPath();
		for (String sourceRoot : compileSourceRoots) {
			if (basePath.resolve(sourceRoot).toFile().equals(dir)) {
				return true;
			}
		}
		return false;
	}

	private Map getGlobalVars() {
		return Collections.emptyMap();
	}

	private TemplateEngine getTemplateEngine() {
		return new VelocityTemplateEngine();
	}

	private Map getArchetypes() {
		ArchetypeLocator locator = new ArchetypeLocator(templateDir.toPath());
		locator.discover();
		return locator.getTemplates(Charset.forName(encoding));
	}

	private Map> getInstances(Map archetypes) {
		return compileSourceRoots.parallelStream()
				.map(f -> project.getBasedir().toPath().resolve(f).toFile())
				.map(root -> new InstanceLocator(root, archetypes.keySet()))
				.map(instanceLocator -> {
					instanceLocator.discover();
					return instanceLocator.getTemplateInstances();
				})
				.map(Map::entrySet)
				.flatMap(Collection::stream)
				.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, (a, b) -> {
					a.addAll(b);
					return a;
				}));
	}
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy