View Javadoc
1   /*******************************************************************************
2    *   Gisgraphy Project 
3    * 
4    *   This library is free software; you can redistribute it and/or
5    *   modify it under the terms of the GNU Lesser General Public
6    *   License as published by the Free Software Foundation; either
7    *   version 2.1 of the License, or (at your option) any later version.
8    * 
9    *   This library is distributed in the hope that it will be useful,
10   *   but WITHOUT ANY WARRANTY; without even the implied warranty of
11   *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12   *   Lesser General Public License for more details.
13   * 
14   *   You should have received a copy of the GNU Lesser General Public
15   *   License along with this library; if not, write to the Free Software
16   *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA
17   * 
18   *  Copyright 2008  Gisgraphy project 
19   *  David Masclet <davidmasclet@gisgraphy.com>
20   *  
21   *  
22   *******************************************************************************/
23  package com.gisgraphy.helper;
24  
25  import java.io.BufferedInputStream;
26  import java.io.File;
27  import java.io.FileInputStream;
28  import java.io.FileOutputStream;
29  import java.io.IOException;
30  import java.io.InputStream;
31  import java.util.zip.GZIPInputStream;
32  
33  import org.apache.tools.bzip2.CBZip2InputStream;
34  import org.apache.tools.tar.TarEntry;
35  import org.apache.tools.tar.TarInputStream;
36  import org.slf4j.Logger;
37  import org.slf4j.LoggerFactory;
38  
39  /**
40   * Utility class to untar files, files can be zipped in multi format (extension
41   * tar, tar.gzip,tar.gz, tar.bz2, tar.bzip2 are supported).
42   * 
43   * @author <a href="mailto:david.masclet@gisgraphy.com">David Masclet</a>
44   * 
45   */
46  public class Untar {
47      private String tarFileName;
48      private File dest;
49      private String currentFileNameIntoArchiveExtracted;
50  
51      /**
52       * The logger
53       */
54      private static final Logger logger = LoggerFactory.getLogger(Untar.class);
55  
56      /**
57       * @param tarFileName
58       *            the path to the file we want to untar
59       * @param dest
60       *            the path where the file should be untar
61       */
62      public Untar(String tarFileName, File dest) {
63  	this.tarFileName = tarFileName;
64  	this.dest = dest;
65      }
66  
67      private InputStream getDecompressedInputStream(final String name, final InputStream istream) throws IOException {
68  	logger.info("untar: decompress " + name + " to " + dest);
69  	if (name == null) {
70  	    throw new RuntimeException("fileName to decompress can not be null");
71  	}
72  	if (name.toLowerCase().endsWith("gzip") || name.toLowerCase().endsWith("gz")) {
73  	    return new BufferedInputStream(new GZIPInputStream(istream));
74  	} else if (name.toLowerCase().endsWith("bz2") || name.toLowerCase().endsWith("bzip2")) {
75  	    final char[] magic = new char[] { 'B', 'Z' };
76  	    for (int i = 0; i < magic.length; i++) {
77  		if (istream.read() != magic[i]) {
78  		    throw new RuntimeException("Invalid bz2 file." + name);
79  		}
80  	    }
81  	    return new BufferedInputStream(new CBZip2InputStream(istream));
82  	} else if (name.toLowerCase().endsWith("tar")) {
83  	    return istream;
84  	}
85  	throw new RuntimeException("can only detect compression for extension tar, gzip, gz, bz2, or bzip2");
86      }
87  
88      /**
89       * process the untar operation
90       * 
91       * @throws IOException
92       */
93      public void untar() throws IOException {
94  	logger.info("untar: untar " + tarFileName + " to " + dest);
95  	TarInputStream tin = null;
96  	try {
97  	    if (!dest.exists()) {
98  		dest.mkdir();
99  	    }
100 
101 	    tin = new TarInputStream(getDecompressedInputStream(tarFileName, new FileInputStream(new File(tarFileName))));
102 
103 	    TarEntry tarEntry = tin.getNextEntry();
104 
105 	    while (tarEntry != null) {
106 		File destPath = new File(dest.toString() + File.separatorChar + tarEntry.getName());
107 
108 		if (tarEntry.isDirectory()) {
109 		    destPath.mkdir();
110 		} else {
111 		    if (!destPath.getParentFile().exists()) {
112 			destPath.getParentFile().mkdirs();
113 		    }
114 		    currentFileNameIntoArchiveExtracted = tarEntry.getName();
115 		    logger.info("untar: untar " + tarEntry.getName() + " to " + destPath);
116 		    FileOutputStream fout = new FileOutputStream(destPath);
117 		    try {
118 			tin.copyEntryContents(fout);
119 		    } finally {
120 			fout.flush();
121 			fout.close();
122 		    }
123 		}
124 		tarEntry = tin.getNextEntry();
125 	    }
126 	} finally {
127 	    currentFileNameIntoArchiveExtracted = null;
128 	    if (tin != null) {
129 		tin.close();
130 	    }
131 	}
132 
133     }
134 
135     public String getCurrentFileNameIntoArchiveExtracted() {
136 	return currentFileNameIntoArchiveExtracted;
137     }
138 }