001    /**
002     * Copyright (c) 2000-2013 Liferay, Inc. All rights reserved.
003     *
004     * This library is free software; you can redistribute it and/or modify it under
005     * the terms of the GNU Lesser General Public License as published by the Free
006     * Software Foundation; either version 2.1 of the License, or (at your option)
007     * any later version.
008     *
009     * This library is distributed in the hope that it will be useful, but WITHOUT
010     * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
011     * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
012     * details.
013     */
014    
015    package com.liferay.portal.zip;
016    
017    import com.liferay.portal.kernel.log.Log;
018    import com.liferay.portal.kernel.log.LogFactoryUtil;
019    import com.liferay.portal.kernel.util.FileUtil;
020    import com.liferay.portal.kernel.util.StringPool;
021    import com.liferay.portal.kernel.util.Validator;
022    import com.liferay.portal.kernel.zip.ZipReader;
023    
024    import de.schlichtherle.io.ArchiveBusyWarningException;
025    import de.schlichtherle.io.ArchiveDetector;
026    import de.schlichtherle.io.ArchiveException;
027    import de.schlichtherle.io.DefaultArchiveDetector;
028    import de.schlichtherle.io.File;
029    import de.schlichtherle.io.FileInputStream;
030    import de.schlichtherle.io.FileOutputStream;
031    import de.schlichtherle.io.archive.zip.ZipDriver;
032    
033    import java.io.IOException;
034    import java.io.InputStream;
035    import java.io.OutputStream;
036    
037    import java.util.ArrayList;
038    import java.util.Collections;
039    import java.util.List;
040    
041    /**
042     * @author Raymond Aug??
043     */
044    public class ZipReaderImpl implements ZipReader {
045    
046            static {
047                    File.setDefaultArchiveDetector(
048                            new DefaultArchiveDetector(
049                                    ArchiveDetector.ALL, "lar|" + ArchiveDetector.ALL.getSuffixes(),
050                                    new ZipDriver()));
051            }
052    
053            public ZipReaderImpl(InputStream inputStream) throws IOException {
054                    _zipFile = new File(FileUtil.createTempFile("zip"));
055    
056                    OutputStream outputStream = new FileOutputStream(_zipFile);
057    
058                    try {
059                            File.cat(inputStream, outputStream);
060                    }
061                    finally {
062                            outputStream.close();
063                            inputStream.close();
064                    }
065            }
066    
067            public ZipReaderImpl(java.io.File file) {
068                    _zipFile = new File(file);
069            }
070    
071            @Override
072            public void close() {
073                    try {
074                            File.umount(_zipFile);
075                    }
076                    catch (ArchiveBusyWarningException abwe) {
077                            if (_log.isWarnEnabled()) {
078                                    _log.warn(abwe, abwe);
079                            }
080                    }
081                    catch (ArchiveException ae) {
082                            _log.error(ae, ae);
083                    }
084            }
085    
086            @Override
087            public List<String> getEntries() {
088                    List<String> folderEntries = new ArrayList<String>();
089    
090                    File[] files = (File[])_zipFile.listFiles();
091    
092                    for (File file : files) {
093                            if (!file.isDirectory()) {
094                                    folderEntries.add(file.getEnclEntryName());
095                            }
096                            else {
097                                    processDirectory(file, folderEntries);
098                            }
099                    }
100    
101                    return folderEntries;
102            }
103    
104            @Override
105            public byte[] getEntryAsByteArray(String name) {
106                    if (Validator.isNull(name)) {
107                            return null;
108                    }
109    
110                    byte[] bytes = null;
111    
112                    try {
113                            InputStream is = getEntryAsInputStream(name);
114    
115                            if (is != null) {
116                                    bytes = FileUtil.getBytes(is);
117                            }
118                    }
119                    catch (IOException ioe) {
120                            _log.error(ioe, ioe);
121                    }
122    
123                    return bytes;
124            }
125    
126            @Override
127            public InputStream getEntryAsInputStream(String name) {
128                    if (Validator.isNull(name)) {
129                            return null;
130                    }
131    
132                    if (name.startsWith(StringPool.SLASH)) {
133                            name = name.substring(1);
134                    }
135    
136                    File file = new File(_zipFile, name, DefaultArchiveDetector.NULL);
137    
138                    if (file.exists() && !file.isDirectory()) {
139                            try {
140                                    if (_log.isDebugEnabled()) {
141                                            _log.debug("Extracting " + name);
142                                    }
143    
144                                    return new FileInputStream(file);
145                            }
146                            catch (IOException ioe) {
147                                    _log.error(ioe, ioe);
148                            }
149                    }
150    
151                    return null;
152            }
153    
154            @Override
155            public String getEntryAsString(String name) {
156                    if (Validator.isNull(name)) {
157                            return null;
158                    }
159    
160                    byte[] bytes = getEntryAsByteArray(name);
161    
162                    if (bytes != null) {
163                            return new String(bytes);
164                    }
165    
166                    return null;
167            }
168    
169            @Override
170            public List<String> getFolderEntries(String path) {
171                    if (Validator.isNull(path)) {
172                            return Collections.emptyList();
173                    }
174    
175                    List<String> folderEntries = new ArrayList<String>();
176    
177                    File directory = new File(_zipFile.getPath() + StringPool.SLASH + path);
178    
179                    if (!directory.exists()) {
180                            return folderEntries;
181                    }
182    
183                    File[] files = (File[])directory.listFiles();
184    
185                    for (File file : files) {
186                            if (!file.isDirectory()) {
187                                    folderEntries.add(file.getEnclEntryName());
188                            }
189                    }
190    
191                    return folderEntries;
192            }
193    
194            protected void processDirectory(
195                    File directory, List<String> folderEntries) {
196    
197                    File[] files = (File[])directory.listFiles();
198    
199                    for (File file : files) {
200                            if (!file.isDirectory()) {
201                                    folderEntries.add(file.getEnclEntryName());
202                            }
203                            else {
204                                    processDirectory(file, folderEntries);
205                            }
206                    }
207            }
208    
209            private static Log _log = LogFactoryUtil.getLog(ZipReaderImpl.class);
210    
211            private File _zipFile;
212    
213    }