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 29266eb190010eaa383505dd2b6afc9d0e5fd59e Author: Tony CHEMIT <chemit@codelutin.com> Date: Sat Jul 26 16:54:09 2014 +0200 refs #3356 add new csv package with the 3 new mojos + deprecates csv generation in bundle mojo --- i18n-maven-plugin/pom.xml | 5 + .../org/nuiton/i18n/plugin/bundle/BundleMojo.java | 12 ++ .../plugin/bundle/csv/AbstractCsvBundleMojo.java | 33 ++++ .../plugin/bundle/csv/GenerateCsvBundleMojo.java | 211 +++++++++++++++++++++ .../i18n/plugin/bundle/csv/I18nBundleModel.java | 44 +++++ .../i18n/plugin/bundle/csv/I18nBundleModelRow.java | 35 ++++ .../plugin/bundle/csv/MergeBackCsvBundleMojo.java | 84 ++++++++ .../i18n/plugin/bundle/csv/SplitCsvBundleMojo.java | 113 +++++++++++ pom.xml | 6 + 9 files changed, 543 insertions(+) diff --git a/i18n-maven-plugin/pom.xml b/i18n-maven-plugin/pom.xml index 5458e59..ca94a48 100644 --- a/i18n-maven-plugin/pom.xml +++ b/i18n-maven-plugin/pom.xml @@ -52,6 +52,11 @@ </dependency> <dependency> + <groupId>org.nuiton</groupId> + <artifactId>nuiton-csv</artifactId> + </dependency> + + <dependency> <groupId>org.antlr</groupId> <artifactId>antlr4-runtime</artifactId> </dependency> 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 72268c8..78f9097 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 @@ -100,8 +100,10 @@ public class BundleMojo extends AbstractMakeI18nBundleMojo { * Useful to translate from a language to another one. * * @since 2.5 + * @deprecated since 3.3, prefer use the new mojo generate-csv-bundle instead */ @Parameter(property = "i18n.generateCsvFile", defaultValue = "false") + @Deprecated protected boolean generateCsvFile; /** @@ -109,9 +111,11 @@ public class BundleMojo extends AbstractMakeI18nBundleMojo { * {@link #generateCsvFile} is on. * * @since 2.5 + * @deprecated since 3.3, prefer use the new mojo generate-csv-bundle instead */ @Parameter(property = "i18n.bundleCsvFile", defaultValue = "${basedir}/target/${project.artifactId}-i18n.csv") + @Deprecated protected File bundleCsvFile; /** @@ -119,8 +123,10 @@ public class BundleMojo extends AbstractMakeI18nBundleMojo { * {@link #generateCsvFile} is on. * * @since 2.5 + * @deprecated since 3.3, prefer use the new mojo generate-csv-bundle instead */ @Parameter(property = "i18n.bundleCsvSeparator", defaultValue = "\t") + @Deprecated protected String bundleCsvSeparator; /** @@ -151,6 +157,12 @@ public class BundleMojo extends AbstractMakeI18nBundleMojo { addResourceDir(bundleOutputDir, "**/*.properties"); if (generateCsvFile) { + getLog().warn(""); + getLog().warn("--------------------------------------------------------------------------------------------"); + getLog().warn("Please use now the i18n:generate-csv-bundle mojo."); + getLog().warn("The csv bundle generation will be removed from this mojo soon."); + getLog().warn("--------------------------------------------------------------------------------------------"); + getLog().warn(""); addResourceDir(bundleOutputDir, "**/*.csv"); } 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 new file mode 100644 index 0000000..e9786fd --- /dev/null +++ b/i18n-maven-plugin/src/main/java/org/nuiton/i18n/plugin/bundle/csv/AbstractCsvBundleMojo.java @@ -0,0 +1,33 @@ +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. + * + * @author Tony Chemit - chemit@codelutin.com + * @since 3.3 + */ +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 + */ + @Parameter(property = "i18n.bundleCsvSeparator", defaultValue = "\t") + protected char bundleCsvSeparator; + +} diff --git a/i18n-maven-plugin/src/main/java/org/nuiton/i18n/plugin/bundle/csv/GenerateCsvBundleMojo.java b/i18n-maven-plugin/src/main/java/org/nuiton/i18n/plugin/bundle/csv/GenerateCsvBundleMojo.java new file mode 100644 index 0000000..e7fc82d --- /dev/null +++ b/i18n-maven-plugin/src/main/java/org/nuiton/i18n/plugin/bundle/csv/GenerateCsvBundleMojo.java @@ -0,0 +1,211 @@ +package org.nuiton.i18n.plugin.bundle.csv; + +import org.apache.commons.lang3.StringUtils; +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.csv.Export; +import org.nuiton.io.SortedProperties; + +import java.io.File; +import java.nio.charset.Charset; +import java.util.Arrays; +import java.util.LinkedList; +import java.util.List; +import java.util.Locale; +import java.util.Map; +import java.util.TreeMap; + +/** + * To generate a csv file from the full bundle of the module. + * + * The csv file will have a first column with i18n keys, and a + * column for each locale defined in {@link #locales}. + * + * Created on 7/26/14. + * + * @author Tony Chemit - chemit@codelutin.com + * @since 3.3 + */ +@Mojo(name = "generate-csv-bundle", + defaultPhase = LifecyclePhase.GENERATE_RESOURCES, + requiresProject = true, + requiresDependencyResolution = ResolutionScope.RUNTIME) +public class GenerateCsvBundleMojo 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; + + /** + * 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; + + /** + * 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(); + + // 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); + } + } + } + + @Override + protected void doAction() throws Exception { + + if (!silent) { + getLog().info("config - locales : " + Arrays.toString(locales)); + getLog().info("config - bundle dir : " + outputFolder); + getLog().info("config - bundle name : " + bundleOutputName); + getLog().info("config - csv separator : " + bundleCsvSeparator); + getLog().info("config - csv file : " + bundleCsvFile); + getLog().info("config - input encoding : " + bundleInputEncoding); + getLog().info("config - output encoding : " + bundleOutputEncoding); + } + + // fill rows to export + + Map<String, I18nBundleModelRow> rowsByKey = new TreeMap<String, I18nBundleModelRow>(); + + for (Locale locale : locales) { + + File bundleFile = getI18nFile(outputFolder, + bundleOutputName, + locale, + false + ); + + SortedProperties properties = new SortedProperties(bundleOutputEncoding); + properties.load(bundleFile); + + for (Object o : properties.keySet()) { + String key = (String) o; + I18nBundleModelRow row = rowsByKey.get(key); + if (row == null) { + row = new I18nBundleModelRow(); + row.setKey(key); + rowsByKey.put(key, row); + } + row.setLocaleValue(locale, (String) properties.get(o)); + } + } + + List<I18nBundleModelRow> rows = new LinkedList<I18nBundleModelRow>(rowsByKey.values()); + if (!isSilent()) { + + getLog().info(String.format("Found %d translations.", rows.size())); + } + + // do the export + + if (!bundleCsvFile.exists()) { + createNewFile(bundleCsvFile); + } + + if (!isSilent()) { + getLog().info("Generate csv bundle file at " + bundleCsvFile); + } + + I18nBundleModel exportModel = new I18nBundleModel(bundleCsvSeparator, locales); + + Export.exportToFile(exportModel, rows, bundleCsvFile, Charset.forName(encoding)); + + } + + + 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; + } +} diff --git a/i18n-maven-plugin/src/main/java/org/nuiton/i18n/plugin/bundle/csv/I18nBundleModel.java b/i18n-maven-plugin/src/main/java/org/nuiton/i18n/plugin/bundle/csv/I18nBundleModel.java new file mode 100644 index 0000000..020a65b --- /dev/null +++ b/i18n-maven-plugin/src/main/java/org/nuiton/i18n/plugin/bundle/csv/I18nBundleModel.java @@ -0,0 +1,44 @@ +package org.nuiton.i18n.plugin.bundle.csv; + +import org.nuiton.csv.ValueGetterSetter; +import org.nuiton.csv.ext.AbstractImportExportModel; + +import java.util.Locale; + +/** + * Created on 7/26/14. + * + * @author Tony Chemit - chemit@codelutin.com + * @since 3.3 + */ +public class I18nBundleModel extends AbstractImportExportModel<I18nBundleModelRow> { + + public I18nBundleModel(char separator, Locale[] locales) { + super(separator); + + newMandatoryColumn("key"); + newColumnForExport("key"); + + for (final Locale locale : locales) { + + ValueGetterSetter<I18nBundleModelRow, String> getterSetter = new ValueGetterSetter<I18nBundleModelRow, String>() { + @Override + public String get(I18nBundleModelRow row) throws Exception { + return row.getLocaleValue(locale); + } + + @Override + public void set(I18nBundleModelRow row, String s) throws Exception { + row.setLocaleValue(locale, s); + } + }; + newColumnForExport(locale.getCountry(), getterSetter); + newMandatoryColumn(locale.getCountry(), getterSetter); + } + } + + @Override + public I18nBundleModelRow newEmptyInstance() { + return new I18nBundleModelRow(); + } +} diff --git a/i18n-maven-plugin/src/main/java/org/nuiton/i18n/plugin/bundle/csv/I18nBundleModelRow.java b/i18n-maven-plugin/src/main/java/org/nuiton/i18n/plugin/bundle/csv/I18nBundleModelRow.java new file mode 100644 index 0000000..0c78852 --- /dev/null +++ b/i18n-maven-plugin/src/main/java/org/nuiton/i18n/plugin/bundle/csv/I18nBundleModelRow.java @@ -0,0 +1,35 @@ +package org.nuiton.i18n.plugin.bundle.csv; + +import java.util.HashMap; +import java.util.Locale; +import java.util.Map; + +/** +* Created on 7/26/14. +* +* @author Tony Chemit - chemit@codelutin.com +* @since 3.3 +*/ +public class I18nBundleModelRow { + + String key; + + Map<Locale, String> localeValue = new HashMap<Locale, String>(); + + public String getKey() { + return key; + } + + public void setKey(String key) { + this.key = key; + } + + public void setLocaleValue(Locale locale, String s) { + localeValue.put(locale, s); + } + + public String getLocaleValue(Locale locale) { + return localeValue.get(locale); + } + +} 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 new file mode 100644 index 0000000..3272a02 --- /dev/null +++ b/i18n-maven-plugin/src/main/java/org/nuiton/i18n/plugin/bundle/csv/MergeBackCsvBundleMojo.java @@ -0,0 +1,84 @@ +package org.nuiton.i18n.plugin.bundle.csv; + +import com.google.common.collect.Lists; +import org.apache.commons.io.FileUtils; +import org.apache.commons.io.IOUtils; +import org.apache.maven.plugins.annotations.LifecyclePhase; +import org.apache.maven.plugins.annotations.Mojo; +import org.apache.maven.plugins.annotations.ResolutionScope; +import org.nuiton.csv.Import; +import org.nuiton.io.SortedProperties; + +import java.io.File; +import java.io.FileInputStream; +import java.util.Arrays; +import java.util.LinkedList; +import java.util.Locale; + +/** + * To merge back from a csv bundle to a module i18n bundle files. + * <p/> + * Created on 7/26/14. + * + * @author Tony Chemit - chemit@codelutin.com + * @since 3.3 + */ +@Mojo(name = "merge-back-csv-bundle", + defaultPhase = LifecyclePhase.GENERATE_RESOURCES, + requiresProject = true, + requiresDependencyResolution = ResolutionScope.RUNTIME) +public class MergeBackCsvBundleMojo extends AbstractCsvBundleMojo { + + @Override + protected void doAction() throws Exception { + + if (!silent) { + getLog().info("config - locales : " + Arrays.toString(locales)); + getLog().info("config - csv separator : " + bundleCsvSeparator); + getLog().info("config - csv file : " + bundleCsvFile); + getLog().info("config - merge directory : " + src); + + } + + LinkedList<I18nBundleModelRow> rows; + + I18nBundleModel importModel = new I18nBundleModel(bundleCsvSeparator, locales); + FileInputStream inputStream = FileUtils.openInputStream(bundleCsvFile); + Import<I18nBundleModelRow> newImport; + try { + newImport = Import.newImport(importModel, inputStream); + + rows = Lists.newLinkedList(newImport); + inputStream.close(); + newImport.close(); + } finally { + IOUtils.closeQuietly(inputStream); + } + + for (Locale locale : locales) { + + File bundleFile = getI18nFile(src, + artifactId, + locale, + false); + + SortedProperties properties = new SortedProperties(encoding); + + // load old values + properties.load(bundleFile, encoding); + + // push back values from csv file + for (I18nBundleModelRow row : rows) { + properties.put(row.getKey(), row.getLocaleValue(locale)); + } + + if (!isSilent()) { + getLog().info(String.format("Merge locale bundle %s in %s", locale, bundleFile)); + } + properties.store(bundleFile); + + } + + } + +} 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 new file mode 100644 index 0000000..dfcc5c0 --- /dev/null +++ b/i18n-maven-plugin/src/main/java/org/nuiton/i18n/plugin/bundle/csv/SplitCsvBundleMojo.java @@ -0,0 +1,113 @@ +package org.nuiton.i18n.plugin.bundle.csv; + +import com.google.common.collect.Lists; +import org.apache.commons.io.FileUtils; +import org.apache.commons.io.IOUtils; +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.csv.Import; +import org.nuiton.io.SortedProperties; + +import java.io.File; +import java.io.FileInputStream; +import java.util.Arrays; +import java.util.LinkedList; +import java.util.Locale; + +/** + * To split a previously csv i18n file into simple i18n bundles for the locales defined in {@link #locales}. + * <p/> + * The order of {@link #locales} will be used to extract for each locale i18n bundle (means the order defined + * in the csv file is not used). Make sure to use exactly the same order. + * <p/> + * Created on 7/26/14. + * + * @author Tony Chemit - chemit@codelutin.com + * @since 3.3 + */ +@Mojo(name = "split-csv-bundle", + defaultPhase = LifecyclePhase.GENERATE_RESOURCES, + requiresProject = true, + requiresDependencyResolution = ResolutionScope.RUNTIME) +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; + + /** + * 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; + + @Override + protected void doAction() throws Exception { + + if (!silent) { + 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); + getLog().info("config - csv file : " + bundleCsvFile); + + } + + LinkedList<I18nBundleModelRow> rows; + + I18nBundleModel importModel = new I18nBundleModel(bundleCsvSeparator, locales); + FileInputStream inputStream = FileUtils.openInputStream(bundleCsvFile); + Import<I18nBundleModelRow> newImport; + try { + newImport = Import.newImport(importModel, inputStream); + + rows = Lists.newLinkedList(newImport); + inputStream.close(); + newImport.close(); + } finally { + IOUtils.closeQuietly(inputStream); + } + + for (Locale locale : locales) { + + File bundleFile = getI18nFile(bundleOutputDir, + artifactId, + locale, + false); + + SortedProperties properties = new SortedProperties(encoding); + + for (I18nBundleModelRow row : rows) { + properties.put(row.getKey(), row.getLocaleValue(locale)); + } + + if (!isSilent()) { + getLog().info(String.format("Extract locale bundle %s to %s", locale, bundleFile)); + } + properties.store(bundleFile); + + } + + } + + @Override + public void init() throws Exception { + super.init(); + + if (isVerbose()) { + getLog().info("Will split bundles in " + bundleOutputDir); + } + createDirectoryIfNecessary(bundleOutputDir); + + } + +} diff --git a/pom.xml b/pom.xml index 74f4392..10390eb 100644 --- a/pom.xml +++ b/pom.xml @@ -122,6 +122,12 @@ </dependency> <dependency> + <groupId>org.nuiton</groupId> + <artifactId>nuiton-csv</artifactId> + <version>3.0-rc-1</version> + </dependency> + + <dependency> <groupId>org.antlr</groupId> <artifactId>antlr4-runtime</artifactId> <version>${antlrVersion}</version> -- To stop receiving notification emails like this one, please contact nuiton.org SCM administrator <admin+scm@nuiton.org>.