View Javadoc
1   package org.apache.maven.plugin.assembly.archive.archiver;
2   
3   /*
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   *   http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing,
15   * software distributed under the License is distributed on an
16   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17   * KIND, either express or implied.  See the License for the
18   * specific language governing permissions and limitations
19   * under the License.
20   */
21  
22  import org.apache.maven.plugin.assembly.filter.ContainerDescriptorHandler;
23  import org.codehaus.plexus.archiver.ArchiveEntry;
24  import org.codehaus.plexus.archiver.ArchiveFinalizer;
25  import org.codehaus.plexus.archiver.ArchivedFileSet;
26  import org.codehaus.plexus.archiver.Archiver;
27  import org.codehaus.plexus.archiver.ArchiverException;
28  import org.codehaus.plexus.archiver.FileSet;
29  import org.codehaus.plexus.archiver.FinalizerEnabled;
30  import org.codehaus.plexus.archiver.ResourceIterator;
31  import org.codehaus.plexus.archiver.util.DefaultArchivedFileSet;
32  import org.codehaus.plexus.archiver.util.DefaultFileSet;
33  import org.codehaus.plexus.components.io.fileselectors.FileInfo;
34  import org.codehaus.plexus.components.io.fileselectors.FileSelector;
35  import org.codehaus.plexus.components.io.resources.PlexusIoResource;
36  import org.codehaus.plexus.components.io.resources.PlexusIoResourceCollection;
37  import org.codehaus.plexus.logging.Logger;
38  
39  import javax.annotation.Nonnull;
40  import java.io.File;
41  import java.io.FileInputStream;
42  import java.io.IOException;
43  import java.io.InputStream;
44  import java.util.ArrayList;
45  import java.util.Arrays;
46  import java.util.List;
47  import java.util.Map;
48  
49  /**
50   * Delegating archiver implementation that supports:
51   * <ul>
52   * <li>dry-running (where the delegate archiver is never actually called)</li>
53   * <li>prefixing (where all paths have a set global prefix prepended before addition)</li>
54   * <li>duplication checks on archive additions (for archive-file path + prefix)</li>
55   * </ul>
56   *
57   * @author jdcasey
58   * @version $Id: AssemblyProxyArchiver.java 1645047 2014-12-12 19:45:29Z krosenvold $
59   */
60  public class AssemblyProxyArchiver
61      implements Archiver
62  {
63  
64      private final Archiver delegate;
65  
66      private String rootPrefix;
67  
68      private FileSelector[] selectors;
69  
70      private final ThreadLocal<Boolean> inPublicApi = new ThreadLocal<Boolean>();
71  
72      private final Logger logger;
73  
74      private boolean forced;
75  
76  
77      private final String assemblyWorkPath;
78  
79      /**
80       * @since 2.2
81       */
82      private boolean useJvmChmod;
83  
84      public AssemblyProxyArchiver( final String rootPrefix, final Archiver delegate,
85                                    final List<ContainerDescriptorHandler> containerDescriptorHandlers,
86                                    final List<FileSelector> extraSelectors, final List<ArchiveFinalizer> extraFinalizers,
87                                    final File assemblyWorkDir, final Logger logger )
88      {
89          this.rootPrefix = rootPrefix;
90          this.delegate = delegate;
91  
92          assemblyWorkPath = assemblyWorkDir.getAbsolutePath().replace( '\\', '/' );
93  
94          this.logger = logger;
95  
96          if ( !"".equals( rootPrefix ) && !rootPrefix.endsWith( "/" ) )
97          {
98              this.rootPrefix += "/";
99          }
100 
101         final List<FileSelector> selectors = new ArrayList<FileSelector>();
102 
103         FinalizerEnabled finalizer = ( delegate instanceof FinalizerEnabled ) ? (FinalizerEnabled) delegate : null;
104 
105         if ( containerDescriptorHandlers != null )
106         {
107             for ( final ContainerDescriptorHandler handler : containerDescriptorHandlers )
108             {
109                 selectors.add( handler );
110 
111                 if ( finalizer != null )
112                 {
113                     finalizer.addArchiveFinalizer( handler );
114                 }
115             }
116         }
117 
118         if ( extraSelectors != null )
119         {
120             for ( final FileSelector selector : extraSelectors )
121             {
122                 selectors.add( selector );
123             }
124         }
125 
126         if ( ( extraFinalizers != null ) && finalizer != null )
127         {
128             for ( ArchiveFinalizer extraFinalizer : extraFinalizers )
129             {
130                 finalizer.addArchiveFinalizer( extraFinalizer );
131             }
132         }
133 
134         if ( !selectors.isEmpty() )
135         {
136             this.selectors = selectors.toArray( new FileSelector[selectors.size()] );
137         }
138     }
139 
140     /**
141      * {@inheritDoc}
142      */
143     public void addArchivedFileSet( @Nonnull final File archiveFile, final String prefix, final String[] includes,
144                                     final String[] excludes )
145     {
146         inPublicApi.set( Boolean.TRUE );
147         try
148         {
149             final DefaultArchivedFileSet fs = new DefaultArchivedFileSet();
150 
151             fs.setArchive( archiveFile );
152             fs.setIncludes( includes );
153             fs.setExcludes( excludes );
154             fs.setPrefix( rootPrefix + prefix );
155             fs.setFileSelectors( selectors );
156 
157             debug( "Adding archived file-set in: " + archiveFile + " to archive location: " + fs.getPrefix() );
158 
159             delegate.addArchivedFileSet( fs );
160         }
161         finally
162         {
163             inPublicApi.set( null );
164         }
165     }
166 
167     private void debug( final String message )
168     {
169         if ( ( logger != null ) && logger.isDebugEnabled() )
170         {
171             logger.debug( message );
172         }
173     }
174 
175     /**
176      * {@inheritDoc}
177      */
178     public void addArchivedFileSet( @Nonnull final File archiveFile, final String prefix )
179     {
180         inPublicApi.set( Boolean.TRUE );
181         try
182         {
183             final DefaultArchivedFileSet fs = new DefaultArchivedFileSet();
184 
185             fs.setArchive( archiveFile );
186             fs.setPrefix( rootPrefix + prefix );
187             fs.setFileSelectors( selectors );
188 
189             debug( "Adding archived file-set in: " + archiveFile + " to archive location: " + fs.getPrefix() );
190 
191             delegate.addArchivedFileSet( fs );
192         }
193         finally
194         {
195             inPublicApi.set( null );
196         }
197     }
198 
199     /**
200      * {@inheritDoc}
201      */
202     public void addArchivedFileSet( final File archiveFile, final String[] includes, final String[] excludes )
203     {
204         inPublicApi.set( Boolean.TRUE );
205         try
206         {
207             final DefaultArchivedFileSet fs = new DefaultArchivedFileSet();
208 
209             fs.setArchive( archiveFile );
210             fs.setIncludes( includes );
211             fs.setExcludes( excludes );
212             fs.setPrefix( rootPrefix );
213             fs.setFileSelectors( selectors );
214 
215             debug( "Adding archived file-set in: " + archiveFile + " to archive location: " + fs.getPrefix() );
216 
217             delegate.addArchivedFileSet( fs );
218         }
219         finally
220         {
221             inPublicApi.set( null );
222         }
223     }
224 
225     /**
226      * {@inheritDoc}
227      */
228     public void addArchivedFileSet( @Nonnull final File archiveFile )
229     {
230         inPublicApi.set( Boolean.TRUE );
231         try
232         {
233             final DefaultArchivedFileSet fs = new DefaultArchivedFileSet();
234 
235             fs.setArchive( archiveFile );
236             fs.setPrefix( rootPrefix );
237             fs.setFileSelectors( selectors );
238 
239             debug( "Adding archived file-set in: " + archiveFile + " to archive location: " + fs.getPrefix() );
240 
241             delegate.addArchivedFileSet( fs );
242         }
243         finally
244         {
245             inPublicApi.set( null );
246         }
247     }
248 
249     /**
250      * {@inheritDoc}
251      */
252     public void addDirectory( @Nonnull final File directory, final String prefix, final String[] includes,
253                               final String[] excludes )
254     {
255         inPublicApi.set( Boolean.TRUE );
256         try
257         {
258             final DefaultFileSet fs = new DefaultFileSet();
259 
260             fs.setDirectory( directory );
261             fs.setIncludes( includes );
262             fs.setExcludes( excludes );
263             fs.setPrefix( rootPrefix + prefix );
264             fs.setFileSelectors( selectors );
265 
266             debug( "Adding directory file-set in: " + directory + " to archive location: " + fs.getPrefix() );
267 
268             doAddFileSet( fs );
269         }
270         finally
271         {
272             inPublicApi.set( null );
273         }
274     }
275 
276     /**
277      * {@inheritDoc}
278      */
279     public void addSymlink( String symlinkName, String symlinkDestination )
280     {
281         inPublicApi.set( Boolean.TRUE );
282         try
283         {
284             delegate.addSymlink( symlinkName, symlinkDestination );
285         }
286         finally
287         {
288             inPublicApi.set( null );
289         }
290 
291     }
292 
293     /**
294      * {@inheritDoc}
295      */
296     public void addSymlink( String symlinkName, int permissions, String symlinkDestination )
297     {
298         inPublicApi.set( Boolean.TRUE );
299         try
300         {
301             delegate.addSymlink( symlinkName, permissions, symlinkDestination );
302         }
303         finally
304         {
305             inPublicApi.set( null );
306         }
307 
308     }
309 
310     /**
311      * {@inheritDoc}
312      */
313     public void addDirectory( @Nonnull final File directory, final String prefix )
314     {
315         inPublicApi.set( Boolean.TRUE );
316         try
317         {
318             final DefaultFileSet fs = new DefaultFileSet();
319 
320             fs.setDirectory( directory );
321             fs.setPrefix( rootPrefix + prefix );
322             fs.setFileSelectors( selectors );
323 
324             debug( "Adding directory file-set in: " + directory + " to archive location: " + fs.getPrefix() );
325 
326             doAddFileSet( fs );
327         }
328         finally
329         {
330             inPublicApi.set( null );
331         }
332     }
333 
334     /**
335      * {@inheritDoc}
336      */
337     public void addDirectory( @Nonnull final File directory, final String[] includes, final String[] excludes )
338     {
339         inPublicApi.set( Boolean.TRUE );
340         try
341         {
342             final DefaultFileSet fs = new DefaultFileSet();
343 
344             fs.setDirectory( directory );
345             fs.setIncludes( includes );
346             fs.setExcludes( excludes );
347             fs.setPrefix( rootPrefix );
348             fs.setFileSelectors( selectors );
349 
350             debug( "Adding directory file-set in: " + directory + " to archive location: " + fs.getPrefix() );
351 
352             doAddFileSet( fs );
353         }
354         finally
355         {
356             inPublicApi.set( null );
357         }
358     }
359 
360     /**
361      * {@inheritDoc}
362      */
363     public void addDirectory( @Nonnull final File directory )
364     {
365         inPublicApi.set( Boolean.TRUE );
366         try
367         {
368             final DefaultFileSet fs = new DefaultFileSet();
369 
370             fs.setDirectory( directory );
371             fs.setPrefix( rootPrefix );
372             fs.setFileSelectors( selectors );
373 
374             debug( "Adding directory file-set in: " + directory + " to archive location: " + fs.getPrefix() );
375 
376             doAddFileSet( fs );
377         }
378         finally
379         {
380             inPublicApi.set( null );
381         }
382     }
383 
384     /**
385      * {@inheritDoc}
386      */
387     public void addFile( @Nonnull final File inputFile, @Nonnull final String destFileName, final int permissions )
388     {
389         if ( acceptFile( inputFile ) )
390         {
391             inPublicApi.set( Boolean.TRUE );
392             try
393             {
394                 debug( "Adding file: " + inputFile + " to archive location: " + rootPrefix + destFileName );
395 
396                 delegate.addFile( inputFile, rootPrefix + destFileName, permissions );
397             }
398             finally
399             {
400                 inPublicApi.set( null );
401             }
402         }
403     }
404 
405     /**
406      * {@inheritDoc}
407      */
408     public void addFile( @Nonnull final File inputFile, @Nonnull final String destFileName )
409     {
410         if ( acceptFile( inputFile ) )
411         {
412             inPublicApi.set( Boolean.TRUE );
413             try
414             {
415                 debug( "Adding file: " + inputFile + " to archive location: " + rootPrefix + destFileName );
416 
417                 delegate.addFile( inputFile, rootPrefix + destFileName );
418             }
419             finally
420             {
421                 inPublicApi.set( null );
422             }
423         }
424     }
425 
426     /**
427      * {@inheritDoc}
428      */
429     public void createArchive()
430         throws IOException
431     {
432         inPublicApi.set( Boolean.TRUE );
433         try
434         {
435             delegate.setForced( forced );
436             delegate.createArchive();
437         }
438         finally
439         {
440             inPublicApi.set( null );
441         }
442     }
443 
444     /**
445      * {@inheritDoc}
446      */
447     public int getDefaultDirectoryMode()
448     {
449         inPublicApi.set( Boolean.TRUE );
450         try
451         {
452             return delegate.getDefaultDirectoryMode();
453         }
454         finally
455         {
456             inPublicApi.set( null );
457         }
458     }
459 
460     /**
461      * {@inheritDoc}
462      */
463     public int getDefaultFileMode()
464     {
465         inPublicApi.set( Boolean.TRUE );
466         try
467         {
468             return delegate.getDefaultFileMode();
469         }
470         finally
471         {
472             inPublicApi.set( null );
473         }
474     }
475 
476     /**
477      * {@inheritDoc}
478      */
479     public File getDestFile()
480     {
481         inPublicApi.set( Boolean.TRUE );
482         try
483         {
484             return delegate.getDestFile();
485         }
486         finally
487         {
488             inPublicApi.set( null );
489         }
490     }
491 
492     @SuppressWarnings( { "rawtypes", "deprecation" } )
493     /** {@inheritDoc} */ public Map<String, ArchiveEntry> getFiles()
494     {
495         inPublicApi.set( Boolean.TRUE );
496         try
497         {
498             return delegate.getFiles();
499         }
500         finally
501         {
502             inPublicApi.set( null );
503         }
504     }
505 
506     /**
507      * {@inheritDoc}
508      */
509     public boolean getIncludeEmptyDirs()
510     {
511         inPublicApi.set( Boolean.TRUE );
512         try
513         {
514             return delegate.getIncludeEmptyDirs();
515         }
516         finally
517         {
518             inPublicApi.set( null );
519         }
520     }
521 
522     /**
523      * {@inheritDoc}
524      */
525     public boolean isForced()
526     {
527         inPublicApi.set( Boolean.TRUE );
528         try
529         {
530             return delegate.isForced();
531         }
532         finally
533         {
534             inPublicApi.set( null );
535         }
536     }
537 
538     /**
539      * {@inheritDoc}
540      */
541     public boolean isSupportingForced()
542     {
543         inPublicApi.set( Boolean.TRUE );
544         try
545         {
546             return delegate.isSupportingForced();
547         }
548         finally
549         {
550             inPublicApi.set( null );
551         }
552     }
553 
554     /**
555      * {@inheritDoc}
556      */
557     public void setDefaultDirectoryMode( final int mode )
558     {
559         inPublicApi.set( Boolean.TRUE );
560         try
561         {
562             delegate.setDefaultDirectoryMode( mode );
563         }
564         finally
565         {
566             inPublicApi.set( null );
567         }
568     }
569 
570     /**
571      * {@inheritDoc}
572      */
573     public void setDefaultFileMode( final int mode )
574     {
575         inPublicApi.set( Boolean.TRUE );
576         try
577         {
578             delegate.setDefaultFileMode( mode );
579         }
580         finally
581         {
582             inPublicApi.set( null );
583         }
584     }
585 
586     /**
587      * {@inheritDoc}
588      */
589     public void setDestFile( final File destFile )
590     {
591         inPublicApi.set( Boolean.TRUE );
592         try
593         {
594             delegate.setDestFile( destFile );
595         }
596         finally
597         {
598             inPublicApi.set( null );
599         }
600     }
601 
602     /**
603      * {@inheritDoc}
604      */
605     public void setForced( final boolean forced )
606     {
607         inPublicApi.set( Boolean.TRUE );
608         try
609         {
610             this.forced = forced;
611             delegate.setForced( forced );
612         }
613         finally
614         {
615             inPublicApi.set( null );
616         }
617     }
618 
619     /**
620      * {@inheritDoc}
621      */
622     public void setIncludeEmptyDirs( final boolean includeEmptyDirs )
623     {
624         inPublicApi.set( Boolean.TRUE );
625         try
626         {
627             delegate.setIncludeEmptyDirs( includeEmptyDirs );
628         }
629         finally
630         {
631             inPublicApi.set( null );
632         }
633     }
634 
635     /**
636      * {@inheritDoc}
637      */
638     public void setDotFileDirectory( final File dotFileDirectory )
639     {
640         throw new UnsupportedOperationException(
641             "Undocumented feature of plexus-archiver; this is not yet supported." );
642     }
643 
644     /**
645      * {@inheritDoc}
646      */
647     public void addArchivedFileSet( final ArchivedFileSet fileSet )
648     {
649         inPublicApi.set( Boolean.TRUE );
650         try
651         {
652             final PrefixedArchivedFileSet fs = new PrefixedArchivedFileSet( fileSet, rootPrefix, selectors );
653 
654             debug( "Adding archived file-set in: " + fileSet.getArchive() + " to archive location: " + fs.getPrefix() );
655 
656             delegate.addArchivedFileSet( fs );
657         }
658         finally
659         {
660             inPublicApi.set( null );
661         }
662     }
663 
664     /**
665      * {@inheritDoc}
666      */
667     public void addFileSet( @Nonnull final FileSet fileSet )
668     {
669         inPublicApi.set( Boolean.TRUE );
670         try
671         {
672             final PrefixedFileSet fs = new PrefixedFileSet( fileSet, rootPrefix, selectors );
673 
674             debug( "Adding file-set in: " + fileSet.getDirectory() + " to archive location: " + fs.getPrefix() );
675 
676             doAddFileSet( fs );
677         }
678         finally
679         {
680             inPublicApi.set( null );
681         }
682     }
683 
684     private void doAddFileSet( final FileSet fs )
685     {
686         final String fsPath = fs.getDirectory().getAbsolutePath().replace( '\\', '/' );
687 
688         if ( fsPath.equals( assemblyWorkPath ) )
689         {
690             logger.debug( "SKIPPING fileset with source directory matching assembly working-directory: " + fsPath );
691         }
692         else if ( assemblyWorkPath.startsWith( fsPath ) )
693         {
694             final List<String> newEx = new ArrayList<String>();
695             if ( fs.getExcludes() != null )
696             {
697                 newEx.addAll( Arrays.asList( fs.getExcludes() ) );
698             }
699 
700             final String workDirExclude = assemblyWorkPath.substring( fsPath.length() + 1 );
701 
702             logger.debug(
703                 "Adding exclude for assembly working-directory: " + workDirExclude + "\nFile-Set source directory: "
704                     + fsPath );
705 
706             newEx.add( workDirExclude );
707 
708             final List<String> newIn = new ArrayList<String>();
709             if ( fs.getIncludes() != null )
710             {
711                 for ( final String include : fs.getIncludes() )
712                 {
713                     if ( !include.startsWith( workDirExclude ) )
714                     {
715                         newIn.add( include );
716                     }
717                 }
718             }
719 
720             final DefaultFileSet dfs = new DefaultFileSet();
721 
722             dfs.setCaseSensitive( fs.isCaseSensitive() );
723             dfs.setDirectory( fs.getDirectory() );
724             dfs.setExcludes( newEx.toArray( new String[newEx.size()] ) );
725             dfs.setFileSelectors( fs.getFileSelectors() );
726             dfs.setIncludes( newIn.toArray( new String[newIn.size()] ) );
727             dfs.setIncludingEmptyDirectories( fs.isIncludingEmptyDirectories() );
728             dfs.setPrefix( fs.getPrefix() );
729             dfs.setUsingDefaultExcludes( fs.isUsingDefaultExcludes() );
730 
731             delegate.addFileSet( dfs );
732         }
733         else
734         {
735             delegate.addFileSet( fs );
736         }
737     }
738 
739     private boolean acceptFile( final File inputFile )
740     {
741         if ( !Boolean.TRUE.equals( inPublicApi.get() ) )
742         {
743             if ( selectors != null )
744             {
745                 final FileInfo fileInfo = new DefaultFileInfo( inputFile );
746 
747                 for ( final FileSelector selector : selectors )
748                 {
749                     try
750                     {
751                         if ( !selector.isSelected( fileInfo ) )
752                         {
753                             return false;
754                         }
755                     }
756                     catch ( final IOException e )
757                     {
758                         throw new ArchiverException(
759                             "Error processing file: " + inputFile + " using selector: " + selector, e );
760                     }
761                 }
762             }
763         }
764 
765         return true;
766     }
767 
768     private static final class DefaultFileInfo
769         implements FileInfo
770     {
771 
772         private final File inputFile;
773 
774         DefaultFileInfo( final File inputFile )
775         {
776             this.inputFile = inputFile;
777         }
778 
779         public InputStream getContents()
780             throws IOException
781         {
782             return new FileInputStream( inputFile );
783         }
784 
785         public String getName()
786         {
787             return inputFile.getName();
788         }
789 
790         public boolean isDirectory()
791         {
792             return inputFile.isDirectory();
793         }
794 
795         public boolean isFile()
796         {
797             return inputFile.isFile();
798         }
799 
800         public boolean isSymbolicLink()
801         {
802             return false;
803         }
804     }
805 
806     /**
807      * {@inheritDoc}
808      */
809     public void addResource( final PlexusIoResource resource, final String destFileName, final int permissions )
810     {
811         File file = new File( resource.getName() ); // zOMG.
812         if ( acceptFile( file ) )
813         {
814 
815             inPublicApi.set( Boolean.TRUE );
816             try
817             {
818                 delegate.addResource( resource, rootPrefix + destFileName, permissions );
819             }
820             finally
821             {
822                 inPublicApi.set( null );
823             }
824         }
825     }
826 
827     /**
828      * {@inheritDoc}
829      */
830     public void addResources( final PlexusIoResourceCollection resources )
831     {
832         inPublicApi.set( Boolean.TRUE );
833         try
834         {
835             delegate.addResources( resources );
836         }
837         finally
838         {
839             inPublicApi.set( null );
840         }
841     }
842 
843     /**
844      * {@inheritDoc}
845      */
846     @Nonnull
847     public ResourceIterator getResources()
848     {
849         return delegate.getResources();
850     }
851 
852     /**
853      * {@inheritDoc}
854      */
855     public String getDuplicateBehavior()
856     {
857         return delegate.getDuplicateBehavior();
858     }
859 
860     /**
861      * {@inheritDoc}
862      */
863     public void setDuplicateBehavior( final String duplicate )
864     {
865         inPublicApi.set( Boolean.TRUE );
866         try
867         {
868             delegate.setDuplicateBehavior( duplicate );
869         }
870         finally
871         {
872             inPublicApi.set( null );
873         }
874     }
875 
876     /**
877      * {@inheritDoc}
878      */
879     public int getDirectoryMode()
880     {
881         return delegate.getDirectoryMode();
882     }
883 
884     /**
885      * {@inheritDoc}
886      */
887     public int getFileMode()
888     {
889         return delegate.getFileMode();
890     }
891 
892     /**
893      * {@inheritDoc}
894      */
895     public int getOverrideDirectoryMode()
896     {
897         return delegate.getOverrideDirectoryMode();
898     }
899 
900     /**
901      * {@inheritDoc}
902      */
903     public int getOverrideFileMode()
904     {
905         return delegate.getOverrideFileMode();
906     }
907 
908     /**
909      * {@inheritDoc}
910      */
911     public void setDirectoryMode( final int mode )
912     {
913         inPublicApi.set( Boolean.TRUE );
914         try
915         {
916             delegate.setDirectoryMode( mode );
917         }
918         finally
919         {
920             inPublicApi.set( null );
921         }
922     }
923 
924     /**
925      * {@inheritDoc}
926      */
927     public void setFileMode( final int mode )
928     {
929         inPublicApi.set( Boolean.TRUE );
930         try
931         {
932             delegate.setFileMode( mode );
933         }
934         finally
935         {
936             inPublicApi.set( null );
937         }
938     }
939 
940     /**
941      * {@inheritDoc}
942      */
943     public boolean isUseJvmChmod()
944     {
945         return useJvmChmod;
946     }
947 
948     /**
949      * {@inheritDoc}
950      */
951     public void setUseJvmChmod( final boolean useJvmChmod )
952     {
953         this.useJvmChmod = useJvmChmod;
954     }
955 
956     /**
957      * {@inheritDoc}
958      */
959     public boolean isIgnorePermissions()
960     {
961         return delegate.isIgnorePermissions();
962     }
963 
964     /**
965      * {@inheritDoc}
966      */
967     public void setIgnorePermissions( final boolean ignorePermissions )
968     {
969         delegate.setIgnorePermissions( ignorePermissions );
970     }
971 
972 }