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

org.jboss.maven.shared.resource.ResourceDelegate Maven / Gradle / Ivy

There is a newer version: 2.3.10
Show newest version
/*
 * 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 list, String[] defaultArray) {
		if ( list == null || list.isEmpty() ) {
			return defaultArray;
		}
		else {
			return list.toArray( new String[ list.size() ] );
		}
	}
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy