io.wcm.maven.plugins.i18n.TransformMojo.java Source code

Java tutorial

Introduction

Here is the source code for io.wcm.maven.plugins.i18n.TransformMojo.java

Source

/*
 * #%L
 * wcm.io
 * %%
 * Copyright (C) 2014 wcm.io
 * %%
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 * #L%
 */
package io.wcm.maven.plugins.i18n;

import io.wcm.maven.plugins.i18n.readers.I18nReader;
import io.wcm.maven.plugins.i18n.readers.JsonI18nReader;
import io.wcm.maven.plugins.i18n.readers.PropertiesI18nReader;
import io.wcm.maven.plugins.i18n.readers.XmlI18nReader;

import java.io.File;
import java.io.IOException;
import java.util.Collections;
import java.util.List;

import org.apache.commons.lang3.CharEncoding;
import org.apache.commons.lang3.StringUtils;
import org.apache.maven.model.Build;
import org.apache.maven.model.Resource;
import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugin.MojoFailureException;
import org.apache.maven.plugins.annotations.LifecyclePhase;
import org.apache.maven.plugins.annotations.Mojo;
import org.apache.maven.plugins.annotations.Parameter;
import org.apache.maven.project.MavenProject;
import org.apache.sling.commons.json.JSONException;
import org.codehaus.plexus.util.FileUtils;

/**
 * Transform i18n resources in Java Properties, JSON or XML file format to Sling i18n Messages JSON or XML format.
 */
@Mojo(name = "transform", defaultPhase = LifecyclePhase.GENERATE_RESOURCES, requiresProject = true, threadSafe = true)
public class TransformMojo extends AbstractMojo {

    // file extensions
    private static final String FILE_EXTENSION_JSON = "json";
    private static final String FILE_EXTENSION_XML = "xml";
    private static final String FILE_EXTENSION_PROPERTIES = "properties";

    /**
     * Source path containing the i18n source .properties or .xml files.
     */
    @Parameter(defaultValue = "${basedir}/src/main/resources/i18n")
    private String source;

    /**
     * Relative target path for the generated resources.
     */
    @Parameter(defaultValue = "SLING-INF/app-root/i18n")
    private String target;

    /**
     * Output format for i18n: "json" or "xml"
     */
    @Parameter(defaultValue = "json")
    private String outputFormat;

    @Parameter(defaultValue = "generated-i18n-resources")
    private String generatedResourcesFolderPath;

    @Parameter(property = "project", required = true, readonly = true)
    private MavenProject project;

    private File generatedResourcesFolder;
    private List<File> i18nSourceFiles;

    @Override
    public void execute() throws MojoExecutionException, MojoFailureException {
        OutputFormat selectedOutputFormat = OutputFormat.valueOf(StringUtils.upperCase(outputFormat));
        try {
            intialize();

            List<File> sourceFiles = getI18nSourceFiles();

            for (File file : sourceFiles) {
                try {
                    // transform i18n files
                    String languageKey = FileUtils.removeExtension(file.getName());
                    I18nReader reader = getI18nReader(file);
                    SlingI18nMap i18nMap = new SlingI18nMap(languageKey, reader.read(file));

                    // write mappings to target file
                    File targetFile = getTargetFile(file, selectedOutputFormat);
                    writeTargetI18nFile(i18nMap, targetFile, selectedOutputFormat);

                    getLog().info("Transformed " + file.getPath() + " to  " + targetFile.getPath());
                } catch (IOException | JSONException ex) {
                    throw new MojoFailureException("Unable to transform i18n resource: " + file.getPath(), ex);
                }
            }
        } catch (IOException ex) {
            throw new MojoFailureException("Failure to transform i18n resources", ex);
        }
    }

    /**
     * Initialize parameters, which cannot get defaults from annotations. Currently only the root nodes.
     * @throws IOException
     */
    private void intialize() throws IOException {
        getLog().debug("Initializing i18n plugin...");

        // resource
        if (!getI18nSourceFiles().isEmpty()) {
            File myGeneratedResourcesFolder = getGeneratedResourcesFolder();
            addResource(myGeneratedResourcesFolder.getPath(), target);
        }

    }

    private void addResource(String sourceDirectory, String targetPath) {

        // construct resource
        Resource resource = new Resource();
        resource.setDirectory(sourceDirectory);
        resource.setTargetPath(targetPath);

        // add to build
        Build build = this.project.getBuild();
        build.addResource(resource);
        getLog().debug("Added resource: " + resource.getDirectory() + " -> " + resource.getTargetPath());
    }

    /**
     * Fetches i18n source files from source directory.
     * @return a list of XML files
     * @throws IOException
     */
    @SuppressWarnings("unchecked")
    private List<File> getI18nSourceFiles() throws IOException {

        if (i18nSourceFiles == null) {
            File sourceDirectory = getSourceDirectory();

            if (!sourceDirectory.isDirectory()) {
                i18nSourceFiles = Collections.emptyList();
            } else {
                // get list of xml files
                String includes = "**/*." + FILE_EXTENSION_PROPERTIES + "," + "**/*." + FILE_EXTENSION_XML + ","
                        + "**/*." + FILE_EXTENSION_JSON;
                String excludes = FileUtils.getDefaultExcludesAsString();

                i18nSourceFiles = FileUtils.getFiles(sourceDirectory, includes, excludes);
            }
        }

        return i18nSourceFiles;
    }

    /**
     * Get directory containing source i18n files.
     * @return directory containing source i18n files.
     * @throws IOException
     */
    private File getSourceDirectory() throws IOException {
        File file = new File(source);
        if (!file.isDirectory()) {
            getLog().debug("Could not find directory at '" + source + "'");
        }
        return file.getCanonicalFile();
    }

    /**
     * Writes mappings to file in Sling compatible JSON format.
     * @param i18nMap mappings
     * @param targetfile target file
     * @param selectedOutputFormat Output format
     * @throws IOException
     * @throws JSONException
     */
    private void writeTargetI18nFile(SlingI18nMap i18nMap, File targetfile, OutputFormat selectedOutputFormat)
            throws IOException, JSONException {
        if (selectedOutputFormat == OutputFormat.XML) {
            FileUtils.fileWrite(targetfile, CharEncoding.UTF_8, i18nMap.getI18nXmlString());
        } else {
            FileUtils.fileWrite(targetfile, CharEncoding.UTF_8, i18nMap.getI18nJsonString());
        }
    }

    /**
     * Get the JSON file for source file.
     * @param sourceFile the source file
     * @param selectedOutputFormat Output format
     * @return File with name and path based on file parameter
     * @throws IOException
     */
    private File getTargetFile(File sourceFile, OutputFormat selectedOutputFormat) throws IOException {

        File sourceDirectory = getSourceDirectory();
        String relativePath = StringUtils.substringAfter(sourceFile.getAbsolutePath(),
                sourceDirectory.getAbsolutePath());
        String relativeTargetPath = FileUtils.removeExtension(relativePath) + "."
                + selectedOutputFormat.getFileExtension();

        File jsonFile = new File(getGeneratedResourcesFolder().getPath() + relativeTargetPath);

        jsonFile = jsonFile.getCanonicalFile();

        File parentDirectory = jsonFile.getParentFile();
        if (!parentDirectory.exists()) {
            parentDirectory.mkdirs();
        }

        return jsonFile;
    }

    private File getGeneratedResourcesFolder() {
        if (generatedResourcesFolder == null) {
            String generatedResourcesFolderAbsolutePath = this.project.getBuild().getDirectory() + "/"
                    + generatedResourcesFolderPath;
            generatedResourcesFolder = new File(generatedResourcesFolderAbsolutePath);
            if (!generatedResourcesFolder.exists()) {
                generatedResourcesFolder.mkdirs();
            }
        }
        return generatedResourcesFolder;
    }

    /**
     * Get i18n reader for source file.
     * @param sourceFile Source file
     * @return I18n reader
     * @throws MojoFailureException
     */
    private I18nReader getI18nReader(File sourceFile) throws MojoFailureException {
        String extension = FileUtils.getExtension(sourceFile.getName());
        if (StringUtils.equalsIgnoreCase(extension, FILE_EXTENSION_PROPERTIES)) {
            return new PropertiesI18nReader();
        }
        if (StringUtils.equalsIgnoreCase(extension, FILE_EXTENSION_XML)) {
            return new XmlI18nReader();
        }
        if (StringUtils.equalsIgnoreCase(extension, FILE_EXTENSION_JSON)) {
            return new JsonI18nReader();
        }
        throw new MojoFailureException(
                "Unsupported file extension '" + extension + "': " + sourceFile.getAbsolutePath());
    }

}