package org.codehaus.mojo.unix.core; /* * The MIT License * * Copyright 2009 The Codehaus. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies * of the Software, and to permit persons to whom the Software is furnished to do * so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ import fj.Effect; import fj.F2; import fj.pre.*; import fj.data.*; import static fj.data.Option.*; import org.codehaus.mojo.unix.*; import static org.codehaus.mojo.unix.FileAttributes.*; import org.codehaus.mojo.unix.util.*; import org.codehaus.mojo.unix.util.line.*; import static org.codehaus.mojo.unix.util.line.LineStreamUtil.*; import static org.codehaus.mojo.unix.util.Validate.*; import org.codehaus.mojo.unix.util.vfs.*; import java.io.*; import java.util.List; /** * @author <a href="mailto:trygvis@codehaus.org">Trygve Laugstøl</a> * @version $Id$ */ public class SetAttributesOperation extends AssemblyOperation { private final IncludeExcludeFileSelector selector; public final Option<F2<UnixFsObject, FileAttributes, FileAttributes>> applyFileAttributes; public final Option<F2<UnixFsObject, FileAttributes, FileAttributes>> applyDirectoryAttributes; private final RelativePath basedir; private final List<String> includes; private final List<String> excludes; private final Option<FileAttributes> fileAttributes; private final Option<FileAttributes> directoryAttributes; public SetAttributesOperation( RelativePath basedir, List<String> includes, List<String> excludes, Option<FileAttributes> fileAttributes, Option<FileAttributes> directoryAttributes ) { validateNotNull( basedir, includes, excludes, fileAttributes, directoryAttributes ); this.basedir = basedir; this.includes = includes; this.excludes = excludes; this.fileAttributes = fileAttributes; this.directoryAttributes = directoryAttributes; selector = IncludeExcludeFileSelector.build( null ). addStringIncludes( includes ). addStringExcludes( excludes ). create(); if ( fileAttributes.isSome() ) { F2<UnixFsObject, FileAttributes, FileAttributes> f = new ApplyAttributes( UnixFsObject.RegularFile.class, basedir, fileAttributes.some() ); applyFileAttributes = some( f ); } else { applyFileAttributes = none(); } if ( directoryAttributes.isSome() ) { F2<UnixFsObject, FileAttributes, FileAttributes> f = new ApplyAttributes( UnixFsObject.Directory.class, basedir, directoryAttributes.some() ); applyDirectoryAttributes = some( f ); } else { applyDirectoryAttributes = none(); } } public void perform( final FileCollector fileCollector ) throws IOException { Effect<F2<UnixFsObject, FileAttributes, FileAttributes>> effect = new Effect<F2<UnixFsObject, FileAttributes, FileAttributes>>() { public void e( F2<UnixFsObject, FileAttributes, FileAttributes> applyAttributes ) { fileCollector.apply( applyAttributes ); } }; applyFileAttributes.foreach( effect ); applyDirectoryAttributes.foreach( effect ); } public void streamTo( LineStreamWriter streamWriter ) { streamWriter.add( "Set attributes:" ). add( " Basedir: " + basedir ); if ( !includes.isEmpty() ) { streamWriter.add( " Includes: "). addAllLines( prefix( includes, " " ) ); } else { streamWriter.add( " No includes set" ); } if ( !excludes.isEmpty() ) { streamWriter.add( " Excludes: " ). addAllLines( prefix( excludes, " " ) ); } else { streamWriter.add( " No excludes set" ); } streamWriter.add( " Attributes: "). add( " File : " + fileAttributes.map( singleLineShow.showS_() ).orSome( "None" ) ). add( " Directory: " + directoryAttributes.map( singleLineShow.showS_() ).orSome( "None" ) ); } private final class ApplyAttributes implements F2<UnixFsObject, FileAttributes, FileAttributes> { private final Class<? extends UnixFsObject> klass; private final RelativePath basedir; private final FileAttributes attributes; private ApplyAttributes( Class<? extends UnixFsObject> klass, RelativePath basedir, FileAttributes attributes ) { this.klass = klass; this.basedir = basedir; this.attributes = attributes; } public FileAttributes f( UnixFsObject fsObject, FileAttributes currentAttributes ) { if ( !klass.isAssignableFrom( fsObject.getClass() ) ) { return currentAttributes; } // Remove the basedir part of the path before matching String massagedPath; if ( basedir == RelativePath.BASE ) { massagedPath = fsObject.path.string; } else { Option<RelativePath> option = fsObject.path.subtract( basedir ); if ( option.isNone() ) { return currentAttributes; } massagedPath = option.some().string; } if ( !selector.matches( massagedPath ) ) { return currentAttributes; } // Use 'currentAttributes' as a default, which means that any attribute that is set in 'attributes' // will override any currently set attribute return currentAttributes.useAsDefaultsFor( attributes ); } } }