diff -r 41bc0d04ee42 kernel/kernel-util/pom.xml --- a/kernel/kernel-util/pom.xml Fri Apr 04 09:23:31 2014 +0800 +++ b/kernel/kernel-util/pom.xml Wed Apr 30 15:43:51 2014 +0800 @@ -39,6 +39,17 @@ commons-logging + org.apache.commons + commons-compress + 1.8 + + + org.tukaani + xz + + + + javax.servlet servlet-api diff -r 41bc0d04ee42 kernel/kernel-util/src/main/java/org/sakaiproject/content/util/ZipContentUtil.java --- a/kernel/kernel-util/src/main/java/org/sakaiproject/content/util/ZipContentUtil.java Fri Apr 04 09:23:31 2014 +0800 +++ b/kernel/kernel-util/src/main/java/org/sakaiproject/content/util/ZipContentUtil.java Wed Apr 30 15:43:51 2014 +0800 @@ -6,16 +6,17 @@ import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; +import java.util.Arrays; import java.util.Enumeration; import java.util.HashMap; import java.util.List; import java.util.Map; -import java.util.zip.ZipEntry; -import java.util.zip.ZipFile; -import java.util.zip.ZipOutputStream; import javax.activation.MimetypesFileTypeMap; +import org.apache.commons.compress.archivers.zip.ZipArchiveEntry; +import org.apache.commons.compress.archivers.zip.ZipArchiveOutputStream; +import org.apache.commons.compress.archivers.zip.ZipFile; import org.apache.commons.io.IOUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -75,14 +76,14 @@ public void compressFolder(Reference reference) { File temp = null; FileInputStream fis = null; - ZipOutputStream out = null; + ZipArchiveOutputStream out = null; ToolSession toolSession = SessionManager.getCurrentToolSession(); try { // Create the compressed archive in the filesystem temp = File.createTempFile("sakai_content-", ".tmp"); temp.deleteOnExit(); ContentCollection collection = ContentHostingService.getCollection(reference.getId()); - out = new ZipOutputStream(new BufferedOutputStream(new FileOutputStream(temp),BUFFER_SIZE)); + out = new ZipArchiveOutputStream(new BufferedOutputStream(new FileOutputStream(temp),BUFFER_SIZE)); storeContentCollection(reference.getId(),collection,out); out.close(); @@ -203,25 +204,42 @@ // Extract Zip File File temp = null; + temp = exportResourceToFile(resource); + String[] charsets = ServerConfigurationService.getStrings("content.zip.charset"); + if (charsets.length == 0) { + charsets = new String[]{"UTF-8"}; + } try { - temp = exportResourceToFile(resource); - ZipFile zipFile = new ZipFile(temp,ZipFile.OPEN_READ); - Enumeration entries = zipFile.entries(); - - while (entries.hasMoreElements()) { - ZipEntry nextElement = entries.nextElement(); - if (nextElement.isDirectory()) { - createContentCollection(rootCollectionId, nextElement); - } - else { - createContentResource(rootCollectionId, nextElement, zipFile); + boolean extracted = false; + for (String charset: charsets) { + ZipFile zipFile = new ZipFile(temp, charset); + try { + Enumeration entries = zipFile.getEntries(); + while (entries.hasMoreElements()) { + ZipArchiveEntry nextElement = entries.nextElement(); + if (nextElement.isDirectory()) { + createContentCollection(rootCollectionId, nextElement); + } + else { + createContentResource(rootCollectionId, nextElement, zipFile); + } + } + extracted = true; + break; + } catch (Exception e) { + LOG.warn(String.format("Cannot extract archive %s with charset %s.", referenceId, charset)); + } finally { + zipFile.close(); } } - zipFile.close(); + if (!extracted) { + // If the zip file cannot be extracted by any charsets, throw a exception. + throw new IllegalArgumentException(String.format("Cannot extract archives %s with any charset %s.", referenceId, Arrays.toString(charsets))); + } } catch (Exception e) { e.printStackTrace(); } finally { - temp.delete(); + temp.delete(); } } @@ -260,20 +278,38 @@ // Extract Zip File File temp = null; + temp = exportResourceToFile(resource); + String[] charsets = ServerConfigurationService.getStrings("content.zip.charset"); + if (charsets.length == 0) { + charsets = new String[]{"UTF-8"}; + } try { - temp = exportResourceToFile(resource); - ZipFile zipFile = new ZipFile(temp,ZipFile.OPEN_READ); - Enumeration entries = zipFile.entries(); - - int i = 0; - //use <= getMAX_ZIP_EXTRACT_SIZE() so the returned value will be - //larger than the max and then rejected - while (entries.hasMoreElements() && i <= getMaxZipExtractFiles()) { - ZipEntry nextElement = entries.nextElement(); - ret.put(nextElement.getName(), nextElement.getSize()); - i++; + boolean extracted = false; + for (String charset: charsets) { + ret.clear(); + ZipFile zipFile = new ZipFile(temp, charset); + try { + Enumeration entries = zipFile.getEntries(); + int i = 0; + //use <= getMAX_ZIP_EXTRACT_SIZE() so the returned value will be + //larger than the max and then rejected + while (entries.hasMoreElements() && i <= getMaxZipExtractFiles()) { + ZipArchiveEntry nextElement = entries.nextElement(); + ret.put(nextElement.getName(), nextElement.getSize()); + i++; + } + extracted = true; + break; + } catch (Exception e) { + LOG.warn(String.format("Cannot get menifest of %s with charset %s.", referenceId, charset)); + } finally { + zipFile.close(); + } } - zipFile.close(); + if (!extracted) { + // If the zip file cannot be extracted by any charsets, throw a exception. + throw new IllegalArgumentException(String.format("Cannot extract archives %s with any charset %s.", referenceId, Arrays.toString(charsets))); + } } catch (Exception e) { e.printStackTrace(); @@ -299,7 +335,7 @@ * @throws Exception */ private void createContentResource(String rootCollectionId, - ZipEntry nextElement, ZipFile zipFile) throws Exception { + ZipArchiveEntry nextElement, ZipFile zipFile) throws Exception { String resourceId = rootCollectionId + nextElement.getName(); String resourceName = extractName(nextElement.getName()); ContentResourceEdit resourceEdit = ContentHostingService.addResource(resourceId); @@ -318,7 +354,7 @@ * @throws Exception */ private void createContentCollection(String rootCollectionId, - ZipEntry element) throws Exception { + ZipArchiveEntry element) throws Exception { String resourceId = rootCollectionId + element.getName(); String resourceName = extractName(element.getName()); ContentCollectionEdit collection = ContentHostingService.addCollection(resourceId); @@ -371,7 +407,7 @@ * @param out * @throws Exception */ - private void storeContentCollection(String rootId, ContentCollection collection, ZipOutputStream out) throws Exception { + private void storeContentCollection(String rootId, ContentCollection collection, ZipArchiveOutputStream out) throws Exception { List members = collection.getMembers(); for (String memberId: members) { if (memberId.endsWith(Entity.SEPARATOR)) { @@ -393,11 +429,11 @@ * @param out * @throws Exception */ - private void storeContentResource(String rootId, ContentResource resource, ZipOutputStream out) throws Exception { + private void storeContentResource(String rootId, ContentResource resource, ZipArchiveOutputStream out) throws Exception { String filename = resource.getId().substring(rootId.length(),resource.getId().length()); - ZipEntry zipEntry = new ZipEntry(filename); + ZipArchiveEntry zipEntry = new ZipArchiveEntry(filename); zipEntry.setSize(resource.getContentLength()); - out.putNextEntry(zipEntry); + out.putArchiveEntry(zipEntry); InputStream contentStream = null; try { contentStream = resource.streamContent();