This is an automated email from the git hooks/post-receive script. New commit to branch develop in repository i18n. See http://git.nuiton.org/i18n.git commit aa99cc4eaa80f6b993f7ce9b808f678a6ea325aa Author: Tony CHEMIT <chemit@codelutin.com> Date: Sun Jul 27 13:05:35 2014 +0200 fixes #3358: Sanity mojo parameters --- .../i18n/plugin/AbstractI18nGenerateMojo.java | 66 +++++ .../org/nuiton/i18n/plugin/AbstractI18nMojo.java | 111 +------- .../java/org/nuiton/i18n/plugin/GenerateMojo.java | 35 ++- .../java/org/nuiton/i18n/plugin/GetterMojo.java | 14 +- .../main/java/org/nuiton/i18n/plugin/I18nUtil.java | 41 +++ .../i18n/plugin/bundle/AbstractI18nBundleMojo.java | 5 +- .../plugin/bundle/AbstractMakeI18nBundleMojo.java | 284 --------------------- .../org/nuiton/i18n/plugin/bundle/BundleMojo.java | 233 ++++++++++++++++- .../plugin/bundle/CollectI18nArtifactsMojo.java | 4 + .../plugin/bundle/csv/AbstractCsvBundleMojo.java | 11 - .../plugin/bundle/csv/MergeBackCsvBundleMojo.java | 29 ++- .../i18n/plugin/bundle/csv/SplitCsvBundleMojo.java | 29 ++- .../i18n/plugin/parser/AbstractI18nParserMojo.java | 34 ++- 13 files changed, 449 insertions(+), 447 deletions(-) diff --git a/i18n-maven-plugin/src/main/java/org/nuiton/i18n/plugin/AbstractI18nGenerateMojo.java b/i18n-maven-plugin/src/main/java/org/nuiton/i18n/plugin/AbstractI18nGenerateMojo.java new file mode 100644 index 0000000..99f5c13 --- /dev/null +++ b/i18n-maven-plugin/src/main/java/org/nuiton/i18n/plugin/AbstractI18nGenerateMojo.java @@ -0,0 +1,66 @@ +package org.nuiton.i18n.plugin; + +import org.apache.maven.plugins.annotations.Parameter; + +import java.io.File; +import java.io.IOException; + +/** + * Created on 7/27/14. + * + * @author Tony Chemit - chemit@codelutin.com + * @since 3.3 + */ +public abstract class AbstractI18nGenerateMojo extends AbstractI18nMojo { + + /** Le nombre de getters détectés pendant le cycle de vie du build. */ + private static int NB_GETTER_FILES; + + /** + * Name to use as prefix of generated files. + * <p/> + * <b>Note :</b> By default, use the artifact id. + */ + @Parameter(property = "i18n.artifactId", defaultValue = "${project.artifactId}", readonly = true) + protected String artifactId; + + /** Directory where to generate i18n files. */ + @Parameter(property = "i18n.out", defaultValue = "${basedir}/target/generated-sources/i18n", required = true) + protected File out; + + /** + * @return {@code true} si des getters ont etes enregistres pendant le + * cycle de vie, {@code false} sinon. + */ + protected boolean needGeneration() { + boolean needGeneration = NB_GETTER_FILES > 0; + return needGeneration; + } + + /** + * Prend en compte qu'un getter a été détecté. + * <p/> + * Cela veut dire qu'un goal de parser a détecté des clefs. Il faudra donc + * activer les goal get et gen. + */ + protected void addGetter() { + NB_GETTER_FILES++; + } + + /** + * @param root le repertoire ou sont stockes les fichiers getter + * @param getter le nom du getter + * @param create {@code true} pour creer le fichier si non present + * @return le fichier i18n + * @throws IOException si probleme lors de la creation du fichier + */ + protected File getGetterFile(File root, String getter, boolean create) + throws IOException { + File file = new File( + root.getAbsolutePath() + File.separatorChar + getter); + if (create && !file.exists()) { + createNewFile(file); + } + return file; + } +} diff --git a/i18n-maven-plugin/src/main/java/org/nuiton/i18n/plugin/AbstractI18nMojo.java b/i18n-maven-plugin/src/main/java/org/nuiton/i18n/plugin/AbstractI18nMojo.java index 44924de..0cbeafe 100644 --- a/i18n-maven-plugin/src/main/java/org/nuiton/i18n/plugin/AbstractI18nMojo.java +++ b/i18n-maven-plugin/src/main/java/org/nuiton/i18n/plugin/AbstractI18nMojo.java @@ -50,9 +50,6 @@ import java.util.TreeSet; */ public abstract class AbstractI18nMojo extends AbstractPlugin implements PluginWithEncoding { - /** Le nombre de getters détectés pendant le cycle de vie du build. */ - private static int NB_GETTER_FILES; - /** * Dependance du projet. * @@ -62,14 +59,6 @@ public abstract class AbstractI18nMojo extends AbstractPlugin implements PluginW protected MavenProject project; /** - * Name to use as prefix of generated files. - * <p/> - * <b>Note :</b> By default, use the artifact id. - */ - @Parameter(property = "i18n.artifactId", defaultValue = "${project.artifactId}", readonly = true) - protected String artifactId; - - /** * Locales to treate, separated by comma. * <p/> * Example : @@ -78,28 +67,11 @@ public abstract class AbstractI18nMojo extends AbstractPlugin implements PluginW @Parameter(property = "i18n.bundles", defaultValue = "fr_FR,en_GB", required = true) protected String bundles; - /** Directory where to find project i18n files. */ - @Parameter(property = "i18n.src", defaultValue = "${basedir}/src/main/resources/i18n", required = true) - protected File src; - - /** Directory where to generate i18n files. */ - @Parameter(property = "i18n.out", defaultValue = "${basedir}/target/generated-sources/i18n", required = true) - protected File out; - /** Encoding used to load and store properties. */ @Parameter(property = "i18n.encoding", defaultValue = "${project.build.sourceEncoding}", required = true) protected String encoding; /** - * To update generated files to user i18n files. - * <p/> - * <b>Note :</b> By default, this is active, in order to have a project uptodate - * with last i18n bundles detected. - */ - @Parameter(property = "i18n.genSrc", defaultValue = "true") - protected boolean genSrc; - - /** * Verbose flag. * <p/> * <b>Note :</b> if not setted, we used the {@code maven.verbose} property. @@ -115,15 +87,6 @@ public abstract class AbstractI18nMojo extends AbstractPlugin implements PluginW @Parameter(property = "i18n.silent", defaultValue = "false") protected boolean silent; - /** - * Strict mode to only keep in user i18n detected i18n keys and remove obsolete keys. - * <p/> - * <b>Note :</b> By default not active. Use this with care since it can - * delete keys. Moreover if this flag is activated, then all files will be parsed. - */ - @Parameter(property = "i18n.strictMode", defaultValue = "false") - protected boolean strictMode; - /** locales to process */ protected Locale[] locales; @@ -132,7 +95,8 @@ public abstract class AbstractI18nMojo extends AbstractPlugin implements PluginW protected boolean checkPackaging() { // nothing to do on a pom module - return !acceptPackaging(Packaging.pom); + boolean result = !acceptPackaging(Packaging.pom); + return result; } @Override @@ -146,75 +110,10 @@ public abstract class AbstractI18nMojo extends AbstractPlugin implements PluginW locales = I18nUtil.parseLocales(bundles); if (locales == null || locales.length == 0) { throw new IllegalStateException( - "Il faut au moins une locale declaree (utiliser " + - "la propriete 'bundles')"); + "You need at least one locale, please fill the 'bundles' property."); } } - public String getArtifactId() { - return artifactId; - } - - /** - * @return {@code true} si des getters ont etes enregistres pendant le - * cycle de vie, {@code false} sinon. - */ - protected boolean needGeneration() { - boolean needGeneration = NB_GETTER_FILES > 0; - return needGeneration; - } - - /** - * Prend en compte qu'un getter a été détecté. - * <p/> - * Cela veut dire qu'un goal de parser a détecté des clefs. Il faudra donc - * activer les goal get et gen. - */ - protected void addGetter() { - NB_GETTER_FILES++; - } - - /** - * @param root le repertoire ou sont stockes les fichiers i18n - * @param artifactId le nom de l'artifact - * @param locale le nom de la locale (peut-être nulle) - * @param create {@code true} pour creer le fichier si non present - * @return le fichier i18n - * @throws IOException si probleme lors de la creation du fichier - */ - public File getI18nFile(File root, - String artifactId, - Locale locale, - boolean create) throws IOException { - String path = root.getAbsolutePath() + File.separatorChar + artifactId; - if (locale != null) { - path += "_" + locale.toString(); - } - path += ".properties"; - File file = new File(path); - if (create && !file.exists()) { - createNewFile(file); - } - return file; - } - - /** - * @param root le repertoire ou sont stockes les fichiers getter - * @param getter le nom du getter - * @param create {@code true} pour creer le fichier si non present - * @return le fichier i18n - * @throws IOException si probleme lors de la creation du fichier - */ - public File getGetterFile(File root, String getter, boolean create) - throws IOException { - File file = new File( - root.getAbsolutePath() + File.separatorChar + getter); - if (create && !file.exists()) { - createNewFile(file); - } - return file; - } - protected void checkBundle(Locale locale, Properties propertiesOut, boolean showEmpty, @@ -301,10 +200,6 @@ public abstract class AbstractI18nMojo extends AbstractPlugin implements PluginW return silent; } - public boolean isStrictMode() { - return strictMode; - } - @Override public String getEncoding() { return encoding; diff --git a/i18n-maven-plugin/src/main/java/org/nuiton/i18n/plugin/GenerateMojo.java b/i18n-maven-plugin/src/main/java/org/nuiton/i18n/plugin/GenerateMojo.java index 55dea47..84df835 100644 --- a/i18n-maven-plugin/src/main/java/org/nuiton/i18n/plugin/GenerateMojo.java +++ b/i18n-maven-plugin/src/main/java/org/nuiton/i18n/plugin/GenerateMojo.java @@ -43,7 +43,29 @@ import java.util.Locale; */ @Mojo(name = "gen", defaultPhase = LifecyclePhase.GENERATE_RESOURCES) @Execute(goal = "get") -public class GenerateMojo extends AbstractI18nMojo { +public class GenerateMojo extends AbstractI18nGenerateMojo { + + /** Directory where to find project i18n files. */ + @Parameter(property = "i18n.src", defaultValue = "${basedir}/src/main/resources/i18n", required = true) + protected File src; + + /** + * To update generated files to user i18n files. + * <p/> + * <b>Note :</b> By default, this is active, in order to have a project uptodate + * with last i18n bundles detected. + */ + @Parameter(property = "i18n.genSrc", defaultValue = "true") + protected boolean genSrc; + + /** + * Strict mode to only keep in user i18n detected i18n keys and remove obsolete keys. + * <p/> + * <b>Note :</b> By default not active. Use this with care since it can + * delete keys. Moreover if this flag is activated, then all files will be parsed. + */ + @Parameter(property = "i18n.strictMode", defaultValue = "false") + protected boolean strictMode; /** * A flag to check that bundles are complete (no missing i18n translations). @@ -81,11 +103,12 @@ public class GenerateMojo extends AbstractI18nMojo { @Override protected boolean checkSkip() { + boolean result = true; if (!needGeneration()) { getLog().info("No getter detected - all files are up to date."); - return false; + result = false; } - return true; + return result; } @Override @@ -100,9 +123,9 @@ public class GenerateMojo extends AbstractI18nMojo { getLog().info("prepare bundle for locale " + locale); } // Merge - File bundleSrc = getI18nFile(src, artifactId, locale, false); - File bundleOut = getI18nFile(out, artifactId, locale, false); - File bundleGetterOut = getI18nFile( + File bundleSrc = I18nUtil.getI18nFile(src, artifactId, locale, false); + File bundleOut = I18nUtil.getI18nFile(out, artifactId, locale, false); + File bundleGetterOut = I18nUtil.getI18nFile( out, artifactId + GetterMojo.FROM_GETTERS, locale, false); SortedProperties propertiesSrc = new SortedProperties(encoding); diff --git a/i18n-maven-plugin/src/main/java/org/nuiton/i18n/plugin/GetterMojo.java b/i18n-maven-plugin/src/main/java/org/nuiton/i18n/plugin/GetterMojo.java index a4b90fc..82bcb80 100644 --- a/i18n-maven-plugin/src/main/java/org/nuiton/i18n/plugin/GetterMojo.java +++ b/i18n-maven-plugin/src/main/java/org/nuiton/i18n/plugin/GetterMojo.java @@ -39,10 +39,10 @@ import java.util.Locale; /** * Recupere les différents fichiers des parsers en un fichier de proprietes. * - * @author julien + * @author Julien Ruchaud - ruchaud@codelutin.com */ @Mojo(name = "get", defaultPhase = LifecyclePhase.GENERATE_RESOURCES) -public class GetterMojo extends AbstractI18nMojo { +public class GetterMojo extends AbstractI18nGenerateMojo { /** * To keep generated getter files. @@ -57,11 +57,13 @@ public class GetterMojo extends AbstractI18nMojo { @Override protected boolean checkSkip() { + boolean result = true; + if (!needGeneration()) { getLog().info("No getter detected - all files are up to date."); - return false; + result = false; } - return true; + return result; } @Override @@ -69,7 +71,7 @@ public class GetterMojo extends AbstractI18nMojo { if (!silent) { getLog().info("config - basedir : " + out.getAbsolutePath()); - getLog().info("config - locales : " + Arrays.toString(locales)); + getLog().info("config - locales : " + Arrays.toString(locales)); } File bundleGetters = new File(out.getAbsoluteFile(), @@ -118,7 +120,7 @@ public class GetterMojo extends AbstractI18nMojo { if (getLog().isDebugEnabled()) { getLog().debug("generate bundle for locale " + locale); } - File bundleOut = getI18nFile(out, artifactId + FROM_GETTERS, locale, false); + File bundleOut = I18nUtil.getI18nFile(out, artifactId + FROM_GETTERS, locale, false); copyFile(bundleGetters, bundleOut); if (!silent && verbose) { getLog().info("generate bundle " + locale); diff --git a/i18n-maven-plugin/src/main/java/org/nuiton/i18n/plugin/I18nUtil.java b/i18n-maven-plugin/src/main/java/org/nuiton/i18n/plugin/I18nUtil.java new file mode 100644 index 0000000..90a98c9 --- /dev/null +++ b/i18n-maven-plugin/src/main/java/org/nuiton/i18n/plugin/I18nUtil.java @@ -0,0 +1,41 @@ +package org.nuiton.i18n.plugin; + +import org.nuiton.plugin.PluginHelper; + +import java.io.File; +import java.io.IOException; +import java.util.Locale; + +/** + * Place here some useful methods. + * + * Created on 7/27/14. + * + * @author Tony Chemit - chemit@codelutin.com + * @since 3.3 + */ +public class I18nUtil { + /** + * @param root le repertoire ou sont stockes les fichiers i18n + * @param artifactId le nom de l'artifact + * @param locale le nom de la locale (peut-être nulle) + * @param create {@code true} pour creer le fichier si non present + * @return le fichier i18n + * @throws IOException si probleme lors de la creation du fichier + */ + public static File getI18nFile(File root, + String artifactId, + Locale locale, + boolean create) throws IOException { + String path = root.getAbsolutePath() + File.separatorChar + artifactId; + if (locale != null) { + path += "_" + locale.toString(); + } + path += ".properties"; + File file = new File(path); + if (create && !file.exists()) { + PluginHelper.createNewFile(file); + } + return file; + } +} diff --git a/i18n-maven-plugin/src/main/java/org/nuiton/i18n/plugin/bundle/AbstractI18nBundleMojo.java b/i18n-maven-plugin/src/main/java/org/nuiton/i18n/plugin/bundle/AbstractI18nBundleMojo.java index b855267..8458d45 100644 --- a/i18n-maven-plugin/src/main/java/org/nuiton/i18n/plugin/bundle/AbstractI18nBundleMojo.java +++ b/i18n-maven-plugin/src/main/java/org/nuiton/i18n/plugin/bundle/AbstractI18nBundleMojo.java @@ -27,6 +27,7 @@ package org.nuiton.i18n.plugin.bundle; import org.apache.maven.plugins.annotations.Parameter; import org.nuiton.i18n.plugin.AbstractI18nMojo; +import org.nuiton.i18n.plugin.I18nUtil; import java.io.File; import java.io.IOException; @@ -83,8 +84,8 @@ public abstract class AbstractI18nBundleMojo extends AbstractI18nMojo { */ protected File getCollectOutputFile(Locale locale, boolean create) throws IOException { - File bundleOut = getI18nFile(collectOutputDir, collectOutputName, - locale, create); + File bundleOut = I18nUtil.getI18nFile(collectOutputDir, collectOutputName, + locale, create); return bundleOut; } diff --git a/i18n-maven-plugin/src/main/java/org/nuiton/i18n/plugin/bundle/AbstractMakeI18nBundleMojo.java b/i18n-maven-plugin/src/main/java/org/nuiton/i18n/plugin/bundle/AbstractMakeI18nBundleMojo.java deleted file mode 100644 index 6ea4bf3..0000000 --- a/i18n-maven-plugin/src/main/java/org/nuiton/i18n/plugin/bundle/AbstractMakeI18nBundleMojo.java +++ /dev/null @@ -1,284 +0,0 @@ -/* - * #%L - * I18n :: Maven Plugin - * - * $Id$ - * $HeadURL$ - * %% - * Copyright (C) 2007 - 2010 CodeLutin - * %% - * 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 - * <http://www.gnu.org/licenses/lgpl-3.0.html>. - * #L% - */ -package org.nuiton.i18n.plugin.bundle; - -import org.apache.commons.io.FileUtils; -import org.apache.commons.lang3.StringUtils; -import org.apache.maven.plugin.MojoFailureException; -import org.apache.maven.plugins.annotations.Parameter; - -import java.io.File; -import java.io.IOException; -import java.util.HashMap; -import java.util.Locale; -import java.util.Map; -import java.util.SortedSet; - -/** - * Common mojo to all final bundle maker. - * - * @author tchemit <chemit@codelutin.com> - * @since 2.0 - */ -public abstract class AbstractMakeI18nBundleMojo extends AbstractI18nBundleMojo { - - /** - * Encoding used to load any i18n property files. - * <p/> - * If not defined, will use the {@link #encoding} parameter. - * - * @since 2.4 - */ - @Parameter(property = "i18n.bundleInputEncoding") - protected String bundleInputEncoding; - - /** - * Encoding used to write any i18n property files. - * <p/> - * If not defined, will use the {@link #encoding} parameter. - * - * @since 2.4 - */ - @Parameter(property = "i18n.bundleOutputEncoding") - protected String bundleOutputEncoding; - - /** - * Root directory where to generate aggregated bundles (this directory will - * be added as resources of the project). - * - * @since 1.0.0 - */ - @Parameter(property = "i18n.bundleOutputDir", defaultValue = "${basedir}/target/generated-sources/resources", required = true) - protected File bundleOutputDir; - - /** - * Package name of the generate aggregated bundles. - * <p/> - * <strong>Note:</strong> By default we use the <code>META-INF</code> package - * since it is the favorite package of <code>I18n</code> runtime initializer. - * <p/> - * The package name is dotted as it will be stored as folder like in Java - * language. - * <p/> - * Example : - * <pre> - * package name : foo.bar - * directory : foo/bar - * </pre> - * - * @since 2.3.2 - */ - @Parameter(property = "i18n.bundleOutputPackage", defaultValue = "META-INF", required = true) - protected String bundleOutputPackage; - - /** - * Name of the bundle to generate. - * - * @since 1.0.2 - */ - @Parameter(property = "i18n.bundleOutputName", defaultValue = "${project.artifactId}-i18n", required = true) - protected String bundleOutputName; - - /** - * A flag to generate a bundle with the first locale defined as a default - * bundle (with no locale specialization). - * - * @since 2.1 - */ - @Parameter(property = "i18n.generateDefaultLocale", defaultValue = "false") - protected boolean generateDefaultLocale; - - /** - * A flag to check that bundles are complete (no missing i18n translations). - * <p/> - * <b>Note :</b> This behaviour will be activated is {@link #failsIfWarning} is on. - * - * @since 1.0.0 - */ - @Parameter(property = "i18n.checkBundle", defaultValue = "true") - protected boolean checkBundle; - - /** - * A flag to show missing i18n translation. - * <p/> - * <b>Note :</b> Need the {@link #checkBundle} to be activated). - * - * @since 1.0.0 - */ - @Parameter(property = "i18n.showEmpty", defaultValue = "false") - protected boolean showEmpty; - - /** - * A flag to make the build fails if there is some warnings while generating - * bundle, says when it misses some translations. - * <p/> - * <b>Note :</b> This parameter should be used in a release profile to - * ensure bundles are complete. - * - * @since 2.0 - */ - @Parameter(property = "i18n.failsIfWarning", defaultValue = "false") - protected boolean failsIfWarning; - - /** to keep all none translated i18n keys by locale. */ - protected Map<Locale, SortedSet<String>> unsafeMapping; - - /** - * The definitive directory where to generate the bundles (includes the - * package of bundle). - * - * @since 2.3.2 - */ - protected File outputFolder; - - @Override - public void init() throws Exception { - super.init(); - - if (failsIfWarning) { - - // check bundle if wants to fail on unsafe bundles - checkBundle = true; - - unsafeMapping = new HashMap<Locale, SortedSet<String>>(); - } else { - unsafeMapping = null; - } - - // get the definitive folder where to generate bundles (including - // bundle package) - - outputFolder = getBundleOutputFolder(); - - if (isVerbose()) { - getLog().info("Will generates bundles in " + outputFolder); - } - createDirectoryIfNecessary(outputFolder); - - if (StringUtils.isEmpty(bundleInputEncoding)) { - - // use the default encoding - bundleInputEncoding = getEncoding(); - if (getLog().isDebugEnabled()) { - getLog().debug("Use as input encoding the default one : " + - bundleInputEncoding); - } - } - - if (StringUtils.isEmpty(bundleOutputEncoding)) { - - // use the default encoding - bundleOutputEncoding = getEncoding(); - - if (getLog().isDebugEnabled()) { - getLog().debug("Use as output encoding the default one : " + - bundleOutputEncoding); - } - } - } - - protected void failsIfWarning() throws MojoFailureException { - if (!failsIfWarning) { - - // no check - return; - } - - if (unsafeMapping != null && !unsafeMapping.isEmpty()) { - - // there is at least one not complete bundle, faisl the build - throw new MojoFailureException( - "Bundles for locale(s) " + unsafeMapping.keySet() + - " are not complete. Use the -Di18n.showEmpty to see " + - "missing translations."); - } - } - - /** - * Gets the bundle file for the given parameters. - * - * @param root the root directory where bundles are stored - * @param artifactId the artifactId (says the prefix of bundle) - * @param locale the locale used in bundle ({@code null} means no locale specialized) - * @param create a flag to create the file if none existing - * @return the bundle file - * @throws IOException if any IO problem while creating it (if needed). - * @since 2.1 - */ - protected abstract File getBundleFile(File root, - String artifactId, - Locale locale, - boolean create) throws IOException; - - /** - * Generates the default bundle, says the bundle with no locale specialized. - * <p/> - * This bundle is a copy of the bundle of the first locale (which in fact - * is considered as the main locale). - * - * @throws IOException if any IO problem while the copy. - * @since 2.1 - */ - protected void generateDefaultBundle() throws IOException { - - File bundleFirstLocale = getBundleFile(outputFolder, - bundleOutputName, - locales[0], - false - ); - - File bundleWithoutLocale = getBundleFile(outputFolder, - bundleOutputName, - null, - false - ); - - if (!isSilent()) { - getLog().info("Generate default bundle at " + bundleWithoutLocale); - } - - FileUtils.copyFile(bundleFirstLocale, bundleWithoutLocale); - } - - protected File getBundleOutputFolder() { - File result = bundleOutputDir; - if (StringUtils.isNotEmpty(bundleOutputPackage)) { - String[] paths = bundleOutputPackage.split("\\."); - for (String path : paths) { - result = new File(result, path); - } - } - return result; - } - - public String getBundleOutputEncoding() { - return bundleOutputEncoding; - } - - public String getBundleInputEncoding() { - return bundleInputEncoding; - } - -} diff --git a/i18n-maven-plugin/src/main/java/org/nuiton/i18n/plugin/bundle/BundleMojo.java b/i18n-maven-plugin/src/main/java/org/nuiton/i18n/plugin/bundle/BundleMojo.java index 78f9097..85f76bb 100644 --- a/i18n-maven-plugin/src/main/java/org/nuiton/i18n/plugin/bundle/BundleMojo.java +++ b/i18n-maven-plugin/src/main/java/org/nuiton/i18n/plugin/bundle/BundleMojo.java @@ -25,9 +25,11 @@ package org.nuiton.i18n.plugin.bundle; +import org.apache.commons.io.FileUtils; import org.apache.commons.io.IOUtils; import org.apache.commons.lang3.StringUtils; import org.apache.maven.plugin.MojoExecutionException; +import org.apache.maven.plugin.MojoFailureException; import org.apache.maven.plugins.annotations.Component; import org.apache.maven.plugins.annotations.Execute; import org.apache.maven.plugins.annotations.LifecyclePhase; @@ -37,6 +39,7 @@ import org.apache.maven.plugins.annotations.ResolutionScope; import org.nuiton.i18n.bundle.I18nBundleEntry; import org.nuiton.i18n.bundle.I18nBundleUtil; import org.nuiton.i18n.init.DefaultI18nInitializer; +import org.nuiton.i18n.plugin.I18nUtil; import org.nuiton.io.SortedProperties; import org.nuiton.plugin.PluginHelper; @@ -49,6 +52,7 @@ import java.nio.charset.Charset; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; +import java.util.HashMap; import java.util.HashSet; import java.util.LinkedHashMap; import java.util.List; @@ -57,6 +61,7 @@ import java.util.Map; import java.util.Map.Entry; import java.util.Properties; import java.util.Set; +import java.util.SortedSet; /** * Generate an aggregate i18n bundle for all dependencies of the project. @@ -80,7 +85,116 @@ import java.util.Set; requiresProject = true, requiresDependencyResolution = ResolutionScope.RUNTIME) @Execute(goal = "collect-i18n-artifacts") -public class BundleMojo extends AbstractMakeI18nBundleMojo { +public class BundleMojo extends AbstractI18nBundleMojo { + + /** + * Encoding used to load any i18n property files. + * <p/> + * If not defined, will use the {@link #encoding} parameter. + * + * @since 2.4 + */ + @Parameter(property = "i18n.bundleInputEncoding") + protected String bundleInputEncoding; + + /** + * Encoding used to write any i18n property files. + * <p/> + * If not defined, will use the {@link #encoding} parameter. + * + * @since 2.4 + */ + @Parameter(property = "i18n.bundleOutputEncoding") + protected String bundleOutputEncoding; + + /** + * Root directory where to generate aggregated bundles (this directory will + * be added as resources of the project). + * + * @since 1.0.0 + */ + @Parameter(property = "i18n.bundleOutputDir", defaultValue = "${basedir}/target/generated-sources/resources", required = true) + protected File bundleOutputDir; + + /** + * Package name of the generate aggregated bundles. + * <p/> + * <strong>Note:</strong> By default we use the <code>META-INF</code> package + * since it is the favorite package of <code>I18n</code> runtime initializer. + * <p/> + * The package name is dotted as it will be stored as folder like in Java + * language. + * <p/> + * Example : + * <pre> + * package name : foo.bar + * directory : foo/bar + * </pre> + * + * @since 2.3.2 + */ + @Parameter(property = "i18n.bundleOutputPackage", defaultValue = "META-INF", required = true) + protected String bundleOutputPackage; + + /** + * Name of the bundle to generate. + * + * @since 1.0.2 + */ + @Parameter(property = "i18n.bundleOutputName", defaultValue = "${project.artifactId}-i18n", required = true) + protected String bundleOutputName; + + /** + * A flag to generate a bundle with the first locale defined as a default + * bundle (with no locale specialization). + * + * @since 2.1 + */ + @Parameter(property = "i18n.generateDefaultLocale", defaultValue = "false") + protected boolean generateDefaultLocale; + + /** + * A flag to check that bundles are complete (no missing i18n translations). + * <p/> + * <b>Note :</b> This behaviour will be activated is {@link #failsIfWarning} is on. + * + * @since 1.0.0 + */ + @Parameter(property = "i18n.checkBundle", defaultValue = "true") + protected boolean checkBundle; + + /** + * A flag to show missing i18n translation. + * <p/> + * <b>Note :</b> Need the {@link #checkBundle} to be activated). + * + * @since 1.0.0 + */ + @Parameter(property = "i18n.showEmpty", defaultValue = "false") + protected boolean showEmpty; + + /** + * A flag to make the build fails if there is some warnings while generating + * bundle, says when it misses some translations. + * <p/> + * <b>Note :</b> This parameter should be used in a release profile to + * ensure bundles are complete. + * + * @since 2.0 + */ + @Parameter(property = "i18n.failsIfWarning", defaultValue = "false") + protected boolean failsIfWarning; + + /** to keep all none translated i18n keys by locale. */ + protected Map<Locale, SortedSet<String>> unsafeMapping; + + /** + * The definitive directory where to generate the bundles (includes the + * package of bundle). + * + * @since 2.3.2 + */ + protected File outputFolder; /** * A flag to generate the i18n definition file. @@ -152,6 +266,47 @@ public class BundleMojo extends AbstractMakeI18nBundleMojo { public void init() throws Exception { super.init(); + if (failsIfWarning) { + + // check bundle if wants to fail on unsafe bundles + checkBundle = true; + + unsafeMapping = new HashMap<Locale, SortedSet<String>>(); + } else { + unsafeMapping = null; + } + + // get the definitive folder where to generate bundles (including + // bundle package) + + outputFolder = getBundleOutputFolder(); + + if (isVerbose()) { + getLog().info("Will generates bundles in " + outputFolder); + } + createDirectoryIfNecessary(outputFolder); + + if (StringUtils.isEmpty(bundleInputEncoding)) { + + // use the default encoding + bundleInputEncoding = getEncoding(); + if (getLog().isDebugEnabled()) { + getLog().debug("Use as input encoding the default one : " + + bundleInputEncoding); + } + } + + if (StringUtils.isEmpty(bundleOutputEncoding)) { + + // use the default encoding + bundleOutputEncoding = getEncoding(); + + if (getLog().isDebugEnabled()) { + getLog().debug("Use as output encoding the default one : " + + bundleOutputEncoding); + } + } + // add root bundle directory as resources of the project addResourceDir(bundleOutputDir, "**/*.properties"); @@ -212,10 +367,10 @@ public class BundleMojo extends AbstractMakeI18nBundleMojo { long t0 = System.nanoTime(); - File bundleOut = getI18nFile(outputFolder, - bundleOutputName, - locale, - false + File bundleOut = I18nUtil.getI18nFile(outputFolder, + bundleOutputName, + locale, + false ); SortedProperties propertiesOut = @@ -305,12 +460,11 @@ public class BundleMojo extends AbstractMakeI18nBundleMojo { } } - @Override protected File getBundleFile(File root, String artifactId, Locale locale, boolean create) throws IOException { - return getI18nFile(root, artifactId, locale, create); + return I18nUtil.getI18nFile(root, artifactId, locale, create); } protected void generateDefinitionFile(String version, @@ -427,4 +581,69 @@ public class BundleMojo extends AbstractMakeI18nBundleMojo { } } + protected void failsIfWarning() throws MojoFailureException { + if (!failsIfWarning) { + + // no check + return; + } + + if (unsafeMapping != null && !unsafeMapping.isEmpty()) { + + // there is at least one not complete bundle, faisl the build + throw new MojoFailureException( + "Bundles for locale(s) " + unsafeMapping.keySet() + + " are not complete. Use the -Di18n.showEmpty to see " + + "missing translations."); + } + } + + /** + * Generates the default bundle, says the bundle with no locale specialized. + * <p/> + * This bundle is a copy of the bundle of the first locale (which in fact + * is considered as the main locale). + * + * @throws IOException if any IO problem while the copy. + * @since 2.1 + */ + protected void generateDefaultBundle() throws IOException { + + File bundleFirstLocale = getBundleFile(outputFolder, + bundleOutputName, + locales[0], + false + ); + + File bundleWithoutLocale = getBundleFile(outputFolder, + bundleOutputName, + null, + false + ); + + if (!isSilent()) { + getLog().info("Generate default bundle at " + bundleWithoutLocale); + } + + FileUtils.copyFile(bundleFirstLocale, bundleWithoutLocale); + } + + protected File getBundleOutputFolder() { + File result = bundleOutputDir; + if (StringUtils.isNotEmpty(bundleOutputPackage)) { + String[] paths = bundleOutputPackage.split("\\."); + for (String path : paths) { + result = new File(result, path); + } + } + return result; + } + + public String getBundleOutputEncoding() { + return bundleOutputEncoding; + } + + public String getBundleInputEncoding() { + return bundleInputEncoding; + } } diff --git a/i18n-maven-plugin/src/main/java/org/nuiton/i18n/plugin/bundle/CollectI18nArtifactsMojo.java b/i18n-maven-plugin/src/main/java/org/nuiton/i18n/plugin/bundle/CollectI18nArtifactsMojo.java index 80b15e0..fc5a539 100644 --- a/i18n-maven-plugin/src/main/java/org/nuiton/i18n/plugin/bundle/CollectI18nArtifactsMojo.java +++ b/i18n-maven-plugin/src/main/java/org/nuiton/i18n/plugin/bundle/CollectI18nArtifactsMojo.java @@ -68,6 +68,10 @@ import java.util.Map; requiresDependencyResolution = ResolutionScope.RUNTIME) public class CollectI18nArtifactsMojo extends AbstractI18nBundleMojo { + /** Directory where to find project i18n files. */ + @Parameter(property = "i18n.src", defaultValue = "${basedir}/src/main/resources/i18n", required = true) + protected File src; + /** * Local Repository. * diff --git a/i18n-maven-plugin/src/main/java/org/nuiton/i18n/plugin/bundle/csv/AbstractCsvBundleMojo.java b/i18n-maven-plugin/src/main/java/org/nuiton/i18n/plugin/bundle/csv/AbstractCsvBundleMojo.java index e9786fd..fc4201f 100644 --- a/i18n-maven-plugin/src/main/java/org/nuiton/i18n/plugin/bundle/csv/AbstractCsvBundleMojo.java +++ b/i18n-maven-plugin/src/main/java/org/nuiton/i18n/plugin/bundle/csv/AbstractCsvBundleMojo.java @@ -3,8 +3,6 @@ package org.nuiton.i18n.plugin.bundle.csv; import org.apache.maven.plugins.annotations.Parameter; import org.nuiton.i18n.plugin.AbstractI18nMojo; -import java.io.File; - /** * Created on 7/26/14. * @@ -14,15 +12,6 @@ import java.io.File; public abstract class AbstractCsvBundleMojo extends AbstractI18nMojo { /** - * Location of the csv file to split. - * - * @since 3.3 - */ - @Parameter(property = "i18n.bundleCsvFile", - defaultValue = "${basedir}/target/${project.artifactId}-i18n.csv") - protected File bundleCsvFile; - - /** * Char separator in the csv bundle file. * * @since 3.3 diff --git a/i18n-maven-plugin/src/main/java/org/nuiton/i18n/plugin/bundle/csv/MergeBackCsvBundleMojo.java b/i18n-maven-plugin/src/main/java/org/nuiton/i18n/plugin/bundle/csv/MergeBackCsvBundleMojo.java index 40b5a5f..5f39276 100644 --- a/i18n-maven-plugin/src/main/java/org/nuiton/i18n/plugin/bundle/csv/MergeBackCsvBundleMojo.java +++ b/i18n-maven-plugin/src/main/java/org/nuiton/i18n/plugin/bundle/csv/MergeBackCsvBundleMojo.java @@ -8,6 +8,7 @@ import org.apache.maven.plugins.annotations.Mojo; import org.apache.maven.plugins.annotations.Parameter; import org.apache.maven.plugins.annotations.ResolutionScope; import org.nuiton.csv.Import; +import org.nuiton.i18n.plugin.I18nUtil; import org.nuiton.io.SortedProperties; import java.io.File; @@ -34,12 +35,28 @@ public class MergeBackCsvBundleMojo extends AbstractCsvBundleMojo { * To accept to add new keys in the original i18n bundle. * <p/> * The option is {@code false} by default, since merging operation should not add any new keys. - * - * @since 3.3 */ @Parameter(property = "i18n.mergeNewKeys", defaultValue = "false") protected boolean mergeNewKeys; + /** Directory where to find project i18n files. */ + @Parameter(property = "i18n.src", defaultValue = "${project.basedir}/src/main/resources/i18n", required = true) + protected File src; + + /** + * Name to use as prefix of generated files. + * <p/> + * <strong>Note :</strong> By default, use the artifact id. + */ + @Parameter(property = "i18n.artifactId", defaultValue = "${project.artifactId}", readonly = true) + protected String artifactId; + + /** + * Location of the csv file to split. + */ + @Parameter(property = "i18n.bundleCsvFile", required = true) + protected File bundleCsvFile; + @Override protected void doAction() throws Exception { @@ -72,10 +89,10 @@ public class MergeBackCsvBundleMojo extends AbstractCsvBundleMojo { for (Locale locale : locales) { - File bundleFile = getI18nFile(src, - artifactId, - locale, - false); + File bundleFile = I18nUtil.getI18nFile(src, + artifactId, + locale, + false); SortedProperties properties = new SortedProperties(encoding); diff --git a/i18n-maven-plugin/src/main/java/org/nuiton/i18n/plugin/bundle/csv/SplitCsvBundleMojo.java b/i18n-maven-plugin/src/main/java/org/nuiton/i18n/plugin/bundle/csv/SplitCsvBundleMojo.java index dfcc5c0..a0237d9 100644 --- a/i18n-maven-plugin/src/main/java/org/nuiton/i18n/plugin/bundle/csv/SplitCsvBundleMojo.java +++ b/i18n-maven-plugin/src/main/java/org/nuiton/i18n/plugin/bundle/csv/SplitCsvBundleMojo.java @@ -8,6 +8,7 @@ import org.apache.maven.plugins.annotations.Mojo; import org.apache.maven.plugins.annotations.Parameter; import org.apache.maven.plugins.annotations.ResolutionScope; import org.nuiton.csv.Import; +import org.nuiton.i18n.plugin.I18nUtil; import org.nuiton.io.SortedProperties; import java.io.File; @@ -35,8 +36,6 @@ public class SplitCsvBundleMojo extends AbstractCsvBundleMojo { /** * Name of the bundle to generate. - * - * @since 1.0.2 */ @Parameter(property = "i18n.bundleOutputName", defaultValue = "${project.artifactId}-i18n", required = true) protected String bundleOutputName; @@ -44,17 +43,29 @@ public class SplitCsvBundleMojo extends AbstractCsvBundleMojo { /** * Root directory where to generate aggregated bundles (this directory will * be added as resources of the project). - * - * @since 1.0.0 */ @Parameter(property = "i18n.bundleOutputDir", defaultValue = "${project.build.directory}", required = true) protected File bundleOutputDir; + /** + * Name to use as prefix of generated files. + * <p/> + * <string>Note :</string> By default, use the artifact id. + */ + @Parameter(property = "i18n.artifactId", defaultValue = "${project.artifactId}", readonly = true) + protected String artifactId; + + /** + * Location of the csv file to split. + */ + @Parameter(property = "i18n.bundleCsvFile", required = true) + protected File bundleCsvFile; + @Override protected void doAction() throws Exception { if (!silent) { - getLog().info("config - locales : " + Arrays.toString(locales)); + getLog().info("config - locales : " + Arrays.toString(locales)); getLog().info("config - bundle directory : " + bundleOutputDir); getLog().info("config - bundle name : " + bundleOutputName); getLog().info("config - csv separator : " + bundleCsvSeparator); @@ -79,10 +90,10 @@ public class SplitCsvBundleMojo extends AbstractCsvBundleMojo { for (Locale locale : locales) { - File bundleFile = getI18nFile(bundleOutputDir, - artifactId, - locale, - false); + File bundleFile = I18nUtil.getI18nFile(bundleOutputDir, + artifactId, + locale, + false); SortedProperties properties = new SortedProperties(encoding); diff --git a/i18n-maven-plugin/src/main/java/org/nuiton/i18n/plugin/parser/AbstractI18nParserMojo.java b/i18n-maven-plugin/src/main/java/org/nuiton/i18n/plugin/parser/AbstractI18nParserMojo.java index c4b0ca4..7b93389 100644 --- a/i18n-maven-plugin/src/main/java/org/nuiton/i18n/plugin/parser/AbstractI18nParserMojo.java +++ b/i18n-maven-plugin/src/main/java/org/nuiton/i18n/plugin/parser/AbstractI18nParserMojo.java @@ -26,7 +26,8 @@ package org.nuiton.i18n.plugin.parser; import org.apache.maven.plugins.annotations.Parameter; -import org.nuiton.i18n.plugin.AbstractI18nMojo; +import org.nuiton.i18n.plugin.AbstractI18nGenerateMojo; +import org.nuiton.i18n.plugin.I18nUtil; import org.nuiton.io.FileUpdater; import org.nuiton.io.SortedProperties; import org.nuiton.plugin.PluginHelper; @@ -41,7 +42,7 @@ import java.util.regex.Pattern; * * @author tchemit <chemit@codelutin.com> */ -public abstract class AbstractI18nParserMojo extends AbstractI18nMojo implements I18nParserConfiguration { +public abstract class AbstractI18nParserMojo extends AbstractI18nGenerateMojo implements I18nParserConfiguration { /** @return the outGetter to use for the instance (java.getter,...) */ protected abstract String getOutGetter(); @@ -68,6 +69,19 @@ public abstract class AbstractI18nParserMojo extends AbstractI18nMojo implements */ public abstract FileUpdater newFileUpdater(SourceEntry entry); + /** Directory where to find project i18n files. */ + @Parameter(property = "i18n.src", defaultValue = "${basedir}/src/main/resources/i18n", required = true) + protected File src; + + /** + * Strict mode to only keep in user i18n detected i18n keys and remove obsolete keys. + * <p/> + * <b>Note :</b> By default not active. Use this with care since it can + * delete keys. Moreover if this flag is activated, then all files will be parsed. + */ + @Parameter(property = "i18n.strictMode", defaultValue = "false") + protected boolean strictMode; + /** Build directory (used to know if files in sources are up-to-date). */ @Parameter(property = "i18n.cp", defaultValue = "${basedir}/target/classes") protected File cp; @@ -112,7 +126,7 @@ public abstract class AbstractI18nParserMojo extends AbstractI18nMojo implements /** * A regex pattern to accept incoming keys. - * + * <p/> * Only incoming keys which match the pattern will be kept. * * @since 2.5 @@ -132,10 +146,10 @@ public abstract class AbstractI18nParserMojo extends AbstractI18nMojo implements ParserExecutor parserExecutor; - @Override - public boolean isStrictMode() { - return strictMode; - } +// @Override +// public boolean isStrictMode() { +// return strictMode; +// } public boolean isForce() { return force; @@ -210,7 +224,7 @@ public abstract class AbstractI18nParserMojo extends AbstractI18nMojo implements // Anciennes cles disponnibles //fixme : pourquoi on utilise un bundle precis ? le premier ici, // je ne comprends pas - File oldLanguageFile = getI18nFile(src, artifactId, locales[0], true); + File oldLanguageFile = I18nUtil.getI18nFile(src, artifactId, locales[0], true); oldLanguage.load(oldLanguageFile); @@ -299,6 +313,10 @@ public abstract class AbstractI18nParserMojo extends AbstractI18nMojo implements return result; } + public boolean isStrictMode() { + return strictMode; + } + /** * Add the default entry to entries given in configuration. * <p/> -- To stop receiving notification emails like this one, please contact nuiton.org SCM administrator <admin+scm@nuiton.org>.