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

org.nuiton.eugene.plugin.GenerateMojo Maven / Gradle / Ivy

There is a newer version: 3.0-beta-2
Show newest version
/*
 * #%L
 * EUGene :: Maven plugin
 * %%
 * Copyright (C) 2006 - 2017 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%
 */

package org.nuiton.eugene.plugin;

import com.google.common.base.Joiner;
import io.ultreia.java4all.lang.Strings;
import org.apache.commons.lang3.StringUtils;
import org.apache.maven.artifact.Artifact;
import org.apache.maven.execution.MavenSession;
import org.apache.maven.model.PluginExecution;
import org.apache.maven.model.Resource;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugin.MojoFailureException;
import org.apache.maven.plugin.descriptor.PluginDescriptor;
import org.apache.maven.plugins.annotations.Component;
import org.apache.maven.plugins.annotations.Mojo;
import org.apache.maven.plugins.annotations.Parameter;
import org.apache.maven.plugins.annotations.ResolutionScope;
import org.apache.maven.project.MavenProject;
import org.apache.maven.settings.Settings;
import org.nuiton.eugene.DefaultTemplateConfiguration;
import org.nuiton.eugene.LogProxy;
import org.nuiton.eugene.ModelHelper;
import org.nuiton.eugene.ModelReader;
import org.nuiton.eugene.Template;
import org.nuiton.eugene.models.Model;
import org.nuiton.eugene.models.object.reader.InvalidModelPropertiesException;
import org.nuiton.eugene.plugin.writer.BaseChainedFileWriter;
import org.nuiton.eugene.plugin.writer.BaseChainedFileWriterToMemoryModel;
import org.nuiton.eugene.plugin.writer.XmiChainedFileWriter;
import org.nuiton.eugene.writer.ChainedFileWriter;
import org.nuiton.eugene.writer.ChainedFileWriterConfiguration;
import org.nuiton.eugene.writer.ChainedFileWriterData;
import org.nuiton.eugene.writer.ChainedFileWriterEntry;
import org.nuiton.eugene.writer.ChainedFileWriterToMemoryModel;
import org.nuiton.eugene.writer.ChainedWriterEngine;
import org.nuiton.eugene.writer.WriterReport;
import org.nuiton.i18n.spi.GetterFile;
import org.nuiton.plugin.AbstractPlugin;
import org.nuiton.plugin.PluginWithEncoding;

import java.io.File;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * Eugene generator plugin (a.k.a generate mojo)
 * 

* Fill inputs and mojo will chained needed writer. * * @author Tony Chemit - [email protected] * @since 2.5 */ @Mojo(name = "generate", requiresDependencyResolution = ResolutionScope.COMPILE) public class GenerateMojo extends AbstractPlugin implements ChainedFileWriterConfiguration, PluginWithEncoding, LogProxy { /** * Inputs files to used to generate the required model files. *

* An include has the following pattern : *

     *  writer:
     * 
* when you want to use a specific writer with his default io values. *

* Can also write : *

     *  [writer:]directory:includes
     * 
* where {@code includes} is the pattern to find files from the directory * given and must be terminated by the extension of files. *

* Specifying the {@code writer} can be usefull when you want to use a * writer for an unknown extension by any writer. *

* Example : *

     * <inputs>
     *     <input>zargo:</input>
     *     <input>src/main/xmi2:**\/*.zargo</input>
     *     <input>zargo:src/main/xmi:**\/*.zargo2</input>
     * </inputs>
     * 
* * Note: If your using a single input, you can just write : *
     * <inputs>zargo</inputs>
     * 
* * @since 2.0.0 */ @Parameter(property = "eugene.inputs", required = true) protected String[] inputs; /** * List of input (protocol) not to treate separated by comma. *

* Example : *

     * <skipInputs>xmi</skipInputs>
     * <skipInputs>xmi,model</skipInputs>
     * 
* * @since 2.0.0 */ @Parameter(property = "eugene.skipInputs") protected String skipInputs; /** * Where to generate files. * * @since 2.0.0 */ @Parameter(property = "eugene.outputDirectory", defaultValue = "target/generated-sources", required = true) protected File outputDirectory; /** * Where to copy extracted files (when using class-path data). * * @since 2.1.3 */ @Parameter(property = "eugene.extractDirectory", defaultValue = "target/extracted-sources", required = true) protected File extractDirectory; /** * Ecrase les fichiers générés. * * @since 2.0.0 */ @Parameter(property = "eugene.overwrite", defaultValue = "false") protected boolean overwrite; /** * Pour activer le mode verbeux. * * @since 2.0.0 */ @Parameter(property = "eugene.verbose", defaultValue = "${maven.verbose}") protected boolean verbose; /** * Encoding to be used for generation of files. * * Note: If nothing is filled here, we will use the system * property {@code file.encoding}. * * @since 2.0.0 */ @Parameter(property = "eugene.encoding", defaultValue = "${project.build.sourceEncoding}") protected String encoding; /** * A flag to mark the mojo to be used in a test phase. This will permits * to add generated sources in test compile roots. * * @since 2.0.0 */ @Parameter(property = "eugene.testPhase", defaultValue = "false") protected boolean testPhase; /** * The type of model to be used. *

* By default, use an {@code objectmodel}. * * @since 2.0.0 */ @Parameter(property = "eugene.modelType", defaultValue = "objectmodel", required = true) protected String modelType; /** * Properties to pass to writer. * * @since 2.0.0 */ @Parameter protected Map properties; /** * Ne génère rien, analyse juste la configuration. * * @since 2.0.0 */ @Parameter(property = "eugene.dryRun", defaultValue = "false") protected boolean dryRun; /** * Nom du paquetage pour les fichiers générés (xmi input sepcific). * * @since 2.0.0 */ @Parameter(property = "generator.fullPackagePath", defaultValue = "${project.groupId}.${project.artifactId}") protected String fullPackagePath; /** * Nom du resolver a utiliser pour les transformations xmi vers model * (xmi input sepcific). * * @since 2.0.0 */ @Parameter(property = "generator.resolver", defaultValue = "org.nuiton.eugene.ResourceResolver") protected String resolver; /** * Templates à utiliser, séparés par des virgules pour les transformations * depuis les models (model input sepcific). * * @since 0.50 */ @Parameter(property = "eugene.templates") protected String templates; /** * Templates à ne pas utiliser lors de la transformations des models * (model input sepcific). * * @since 0.63 */ @Parameter(property = "eugene.excludeTemplates") protected String[] excludeTemplates; /** * Nom par défaut du paquetage généré (model input specific). * * @since 0.50 */ @Parameter(property = "eugene.defaultPackage", defaultValue = "${project.groupId}.${project.artifactId}") protected String defaultPackage; /** * List of packages to generate (comma separated). (model input specific). *

* If the parameter is not filled, will generate all packages. * * @since 1.0.0-rc-8 */ @Parameter(property = "eugene.generatedPackages") protected String generatedPackages; /** * List of package to extract from xmi to models. (model input specific). *

* If the parameter is not filled, will extract all packages. * * @since 1.0.0-rc-8 */ @Parameter(property = "eugene.extractedPackages", defaultValue = "${project.groupId}.${project.artifactId}") protected String extractedPackages; /** * A flag to fail if model properties is not safe (means some tagValues or stereotypes are not correct). * * Note: since version 3.0, the default value is {@code true}. * * @since 2.9 */ @Parameter(property = "eugene.failIfUnsafe", defaultValue = "true") protected boolean failIfUnsafe; /** * A flag to execute only once the plugin execution in a module. * * @since 2.9 */ @Parameter(property = "eugene.executeOnce", defaultValue = "true") protected boolean executeOnce; /** * To use a new object model extension file. * * @since 3.0 */ @Parameter(property = "eugene.modelExtensionFile") protected File modelExtensionFile; /** * Resources directory (Where to generate may be some files). * * @since 3.0 */ @Parameter(property = "eugene.resourceDirectory", defaultValue = "src/main/resources", readonly = true, required = true) protected File resourceDirectory; /** Directory where to generate getters files. */ @Parameter(property = "i18n.gettersDirectory", defaultValue = "${project.build.directory}/i18n/getters", required = true) protected File gettersDirectory; /** * Maven project. * * @since 2.0.0 */ @Parameter(defaultValue = "${project}", readonly = true) protected MavenProject project; /** * Le settings (pour obtenir le mode offline). * * @since 2.0.0 */ @Parameter(defaultValue = "${settings}", readonly = true) protected Settings settings; /** * Maven session. */ @Parameter(defaultValue = "${session}", readonly = true) protected MavenSession session; /** * All available models (obtain by plexus, keys are plexus roles, * values are a instance of corresponding model). */ @Component(role = Model.class) protected Map _models; /** All available writers introspects via plexus. */ @Component(role = ChainedFileWriter.class) protected Map writers; /** All available writers introspects via plexus. */ @Component(role = ModelReader.class) protected Map> modelReaders; /** All available templates introspects via plexus. */ @Component(role = Template.class) protected Map> modelTemplates; /** The engine to compute {@link ChainedFileWriter} from inputs entries. */ @Component(role = ChainedWriterEngine.class) protected ChainedWriterEngine engine; protected ModelHelper modelHelper; /** fixed classloader */ protected ClassLoader fixedClassLoader; protected List> templateList; protected GetterFile i18nGetterFile; protected WriterReport newWriterReport() { return new WriterReport() { @Override public void addFile(String entry, File file, boolean b) { super.addFile(entry, file, b); if (b || isVerbose()) { getLog().info("Will generate " + file); } if (getLog().isDebugEnabled()) { getLog().debug(String.format("[%1$s] Will generate %2$s", entry, file)); } } @Override public void addResource(String entry, File file, boolean b) { super.addResource(entry, file, b); if (b || isVerbose()) { getLog().info("Will copy resource " + file); } if (getLog().isDebugEnabled()) { getLog().debug(String.format("[%1$s] Will copy resource %2$s", entry, file)); } } }; } @Override protected void init() throws Exception { if (getLog().isDebugEnabled()) { verbose = true; } modelHelper = new ModelHelper(_models, modelReaders); modelType = modelType.trim().toLowerCase(); // Check model type is accepted // pouvoir associé un nom à un type de service). Model model = modelHelper.getModel(modelType); // Model model = _models.get(modelType); if (model == null) { throw new MojoExecutionException( "No modelType named '" + modelType + "', use one of " + _models.keySet() ); } if (inputs.length == 0) { throw new MojoExecutionException( "Must specify something to include using the includes " + "property" ); } //FIXME-TC20091217 use a configurator in plexus ? // Actually we obtain a different instance of the mojo conflit with mojo and plexus :) engine.init(this); Set availableWriters = engine.getAvailableWriters(); if (availableWriters.isEmpty()) { throw new MojoExecutionException( "Could not find any writer in class-path."); } for (ChainedFileWriter writer : availableWriters) { if (writer instanceof BaseChainedFileWriter) { // add log support ((BaseChainedFileWriter) writer).setLog(getLog()); } writer.setWriterReport(newWriterReport()); } // detect top level writers for (String include : inputs) { if (isVerbose()) { getLog().info("Register include : " + include); } engine.registerInclude(include); } if (engine.getSelectedWriters().isEmpty()) { return; } if (properties == null) { properties = new LinkedHashMap<>(); } if (engine.containsWriter("xmi")) { // add xmi writer support properties.put(XmiChainedFileWriter.PROP_FULL_PACKAGE_PATH, fullPackagePath); properties.put(XmiChainedFileWriter.PROP_EXTRACTED_PACKAGES, extractedPackages); properties.put(XmiChainedFileWriter.PROP_RESOLVER, resolver); } if (engine.containsWriter("model")) { // add model writer support properties.put(BaseChainedFileWriterToMemoryModel.PROP_FAIL_IF_UNSAFE, failIfUnsafe); } // init templates templateList = initTemplates(); } @Override protected boolean checkSkip() { if (engine.getSelectedWriters().isEmpty()) { getLog().warn("No phase was detected, skip the goal."); return false; } if (executeOnce && !needInvoke(true, false, getProjectCacheKey())) { getLog().info("Skip - already executed."); return false; } return true; } @Override protected void doAction() throws Exception { if (dryRun) { getLog().warn("dryRun property is set, no file will be generated."); } if (isVerbose()) { if (isTestPhase()) { getLog().info(" using testPhase"); } } ClassLoader contextClassLoader = Thread.currentThread().getContextClassLoader(); Thread.currentThread().setContextClassLoader(getClassLoader()); try { List skipInputList = new ArrayList<>(); if (!StringUtils.isEmpty(skipInputs)) { for (String s : skipInputs.split(",")) { skipInputList.add(s.trim()); } } // launch writers in incoming order of dicovering of them Set models = new HashSet<>(); for (ChainedFileWriter writer : engine.getSelectedWriters()) { if (skipInputList.contains(writer.getInputProtocol())) { getLog().info("Skip phase [" + writer.getInputProtocol() + "] as required in skipInputs configuration."); continue; } long t0 = System.nanoTime(); getLog().info("Process phase [" + writer.getInputProtocol() + "]"); if (dryRun || isVerbose()) { for (ChainedFileWriterEntry entry : writer.getEntries()) { getLog().info(" entry : " + entry); } if (dryRun) { continue; } } if (getLog().isDebugEnabled()) { getLog().debug("Generating files and copying resources..."); } // obtains data to react for this writer ChainedFileWriterData data = engine.getData(writer); try { // launch generation writer.generate(this, data); } catch (InvalidModelPropertiesException e) { throw new MojoFailureException("failIfUnsafe flag is on, and some errors occurs while loading model.", e); } if (writer instanceof ChainedFileWriterToMemoryModel) { // keep result ChainedFileWriterToMemoryModel writerToMemoryModel = (ChainedFileWriterToMemoryModel) writer; models.add(writerToMemoryModel); } else { WriterReport writerReport = writer.getWriterReport(); String messageResources = reportCopiedResources(writerReport); getLog().info(messageResources); String message = reportGeneratedFiles(writerReport, t0); getLog().info(message); } } if (!models.isEmpty()) { // apply templates //TODO merge all models in a unique one ? or apply templates on each model ? long t0 = System.nanoTime(); WriterReport writerReport = newWriterReport(); getLog().info("Process phase [generator]"); for (ChainedFileWriterToMemoryModel entry : models) { Model model = entry.getModel(); Long lastModified = entry.getLastModifiedSource(); File outputDir = entry.getOutputDirectory(); applyTemplates(model, lastModified, outputDir, templateList, writerReport); // must fix source compile roots fixCompileSourceRoots(outputDir); } String message = reportGeneratedFiles(writerReport, t0); getLog().info(message); if (i18nGetterFile != null && i18nGetterFile.isNotEmpty()) { i18nGetterFile.store(); } } } finally { Thread.currentThread().setContextClassLoader(contextClassLoader); // always clear everything to avoid side-effects in goal is // invoked more than once properties.clear(); engine.clear(); } } protected void applyTemplates(Model model, Long lastModifiedSource, File outputDirectory, List> templateList, WriterReport writerReport) throws IOException { i18nGetterFile = new GetterFile(gettersDirectory, "eugene.getter"); for (Template template : templateList) { getLog().info("Apply generator " + template.getClass().getSimpleName()); // set the lastModified source property template.setProperty(Template.PROP_LAST_MODIFIED_SOURCE, lastModifiedSource); template.setProperty(Template.PROP_WRITER_REPORT, writerReport); template.setLog(this); template.setProperty(Template.PROP_OUTPUT_DIRECTORY, outputDirectory); template.setProperty(Template.PROP_RESOURCE_DIRECTORY, resourceDirectory); template.setProperty(Template.PROP_I18N_GETTER_FILE, i18nGetterFile); if (isVerbose()) { getLog().info(" overwrite = " + template.isOverwrite()); getLog().info(" encoding = " + template.getEncoding()); getLog().info(" lastModifiedSource = " + template.getLastModifiedSource()); getLog().info(" exclude = " + template.getExcludeTemplates()); getLog().info(" output directory = " + outputDirectory); } // apply template template.applyTemplate(model, outputDirectory); } } /** * Add a single input to the {@link #inputs} property. * * Note: This is a convinient way to allow in pom to write *

     * <inputs>zargo</inputs>
     * 
* in stead of array notation : *
     * <inputs>
     *     <input>zargo:</input>
     * </inputs>
     * 
* * @param inputs unique input to add */ public void setInputs(String inputs) { this.inputs = new String[]{inputs}; } @Override public File getOutputDirectory() { return outputDirectory; } @Override public File getExtractDirectory() { return extractDirectory; } @Override public Map getProperties() { return properties; } @Override public ClassLoader getClassLoader() { try { return getFixedClassLoader(); } catch (MojoExecutionException e) { throw new IllegalStateException("could not obtain classLoader", e); } } @Override public MavenProject getProject() { return project; } @Override public void setProject(MavenProject project) { this.project = project; } @Override public boolean isVerbose() { return verbose; } @Override public void setVerbose(boolean verbose) { this.verbose = verbose; } @Override public String getEncoding() { return encoding; } @Override public void setEncoding(String encoding) { this.encoding = encoding; } @Override public boolean isOverwrite() { return overwrite; } @Override public boolean isOffline() { return settings.isOffline(); } @Override public boolean isTestPhase() { return testPhase; } @Override public String getModelType() { return modelType; } @Override public Map getWriters() { return writers; } @Override public ModelHelper getModelHelper() { return modelHelper; } @Override public File getBasedir() { return getProject().getBasedir(); } @Override public File getModelExtensionFile() { return modelExtensionFile; } /** * @return the string representation of excludesTemplates * (separated by comma) */ protected String getExcludeTemplatesAsString() { String result = ""; for (int i = 0; i < excludeTemplates.length; i++) { result += excludeTemplates[i]; if (i != excludeTemplates.length - 1) { result += ","; } } return result; } /** * Prepare le classLoader a utiliser dans le generateur. *

* Si le mojo est en phase de test {@link #testPhase} a été renseigné, * target/selectedClasses est rajouté. *

* Si des références à des sibling modules, ils seront rajoutés aussi. * * @return le class loader modifie * @throws MojoExecutionException if any pb */ public ClassLoader getFixedClassLoader() throws MojoExecutionException { if (fixedClassLoader == null) { Set urlsAsString = new HashSet<>(); List urls = new ArrayList<>(); try { ClassLoader loader; if (testPhase) { File extraClassPathDirectory = new File( getProject().getBuild().getOutputDirectory()); if (verbose) { getLog().info("Add in generator's classLoader : " + extraClassPathDirectory); } addDirectoryToUrlsList( extraClassPathDirectory, urls, urlsAsString ); addDirectoryToUrlsList( new File(getProject().getBuild().getTestSourceDirectory()), urls, urlsAsString ); } else { addDirectoryToUrlsList( resourceDirectory, urls, urlsAsString); addDirectoryToUrlsList( new File(getProject().getBuild().getSourceDirectory()), urls, urlsAsString ); } if (project.getProjectReferences() != null) { // this case is for multi-module when calling from a // parent module for (Object o : project.getProjectReferences().entrySet()) { Map.Entry entry = (Map.Entry) o; MavenProject relatedProject = (MavenProject) entry.getValue(); if (verbose) { getLog().info("Add project reference in " + "generator's classLoader : '" + relatedProject.getArtifact() + "'"); } //TODO il faudrait peut-etre aussi ajouter les //TODO dependances ? if (relatedProject.getArtifact().getFile() != null) { addDirectoryToUrlsList( relatedProject.getArtifact().getFile(), urls, urlsAsString ); } } } if (!project.getArtifacts().isEmpty()) { // this is a special case when artifacts were resolved // (for example in site phase) if (isVerbose()) { getLog().info( "Use resolved artifacts to build class-path"); } for (Object o : project.getArtifacts()) { Artifact a = (Artifact) o; if (!a.getScope().equals("provided")) { addDirectoryToUrlsList( a.getFile(), urls, urlsAsString ); } } } // we ask to add the directory in classloader loader = getClass().getClassLoader(); if (isVerbose()) { getLog().info("original classloader " + loader); } if (loader instanceof URLClassLoader) { // on reinjecte les urls de loader de base // car sinon on risque de ne pas retrouver les resources... for (URL u : ((URLClassLoader) loader).getURLs()) { addUrlToUrlsList(u, urls, urlsAsString); if (isVerbose()) { getLog().debug("original cp entry: " + u); } } // et on force l'utilisation du classloader parent // s'il existe if (loader.getParent() != null) { loader = loader.getParent(); } } if (!urls.isEmpty()) { loader = new URLClassLoader( urls.toArray(new URL[urls.size()]), loader); } if (isVerbose()) { for (URL u : urls) { getLog().info("cp entry: " + u); } } fixedClassLoader = loader; } catch (MalformedURLException e) { throw new MojoExecutionException(e.getMessage()); } finally { urls.clear(); urlsAsString.clear(); } } return fixedClassLoader; } /** * permet d'ajout le répertoire de génération des fichiers java dans * les répertoires de compilation du projet Maven. * * @param destDirGen le repertoire a traiter */ protected void fixCompileSourceRoots(File destDirGen) { //FIXME-TC20091215 : should never have a null project, this is not //FIXME-TC20091215 : normal if (project == null) { // no project defined, can not fix anything // this case could appears if we wanted to do some tests of the // plugin return; } //TODO-TC20091016 should use AbstractPlugin api if (isTestPhase()) { if (!project.getTestCompileSourceRoots().contains( destDirGen.getPath())) { if (isVerbose()) { getLog().info("Add test compile source root : " + destDirGen); } project.addTestCompileSourceRoot(destDirGen.getPath()); Resource resources = new Resource(); resources.setDirectory(destDirGen.getAbsolutePath()); resources.setExcludes(Collections.singletonList("**/*.java")); if (isVerbose()) { getLog().info("Add test resource root :" + resources); } project.addTestResource(resources); } } else { if (!project.getCompileSourceRoots().contains( destDirGen.getPath())) { if (isVerbose()) { getLog().info("Add compile source root : " + destDirGen); } project.addCompileSourceRoot(destDirGen.getPath()); Resource resources = new Resource(); resources.setDirectory(destDirGen.getAbsolutePath()); resources.setExcludes(Collections.singletonList("**/*.java")); if (isVerbose()) { getLog().info("Add resource root :" + resources); } project.addResource(resources); } } } protected List> initTemplates() { ClassLoader loader = getClassLoader(); Properties templateProperties = new Properties(); templateProperties.put(Template.PROP_DEFAULT_PACKAGE, defaultPackage); templateProperties.put(Template.PROP_ENCODING, getEncoding()); templateProperties.put(Template.PROP_VERBOSE, verbose); templateProperties.put(Template.PROP_OVERWRITE, isOverwrite()); templateProperties.put(Template.PROP_CLASS_LOADER, loader); templateProperties.put(Template.PROP_EXCLUDE_TEMPLATES, getExcludeTemplatesAsString()); if (StringUtils.isEmpty(generatedPackages)) { if (verbose) { getLog().info("generating all packages"); } } else { templateProperties.put(Template.PROP_GENERATED_PACKAGES, generatedPackages); if (verbose) { getLog().info("generating only for packages " + generatedPackages); } } // init templates List> templatesList = new ArrayList<>(); if (StringUtils.isNotEmpty(templates)) { String[] templatesNames = templates.split(","); for (String templateName : templatesNames) { // remove trailing spaces templateName = templateName.trim(); Template template = (Template) modelTemplates.get(templateName); if (template == null) { getLog().warn(String.format("template [%s] is not registred via plexus, try to read it directly", templateName)); try { template = (Template) Class.forName( templateName, true, loader).newInstance(); } catch (Exception e) { throw new IllegalStateException( String.format("Can't obtain template [%s] for reason %s", templateName, e.getMessage()), e ); } } if (verbose) { getLog().info("will use the template [" + templateName + "]"); } // will use this template templatesList.add(template); // set the properties of the template template.setConfiguration( new DefaultTemplateConfiguration(templateProperties)); } } return templatesList; } protected String reportGeneratedFiles(WriterReport writerReport, long t0) { String result; int nbFiles = writerReport.getFilesCount(); if (nbFiles == 0) { result = "No file generated."; } else { long delay = System.nanoTime() - t0; if (nbFiles == 1) { result = "Generate one file in " + Strings.convertTime(delay) + "."; } else { result = "Generate " + nbFiles + " files in " + Strings.convertTime(delay) + "."; } } return result; } protected String reportCopiedResources(WriterReport writerReport) { String result; int nbResources = writerReport.getResourcesCount(); if (nbResources == 0) { result = "No resources copied."; } else { if (nbResources == 1) { result = "One resource copied."; } else { result = nbResources + " resources copied."; } // int nbFiles = writerReport.getFilesCount(); // if (nbFiles == 0) { // result += " (will regenerate all files)."; // } } return result; } @Override public void info(String message) { getLog().info(message); } @Override public void debug(String message) { getLog().debug(message); } @Override public void warn(String message) { getLog().warn(message); } @Override public void error(String message) { getLog().error(message); } private String getProjectCacheKey() { String key = getClass().getSimpleName() + ":" + getProject().getGroupId() + ":" + getProject().getArtifactId() + ":" + getProject().getArtifact().getClassifier() + ":" + getProject().getVersion(); String o = (String) getProject().getProperties().get(key); if (o == null) { // first time coming here, let's get number of execution of this plugin for current module List executions = ((PluginDescriptor) getPluginContext().get("pluginDescriptor")).getPlugin().getExecutions(); if (isVerbose()) { getLog().info("First coming in plugin for this module: " + executions); } o = Joiner.on("|").join(executions.stream().map(PluginExecution::getId).collect(Collectors.toList())); getProject().getProperties().put(key, o); } List executions = new ArrayList<>(Arrays.asList(o.split("\\|"))); String currentExecution = executions.remove(0); if (executions.isEmpty()) { // last execution getProject().getProperties().remove(key); } else { getProject().getProperties().put(key, Joiner.on("|").join(executions)); } return key+":"+currentExecution; } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy