be.hikage.maven.plugin.xmlmerge.MergeXmlMojo.java Source code

Java tutorial

Introduction

Here is the source code for be.hikage.maven.plugin.xmlmerge.MergeXmlMojo.java

Source

/*
 * Copyright  2011  The original author or authors
 *
 * 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.
 */

package be.hikage.maven.plugin.xmlmerge;

import be.hikage.maven.plugin.xmlmerge.utils.Dom4JUtils;
import be.hikage.maven.plugin.xmlmerge.utils.PathUtils;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.filefilter.DirectoryFileFilter;
import org.apache.commons.io.filefilter.RegexFileFilter;
import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugin.MojoExecutionException;
import org.codehaus.plexus.util.StringUtils;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.SAXReader;
import org.dom4j.io.XMLWriter;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * Goal which merge XML file
 *
 * @goal mergexml
 * @phase prepare-package
 */
public class MergeXmlMojo extends AbstractMojo {

    /**
     * The input directory in which the XML Merge Data can be found.
     *
     * @parameter default-value="${basedir}/src/main/xmlmerge"
     * @required
     */
    private File inputDirectory;

    /**
     * The input directory in which the XML Document base can be found.
     *
     * @parameter default-value="${project.build.outputDirectory}"
     * @required
     */
    private File baseDirectory;

    /**
     * The output directory into which to copy the resources.
     *
     * @parameter default-value="${project.build.outputDirectory}"
     * @required
     */
    private File outputDirectory;

    /**
     * Flag to indicate if the Merge Document must be deleted after processing
     *
     * @parameter default-value="false"
     * @required
     */
    private Boolean removeMergeDocumentAfterProcessing;

    /**
     * The Xml Merge component instance that will be injected
     * by the Plexus runtime.
     *
     * @component
     */
    private XmlMerger xmlMerger;

    /**
     * Flag to indicate that the text contained in prolog must be filtered before applying
     *
     * @parameter default-value="false"
     * @required
     */
    private Boolean processProlog;

    /**
     * The mergeFilenamePattern used to find XML Document to merge.
     * It have to return two groups, including the second is the name of the file in which it must be merged.
     * The default pattern assume that the XML Document to be merged has the same name as the base XML Document
     *
     * @parameter default-value="()(.*\[xX][mM][lL])"
     * @required
     */
    private String mergeFilenamePattern;

    public void execute() throws MojoExecutionException {
        getLog().info("EXECUTE on " + outputDirectory.getAbsolutePath());
        getLog().info("Process prolog : " + processProlog);

        List<File> xmlFiles = new ArrayList<File>();

        Pattern regex = Pattern.compile(mergeFilenamePattern);

        getLog().info("Search file that match " + mergeFilenamePattern);
        findXmlToMerge(inputDirectory, xmlFiles);

        getLog().info("Number of file found to merge :" + xmlFiles.size());

        try {
            for (File fileToMerge : xmlFiles) {
                Matcher matcher = regex.matcher(fileToMerge.getName());
                if (matcher.matches() && matcher.groupCount() == 2) {

                    String baseFileName = matcher.group(2);

                    File basefile = getBaseFile(fileToMerge, baseFileName);
                    File outputFile = getOutputFile(fileToMerge, baseFileName);

                    getLog().debug("Merge Base :" + basefile.getAbsolutePath());
                    getLog().debug("Merge Transform :" + fileToMerge.getAbsolutePath());
                    getLog().debug("Merge Output :" + outputFile.getAbsolutePath());

                    if (basefile.exists()) {

                        StringBuilder prologHeader = processProlog ? new StringBuilder() : null;
                        Document documentBase = Dom4JUtils.readDocument(basefile.toURI().toURL(), prologHeader);
                        Document result = xmlMerger.mergeXml(documentBase, loadXml(fileToMerge));

                        writeMergedXml(outputFile, result, prologHeader);

                        if (removeMergeDocumentAfterProcessing) {
                            boolean fileDeleted = fileToMerge.delete();
                            if (!fileDeleted)
                                getLog().warn("Unable to delete file :" + fileToMerge.getAbsolutePath());
                        }

                    } else {
                        getLog().warn("No filebase found for " + fileToMerge.getAbsolutePath());
                    }

                } else {
                    throw new MojoExecutionException("The file do not matches regex");

                }
            }
        } catch (Exception e) {
            throw new MojoExecutionException("Unable to merge xml", e);
        }

    }

    private File getBaseFile(File fileToMerge, String baseFileName) {

        String relativePath = PathUtils.getRelativePath(fileToMerge, inputDirectory).replace(fileToMerge.getName(),
                "");
        File baseFile = new File(baseDirectory, relativePath + baseFileName);

        return baseFile;
    }

    private File getOutputFile(File fileToMerge, String baseFileName) {

        String relativePath = PathUtils.getRelativePath(fileToMerge, inputDirectory).replace(fileToMerge.getName(),
                "");
        File outputFile = new File(outputDirectory, relativePath + baseFileName);
        return outputFile;
    }

    protected void findXmlToMerge(File fileToProcess, List<File> xmlFiles) {

        RegexFileFilter filter2 = new RegexFileFilter(mergeFilenamePattern);

        Collection<File> filesFound = FileUtils.listFiles(fileToProcess, filter2, DirectoryFileFilter.DIRECTORY);

        xmlFiles.addAll(filesFound);

    }

    private Document loadXml(File baseFile) throws DocumentException {
        SAXReader reader = new SAXReader();
        return reader.read(baseFile);
    }

    private void deleteMergeFile(File fileToMerge) {
        fileToMerge.delete();

    }

    private void writeMergedXml(File baseFile, Document base, StringBuilder prologHeader) throws IOException {
        FileOutputStream fos = new FileOutputStream(baseFile);

        if (processProlog && prologHeader != null && StringUtils.isNotEmpty(prologHeader.toString())) {
            fos.write(prologHeader.toString().getBytes());
        }

        OutputFormat format = OutputFormat.createPrettyPrint();
        format.setSuppressDeclaration(true);
        format.setNewLineAfterDeclaration(false);
        XMLWriter writer = new XMLWriter(fos, format);
        writer.write(base);
        writer.flush();
        writer.close();

    }
}