Index: maven-i18n-plugin/src/java/org/codelutin/i18n/plugin/extension/ParserXml.java diff -u maven-i18n-plugin/src/java/org/codelutin/i18n/plugin/extension/ParserXml.java:1.12 maven-i18n-plugin/src/java/org/codelutin/i18n/plugin/extension/ParserXml.java:1.13 --- maven-i18n-plugin/src/java/org/codelutin/i18n/plugin/extension/ParserXml.java:1.12 Wed Feb 20 20:31:41 2008 +++ maven-i18n-plugin/src/java/org/codelutin/i18n/plugin/extension/ParserXml.java Tue Mar 18 00:23:35 2008 @@ -118,6 +118,7 @@ public void parseLine(File file, String key) { key = extract(key); if(key != null) { + touchFile=true; String keyModified = key; for (ParserEvent event : events) { event.eventChangeKey(key, !oldLanguage.containsKey(key)); Index: maven-i18n-plugin/src/java/org/codelutin/i18n/plugin/extension/ParserJava.java diff -u maven-i18n-plugin/src/java/org/codelutin/i18n/plugin/extension/ParserJava.java:1.13 maven-i18n-plugin/src/java/org/codelutin/i18n/plugin/extension/ParserJava.java:1.14 --- maven-i18n-plugin/src/java/org/codelutin/i18n/plugin/extension/ParserJava.java:1.13 Wed Jan 23 09:41:17 2008 +++ maven-i18n-plugin/src/java/org/codelutin/i18n/plugin/extension/ParserJava.java Tue Mar 18 00:23:35 2008 @@ -19,25 +19,42 @@ package org.codelutin.i18n.plugin.extension; +import org.apache.maven.artifact.Artifact; +import org.apache.maven.project.MavenProject; +import static org.codelutin.i18n.I18n._; +import org.codelutin.i18n.I18nable; import org.codelutin.i18n.plugin.core.AbstractI18nParser; import org.codelutin.i18n.plugin.core.ParserEvent; import org.codelutin.i18n.plugin.core.ParserException; +import org.codelutin.i18n.plugin.core.SourceEntry; import org.codelutin.processor.filters.I18nFilter; +import org.codelutin.util.FileUtil; import java.io.BufferedOutputStream; +import java.io.BufferedWriter; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; +import java.io.FileWriter; +import java.io.IOException; import java.io.InputStreamReader; import java.io.LineNumberReader; import java.io.OutputStream; +import java.lang.annotation.Annotation; +import java.net.MalformedURLException; +import java.net.URL; +import java.net.URLClassLoader; +import java.util.List; +import java.util.Set; +import java.util.Collections; +import java.util.regex.Pattern; /** * Récupération des chaîne à traduire depuis les fichiers java. * * @author julien * @goal parserJava - * @phase generate-resources + * @phase process-classes */ public class ParserJava extends AbstractI18nParser { @@ -53,10 +70,39 @@ */ protected File defaultBasedir; + /** + * @description Dépendance du projet. + * @parameter default-value="${project}" + * @readonly + */ + protected MavenProject project; + + /** + * @description Répertoire sources des fichiers i18n. + * @parameter expression="${i18n.cp}" default-value="${basedir}/target/classes" + * @required + */ + protected File cp; + + /** + * @description pour utiliser l'annotation I18nable pour traiter les fichiers + * @parameter expression="${i18n.ea}" default-value="false" + */ + protected boolean ea; + + /** + * @description pour découvrir les fichiers I18nable. + * @parameter expression="${i18n.detectea}" default-value="false" + */ + protected boolean detectea; + + protected List annotationClass; + protected String[] getDefaultIncludes() { return new String[]{defaultIncludes}; } + protected File getDefaultBasedir() { return defaultBasedir; } @@ -75,35 +121,57 @@ protected I18nFilter filter; + protected URLClassLoader loader; + protected Annotation annotation; + + @Override public void init() { super.init(); filter = new I18nFilter(); + if (detectea) { + // in detect mode, we do not filter by ea, try all files + ea = false; + } + if (ea || detectea) { + loader = initClassLoader(); + annotationClass = initAnnotations(); + } + } + + protected List initAnnotations() { + return Collections.singletonList(org.codelutin.i18n.I18nable.class.getName()); + } + + protected String[] getFilesForEntry(SourceEntry entry) { + + if (detectea || !ea) { + // no filter take all files + return super.getFilesForEntry(entry); + } + + // filter by annotation + return entry.getIncludedFiles(getDefaultBasedir(), getDefaultIncludes(), loader, annotationClass, getLog()); } /* - * (non-Javadoc) - * @see org.codelutin.i18n.plugin.core.Parser#parseFile(java.io.File) - */ + * (non-Javadoc) + * @see org.codelutin.i18n.plugin.core.Parser#parseFile(java.io.File) + */ public void parseFile(File srcFile) { try { int size = result.size(); - LineNumberReader lnr = new LineNumberReader(new InputStreamReader(new FileInputStream(srcFile))); - while (lnr.ready()) { - String line = lnr.readLine(); - parseLine(srcFile, line); - } + parseFile0(srcFile); // Détection de nouvelles clés, sauvegarde du fichier pour pouvoir le restaurer en cas de plantage if (size != result.size()) { - OutputStream outputStream = null; - try { - outputStream = new BufferedOutputStream(new FileOutputStream(out.getAbsolutePath() + File.separatorChar + getOutGetter())); - result.store(outputStream, null); - } finally { - if (outputStream != null) { - outputStream.close(); - } + saveProperties0(); + } + + if (touchFile && detectea) { + Annotation annotation = currentEntry.getAnnotation(srcFile, loader, annotationClass, getLog()); + if (annotation == null) { + addAnnotation(srcFile); } } } catch (Exception e) { @@ -117,7 +185,9 @@ */ public void parseLine(File srcFile, String line) { String keysSet = filter.parse(line); + if (!keysSet.equals(I18nFilter.EMPTY_STRING)) { + touchFile = true; // Found a set of i18n Strings, split it. String[] keys = keysSet.split("="); for (String key : keys) { @@ -134,4 +204,106 @@ } } } + + private void addAnnotation(File srcFile) throws IOException { + + String classname = srcFile.getName(); + + classname = classname.substring(0, classname.length() - 5); + + getLog().info(getLogEntry("add annotation to class "+ classname,0,0,0)); + + BufferedWriter outputStream = null; + try { + + Pattern TYPE_PATTERN = Pattern.compile("^.*(class|interface|enum)\\s*" + classname + ".*"); + String str = FileUtil.readAsString(srcFile); + outputStream = new BufferedWriter(new FileWriter(srcFile)); + boolean foundDeclaration = false; + String[] lines = str.split("\n"); + int size = lines.length; + for (int i = 0; i < size; i++) { + String line = lines[i]; + if (!foundDeclaration) { + // test if the annotion already exist ? + String line2 = line.trim(); + if (line2.startsWith("@I18nable") || line2.startsWith("@" + I18nable.class.getName())) { + foundDeclaration = true; + } else if (TYPE_PATTERN.matcher(line2).matches()) { + foundDeclaration = true; + outputStream.write('@' + I18nable.class.getName() + '\n'); + } + } + outputStream.write(line); + if (i < size - 1) { + outputStream.write("\n"); + } + } + } finally { + if (outputStream != null) { + outputStream.flush(); + outputStream.close(); + } + } + } + + protected void saveProperties0() throws IOException { + OutputStream outputStream = null; + try { + outputStream = new BufferedOutputStream(new FileOutputStream(out.getAbsolutePath() + File.separatorChar + getOutGetter())); + result.store(outputStream, null); + } finally { + if (outputStream != null) { + outputStream.close(); + } + } + } + + protected void parseFile0(File srcFile) throws IOException { + LineNumberReader lnr = new LineNumberReader(new InputStreamReader(new FileInputStream(srcFile))); + while (lnr.ready()) { + String line = lnr.readLine(); + parseLine(srcFile, line); + } + } + + @SuppressWarnings({"unchecked"}) + protected URLClassLoader initClassLoader() { + URLClassLoader loader = null; + if (project != null) { + URLClassLoader result; + try { + Set compileClasspathElements = project.getArtifacts(); + URL[] url = new URL[compileClasspathElements.size() + 1]; + url[0] = cp.toURI().toURL(); + int i = 1; + for (Artifact artifact : compileClasspathElements) { + File file = new File(artifact.getFile().getAbsolutePath()); + if (file.getName().endsWith(".jar")) { + url[i] = new URL("jar", "", file.toURI().toURL().toString() + "!/"); + } else { + url[i] = file.toURI().toURL(); + } + i++; + } + //ClassLoader parent = Thread.currentThread().getContextClassLoader(); + if (compileClasspathElements.size() == 0) { + result = new URLClassLoader(url, getClass().getClassLoader()); + } else { + result = new URLClassLoader(url); + } + } catch (MalformedURLException eee) { + throw new RuntimeException(_("Can't create ClassLoader for script, bad directory: {0} for reason {1}", cp, eee.getMessage()), eee); + } catch (IOException e) { + throw new RuntimeException(_("Can't create ClassLoader for script, bad directory: {0} for reason {1}", cp, e.getMessage()), e); + } + loader = result; + } + if (getLog().isDebugEnabled() && loader != null) { + for (URL entry : loader.getURLs()) { + getLog().info("cp url " + entry); + } + } + return loader; + } } Index: maven-i18n-plugin/src/java/org/codelutin/i18n/plugin/extension/ParserJavaActionConfig.java diff -u maven-i18n-plugin/src/java/org/codelutin/i18n/plugin/extension/ParserJavaActionConfig.java:1.5 maven-i18n-plugin/src/java/org/codelutin/i18n/plugin/extension/ParserJavaActionConfig.java:1.6 --- maven-i18n-plugin/src/java/org/codelutin/i18n/plugin/extension/ParserJavaActionConfig.java:1.5 Wed Jan 23 09:41:17 2008 +++ maven-i18n-plugin/src/java/org/codelutin/i18n/plugin/extension/ParserJavaActionConfig.java Tue Mar 18 00:23:35 2008 @@ -21,6 +21,8 @@ import org.codelutin.i18n.plugin.core.ParserEvent; import java.io.File; +import java.util.ArrayList; +import java.util.List; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -47,6 +49,15 @@ return "java-action-config.getter"; } + protected List initAnnotations() { + List result = new ArrayList(1); + result.add("jaxx.runtime.builder.ActionConfig"); + result.add("jaxx.runtime.builder.SelectActionConfig"); + result.add("jaxx.runtime.builder.TabContentConfig"); + result.add("jaxx.runtime.builder.ToggleActionConfig"); + return result; + } + /* * (non-Javadoc) * @see org.codelutin.i18n.plugin.extension.XmlParser#extract(java.lang.String) @@ -66,6 +77,7 @@ public void parseLine(File srcFile, String line) { String key = extract(line); if (key != null) { + touchFile = true; String keyModified = key; for (ParserEvent event : events) { event.eventChangeKey(key, !oldLanguage.containsKey(key)); @@ -76,7 +88,7 @@ } else { result.put(keyModified, key); } - } + } } } Index: maven-i18n-plugin/src/java/org/codelutin/i18n/plugin/extension/ParserJavaTabConfig.java diff -u /dev/null maven-i18n-plugin/src/java/org/codelutin/i18n/plugin/extension/ParserJavaTabConfig.java:1.1 --- /dev/null Tue Mar 18 00:23:41 2008 +++ maven-i18n-plugin/src/java/org/codelutin/i18n/plugin/extension/ParserJavaTabConfig.java Tue Mar 18 00:23:35 2008 @@ -0,0 +1,38 @@ +/** + * ##% Copyright (C) 2008 Code Lutin, Tony Chemit + * This program is free software; you + * can redistribute it and/or modify it under the terms of the GNU General + * Public License as published by the Free Software Foundation; either version 2 + * 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 Public License for more details. You + * should have received a copy of the GNU General Public License along with this + * program; if not, write to the Free Software Foundation, Inc., 59 Temple Place + * - Suite 330, Boston, MA 02111-1307, USA. + * ##% + */ +package org.codelutin.i18n.plugin.extension; + +import java.util.Collections; + +/** + * Un paseur java pour scanner les annotations TabContentConfig. + * + * @author chemit + * @goal parserJavaTabConfig + * @phase generate-resources + */ +public class ParserJavaTabConfig extends ParserJavaActionConfig { + + @Override + protected String getOutGetter() { + return "java-tab-config.getter"; + } + + @Override + protected java.util.List initAnnotations() { + return Collections.singletonList(org.codelutin.i18n.I18nable.class.getName()); + } + +}