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