org.jboss.maven.shared.resource.ResourceDelegate.java Source code

Java tutorial

Introduction

Here is the source code for org.jboss.maven.shared.resource.ResourceDelegate.java

Source

/*
 * jDocBook, processing of DocBook sources as a Maven plugin
 *
 * Copyright (c) 2009, Red Hat Middleware LLC or third-party contributors as
 * indicated by the @author tags or express copyright attribution
 * statements applied by the authors.  All third-party contributions are
 * distributed under license by Red Hat Middleware LLC.
 *
 * This copyrighted material is made available to anyone wishing to use, modify,
 * copy, or redistribute it subject to the terms and conditions of the GNU
 * Lesser General Public License, as published by the Free Software Foundation.
 *
 * 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 Lesser General Public License
 * for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with this distribution; if not, write to:
 * Free Software Foundation, Inc.
 * 51 Franklin Street, Fifth Floor
 * Boston, MA  02110-1301  USA
 */

package org.jboss.maven.shared.resource;

import java.io.File;
import java.io.IOException;
import java.io.Reader;
import java.io.Writer;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.util.List;
import java.util.Map;

import org.apache.maven.model.Resource;
import org.apache.maven.plugin.logging.Log;
import org.apache.maven.project.MavenProject;
import org.jboss.maven.shared.properties.CompositeMavenProjectProperties;
import org.codehaus.plexus.util.DirectoryScanner;
import org.codehaus.plexus.util.IOUtil;
import org.codehaus.plexus.util.FileUtils;
import org.codehaus.plexus.util.InterpolationFilterReader;

/**
 * A delegate for handling {@link Resource} resolution.
 *
 * @author Steve Ebersole
 */
public class ResourceDelegate {
    public static final String[] DEFAULT_DEFAULT_INCLUDES = new String[] { "**/**" };

    private final File basedir;
    private final File baseTargetDirectory;
    private final String[] defaultIncludes;
    private final String[] defaultExcludes;
    private final Log log;

    private final Map filterProperties;

    /**
     * Constructs a Delegate instance for handling Resource resolution.
     *
     * @param project The project currently being built.
     * @param baseTargetDirectory The base target directory to which we should copy resources.
     * @param log The log instance to use for logging.
     */
    public ResourceDelegate(MavenProject project, File baseTargetDirectory, Log log) {
        this(project, baseTargetDirectory, DEFAULT_DEFAULT_INCLUDES, null, log);
    }

    /**
     * Constructs a Delegate instance for handling Resource resolution.
     *
     * @param project The project currently being built.
     * @param baseTargetDirectory The base target directory to which we should copy resources.
     * @param defaultIncludes default patterns for resource copying inclusion.
     * @param defaultExcludes default patterns for resource copying exclusion.
     * @param log The log instance to use for logging.
     */
    public ResourceDelegate(MavenProject project, File baseTargetDirectory, String[] defaultIncludes,
            String[] defaultExcludes, Log log) {
        this.basedir = project.getBasedir();
        this.baseTargetDirectory = baseTargetDirectory;
        this.defaultIncludes = defaultIncludes;
        this.defaultExcludes = defaultExcludes;
        this.log = log;
        this.filterProperties = new CompositeMavenProjectProperties(project);
    }

    public void process(Resource[] resources) throws ResourceException {
        for (Resource resource : resources) {
            process(resource);
        }
    }

    public void process(Resource resource) throws ResourceException {
        getLog().debug("starting resource processing for : " + resource.getDirectory());
        String[] fileNames = collectFileNames(resource);
        if (fileNames == null) {
            getLog().debug("no matching files found");
            return;
        }

        File destination = resource.getTargetPath() == null ? baseTargetDirectory
                : new File(baseTargetDirectory, resource.getTargetPath());
        if (!destination.exists()) {
            destination.mkdirs();
        }

        for (String fileName : fileNames) {
            if (resource.isFiltering()) {
                copyFilteredFile(new File(resource.getDirectory(), fileName), new File(destination, fileName), null,
                        getFilterWrappers(), filterProperties);
            } else {
                copyFileIfModified(new File(resource.getDirectory(), fileName), new File(destination, fileName));
            }
        }
    }

    /**
     * Given a resource, determine the matching file names which should be
     * processed.
     *
     * @param resource The resource model.
     * @return The collected matching file names.
     */
    private String[] collectFileNames(Resource resource) {
        File resourceDirectory = new File(resource.getDirectory());
        if (!resourceDirectory.exists() && !resource.getDirectory().startsWith("/")) {
            resourceDirectory = new File(basedir, resource.getDirectory());
            if (!resourceDirectory.exists()) {
                resourceDirectory = null;
            }
        }
        if (resourceDirectory == null) {
            throw new ResourceException("could not locate specified resource directory");
        }

        DirectoryScanner scanner = new DirectoryScanner();
        scanner.setBasedir(resource.getDirectory());
        scanner.setIncludes(determineIncludes(resource));
        scanner.setExcludes(determineExcludes(resource));
        scanner.addDefaultExcludes();
        scanner.scan();
        return scanner.getIncludedFiles();
    }

    @SuppressWarnings("unchecked")
    private String[] determineIncludes(Resource resource) {
        return toStringArray(resource.getIncludes(), defaultIncludes);
    }

    @SuppressWarnings("unchecked")
    private String[] determineExcludes(Resource resource) {
        return toStringArray(resource.getExcludes(), defaultExcludes);
    }

    private interface FilterWrapper {
        Reader getReader(Reader fileReader, Map filterProperties);
    }

    private FilterWrapper[] getFilterWrappers() {
        return new FilterWrapper[] {
                // support ${token}
                new FilterWrapper() {
                    public Reader getReader(Reader fileReader, Map filterProperties) {
                        return new InterpolationFilterReader(fileReader, filterProperties, "${", "}");
                    }
                },
                // support @token@
                new FilterWrapper() {
                    public Reader getReader(Reader fileReader, Map filterProperties) {
                        return new InterpolationFilterReader(fileReader, filterProperties, "@", "@");
                    }
                } };
    }

    private static void copyFilteredFile(File from, File to, String encoding, FilterWrapper[] wrappers,
            Map filterProperties) throws ResourceException {
        // buffer so it isn't reading a byte at a time!
        Reader fileReader = null;
        Writer fileWriter = null;
        try {
            // fix for MWAR-36, ensures that the parent dir are created first
            to.getParentFile().mkdirs();

            if (encoding == null || encoding.length() < 1) {
                fileReader = new BufferedReader(new FileReader(from));
                fileWriter = new FileWriter(to);
            } else {
                FileInputStream instream = new FileInputStream(from);
                FileOutputStream outstream = new FileOutputStream(to);
                fileReader = new BufferedReader(new InputStreamReader(instream, encoding));
                fileWriter = new OutputStreamWriter(outstream, encoding);
            }

            Reader reader = fileReader;
            for (FilterWrapper wrapper : wrappers) {
                reader = wrapper.getReader(reader, filterProperties);
            }

            IOUtil.copy(reader, fileWriter);
        } catch (IOException e) {
            throw new ResourceException(e.getMessage(), e);
        } finally {
            IOUtil.close(fileReader);
            IOUtil.close(fileWriter);
        }
    }

    private static void copyFileIfModified(File source, File destination) throws ResourceException {
        if (destination.lastModified() < source.lastModified()) {
            try {
                FileUtils.copyFile(source.getCanonicalFile(), destination);
                destination.setLastModified(source.lastModified());
            } catch (IOException e) {
                throw new ResourceException(e.getMessage(), e);
            }
        }
    }

    private Log getLog() {
        return log;
    }

    private static String[] toStringArray(List<String> list, String[] defaultArray) {
        if (list == null || list.isEmpty()) {
            return defaultArray;
        } else {
            return list.toArray(new String[list.size()]);
        }
    }
}