ZipUtilities.java

  1. /*
  2.  * GovWay - A customizable API Gateway
  3.  * https://govway.org
  4.  *
  5.  * Copyright (c) 2005-2025 Link.it srl (https://link.it).
  6.  *
  7.  * This program is free software: you can redistribute it and/or modify
  8.  * it under the terms of the GNU General Public License version 3, as published by
  9.  * the Free Software Foundation.
  10.  *
  11.  * This program is distributed in the hope that it will be useful,
  12.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14.  * GNU General Public License for more details.
  15.  *
  16.  * You should have received a copy of the GNU General Public License
  17.  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  18.  *
  19.  */


  20. package org.openspcoop2.utils.io;

  21. import java.io.ByteArrayInputStream;
  22. import java.io.ByteArrayOutputStream;
  23. import java.io.File;
  24. import java.io.FileOutputStream;
  25. import java.io.InputStream;
  26. import java.io.OutputStream;
  27. import java.util.ArrayList;
  28. import java.util.Collections;
  29. import java.util.Enumeration;
  30. import java.util.HashMap;
  31. import java.util.Iterator;
  32. import java.util.List;
  33. import java.util.Map;
  34. import java.util.zip.ZipEntry;
  35. import java.util.zip.ZipFile;
  36. import java.util.zip.ZipInputStream;
  37. import java.util.zip.ZipOutputStream;

  38. import org.openspcoop2.utils.UtilsException;
  39. import org.openspcoop2.utils.resources.FileSystemUtilities;

  40. /**
  41.  * ZipUtilities
  42.  *
  43.  *
  44.  * @author Poli Andrea (apoli@link.it)
  45.  * @author $Author$
  46.  * @version $Rev$, $Date$
  47.  */
  48. public class ZipUtilities {

  49.     public static byte[] zip(byte[] content,String name) throws UtilsException{
  50.         try {
  51.             ByteArrayOutputStream bout = new ByteArrayOutputStream();
  52.             ZipOutputStream zipOut = new ZipOutputStream(bout);
  53.             ByteArrayInputStream bin = new ByteArrayInputStream(content);
  54.             ZipEntry zipEntry = new ZipEntry(name);
  55.             zipOut.putNextEntry(zipEntry);
  56.             zipOut.write(content);
  57.             zipOut.flush();
  58.             zipOut.close();
  59.             bin.close();
  60.             bout.flush();
  61.             bout.close();
  62.             return bout.toByteArray();
  63.         }catch(Exception e){
  64.             throw new UtilsException("Errore durante la scrittura dello zip: "+e.getMessage(),e);
  65.         }
  66.     }
  67.    
  68.     public static byte[] zip(List<Entry> entries) throws UtilsException{
  69.         try {
  70.             ByteArrayOutputStream bout = new ByteArrayOutputStream();
  71.             ZipOutputStream zipOut = new ZipOutputStream(bout);
  72.            
  73.             for (Entry entry : entries) {
  74.                 String name = entry.getName();
  75.                 ZipEntry zipEntry = new ZipEntry(name);
  76.                 zipOut.putNextEntry(zipEntry);
  77.                 zipOut.write(entry.getContent());
  78.             }
  79.            
  80.             zipOut.flush();
  81.             zipOut.close();
  82.             bout.flush();
  83.             bout.close();
  84.             return bout.toByteArray();
  85.         }catch(Exception e){
  86.             throw new UtilsException("Errore durante la scrittura dello zip: "+e.getMessage(),e);
  87.         }
  88.     }
  89.    
  90.     public static byte[] unzip(byte[] zipContent) throws UtilsException{
  91.         try {
  92.             ByteArrayOutputStream bout = new ByteArrayOutputStream();
  93.             ByteArrayInputStream bin = new ByteArrayInputStream(zipContent);
  94.             ZipInputStream zis = new ZipInputStream(bin);
  95.             int count = 0;
  96.             ZipEntry zipEntry = zis.getNextEntry();
  97.             while(zipEntry != null){
  98.                 count++;
  99.                 if(count>1) {
  100.                     throw new UtilsException("Errore, il metodo supporta solamente archivi zip contenente un file");
  101.                 }
  102.                 int len;
  103.                 byte[] buffer = new byte[1024];
  104.                 while ((len = zis.read(buffer)) > 0) {
  105.                     bout.write(buffer, 0, len);
  106.                 }
  107.                 zipEntry = zis.getNextEntry();
  108.             }
  109.             zis.closeEntry();
  110.             zis.close();
  111.             bout.flush();
  112.             bout.close();
  113.             bin.close();
  114.             return bout.toByteArray();
  115.         }catch(Exception e){
  116.             throw new UtilsException("Errore durante la lettura dello zip: "+e.getMessage(),e);
  117.         }
  118.     }

  119.     public static List<Entry> read(byte[] zipContent) throws UtilsException{
  120.         try {
  121.             List<Entry> list = new ArrayList<>();
  122.            
  123.             ByteArrayInputStream in = new ByteArrayInputStream(zipContent);
  124.             ZipInputStream zipIn = new ZipInputStream(in);
  125.             ZipEntry entry;
  126.             while ((entry = zipIn.getNextEntry()) != null) {
  127.                 String name = entry.getName();
  128.                 //System.out.println(name);
  129.                
  130.                 if(name!=null && !( name.endsWith("/") || name.endsWith("\\") ) ){
  131.                     Entry zentry = new Entry();
  132.                     zentry.setName(name);
  133.                    
  134.                     ByteArrayOutputStream bout = new ByteArrayOutputStream();
  135.                     byte contents[] = new byte[4096];
  136.                     int direct;
  137.                     while ((direct = zipIn.read(contents, 0, contents.length)) >= 0) {
  138.                         //System.out.println("Read " + direct + "bytes content.");
  139.                         bout.write(contents, 0, direct);
  140.                     }
  141.                     bout.flush();
  142.                     bout.close();
  143.                    
  144.                     zentry.setContent(bout.toByteArray());
  145.                     list.add(zentry);
  146.                 }
  147.                
  148.                 zipIn.closeEntry();
  149.             }
  150.             zipIn.close();
  151.             in.close();

  152.             return list;
  153.            
  154.         }catch(Exception e){
  155.             throw new UtilsException("Errore durante la lettura dello zip: "+e.getMessage(),e);
  156.         }
  157.     }

  158.    
  159.     public static String getRootDir(String entry) throws UtilsException{
  160.         try{
  161.             String rootDir = null;
  162.             String dir = entry;
  163.             int indexOf=dir.indexOf(File.separatorChar);
  164.             if(indexOf<=0){
  165.                 throw new UtilsException("Errore durante l'identificazione della directory radice presente all'interno dello zip ("+indexOf+")");
  166.             }
  167.             dir = dir.substring(0,indexOf);
  168.             if(dir==null || "".equals(dir)){
  169.                 throw new UtilsException("Errore durante l'identificazione della directory radice presente all'interno dello zip ("+dir+")");
  170.             }
  171.             rootDir=dir+File.separatorChar;
  172.             return rootDir;
  173.         }catch(UtilsException ex){
  174.             throw ex;
  175.         }catch(Exception e){
  176.             throw new UtilsException("Errore durante l'identificazione della directory radice presente all'interno dello zip: "+e.getMessage(),e);
  177.         }
  178.     }
  179.    
  180.     public static String getBaseName(String file) throws UtilsException{
  181.         try{
  182.             return (new File(file)).getName();
  183.         }catch(Exception e){
  184.             throw new UtilsException("Errore durante l'identificazione del base name per il file ["+file+"]: "+e.getMessage(),e);
  185.         }
  186.     }
  187.    
  188.     public static String operativeSystemConversion(String entryName){

  189.         char separatorCharWindows = '\\';
  190.         char separatorCharLinux = '/';
  191.         boolean isWindows =  (File.separatorChar == separatorCharWindows);
  192.        
  193.         StringBuilder fixed = new StringBuilder(entryName);
  194.         for( int i = 0; i<fixed.length(); i++){
  195.            
  196.             if(isWindows){
  197.                 // se siamo su windows converto tutti i path "linux" in windows mode
  198.                 if(fixed.charAt(i) == separatorCharLinux){
  199.                     fixed.setCharAt(i, File.separatorChar);
  200.                 }
  201.             }
  202.             else{
  203.                 // se siamo su linux converto tutti i path "windows" in linux mode
  204.                 if(fixed.charAt(i) == separatorCharWindows){
  205.                     fixed.setCharAt(i, File.separatorChar);
  206.                 }
  207.             }
  208.            
  209.         }
  210.        
  211.         //System.out.println("Convertito per Windows: "+isWindows);
  212.        
  213.         return fixed.toString();
  214.     }
  215.    
  216.     public static void unzipFile(String zipFile,String dest) throws UtilsException {
  217.         try{
  218.             File destFile = new File(dest);
  219.             if(destFile.exists()==false){
  220.                 if(destFile.mkdir()==false){
  221.                     throw new Exception("Destinazione ["+dest+"] non esistente e creazione non riuscita");
  222.                 }
  223.             }else{
  224.                 if(destFile.isDirectory()==false){
  225.                     throw new Exception("Destinazione ["+dest+"] non e' una directory");
  226.                 }
  227.                 if(destFile.canWrite()==false){
  228.                     throw new Exception("Destinazione ["+dest+"] non accessibile in scrittura ");
  229.                 }
  230.             }

  231.             OutputStream out = null;
  232.             InputStream iZip = null;
  233.             ZipFile zf = null;
  234.             try{
  235.                 zf = new ZipFile(zipFile);
  236.                 for(Enumeration<?> em = zf.entries(); em.hasMoreElements();){
  237.                     ZipEntry ze = (ZipEntry) em.nextElement();
  238.                     String targetfile = destFile.getAbsolutePath()+File.separatorChar+ze.getName();

  239.                     // Parent
  240.                     FileSystemUtilities.mkdirParentDirectory(targetfile);
  241.                    
  242.                     // File
  243.                     if(ze.getName()!=null && ( ze.getName().endsWith("/") || ze.getName().endsWith("\\") ) ){
  244.                        
  245.                         // Directory
  246.                         File fDir = new File(targetfile);
  247.                         if(fDir.mkdir()==false){
  248.                             try{
  249.                                 throw new Exception("Creazione directory ["+fDir.getAbsolutePath()+"] per entry ["+ze.getName()+"] non riuscita");
  250.                             }finally{
  251.                                 try{
  252.                                     if(zf!=null){
  253.                                         zf.close();
  254.                                     }
  255.                                 }catch(Exception eClose){
  256.                                     // close
  257.                                 }
  258.                             }
  259.                         }
  260.                
  261.                     }
  262.                     else{

  263.                         // Creo file
  264.                         iZip = zf.getInputStream(ze);          
  265.                         out = new FileOutputStream(targetfile);
  266.                         byte[] buf = new byte[1024];
  267.                         int len;
  268.                         while ((len = iZip.read(buf)) > 0) {
  269.                             out.write(buf, 0, len);
  270.                         }
  271.                         iZip.close();
  272.                         iZip = null;
  273.                         out.flush();
  274.                         out.close();
  275.                         out = null;
  276.                        
  277.                     }
  278.                 }
  279.             }finally{
  280.                 try{
  281.                     if(out!=null){
  282.                         out.close();
  283.                     }
  284.                 }catch(Exception eClose){}
  285.                 try{
  286.                     if(iZip!=null){
  287.                         iZip.close();
  288.                     }
  289.                 }catch(Exception eClose){}
  290.                 try{
  291.                     if(zf!=null){
  292.                         zf.close();
  293.                     }
  294.                 }catch(Exception eClose){
  295.                     // close
  296.                 }
  297.             }

  298.         }catch(Exception e){
  299.             throw new UtilsException("Unzip non riuscito: "+e.getMessage(),e);
  300.         }
  301.     }
  302.    
  303.     public static Iterator<ZipEntry> entries(ZipFile zip,boolean ascOrder){
  304.        
  305.         // L'Enumeration ritornato dal metodo standard java.util.zip.ZipFile.entries()
  306.         // attraversa le entries presenti nello zip nello stesso ordine in cui sono state salvate.
  307.        
  308.         List<String> entryNames = new ArrayList<>();
  309.         Map<String, ZipEntry> map = new HashMap<String, ZipEntry>();
  310.         Enumeration<?> e = zip.entries();
  311.         while(e.hasMoreElements()) {
  312.             ZipEntry zipEntry = (ZipEntry)e.nextElement();
  313.             String entryName = zipEntry.getName();
  314.             entryNames.add(entryName);
  315.             map.put(entryName, zipEntry);
  316.         }
  317.        
  318.         if(ascOrder){
  319.             java.util.Collections.sort(entryNames);
  320.         }
  321.         else{
  322.             java.util.Collections.sort(entryNames,Collections.reverseOrder());
  323.         }
  324.        
  325.         List<ZipEntry> zipEntries = new ArrayList<ZipEntry>();
  326.         for (String entry : entryNames) {
  327.             zipEntries.add(map.remove(entry));
  328.         }
  329.         return zipEntries.iterator();
  330.     }
  331.    
  332. }