CompressorUtilities.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.InputStream;
  25. import java.io.OutputStream;
  26. import java.util.ArrayList;
  27. import java.util.List;
  28. import java.util.zip.DeflaterOutputStream;
  29. import java.util.zip.GZIPInputStream;
  30. import java.util.zip.GZIPOutputStream;
  31. import java.util.zip.InflaterInputStream;
  32. import java.util.zip.ZipEntry;
  33. import java.util.zip.ZipFile;
  34. import java.util.zip.ZipOutputStream;

  35. import org.apache.commons.compress.archivers.ArchiveEntry;
  36. import org.apache.commons.compress.archivers.ArchiveInputStream;
  37. import org.apache.commons.compress.archivers.tar.TarArchiveEntry;
  38. import org.apache.commons.compress.archivers.tar.TarArchiveInputStream;
  39. import org.apache.commons.compress.archivers.tar.TarArchiveOutputStream;
  40. import org.apache.commons.compress.archivers.zip.ZipArchiveEntry;
  41. import org.apache.commons.compress.archivers.zip.ZipArchiveInputStream;
  42. import org.apache.commons.compress.archivers.zip.ZipArchiveOutputStream;
  43. import org.apache.commons.compress.compressors.CompressorInputStream;
  44. import org.apache.commons.compress.compressors.gzip.GzipCompressorInputStream;
  45. import org.apache.commons.compress.compressors.gzip.GzipCompressorOutputStream;
  46. import org.openspcoop2.utils.UtilsException;
  47. import org.openspcoop2.utils.resources.FileSystemUtilities;

  48. /**
  49.  * CompressorUtilities
  50.  *
  51.  *
  52.  * @author Poli Andrea (apoli@link.it)
  53.  * @author $Author$
  54.  * @version $Rev$, $Date$
  55.  */
  56. public class CompressorUtilities {

  57.     public static void main(String [] args) throws Exception{
  58.        
  59.         testCompressor(null);
  60.         testArchive(null);
  61.        
  62.     }
  63.    
  64.     private static void print(String msg) {
  65.         System.out.println(msg);
  66.     }
  67.    
  68.     private static final String COMPRESSO_DIMENSIONE = "Compresso, dimensione: ";
  69.     private static final String COMPRESSO_IN_STRING = "Compresso, in stringa: ";
  70.     private static final String DECOMPRESSO_IN_STRING = "De-Compresso, in stringa: ";
  71.     private static final String INFORMAZIONE_DECOMPRESSA_DIFFERENTE = "Informazione decompressa non uguale al sorgente";
  72.     private static final String INFORMAZIONE_DECOMPRESSA_DIFFERENTE_SIZE = "Informazione decompressa non uguale al sorgente (size)";
  73.     private static final String INFORMAZIONE_DECOMPRESSA_DIFFERENTE_ENTRY_1 = "Informazione decompressa non uguale al sorgente (entry1 name:";
  74.     private static final String INFORMAZIONE_DECOMPRESSA_DIFFERENTE_ENTRY_2 = "Informazione decompressa non uguale al sorgente (entry2 name:";
  75.     private static final String INFORMAZIONE_DECOMPRESSA_DIFFERENTE_ENTRY_1_DIFFERENTE = "Informazione decompressa non uguale al sorgente (entry1 contenuto differente)";
  76.     private static final String INFORMAZIONE_DECOMPRESSA_UGUALE = "De-Compresso: test di comparazione completati con successo";
  77.     private static final String DECOMPRESSO = "De-Compresso: ";
  78.     private static final String ATTESO = " atteso:";
  79.    
  80.     public static void testCompressor(CompressorType tipo) throws UtilsException{
  81.        
  82.         String test = "<prova xmlns=\"www.test.it\">PROVA</prova>";
  83.         byte[]testB = test.getBytes();
  84.        
  85.         if(tipo==null || CompressorType.DEFLATER.equals(tipo)) {
  86.             print("\n\n=== DEFLATER ===");
  87.             byte [] compress = compress(testB, CompressorType.DEFLATER);
  88.             print(COMPRESSO_DIMENSIONE+compress.length);
  89.             print(COMPRESSO_IN_STRING+new String(compress));
  90.             String decompresso = new String(decompress(compress, CompressorType.DEFLATER));
  91.             print(DECOMPRESSO_IN_STRING+decompresso);
  92.             if(!decompresso.equals(test)) {
  93.                 throw new UtilsException(INFORMAZIONE_DECOMPRESSA_DIFFERENTE);
  94.             }
  95.         }
  96.        
  97.         if(tipo==null || CompressorType.GZIP.equals(tipo)) {
  98.             print("\n\n=== GZIP ===");
  99.             byte [] compress = compress(testB, CompressorType.GZIP);
  100.             print(COMPRESSO_DIMENSIONE+compress.length);
  101.             print(COMPRESSO_IN_STRING+new String(compress));
  102.             String decompresso = new String(decompress(compress, CompressorType.GZIP));
  103.             print(DECOMPRESSO_IN_STRING+decompresso);
  104.             if(!decompresso.equals(test)) {
  105.                 throw new UtilsException(INFORMAZIONE_DECOMPRESSA_DIFFERENTE);
  106.             }
  107.         }
  108.            
  109.         if(tipo==null || CompressorType.ZIP.equals(tipo)) {
  110.             print("\n\n=== ZIP ===");
  111.             byte [] compress = compress(testB, CompressorType.ZIP);
  112.             print(COMPRESSO_DIMENSIONE+compress.length);
  113.             print(COMPRESSO_IN_STRING+new String(compress));
  114.             String decompresso = new String(decompress(compress, CompressorType.ZIP));
  115.             print(DECOMPRESSO_IN_STRING+decompresso);
  116.             if(!decompresso.equals(test)) {
  117.                 throw new UtilsException(INFORMAZIONE_DECOMPRESSA_DIFFERENTE);
  118.             }
  119.         }
  120.        
  121.     }
  122.    
  123.     public static void testArchive(ArchiveType tipo) throws Exception{
  124.        
  125.         String entryName = "entry1";
  126.         String test = "<prova xmlns=\"www.test.it\">PROVA</prova>";
  127.         byte[]testB = test.getBytes();
  128.        
  129.         String entryName2 = "dir/subdir/entry2";
  130.         String test2 = "<prova xmlns=\"www.test.it\">PROVA2</prova>";
  131.         byte[]test2B = test2.getBytes();
  132.        
  133.         List<Entry> entries = new ArrayList<>();
  134.         entries.add(new Entry(entryName,testB));
  135.         entries.add(new Entry(entryName2,test2B));
  136.        
  137.         if(tipo==null || ArchiveType.ZIP.equals(tipo)) {
  138.             print("\n\n=== ZIP ===");
  139.             byte [] compress = archive(entries, ArchiveType.ZIP);
  140.             print(COMPRESSO_DIMENSIONE+compress.length);
  141.             List<Entry> entriesRead = read(compress, ArchiveType.ZIP);
  142.             print(DECOMPRESSO+entriesRead.size());
  143.             if(entriesRead.size()!=2) {
  144.                 throw new UtilsException(INFORMAZIONE_DECOMPRESSA_DIFFERENTE_SIZE);
  145.             }
  146.             Entry entryRead1 = entriesRead.get(0);
  147.             Entry entryRead2 = entriesRead.get(1);
  148.             if(!entryName.equals(entryRead1.getName())) {
  149.                 throw new UtilsException(INFORMAZIONE_DECOMPRESSA_DIFFERENTE_ENTRY_1+entryRead1.getName()+ATTESO+entryName+")");
  150.             }
  151.             if(!entryName2.equals(entryRead2.getName())) {
  152.                 throw new UtilsException(INFORMAZIONE_DECOMPRESSA_DIFFERENTE_ENTRY_2+entryRead2.getName()+ATTESO+entryName2+")");
  153.             }
  154.             if(!test.equals(new String(entryRead1.getContent()))) {
  155.                 throw new UtilsException(INFORMAZIONE_DECOMPRESSA_DIFFERENTE_ENTRY_1_DIFFERENTE);
  156.             }
  157.             if(!test2.equals(new String(entryRead2.getContent()))) {
  158.                 throw new UtilsException(INFORMAZIONE_DECOMPRESSA_DIFFERENTE_ENTRY_1_DIFFERENTE);
  159.             }
  160.             print(INFORMAZIONE_DECOMPRESSA_UGUALE);
  161.         }
  162.        
  163.         if(tipo==null || ArchiveType.TAR.equals(tipo)) {
  164.             print("\n\n=== TAR ===");
  165.             byte [] compress = archive(entries, ArchiveType.TAR);
  166.             print(COMPRESSO_DIMENSIONE+compress.length);
  167.             List<Entry> entriesRead = read(compress, ArchiveType.TAR);
  168.             print(DECOMPRESSO+entriesRead.size());
  169.             if(entriesRead.size()!=2) {
  170.                 throw new UtilsException(INFORMAZIONE_DECOMPRESSA_DIFFERENTE_SIZE);
  171.             }
  172.             Entry entryRead1 = entriesRead.get(0);
  173.             Entry entryRead2 = entriesRead.get(1);
  174.             if(!entryName.equals(entryRead1.getName())) {
  175.                 throw new UtilsException(INFORMAZIONE_DECOMPRESSA_DIFFERENTE_ENTRY_1+entryRead1.getName()+ATTESO+entryName+")");
  176.             }
  177.             if(!entryName2.equals(entryRead2.getName())) {
  178.                 throw new UtilsException(INFORMAZIONE_DECOMPRESSA_DIFFERENTE_ENTRY_2+entryRead2.getName()+ATTESO+entryName2+")");
  179.             }
  180.             if(!test.equals(new String(entryRead1.getContent()))) {
  181.                 throw new UtilsException(INFORMAZIONE_DECOMPRESSA_DIFFERENTE_ENTRY_1_DIFFERENTE);
  182.             }
  183.             if(!test2.equals(new String(entryRead2.getContent()))) {
  184.                 throw new UtilsException(INFORMAZIONE_DECOMPRESSA_DIFFERENTE_ENTRY_1_DIFFERENTE);
  185.             }
  186.             print(INFORMAZIONE_DECOMPRESSA_UGUALE);
  187.         }
  188.        
  189.         if(tipo==null || ArchiveType.TGZ.equals(tipo)) {
  190.             print("\n\n=== TGZ ===");
  191.             byte [] compress = archive(entries, ArchiveType.TGZ);
  192.             print(COMPRESSO_DIMENSIONE+compress.length);
  193.             List<Entry> entriesRead = read(compress, ArchiveType.TGZ);
  194.             print(DECOMPRESSO+entriesRead.size());
  195.             if(entriesRead.size()!=2) {
  196.                 throw new UtilsException(INFORMAZIONE_DECOMPRESSA_DIFFERENTE_SIZE);
  197.             }
  198.             Entry entryRead1 = entriesRead.get(0);
  199.             Entry entryRead2 = entriesRead.get(1);
  200.             if(!entryName.equals(entryRead1.getName())) {
  201.                 throw new UtilsException(INFORMAZIONE_DECOMPRESSA_DIFFERENTE_ENTRY_1+entryRead1.getName()+ATTESO+entryName+")");
  202.             }
  203.             if(!entryName2.equals(entryRead2.getName())) {
  204.                 throw new UtilsException(INFORMAZIONE_DECOMPRESSA_DIFFERENTE_ENTRY_2+entryRead2.getName()+ATTESO+entryName2+")");
  205.             }
  206.             if(!test.equals(new String(entryRead1.getContent()))) {
  207.                 throw new UtilsException(INFORMAZIONE_DECOMPRESSA_DIFFERENTE_ENTRY_1_DIFFERENTE);
  208.             }
  209.             if(!test2.equals(new String(entryRead2.getContent()))) {
  210.                 throw new UtilsException(INFORMAZIONE_DECOMPRESSA_DIFFERENTE_ENTRY_1_DIFFERENTE);
  211.             }
  212.             print(INFORMAZIONE_DECOMPRESSA_UGUALE);
  213.         }

  214.        
  215.     }
  216.    
  217.     public static byte[] compress(byte[] content, CompressorType type) throws UtilsException {
  218.         ByteArrayOutputStream baos = new ByteArrayOutputStream();
  219.         try {
  220.             OutputStream out = null;
  221.             switch (type) {
  222.             case DEFLATER:
  223.                 out = new DeflaterOutputStream(baos);
  224.                 out.write(content);
  225.                 break;
  226.             case GZIP:
  227.                 out = new GZIPOutputStream(baos);
  228.                 out.write(content);
  229.                 break;
  230.             case ZIP:
  231.                 out = new ZipOutputStream(baos);
  232.                 ((ZipOutputStream)out).putNextEntry(new ZipEntry("dat"));
  233.                 out.write(content);
  234.                 ((ZipOutputStream)out).closeEntry();
  235.                 break;
  236.             }
  237.             if(out==null) {
  238.                 throw new UtilsException("OutputStream undefined");
  239.             }
  240.             out.flush();
  241.             out.close();
  242.             baos.flush();
  243.             baos.close();
  244.             return baos.toByteArray();
  245.         } catch (Exception e) {
  246.             throw new UtilsException(e.getMessage(),e);
  247.         }
  248.     }
  249.    
  250.     public static byte[] archive(List<Entry> entries, ArchiveType type) throws UtilsException{
  251.         try {
  252.             ByteArrayOutputStream bout = new ByteArrayOutputStream();
  253.            
  254.             org.apache.commons.compress.archivers.ArchiveOutputStream<?>  out = null;
  255.             org.apache.commons.compress.compressors.CompressorOutputStream compressorOut = null;
  256.             switch (type) {
  257.             case TAR:
  258.                 out = new TarArchiveOutputStream(bout);
  259.                 break;
  260.             case TGZ:
  261.                 compressorOut = new GzipCompressorOutputStream(bout);
  262.                 out = new TarArchiveOutputStream(compressorOut);
  263.                 break;
  264.             case ZIP:
  265.                 out = new ZipArchiveOutputStream(bout);
  266.                 break;
  267.             }
  268.             if(out==null) {
  269.                 throw new UtilsException("OutputStream undefined");
  270.             }
  271.             for (Entry entry : entries) {
  272.                 String name = entry.getName();
  273.                 ArchiveEntry archiveEntry = null;
  274.                 switch (type) {
  275.                 case TAR:
  276.                 case TGZ:
  277.                     archiveEntry = new TarArchiveEntry(name);
  278.                     ((TarArchiveEntry)archiveEntry).setSize(entry.getContent().length);
  279.                     break;
  280.                 case ZIP:
  281.                     archiveEntry = new ZipArchiveEntry(name);
  282.                     break;
  283.                 }
  284.                 switch (type) {
  285.                 case TAR:
  286.                 case TGZ:
  287.                     ((TarArchiveOutputStream)out).putArchiveEntry((TarArchiveEntry) archiveEntry);
  288.                     break;
  289.                 case ZIP:
  290.                     ((ZipArchiveOutputStream)out).putArchiveEntry((ZipArchiveEntry)archiveEntry);
  291.                     break;
  292.                 }
  293.                 out.write(entry.getContent());
  294.                 out.closeArchiveEntry();
  295.             }
  296.             out.flush();
  297.             out.close();
  298.             if(compressorOut!=null) {
  299.                 compressorOut.flush();
  300.                 compressorOut.close();
  301.             }
  302.             bout.flush();
  303.             bout.close();
  304.             return bout.toByteArray();
  305.         }catch(Exception e){
  306.             throw new UtilsException("Errore durante la scrittura '"+type+"': "+e.getMessage(),e);
  307.         }
  308.     }

  309.     public static byte [] decompress(byte[] bytes, CompressorType type) throws UtilsException {
  310.         InputStream in = null;
  311.         ByteArrayInputStream bin = null;
  312.         ByteArrayOutputStream baos = new ByteArrayOutputStream();
  313.         try {
  314.             bin = new ByteArrayInputStream(bytes);
  315.             byte[] buffer = new byte[8192];
  316.             int len;
  317.             switch (type) {
  318.             case DEFLATER:
  319.                 in = new InflaterInputStream(bin);
  320.                 while((len = in.read(buffer))>0)
  321.                     baos.write(buffer, 0, len);
  322.                 break;
  323.             case GZIP:
  324.                 in = new GZIPInputStream(bin);
  325.                 while((len = in.read(buffer))>0)
  326.                     baos.write(buffer, 0, len);
  327.                 break;
  328.             case ZIP:
  329.                 File f = FileSystemUtilities.createTempFile("unzip", "zip");
  330.                 ZipFile zf = null;
  331.                 try{
  332.                     FileSystemUtilities.writeFile(f, bytes);
  333.                     zf = new ZipFile(f);
  334.                     ZipEntry ze = zf.entries().nextElement();
  335.                     in = zf.getInputStream(ze);
  336.                     while((len = in.read(buffer))>0)
  337.                         baos.write(buffer, 0, len);
  338.                 }finally{
  339.                     try{
  340.                         if(f!=null) {
  341.                             java.nio.file.Files.delete(f.toPath());
  342.                         }
  343.                     }catch(Exception eClose){
  344.                         // ignore
  345.                     }
  346.                     try{
  347.                         if(zf!=null){
  348.                             zf.close();
  349.                         }
  350.                     }catch(Exception eClose){
  351.                         // close
  352.                     }
  353.                 }
  354.                 break;
  355.             }
  356.             baos.flush();
  357.             baos.close();
  358.             return baos.toByteArray();
  359.         }  catch (Exception e) {
  360.             throw new UtilsException(e.getMessage(),e);
  361.         }
  362.     }
  363.    
  364.     public static List<Entry> read(byte[] archiveContent, ArchiveType type) throws UtilsException{
  365.         try {
  366.             List<Entry> list = new ArrayList<>();
  367.            
  368.             ByteArrayInputStream bin = new ByteArrayInputStream(archiveContent);
  369.             ArchiveInputStream<?> in = null;
  370.             CompressorInputStream compressorIn = null;
  371.             switch (type) {
  372.             case TAR:
  373.                 in = new TarArchiveInputStream(bin);
  374.                 break;
  375.             case TGZ:
  376.                 compressorIn = new GzipCompressorInputStream(bin);
  377.                 in = new TarArchiveInputStream(compressorIn);
  378.                 break;
  379.             case ZIP:
  380.                 in = new ZipArchiveInputStream(bin);
  381.                 break;
  382.             }
  383.             if(in==null) {
  384.                 throw new UtilsException("InputStream undefined");
  385.             }
  386.             ArchiveEntry entry;
  387.             while ((entry = in.getNextEntry()) != null) {
  388.                 String name = entry.getName();
  389.                 /**print(name);*/
  390.                
  391.                 if(name!=null && !( name.endsWith("/") || name.endsWith("\\") ) ){
  392.                     Entry zentry = new Entry();
  393.                     zentry.setName(name);
  394.                    
  395.                     ByteArrayOutputStream bout = new ByteArrayOutputStream();
  396.                     byte [] contents = new byte[4096];
  397.                     int direct;
  398.                     while ((direct = in.read(contents, 0, contents.length)) >= 0) {
  399.                         /**print("Read " + direct + "bytes content.");*/
  400.                         bout.write(contents, 0, direct);
  401.                     }
  402.                     bout.flush();
  403.                     bout.close();
  404.                    
  405.                     zentry.setContent(bout.toByteArray());
  406.                     list.add(zentry);
  407.                 }
  408.                
  409.                /** in.closeEntry(); */
  410.             }
  411.             if(compressorIn!=null) {
  412.                 compressorIn.close();
  413.             }
  414.             in.close();
  415.             bin.close();

  416.             return list;
  417.            
  418.         }catch(Exception e){
  419.             throw new UtilsException("Errore durante la lettura '"+type+"': "+e.getMessage(),e);
  420.         }
  421.     }
  422. }