View Javadoc
1   package fr.ifremer.quadrige2.core.dao.technical;
2   
3   /*-
4    * #%L
5    * Quadrige2 Core :: Quadrige2 Core Shared
6    * $Id:$
7    * $HeadURL:$
8    * %%
9    * Copyright (C) 2017 Ifremer
10   * %%
11   * This program is free software: you can redistribute it and/or modify
12   * it under the terms of the GNU Affero General Public License as published by
13   * the Free Software Foundation, either version 3 of the License, or
14   * (at your option) any later version.
15   * 
16   * This program is distributed in the hope that it will be useful,
17   * but WITHOUT ANY WARRANTY; without even the implied warranty of
18   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19   * GNU General Public License for more details.
20   * 
21   * You should have received a copy of the GNU Affero General Public License
22   * along with this program.  If not, see <http://www.gnu.org/licenses/>.
23   * #L%
24   */
25  
26  
27  import org.apache.commons.io.IOUtils;
28  import org.springframework.util.StreamUtils;
29  
30  import java.io.*;
31  import java.util.Enumeration;
32  import java.util.zip.ZipEntry;
33  import java.util.zip.ZipFile;
34  import java.util.zip.ZipOutputStream;
35  
36  /**
37   * <p>ZipUtils class.</p>
38   */
39  public class ZipUtils {
40  
41      /**
42       * <p>Constructor for ZipUtils.</p>
43       */
44      protected ZipUtils() {
45          // helper class
46      }
47  
48      /**
49       * <p>compressFilesInPath.</p>
50       *
51       * @param path a {@link java.lang.String} object.
52       * @param compressedFile a {@link java.io.File} object.
53       * @param deleteAfterCompress a boolean.
54       * @throws java.io.IOException if any.
55       */
56      public static void compressFilesInPath(String path, File compressedFile, boolean deleteAfterCompress) throws IOException {
57          compressFilesInPath(new File(path), compressedFile, deleteAfterCompress);
58      }
59  
60      /**
61       * <p>compressFilesInPath.</p>
62       *
63       * @param fileSource a {@link java.io.File} object.
64       * @param compressedFile a {@link java.io.File} object.
65       * @param deleteAfterCompress a boolean.
66       * @throws java.io.IOException if any.
67       */
68      public static void compressFilesInPath(File fileSource, File compressedFile, boolean deleteAfterCompress) throws IOException {
69          ZipOutputStream zout = new ZipOutputStream(new BufferedOutputStream(new FileOutputStream(compressedFile)));
70          compressDirectory(fileSource, fileSource, compressedFile, zout, deleteAfterCompress);
71          zout.close();
72      }
73  
74  
75      /**
76       * <p>uncompressFileToPath.</p>
77       *
78       * @param compressedFile a {@link java.io.File} object.
79       * @param path a {@link java.lang.String} object.
80       * @param deleteAfterUncompress a boolean.
81       * @throws java.io.IOException if any.
82       */
83      public static void uncompressFileToPath(File compressedFile, String path, boolean deleteAfterUncompress) throws IOException {
84          File destDir;
85          if (path != null) {
86              destDir = new File(path);
87          }
88          else {
89              destDir = new File(compressedFile.getParent());
90          }
91          destDir.mkdirs();
92  
93          ZipFile zipFile = new ZipFile(compressedFile);
94          Enumeration<? extends ZipEntry> entries = zipFile.entries();
95          while (entries.hasMoreElements()) {
96              ZipEntry zipEntry = (ZipEntry) entries.nextElement();
97              if (!zipEntry.isDirectory()) {
98                  File destFile = new File(destDir, zipEntry.getName());
99                  destFile.getParentFile().mkdirs();
100                 OutputStream out = new BufferedOutputStream(new FileOutputStream(destFile));
101                 StreamUtils.copy(zipFile.getInputStream(zipEntry), out);
102                 out.flush();
103                 out.close();
104             }
105         }
106         zipFile.close();
107         if (deleteAfterUncompress) {
108             compressedFile.delete();
109         }
110     }
111 
112     /* -- Internal methods -- */
113 
114 
115     private static void compressDirectory(File rootFileSource, File fileSource, File compressedFile, ZipOutputStream zout, boolean deleteAfterCompress) throws IOException {
116         File[] files = fileSource.listFiles();
117         for (File file : files) {
118             if (file.equals(compressedFile)) {
119                 continue;
120             }
121             if (file.isDirectory()) {
122                 String zipEntryName = toZipEntryName(rootFileSource, file);
123                 zout.putNextEntry(new ZipEntry(zipEntryName));
124                 compressDirectory(rootFileSource, file, compressedFile, zout, deleteAfterCompress);
125                 zout.closeEntry();
126                 if (deleteAfterCompress) {
127                     file.delete();
128                 }
129                 continue;
130             }
131             InputStream in = new BufferedInputStream(new FileInputStream(file));
132             String zipEntryName = toZipEntryName(rootFileSource, file);
133             zout.putNextEntry(new ZipEntry(zipEntryName));
134             IOUtils.copy(in, zout);
135             zout.closeEntry();
136             in.close();
137             if (deleteAfterCompress) {
138                 file.delete();
139             }
140         }
141     }
142 
143     private static String toZipEntryName(File root, File file) {
144         String result = file.getPath();
145         if(root != null) {
146             String rootPath = root.getPath();
147             if(result.startsWith(rootPath)) {
148                 result = result.substring(rootPath.length());
149             }
150         }
151 
152         result = result.replace('\\', '/');
153         if(file.isDirectory()) {
154             result = result + '/';
155         }
156 
157         while(result.startsWith("/")) {
158             result = result.substring(1);
159         }
160 
161         return result;
162     }
163 }