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

org.nuiton.i18n.plugin.parser.ParseJavaEnumerationsMojo Maven / Gradle / Ivy

package org.nuiton.i18n.plugin.parser;

/*
 * #%L
 * I18n :: Maven Plugin
 * %%
 * Copyright (C) 2007 - 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%
 */

import io.ultreia.java4all.i18n.spi.builder.I18nKeySet;
import io.ultreia.java4all.i18n.spi.builder.I18nModule;
import org.antlr.v4.runtime.CharStreams;
import org.antlr.v4.runtime.CommonTokenStream;
import org.antlr.v4.runtime.TokenStream;
import org.apache.maven.plugins.annotations.LifecyclePhase;
import org.apache.maven.plugins.annotations.Mojo;
import org.apache.maven.plugins.annotations.Parameter;
import org.codehaus.plexus.util.StringUtils;
import org.nuiton.i18n.plugin.I18nMojoSupport;
import org.nuiton.i18n.plugin.parser.java.Java8BaseVisitor;
import org.nuiton.i18n.plugin.parser.java.Java8Lexer;
import org.nuiton.i18n.plugin.parser.java.Java8Parser;
import org.nuiton.plugin.PluginHelper;

import java.io.BufferedWriter;
import java.io.File;
import java.io.IOException;
import java.nio.charset.Charset;
import java.nio.file.Path;
import java.util.Date;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.StringTokenizer;
import java.util.TreeMap;
import java.util.TreeSet;

/**
 * Parse java enumerations to generate i18n keys, plus generate a java helper file to get theses translations.
 * 

* Created on 28/08/16. * * @author Tony Chemit - [email protected] * @since 3.6 */ @Mojo(name = "parse-java-enumerations", defaultPhase = LifecyclePhase.GENERATE_SOURCES) public class ParseJavaEnumerationsMojo extends I18nMojoSupport { /** * To generate or not the java helper. * * Note: default behaviour is to not generate it. */ @Parameter(property = "i18n.generateHelper", defaultValue = "false") private boolean generateHelper; /** * List of enumerations set to scan to generate i18n keys. *

*

     *     <enumerationSets>
     *       <enumerationSet>
     *         <name>label</name>
     *         <pattern>myPrefix.@CLASS_NAME@.@NAME@</pattern>
     *         <enums>
     *           <org.nuiton.Enum1>
     *           <org.nuiton.Enum2>
     *           <...>
     *         </enums>
     *       </enumerationSet>
     *     </enumerationSets>
     * 
*

* Example with enum {@code enum org.nuiton.Enum1 { A,B }}, will generate i18n keys: *

    *
  • myPrefix.org.nuiton.Enum1.A
  • *
  • myPrefix.org.nuiton.Enum1.B
  • *
*

* In pattern, you can use variable *

    *

    *

  • {@code @CLASS_NAME@} for enumeration class fully qualified name
  • *
  • {@code @CLASS_SIMPLE_NAME@} for enumeration class simple name
  • *
  • {@code @NAME@} for enumeration name
  • *
  • {@code @ORDINAL@} for enumeration ordinal
  • *
*

* Moreover, two methods will be also generated according to specified name to translate those keys : *

     *     public static String getLabel(Enum)
     *     public static String getLabel(Locale, Enum)
     * 
*/ @Parameter(required = true) private List enumerationSets; private String className; private String packageName; @Override protected void doAction() throws Exception { I18nModule i18nModule = I18nModule.forGetter(getProject().getProperties()); I18nKeySet i18nKeysFile = i18nModule.getModuleKeySet("java-enumeration"); Map> types = new TreeMap<>(); Charset encoding = i18nModule.getConfiguration().getEncoding(); for (EnumerationSet enumerationSet : enumerationSets) { for (String anEnumType : enumerationSet.getEnums()) { Set enumValues = types.get(anEnumType); if (enumValues == null) { types.put(anEnumType, enumValues = getEnumConstants(anEnumType, encoding)); } int ordinal = 0; String simpleName = anEnumType.substring(anEnumType.lastIndexOf('.') + 1); for (String name : enumValues) { i18nKeysFile.addKey(enumerationSet.transformToKey(anEnumType, simpleName, name, (ordinal++) + "")); } } } i18nModule.storeModuleKeySet(i18nKeysFile); className = getFilename(i18nModule.getName(), "I18nEnumHelper"); packageName = i18nModule.getPackageName(); if (generateHelper) { Path file = generateJavaFile(i18nModule, "I18nEnumHelper", this::generateContent); if (isNotSilent()) { getLog().info("Generate i18n helper at " + file); } } } private void generateContent(BufferedWriter writer) { try { writer.write("package " + packageName + ";\n"); writer.write("\n"); writer.write("import java.util.Locale;\n"); writer.write("import javax.annotation.Generated;\n"); writer.write("\n"); writer.write("import static io.ultreia.java4all.i18n.I18n.l;\n"); writer.write("import static io.ultreia.java4all.i18n.I18n.n;\n"); writer.write("import static io.ultreia.java4all.i18n.I18n.t;\n"); writer.write("\n"); writer.write("\n"); writer.write("@Generated(value = \"Generated by " + getClass().getName() + "\",date = \"" + new Date() + "\")\n"); writer.write("public class " + className + " {\n"); writer.write("\n"); for (EnumerationSet enumerationSet : enumerationSets) { String methodName = "get" + StringUtils.capitalise(enumerationSet.getName()); writer.write(" public static > String " + methodName + "(E e) {\n"); writer.write(" return t(" + methodName + "Key(e));\n"); writer.write(" }\n"); writer.write("\n"); writer.write(" public static > String " + methodName + "(Locale locale, E e) {\n"); writer.write(" return l(locale, " + methodName + "Key(e));\n"); writer.write(" }\n"); writer.write("\n"); writer.write(" protected static > String " + methodName + "Key(E e) {\n"); writer.write(" return " + enumerationSet.transformToMessage() + ";\n"); writer.write(" }\n"); writer.write("\n"); } writer.write("\n protected static String removeAnonymousSuffix(String className) {\n"); writer.write(" return className.contains(\"$\") ? className.substring(0, className.indexOf(\"$\")) : className;"); writer.write("\n }\n"); writer.write("}\n"); } catch (IOException e) { throw new RuntimeException("Can't write java file", e); } } private Set getEnumConstants(String anEnumType, Charset encoding) throws IOException { if (isVerbose()) { getLog().info("Scan enum: " + anEnumType); } Set result = new TreeSet<>(); try { Class aClass = Class.forName(anEnumType); if (!aClass.isEnum()) { throw new IllegalStateException("Type " + aClass.getName() + " is not an enum."); } for (Object o : aClass.getEnumConstants()) { result.add(((Enum) o).name()); } } catch (ClassNotFoundException e) { // try with antlr4 File basedir = new File(new File(new File(getProject().getBasedir(), "src"), "main"), "java"); File file = PluginHelper.getFile(basedir, anEnumType.trim().split("\\.")); File javaFile = new File(file.getParentFile(), file.getName() + ".java"); if (javaFile.exists()) { TokenStream tokenStream = new CommonTokenStream(new Java8Lexer(CharStreams.fromFile(javaFile, encoding))); Java8Parser parser = new Java8Parser(tokenStream); // see http://stackoverflow.com/a/32918434/2038100 //parser.setErrorHandler(new BailErrorStrategy()); //parser.getInterpreter().setPredictionMode(PredictionMode.SLL); //parser.getInterpreter().tail_call_preserves_sll = false; parser.getInterpreter().enable_global_context_dfa = true; JavaParserVisitor visitor = new JavaParserVisitor(javaFile); parser.compilationUnit().accept(visitor); Set names = visitor.getNames(); result.addAll(names); } } return result; } public static class EnumerationSet { private String name; private String pattern; private List enums; public String getName() { return name; } public void setName(String name) { this.name = name; } public String getPattern() { return pattern; } public void setPattern(String pattern) { this.pattern = pattern; } public List getEnums() { return enums; } public void setEnums(List enums) { this.enums = enums; } String transformToKey(String className, String simpleName, String name, String ordinal) { String result = pattern; result = result.replace("@CLASS_NAME@", className); result = result.replace("@CLASS_SIMPLE_NAME@", simpleName); result = result.replace("@NAME@", name); result = result.replace("@ORDINAL@", ordinal); return result; } String transformToMessage() { String result = ""; StringTokenizer stringTokenizer = new StringTokenizer(pattern, "@"); while (stringTokenizer.hasMoreTokens()) { if (!result.isEmpty()) { result += " + "; } String token = stringTokenizer.nextToken(); switch (token) { case "CLASS_SIMPLE_NAME": result += "e.getClass().getSimpleName()"; break; case "CLASS_NAME": result += "removeAnonymousSuffix(e.getClass().getName())"; break; case "NAME": result += "e.name()"; break; case "ORDINAL": result += "e.ordinal()"; break; default: result += "\"" + token + "\""; } } if (result.endsWith("+")) { result = result.substring(0, result.length() - 1); } return result; } } protected class JavaParserVisitor extends Java8BaseVisitor { final Set names; final File file; private JavaParserVisitor(File file) { this.file = file; names = new LinkedHashSet<>(); } Set getNames() { return names; } @Override public Void visitEnumConstant(Java8Parser.EnumConstantContext ctx) { String text = ctx.getChild(0).getText(); names.add(text); return super.visitEnumConstant(ctx); } } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy