io.ultreia.java4all.config.plugin.GenerateMojo Maven / Gradle / Ivy
Show all versions of config-maven-plugin Show documentation
package io.ultreia.java4all.config.plugin;
/*
* #%L
* Config :: Maven plugin
* %%
* Copyright (C) 2016 - 2018 Code Lutin, Ultreia.io
* %%
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Lesser Public License for more details.
*
* You should have received a copy of the GNU General Lesser Public
* License along with this program. If not, see
* .
* #L%
*/
import com.google.common.base.Joiner;
import com.google.common.collect.Iterables;
import com.google.common.io.Files;
import io.ultreia.java4all.config.ApplicationConfigProvider;
import io.ultreia.java4all.config.io.spi.ConfigModel;
import io.ultreia.java4all.config.plugin.templates.ApplicationConfigTransformer;
import io.ultreia.java4all.config.plugin.templates.ApplicationConfigTransformerConfig;
import org.apache.commons.lang3.StringUtils;
import org.apache.maven.model.Resource;
import org.apache.maven.plugin.MojoExecutionException;
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.plugins.annotations.ResolutionScope;
import org.nuiton.eugene.DefaultTemplateConfiguration;
import org.nuiton.eugene.Template;
import org.nuiton.eugene.models.object.xml.ObjectModelImpl;
import org.nuiton.plugin.PluginHelper;
import java.io.File;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Properties;
import static java.util.Arrays.asList;
/**
* Generate application config java files from the option definition class.
*
* Created on 28/08/16.
*
* @author Tony Chemit - [email protected]
* @since 3.0
*/
@Mojo(name = "generate", defaultPhase = LifecyclePhase.GENERATE_SOURCES, requiresDependencyResolution = ResolutionScope.COMPILE_PLUS_RUNTIME)
public class GenerateMojo extends ConfigMojoSupport implements ApplicationConfigTransformerConfig {
/**
* To set the package fully qualified name of the generated class.
*
* By default, will use groupId.artifactId (with {@code -} replaced by {@code .}) plus {@code .config}.
*
*
* A special case is designed to remove in artifactId the first component if it is the last one of groupId, for
* example with gav
*
org.nuiton:config
*
* the package name will be {@code org.nuiton.config} and not {@code org.nuiton.nuiton.config}.
*
*/
@Parameter(property = "config.packageName")
private String packageName;
/**
* Model name (will prefix the generated files names with it).
*
* By default, will use artifactId in camelCase format ( example: Model name for artifact id
* {@code config-example} is {@code ConfigExample} ).
*
*/
@Parameter(property = "config.modelName")
private String modelName;
/**
* The simple name of the options class.
*
* By default, will use {@code config.modelName + ConfigOption}.
*
*/
@Parameter(property = "config.optionsClassName")
private String optionsClassName;
/**
* The simple name of the actions class.
*
* By default, will use {@code config.modelName + ConfigAction}.
*
*/
@Parameter(property = "config.actionsClassName")
private String actionsClassName;
/**
* To generate configuration provider classes.
*/
@Parameter(property = "config.generateProvider", defaultValue = "true")
private boolean generateProvider;
/**
* To use nuiton-i18n API to translate descriptions in generate code.
*/
@Parameter(property = "config.useNuitonI18n")
private boolean useNuitonI18n;
/**
* The source directory where to scan options java file.
*/
@Parameter(property = "config.sourceDirectory", defaultValue = "${basedir}/src/main/java", required = true)
private File sourceDirectory;
/**
* The root directory where to generated.
*/
@Parameter(property = "config.outputDirectory", defaultValue = "${project.build.directory}/generated-sources/java", required = true)
private File outputDirectory;
/**
* To skip generate.
*/
@Parameter(property = "config.skip", defaultValue = "false")
private boolean skip;
/** Directory where to generate i18n getters file. */
@Parameter(property = "i18n.gettersDirectory", defaultValue = "${project.build.directory}/i18n/getters", required = true)
private File i18nGettersDirectory;
private ApplicationConfigTransformer template;
private String configClassName;
private String configProviderClassName;
private ConfigModel configModel;
@Override
protected void init() throws Exception {
if (skip) {
return;
}
super.init();
if (modelName == null) {
List artifactIdPaths = new ArrayList<>();
for (String artifactIdPath : getProject().getArtifactId().replaceAll("-", ".").split("\\.")) {
artifactIdPaths.add(StringUtils.capitalize(artifactIdPath));
}
modelName = Joiner.on("").join(artifactIdPaths);
if (isVerbose()) {
getLog().info("Use model name: " + modelName);
}
}
if (getModelFile() == null) {
setModelFile(modelName);
}
File modelFile = getModelFile();
if (!modelFile.exists()) {
throw new MojoExecutionException("No model file found at: " + modelFile);
}
if (packageName == null) {
List groupIdPaths = new ArrayList<>(asList(getProject().getGroupId().split("\\.")));
List artifactIdPaths = new ArrayList<>(Arrays.asList(getProject().getArtifactId().replaceAll("-", ".").split("\\.")));
if (Iterables.getLast(groupIdPaths).equals(Iterables.getFirst(artifactIdPaths, ""))) {
artifactIdPaths.remove(0);
}
groupIdPaths.addAll(artifactIdPaths);
packageName = Joiner.on(".").join(groupIdPaths);
if (isVerbose()) {
getLog().info("Use package name: " + packageName);
}
}
if (optionsClassName == null) {
optionsClassName = modelName + "ConfigOption";
if (isVerbose()) {
getLog().info("Configuration options class: " + optionsClassName);
}
}
if (actionsClassName == null) {
actionsClassName = modelName + "ConfigAction";
if (isVerbose()) {
getLog().info("Configuration actions class: " + actionsClassName);
}
}
ClassLoader loader = this.initClassLoader(getProject(), sourceDirectory, true, false, false, true, true);
// get options
configClassName = modelName + "Config";
getLog().info("Config class name: " + configClassName);
if (generateProvider) {
configProviderClassName = configClassName + "Provider";
if (isVerbose()) {
getLog().info("Config provider class name: " + configClassName);
}
}
configModel = getConfigReader().read(modelFile.toPath());
Properties templateProperties = new Properties();
templateProperties.put(Template.PROP_ENCODING, StandardCharsets.UTF_8.name());
templateProperties.put(Template.PROP_VERBOSE, isVerbose());
templateProperties.put(Template.PROP_OVERWRITE, true);
templateProperties.put(Template.PROP_CLASS_LOADER, loader);
templateProperties.put(ApplicationConfigTransformer.PROP_CONFIG, this);
template = new ApplicationConfigTransformer();
template.setConfiguration(new DefaultTemplateConfiguration(templateProperties));
if (!getProject().getCompileSourceRoots().contains(outputDirectory.getPath())) {
if (isVerbose()) {
getLog().info("Add compile source root : " + outputDirectory);
}
getProject().addCompileSourceRoot(outputDirectory.getPath());
}
}
@Override
protected void doAction() throws Exception {
if (skip) {
getLog().info("Generate mojo is skip.");
return;
}
getLog().info("Generate file(s) to: " + outputDirectory);
ObjectModelImpl objectModel = new ObjectModelImpl();
objectModel.setName(modelName);
template.applyTemplate(objectModel, outputDirectory);
if (generateProvider) {
String content = packageName + "." + configClassName + "Provider";
File serviceLoaderFile = PluginHelper.getFile(outputDirectory, "META-INF", "services", ApplicationConfigProvider.class.getName());
Files.createParentDirs(serviceLoaderFile);
Files.write(content.getBytes(), serviceLoaderFile);
if (isVerbose()) {
getLog().info("Generate serviceLoader provider file: " + serviceLoaderFile);
}
Resource resource = new Resource();
resource.setDirectory(outputDirectory.getAbsolutePath());
resource.setIncludes(Collections.singletonList("**/" + ApplicationConfigProvider.class.getName()));
getProject().addResource(resource);
}
}
@Override
public String getPackageName() {
return packageName;
}
@Override
public String getModelName() {
return modelName;
}
@Override
public String getOptionsClassName() {
return optionsClassName;
}
@Override
public String getActionsClassName() {
return actionsClassName;
}
@Override
public File getI18nGettersDirectory() {
return i18nGettersDirectory;
}
@Override
public boolean isGenerateProvider() {
return generateProvider;
}
@Override
public String getConfigProviderClassName() {
return configProviderClassName;
}
@Override
public String getConfigClassName() {
return configClassName;
}
@Override
public ConfigModel getConfigModel() {
return configModel;
}
@Override
public boolean isUseNuitonI18n() {
return useNuitonI18n;
}
}