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

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

/*
 * #%L
 * I18n :: Maven Plugin
 * 
 * $Id: AbstractI18nParserMojo.java 1971 2012-08-29 19:38:52Z tchemit $
 * $HeadURL: http://svn.nuiton.org/svn/i18n/tags/i18n-2.5.2/i18n-maven-plugin/src/main/java/org/nuiton/i18n/plugin/parser/AbstractI18nParserMojo.java $
 * %%
 * Copyright (C) 2007 - 2010 CodeLutin, Tony Chemit
 * %%
 * 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%
 */

package org.nuiton.i18n.plugin.parser;

import org.apache.maven.plugins.annotations.Parameter;
import org.nuiton.i18n.plugin.AbstractI18nMojo;
import org.nuiton.io.FileUpdater;
import org.nuiton.io.SortedProperties;
import org.nuiton.plugin.PluginHelper;

import java.io.File;
import java.io.IOException;
import java.util.List;
import java.util.regex.Pattern;

/**
 * Abstract implementation for parsing goal.
 *
 * @author tchemit 
 */
public abstract class AbstractI18nParserMojo extends AbstractI18nMojo implements I18nParserConfiguration {

    /** @return the outGetter to use for the instance (java.getter,...) */
    protected abstract String getOutGetter();

    /** @return the default includes to add to directory scanner */
    protected abstract String[] getDefaultIncludes();

    /** @return the default excludes to add to directory scanner */
    protected abstract String[] getDefaultExcludes();

    /** @return the default src directory to use in directory scanner */
    protected abstract File getDefaultBasedir();

    /**
     * @param acceptPattern optional pattern to accept incoming keys
     * @return a new file parser to be used in the parser consumer parserExecutor
     * @since 1.2
     */
    public abstract FileParser newFileParser(Pattern acceptPattern);

    /**
     * @param entry the incoming source entry to attach to the file updater
     * @return a new file updater to detects files to treate
     */
    public abstract FileUpdater newFileUpdater(SourceEntry entry);

    /** Build directory (used to know if files in sources are up-to-date). */
    @Parameter(property = "i18n.cp", defaultValue = "${basedir}/target/classes")
    protected File cp;

    /** To treat default entry offered by the mojo. */
    @Parameter(property = "i18n.treateDefaultEntry", defaultValue = "true")
    protected boolean treateDefaultEntry;

    /** Source entries (src+includes+excludes) to process. */
    @Parameter(property = "i18n.entries")
    protected I18nSourceEntry[] entries;

    /**
     * Flag to display touched files while parsing.
     * 

* Note: the value will be always {@code true} if {@link #verbose} is * set at {@code true}. * * @since 0.9 */ @Parameter(property = "i18n.showTouchedFiles", defaultValue = "${maven.verbose}") protected boolean showTouchedFiles; /** * Flag to save previous getter in a backup before doing parsing. *

* Note: by default, do not perform backup (but it was here originaly so let * it possible...) * * @since 1.0.2 */ @Parameter(property = "i18n.backupGetter", defaultValue = "false") protected boolean backupGetter; /** * To force reparse of all sources. * * @since 1.2 */ @Parameter(property = "i18n.force", defaultValue = "false") protected boolean force; /** * A regex pattern to accept incoming keys. * * Only incoming keys which match the pattern will be kept. * * @since 2.5 */ @Parameter(property = "i18n.acceptKeyFormat") protected String acceptKeyFormat; protected Pattern acceptPattern; private SortedProperties result; protected SortedProperties oldParser; protected SortedProperties oldLanguage; protected long t0; ParserExecutor parserExecutor; @Override public boolean isStrictMode() { return strictMode; } public boolean isForce() { return force; } @Override public void init() throws Exception { super.init(); t0 = System.nanoTime(); result = new SortedProperties(encoding); oldParser = new SortedProperties(encoding); oldLanguage = new SortedProperties(encoding); createDirectoryIfNecessary(out); // // evenements // if (keysModifier) { // addParserEvent(KeysModifier.getInstance( // getKeyModifierStart(), getKeyModifierEnd(), encoding)); // } // check there is something to treate if ((entries == null || entries.length == 0) && !treateDefaultEntry) { // nothing to do throw new IllegalStateException( "No entry defined and treateDefaultEntry is false, " + "will skip the goal."); } if (verbose && entries != null && entries.length > 0) { if (getLog().isInfoEnabled()) { getLog().info("detected entries : " + entries.length); for (SourceEntry e : entries) { getLog().info(e.toString() + ", specific goal ? " + e.getSpecificGoal()); } } } if (acceptKeyFormat != null) { acceptPattern = Pattern.compile(acceptKeyFormat); } parserExecutor = new ParserExecutor(this); } protected boolean onEnterEntry(I18nSourceEntry entry) { boolean skip = entry.init(this); return skip; } @Override protected void doAction() throws Exception { if (!silent && strictMode) { getLog().info("config - strictMode is on (all files will be" + " parsed)."); } if (!silent && force) { getLog().info("config - force is on (all files will be" + " parsed)."); } // Reprise sur un ancien parsing File oldParserFile = getGetterFile(out, getOutGetter(), true); File saveFile = getBackupFile(oldParserFile); oldParser.load(oldParserFile); if (backupGetter) { backupFile(oldParserFile); } // 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); oldLanguage.load(oldLanguageFile); // Parsing if (treateDefaultEntry) { addDefaultEntry(); } for (I18nSourceEntry entry : entries) { boolean skip = onEnterEntry(entry); if (skip) { if (!silent && verbose) { getLog().info("skip [" + entry + "] - " + entry.getSkipMessage()); } continue; } // launch parser for found files String[] files = entry.getFiles(); if (!silent) { getLog().info("start entry " + entry.toString()); getLog().info(files.length + " file(s) to process (among " + entry.getFoudFiles() + " files)"); } for (String file1 : files) { String fileName = entry.getBasedir().getAbsolutePath() + File.separator + file1; File file = new File(fileName); parserExecutor.addFile(newFileParser(acceptPattern), file); } } if (getLog().isDebugEnabled()) { getLog().debug("ask to terminate " + parserExecutor); } // all files are send to parserExecutor, we ask termination of parserExecutor. // this termination treat all sending file before really stop parserExecutor.terminatesAndWaits(); List treadedFiles = parserExecutor.getTreatedFiles(); List touchedFiles = parserExecutor.getTouchedFiles(); // Suppression du fichier sauvegarder if (!backupGetter) { deleteFile(saveFile); } if (treadedFiles.isEmpty()) { if (!silent) { getLog().info("Nothing was parsed - all files are up to date."); } } else { if (showTouchedFiles) { for (File f : touchedFiles) { getLog().info("touch " + f); } } if (!silent) { int i = touchedFiles.size(); int max = treadedFiles.size(); getLog().info(getLogEntry( "Parsing is done. [treated file(s) : " + i + '/' + max + "]", max, 0, t0)); } // save getter saveGetterFile(); // add getter addGetter(); } parserExecutor.clear(); } @Override public boolean isShowTouchedFiles() { return showTouchedFiles; } @Override public SortedProperties getResult() { return result; } /** * Add the default entry to entries given in configuration. *

* This is a convinient method to simplify the configuration of the plugin. */ protected void addDefaultEntry() { if (verbose) { getLog().info("add default entry"); } boolean hasEntries = entries != null && entries.length > 0; I18nSourceEntry[] tmp = new I18nSourceEntry[hasEntries ? entries.length + 1 : 1]; if (hasEntries) { System.arraycopy(entries, 0, tmp, 0, entries.length); } tmp[tmp.length - 1] = new I18nSourceEntry(); entries = tmp; } /** * Save the result in the getter file. * * @throws IOException if any io pb */ protected void saveGetterFile() throws IOException { File getterFile = getGetterFile(out, getOutGetter(), false); result.store(getterFile); } /** * Construit une chaine de log formatée. * * @param msg le prefix du message * @param nbFiles le nombre de fichiers actuellement traités * @param time le time de traitement de ce fichier * @param all le temps de traitement de tous les fichiers * @return la chaine de log formatée */ public static String getLogEntry(String msg, int nbFiles, long time, long all) { long now = System.nanoTime(); long delta = now - time; String s = msg; if (time > 0 && all == 0) { s += " (" + PluginHelper.convertTime(delta) + ")"; } if (all > 0) { s += "(total time:" + PluginHelper.convertTime(now - all) + ")"; } if (nbFiles > 0) { s += " ( ~ " + PluginHelper.convertTime((now - all) / nbFiles) + " / file)"; } return s; } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy