Maven:
        
            <build>
              ...
              </plugins>
                  ...
                  <plugin>
                      <groupId>org.codehaus.groovy.maven</groupId>
                      <artifactId>gmaven-plugin</artifactId>
                      <version>1.0</version>
                      <dependencies>
                          <dependency>
                              <groupId>org.codehaus.groovy.maven.runtime</groupId>
                              <artifactId>gmaven-runtime-1.6</artifactId>
                              <version>1.0</version>
                          </dependency>
                          <dependency>
                              <groupId>org.codehaus.groovy</groupId>
                              <artifactId>groovy-all</artifactId>
                              <version>1.6.9</version>
                          </dependency>
                      </dependencies>
                      <executions>
                          <execution>
                              <id>generate java keys for all properties</id>
                              <phase>generate-sources</phase>
                              <goals>
                                  <goal>execute</goal>
                              </goals>
                              <configuration>
                                  <source>${PROJECT_HOME}/KeyGenerator.groovy</source>
                              </configuration>
                          </execution>
                      </executions>
                  </plugin>
              </plugins>
          </build>
        
        
        Java:
        
          public interface IKey {
              String getKey();
          }
        
        
        Groovy ( KeyGenerator.groovy ):
        
          import org.apache.maven.project.MavenProject
          import org.apache.maven.model.Resource
          
          MavenProject mvnProject = project
          File generatedDir = new File(mvnProject.basedir, "src/main/java/ru/scartel/paymentsystems/generated/")
          
          for (Resource resource: mvnProject.resources) {
            File dir = new File(resource.directory)
          
            // filter only l10n*.properties files
          
            for (File file: dir.listFiles(
                    {
                      return it != null && it.exists() && !it.isDirectory() &&
                              it.name.substring(it.name.lastIndexOf('.') + 1, it.name.length()) == "properties" &&
          
                              it.name.startsWith("l10n")
                    } as FileFilter
            )) {
          
              if (!generatedDir.exists()) {
                if (!generatedDir.mkdirs()) {
                  println "Directory $generatedDir coudn't be created."
          
                  System.exit(1)
                }
              }
          
              Properties props = new Properties()
              file.withReader { reader ->
                props.load(reader)
              }
          
              String className = toClassName(file.name)
              println "Generate properties class $className"
          
              new File(generatedDir, className + ".java").withWriter { out ->
                out.println("package ru.scartel.paymentsystems.generated;")
                out.println()
                out.println("//  Class generated from $file.name")
                out.println()
          
          //      if (file.name.startsWith("l10n")) {
                out.println("import ru.scartel.paymentsystems.common.locale.LocalizedResource;")
                out.println()
                out.println("public enum $className implements IKey {")
          //      } else {
          //        out.println("import ru.scartel.paymentsystems.common.IKey;")
          
          //        out.println()
          //        out.println("public enum $className implements IKey {")
          //      }
                Iterator iter = props.keySet().iterator();
                while (iter.hasNext()) {
                  String key = (String) iter.next()
                  String enumName = toEnumName(key)
                  out.print("    $enumName(\"$key\")")
                  out.println(iter.hasNext() ? "," : ";")
          
                }
                out.println()
                out.println("    public static String PROPERTIES_FILE=\"$file.name\";")
                out.println()
                out.println("    String key;")
                out.println()
                out.println("    $className(String key) {")
                out.println("        this.key = key;")
                out.println("    }")
                out.println()
                out.println("    @Override")
                out.println("    public String getKey() {")
                out.println("        return key;")
                out.println("    }")
                out.println("}")
              }
            }
          }
          
          String toClassName(String fileName) {
            StringBuilder sb = new StringBuilder();
            boolean isUpper = true;
            int idx = fileName.lastIndexOf('.')
            for (int i = 0; i < idx; i++) {
              Character c = fileName.charAt(i);
              if (c == '_') {
                isUpper = true;
              } else {
                sb.append(isUpper ? c.toUpperCase() : c)
                isUpper = false;
              }
            }
            return sb.toString();
          }
          
          String toEnumName(String name) {
            StringBuilder sb = new StringBuilder();
            boolean isLower = false;
            for (int i = 0; i < name.length(); i++) {
              Character c = name.charAt(i);
              if (new Character(c).isUpperCase() && isLower) {
                sb.append('_');
              }
              if (c == '.') {
                sb.append('_');
              } else {
                sb.append(c.toUpperCase());
              }
              isLower = c.isLowerCase()
            }
            return sb.toString();
          }
        
        
        Example of property file:
        
          PS.fileParse.fileNameFormatError=File {0} name format error.
          PS.fileParse.successParse=File {0} successfully parsed. Lines: {1}.
          PS.fileParse.formatError=File {0} format error at line {1}.
          PS.fileParse.formatErrorWithColumn=File {0} format error at line {1}, column {2}.
          PS.fileParse.fileReadError=File {0} read error at line {1}.
          PS.fileParse.readError=Read error at line {0}.
          PS.fileParse.headerError=File {0} header format error.
        
        
        Generated form this property enum:
        
          package ru.scartel.paymentsystems.generated;
          
          //  Class generated from l10n_FileParse.properties
          
          import ru.scartel.paymentsystems.common.IKey;
          
          
          public enum L10nFileParse implements IKey {
              PS_FILE_PARSE_HEADER_ERROR("PS.fileParse.headerError"),
              PS_FILE_PARSE_SUCCESS_PARSE("PS.fileParse.successParse"),
              PS_FILE_PARSE_FILE_READ_ERROR("PS.fileParse.fileReadError"),
              PS_FILE_PARSE_FORMAT_ERROR_WITH_COLUMN("PS.fileParse.formatErrorWithColumn"),
              PS_FILE_PARSE_FORMAT_ERROR("PS.fileParse.formatError"),
              PS_FILE_PARSE_READ_ERROR("PS.fileParse.readError"),
              PS_FILE_PARSE_FILE_NAME_FORMAT_ERROR("PS.fileParse.fileNameFormatError");
          
              public static String PROPERTIES_FILE="l10n_FileParse.properties";
          
              String key;
          
              L10nFileParse(String key) {
                  this.key = key;
              }
          
              @Override
              public String getKey() {
                  return key;
              }
          }