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

org.nuiton.i18n.plugin.parser.impl.AbstractParserXmlMojo Maven / Gradle / Ivy

Go to download

Maven plugin to deal with i18n stuff in a project, mainly base on the nuiton-i18n api (but not only).

The newest version!
/*
 * #%L
 * I18n :: Maven Plugin
 * 
 * $Id$
 * $HeadURL$
 * %%
 * 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.impl;

import org.apache.commons.lang3.StringUtils;
import org.apache.maven.plugin.MojoFailureException;
import org.apache.maven.plugin.logging.Log;
import org.apache.maven.plugins.annotations.Parameter;
import org.nuiton.i18n.plugin.parser.AbstractFileParser;
import org.nuiton.i18n.plugin.parser.AbstractI18nParserMojo;
import org.nuiton.i18n.plugin.parser.FileParser;
import org.nuiton.i18n.plugin.parser.ParserException;
import org.nuiton.io.SortedProperties;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

import javax.xml.namespace.NamespaceContext;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpression;
import javax.xml.xpath.XPathFactory;
import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
import java.util.regex.Pattern;

/**
 * Abstract xml parser mojo.
 *
 * @author Tony Chemit - [email protected]
 * @author Julien Ruchaud - [email protected]
 * @since 2.0
 */
public abstract class AbstractParserXmlMojo extends AbstractI18nParserMojo {

    /** Taille du buffer pour les lectures/écritures */
    protected static final int BUFFER_SIZE = 8 * 1024;

    /** available rules to detect i18n keys in xml files. */
    protected String rules;

    /** XPath factory used to detect i18n keys in xml files. */
    protected XPathFactory factory;

    /** Document builder factory to load xml files. */
    protected DocumentBuilderFactory documentBuilderFactory;

    /**
     * Extra rules files to use for detecting i18n keys in xml validation files.
     *
     * Note :  If the {@code coreRulesFile} is not defined, then you must
     * fill this parameter.
     *
     * @since 2.0
     */
    @Parameter
    protected String[] userRulesFiles;

    /**
     * Defines namespaces mapping if needed.
     *
     * Example :
     * 
     * <namespaces>
     * <s>http://java.sun.com/xml/ns/j2ee/web-jsptaglibrary_2_0.xsd</s>
     * </namespaces>
     * 
* * @since 2.0 */ @Parameter protected Map namespaces; protected abstract String getCoreRuleFile(); protected abstract XmlFileParser newXmlFileParser(XPath xpath, DocumentBuilder builder); /** * Obtain the list of files which define rules to apply. * * @return the list of path to rule files to used. */ protected List getRulefiles() { List result = new ArrayList(); // load optional core rule file String s = getCoreRuleFile(); if (!StringUtils.isEmpty(s)) { result.add(s); } // load user rile files String[] userFiles = getUserRuleFiles(); if (userFiles != null) { for (String f : userFiles) { if (!StringUtils.isEmpty(f)) { result.add(f); } } } return result; } @Override public void init() throws Exception { super.init(); factory = XPathFactory.newInstance(); List files = getRulefiles(); if (files.isEmpty()) { // no rules file defined throw new MojoFailureException("No rules files defined, fill the coreRulesFile or userRulesFiles parameters"); } rules = loadRules(files); documentBuilderFactory = DocumentBuilderFactory.newInstance(); documentBuilderFactory.setNamespaceAware(true); documentBuilderFactory.setValidating(false); documentBuilderFactory.setCoalescing(false); documentBuilderFactory.setIgnoringComments(true); } public final String[] getUserRuleFiles() { return userRulesFiles; } @Override public final FileParser newFileParser(Pattern acceptPattern) { DocumentBuilder builder; try { // never forget this! builder = documentBuilderFactory.newDocumentBuilder(); } catch (ParserConfigurationException ex) { throw new IllegalStateException( "could not load DocumentBuilder for reason " + ex.getMessage(), ex); } XPath xpath = factory.newXPath(); return newXmlFileParser(xpath, builder); } protected String loadRules(List files) { List rules = new ArrayList(); boolean verbose = !isSilent() && isVerbose(); for (String file : files) { getLog().info("Load rules file " + file); try { String fileRules = loadRulesFile(file); rules.add(fileRules); if (verbose) { getLog().info("Rules for file [" + file + "] : " + fileRules); } } catch (IOException e) { throw new ParserException(e); } } String result = StringUtils.join(rules, " | "); if (verbose) { getLog().info("Loaded rules : " + result); } return result; } protected String loadRulesFile(String fileRules) throws IOException { File f = new File(fileRules); InputStream inputStream; if (f.exists()) { // load from a file try { inputStream = new FileInputStream(f); } catch (FileNotFoundException e) { throw new ParserException(e); } } else { // load from classpath ClassLoader classLoader = getClass().getClassLoader(); inputStream = classLoader.getResourceAsStream(fileRules); } if (inputStream == null) { throw new ParserException( "could not found file of rules : " + fileRules); } inputStream = new BufferedInputStream(inputStream); try { // Lecture String readInputStream; readInputStream = readInputStream(inputStream); return readInputStream; } catch (IOException e) { throw new ParserException(e); } finally { inputStream.close(); } } /** * Permet la lecture d'un InputStream et Suppressions. * * @param in le flux entrant * @return le contenu du flux * @throws IOException si problème de lecture dans flux entrant */ private String readInputStream(InputStream in) throws IOException { StringBuilder sb = new StringBuilder(); BufferedReader reader = new BufferedReader( new InputStreamReader(in, encoding)); try { String line; while ((line = reader.readLine()) != null) { line = line.trim(); if (line.startsWith("#")) { // comment line continue; } sb.append(" ").append(line); } } finally { reader.close(); } // Suppression des espaces au début et à la fin String txt = sb.toString().trim(); // contruction du xpath avec des ou txt = txt.replaceAll("\\s+", " | "); // suppression des ou de début et de fin txt = txt.replaceAll("(^ \\| )|( \\| $)", ""); return txt; } public static abstract class XmlFileParser extends AbstractFileParser { private final XPath xpath; private final String rules; private final DocumentBuilder builder; private final Map namespaces; private final Map namespaces2; private final boolean verbose; /** * Fonction d'extraction de la chaine * * @param i18nString le clef i18n * @return la chaine */ public abstract String extract(String i18nString); public XmlFileParser(Log log, String encoding, SortedProperties oldParser, Pattern acceptKeyPattern, boolean showTouchedFiles, String rules, XPath xpath, DocumentBuilder builder, Map namespaces, boolean verbose) { super(log, encoding, oldParser, acceptKeyPattern, showTouchedFiles); this.xpath = xpath; this.rules = rules; this.builder = builder; this.verbose = verbose; if (namespaces != null && !namespaces.isEmpty()) { this.namespaces = namespaces; namespaces2 = new TreeMap(); for (Map.Entry e : namespaces.entrySet()) { namespaces2.put(e.getValue(), e.getKey()); } NamespaceContext ctx = new NamespaceContext() { public String getNamespaceURI(String prefix) { return XmlFileParser.this.namespaces.get(prefix); } @Override public String getPrefix(String namespaceURI) { return namespaces2.get(namespaceURI); } @Override public Iterator getPrefixes(String namespaceURI) { return null; } }; xpath.setNamespaceContext(ctx); } else { namespaces2 = null; this.namespaces = null; } } /** * To prepare the file (if any thing to be done before scanning it). * * @param file the incoming file * @return the real file to process * @throws IOException if any IO problem while preparing file * @since 2.0 */ @Override public File prepareFile(File file) throws IOException { // by default, do nothing return file; } @Override public void parseFile(File file) throws IOException { File fileToProcess = prepareFile(file); if (fileToProcess == null) { // this case means not to treate the file if (verbose) { getLog().info("Skip file " + file); } return; } try { // Recherche des clés à partir d'un xpath if (verbose) { getLog().info("Start parsing file " + fileToProcess); } Document doc = fileToDocument(fileToProcess); XPathExpression expression = xpath.compile(rules); NodeList list = (NodeList) expression.evaluate(doc, XPathConstants.NODESET); if (verbose) { getLog().info("Detected nodes [" + file + "] : " + list.getLength()); } for (int index = 0; index < list.getLength(); index++) { Node node = list.item(index); parseLine(fileToProcess, node.getTextContent()); } } catch (Exception e) { throw new ParserException(e); } } @Override public void parseLine(File file, String key) throws IOException { key = extract(key); if (key != null) { // setTouched(true); registerKey(key); } } protected Document fileToDocument(File fileToProcess) throws SAXException, IOException { return builder.parse(fileToProcess.getAbsolutePath()); } } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy