View Javadoc
1   /**
2    *
3    * Copyright 2004 The Apache Software Foundation
4    *
5    * Licensed under the Apache License, Version 2.0 (the "License");
6    * you may not use this file except in compliance with the License.
7    * You may obtain a copy of the License at
8    *
9    * http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  package org.codehaus.plexus.archiver.tar;
18  
19  import java.io.BufferedInputStream;
20  import java.io.File;
21  import java.io.FileInputStream;
22  import java.io.IOException;
23  import java.io.InputStream;
24  import java.util.zip.GZIPInputStream;
25  import org.apache.commons.compress.archivers.tar.TarArchiveEntry;
26  import org.apache.commons.compress.archivers.tar.TarArchiveInputStream;
27  import org.apache.commons.compress.compressors.bzip2.BZip2CompressorInputStream;
28  import org.apache.commons.compress.compressors.xz.XZCompressorInputStream;
29  import org.codehaus.plexus.archiver.AbstractUnArchiver;
30  import org.codehaus.plexus.archiver.ArchiverException;
31  import org.codehaus.plexus.archiver.util.Streams;
32  import org.codehaus.plexus.components.io.filemappers.FileMapper;
33  import org.codehaus.plexus.util.IOUtil;
34  import org.iq80.snappy.SnappyInputStream;
35  
36  /**
37   * @author <a href="mailto:evenisse@codehaus.org">Emmanuel Venisse</a>
38   */
39  public class TarUnArchiver
40      extends AbstractUnArchiver
41  {
42  
43      public TarUnArchiver()
44      {
45      }
46  
47      public TarUnArchiver( File sourceFile )
48      {
49          super( sourceFile );
50      }
51  
52      /**
53       * compression method
54       */
55      private UntarCompressionMethod compression = UntarCompressionMethod.NONE;
56  
57      /**
58       * Set decompression algorithm to use; default=none.
59       * <p>
60       * Allowable values are </p>
61       * <ul>
62       * <li>none - no compression</li>
63       * <li>gzip - Gzip compression</li>
64       * <li>bzip2 - Bzip2 compression</li>
65       * <li>snappy - Snappy compression</li>
66       * <li>xz - Xz compression</li>
67       * </ul>
68       *
69       * @param method compression method
70       */
71      public void setCompression( UntarCompressionMethod method )
72      {
73          compression = method;
74      }
75  
76      /**
77       * No encoding support in Untar.
78       */
79      public void setEncoding( String encoding )
80      {
81          getLogger().warn( "The TarUnArchiver doesn't support the encoding attribute" );
82      }
83  
84      @Override
85      protected void execute()
86          throws ArchiverException
87      {
88          execute( getSourceFile(), getDestDirectory(), getFileMappers() );
89      }
90  
91      @Override
92      protected void execute( String path, File outputDirectory )
93      {
94          execute( new File( path ), getDestDirectory(), getFileMappers() );
95      }
96  
97      protected void execute( File sourceFile, File destDirectory, FileMapper[] fileMappers )
98          throws ArchiverException
99      {
100         TarArchiveInputStream tis = null;
101         try
102         {
103             getLogger().info( "Expanding: " + sourceFile + " into " + destDirectory );
104             TarFile tarFile = new TarFile( sourceFile );
105             tis = new TarArchiveInputStream(
106                 decompress( compression, sourceFile, new BufferedInputStream( new FileInputStream( sourceFile ) ) ) );
107             TarArchiveEntry te;
108             while ( ( te = tis.getNextTarEntry() ) != null )
109             {
110                 TarResource fileInfo = new TarResource( tarFile, te );
111                 if ( isSelected( te.getName(), fileInfo ) )
112                 {
113                     final String symlinkDestination = te.isSymbolicLink() ? te.getLinkName() : null;
114                     extractFile( sourceFile, destDirectory, tis, te.getName(), te.getModTime(), te.isDirectory(),
115                                  te.getMode() != 0 ? te.getMode() : null, symlinkDestination, fileMappers );
116 
117                 }
118             }
119             getLogger().debug( "expand complete" );
120             tis.close();
121             tis = null;
122         }
123         catch ( IOException ioe )
124         {
125             throw new ArchiverException( "Error while expanding " + sourceFile.getAbsolutePath(), ioe );
126         }
127         finally
128         {
129             IOUtil.close( tis );
130         }
131     }
132 
133     /**
134      * This method wraps the input stream with the
135      * corresponding decompression method
136      *
137      * @param file provides location information for BuildException
138      * @param istream input stream
139      *
140      * @return input stream with on-the-fly decompression
141      *
142      * @throws IOException thrown by GZIPInputStream constructor
143      */
144     private InputStream decompress( UntarCompressionMethod compression, final File file, final InputStream istream )
145         throws IOException, ArchiverException
146     {
147         if ( compression == UntarCompressionMethod.GZIP )
148         {
149             return Streams.bufferedInputStream( new GZIPInputStream( istream ) );
150         }
151         else if ( compression == UntarCompressionMethod.BZIP2 )
152         {
153             return new BZip2CompressorInputStream( istream );
154         }
155         else if ( compression == UntarCompressionMethod.SNAPPY )
156         {
157             return new SnappyInputStream( istream, true );
158         }
159         else if ( compression == UntarCompressionMethod.XZ )
160         {
161             return new XZCompressorInputStream( istream );
162         }
163         return istream;
164     }
165 
166     /**
167      * Valid Modes for Compression attribute to Untar Task
168      */
169     public static enum UntarCompressionMethod
170     {
171 
172         NONE( "none" ),
173         GZIP( "gzip" ),
174         BZIP2( "bzip2" ),
175         SNAPPY( "snappy" ),
176         XZ( "xz" );
177 
178         final String value;
179 
180         /**
181          * Constructor
182          */
183         UntarCompressionMethod( String value )
184         {
185             this.value = value;
186         }
187 
188     }
189 
190 }