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