Advertisement
Guest User

Untitled

a guest
Oct 3rd, 2013
85
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 7.24 KB | None | 0 0
  1. package com.aimms.pro.common;
  2.  
  3. import com.aimms.pro.exceptions.ExtractionException;
  4. import java.io.File;
  5. import java.io.FileNotFoundException;
  6. import java.io.FileOutputStream;
  7. import java.io.IOException;
  8. import java.io.OutputStream;
  9. import java.io.RandomAccessFile;
  10. import java.util.ArrayList;
  11. import java.util.List;
  12.  
  13. import net.sf.sevenzipjbinding.ExtractAskMode;
  14. import net.sf.sevenzipjbinding.ExtractOperationResult;
  15. import net.sf.sevenzipjbinding.IArchiveExtractCallback;
  16. import net.sf.sevenzipjbinding.ISequentialOutStream;
  17. import net.sf.sevenzipjbinding.ISevenZipInArchive;
  18. import net.sf.sevenzipjbinding.PropID;
  19. import net.sf.sevenzipjbinding.SevenZip;
  20. import net.sf.sevenzipjbinding.SevenZipException;
  21. import net.sf.sevenzipjbinding.impl.RandomAccessFileInStream;
  22. import org.slf4j.Logger;
  23. import org.slf4j.LoggerFactory;
  24.  
  25. /**
  26.  * Class taken from https://gist.github.com/borisbrodski/6120309
  27.  *
  28.  * @author Horia
  29.  */
  30. public class ArchiveExtractorHelper {
  31.  
  32.     private final Logger LOG = LoggerFactory.getLogger(getClass());
  33.  
  34.     class ExtractCallback implements IArchiveExtractCallback {
  35.  
  36.         private ISevenZipInArchive inArchive;
  37.         private int index;
  38.         private Boolean skipExtraction;
  39.         private OutputStream outputStream;
  40.         private File file;
  41.  
  42.         ExtractCallback(ISevenZipInArchive inArchive) {
  43.             this.inArchive = inArchive;
  44.         }
  45.  
  46.         @Override
  47.         public void setTotal(long total) throws SevenZipException {
  48.         }
  49.  
  50.         @Override
  51.         public void setCompleted(long completeValue) throws SevenZipException {
  52.         }
  53.  
  54.         @Override
  55.         public ISequentialOutStream getStream(int index,
  56.                 ExtractAskMode extractAskMode) throws SevenZipException {
  57.  
  58.             closeOutputStream();
  59.  
  60.             this.index = index;
  61.             skipExtraction = (Boolean) inArchive.getProperty(index, PropID.IS_FOLDER);
  62.             String path = (String) inArchive.getProperty(index, PropID.PATH);
  63.             file = new File(outputDirectoryFile, path);
  64.             if (extractAskMode != ExtractAskMode.EXTRACT) {
  65.                 if (skipExtraction) {
  66.                     createDirectory(file);
  67.                 }
  68.                 return null;
  69.             }
  70.  
  71.             createDirectory(file.getParentFile());
  72.  
  73.             try {
  74.                 outputStream = new FileOutputStream(file);
  75.             } catch (FileNotFoundException e) {
  76.                 throw new SevenZipException("Error opening file: "
  77.                         + file.getAbsolutePath(), e);
  78.             }
  79.  
  80.             return new ISequentialOutStream() {
  81.                 @Override
  82.                 public int write(byte[] data) throws SevenZipException {
  83.                     try {
  84.                         outputStream.write(data);
  85.                     } catch (IOException e) {
  86.                         throw new SevenZipException("Error writing to file: "
  87.                                 + file.getAbsolutePath());
  88.                     }
  89.                     return data.length; // Return amount of proceed data
  90.                 }
  91.             };
  92.         }
  93.  
  94.         private void createDirectory(File parentFile) throws SevenZipException {
  95.             if (!parentFile.exists()) {
  96.                 if (!parentFile.mkdirs()) {
  97.                     throw new SevenZipException("Error creating directory: "
  98.                             + parentFile.getAbsolutePath());
  99.                 }
  100.             }
  101.         }
  102.  
  103.         private void closeOutputStream() throws SevenZipException {
  104.             if (outputStream != null) {
  105.                 try {
  106.                     outputStream.close();
  107.                 } catch (IOException e) {
  108.                     throw new SevenZipException("Error closing file: "
  109.                             + file.getAbsolutePath());
  110.                 }
  111.             }
  112.         }
  113.  
  114.         @Override
  115.         public void prepareOperation(ExtractAskMode extractAskMode)
  116.                 throws SevenZipException {
  117.         }
  118.  
  119.         @Override
  120.         public void setOperationResult(
  121.                 ExtractOperationResult extractOperationResult)
  122.                 throws SevenZipException {
  123.             if (skipExtraction) {
  124.                 return;
  125.             }
  126.             if (extractOperationResult != ExtractOperationResult.OK) {
  127.                 String path = (String) inArchive.getProperty(index, PropID.PATH);
  128.                 throw new SevenZipException("Extraction error: " + path);
  129.             } else {
  130.             }
  131.         }
  132.     }
  133.     private File archive;
  134.     private String outputDirectory;
  135.     private File outputDirectoryFile;
  136.  
  137.     public ArchiveExtractorHelper(File archive, String outputDirectory) {
  138.         this.archive = archive;
  139.         this.outputDirectory = outputDirectory;
  140.     }
  141.  
  142.     public void extract(String... fileNames) throws ExtractionException {
  143.         checkArchiveFile();
  144.         prepareOutputDirectory();
  145.         extractAllArchive(fileNames);
  146.     }
  147.  
  148.     private void prepareOutputDirectory() throws ExtractionException {
  149.         outputDirectoryFile = new File(outputDirectory);
  150.         if (!outputDirectoryFile.exists()) {
  151.             outputDirectoryFile.mkdirs();
  152.         } else {
  153.             if (outputDirectoryFile.list().length != 0) {
  154.                 LOG.info("Output directory not empty: "
  155.                         + outputDirectory);
  156.             }
  157.         }
  158.     }
  159.  
  160.     private void checkArchiveFile() throws ExtractionException {
  161.         if (!archive.exists()) {
  162.             throw new ExtractionException("Archive file not found: " + archive);
  163.         }
  164.         if (!archive.canRead()) {
  165.             throw new ExtractionException("Can't read archive file: {}" + archive);
  166.         }
  167.     }
  168.  
  169.     private void extractAllArchive(String... files) throws ExtractionException {
  170.         try (RandomAccessFile randomAccessFile = new RandomAccessFile(archive, "r")) {
  171.             extractArchive(randomAccessFile, files);
  172.             LOG.trace("succesfully extracted archive to {}", archive);
  173.         } catch (FileNotFoundException e) {
  174.             throw new ExtractionException("File not found", e);
  175.         } catch (IOException e) {
  176.             throw new ExtractionException("Error closing archive file", e);
  177.         }
  178.     }
  179.  
  180.     private int[] transformFileNamesToIndexes(ISevenZipInArchive inArchive, String... fileNames) throws SevenZipException {
  181.         int[] filesToExtract = null;
  182.         if (fileNames == null || fileNames.length == 0) {
  183.             return filesToExtract;
  184.         }
  185.         int count = inArchive.getNumberOfItems();
  186.         List<Integer> itemsToExtract = new ArrayList<>();
  187.         for (String fileName : fileNames) {
  188.             for (int index = 0; index < count; index++) {
  189.                 if (!((Boolean) inArchive.getProperty(index, PropID.IS_FOLDER)).booleanValue()) {
  190.                     if (fileName.equals(inArchive.getProperty(index, PropID.PATH))) {
  191.                         itemsToExtract.add(index);
  192.                         break;
  193.                     }
  194.                 }
  195.             }
  196.         }
  197.         int index = 0;
  198.         filesToExtract = new int[itemsToExtract.size()];
  199.         for (Integer integer : itemsToExtract) {
  200.             filesToExtract[index++] = integer.intValue();
  201.         }
  202.         return filesToExtract;
  203.     }
  204.  
  205.     private void extractArchive(RandomAccessFile file, String... fileNames) throws ExtractionException {
  206.         ISevenZipInArchive inArchive;
  207.         boolean ok = false;
  208.         int[] filesToExtract;
  209.         try {
  210.             inArchive = SevenZip.openInArchive(null, new RandomAccessFileInStream(file));
  211.             filesToExtract = transformFileNamesToIndexes(inArchive, fileNames);
  212.         } catch (SevenZipException e) {
  213.             throw new ExtractionException("Error opening archive", e);
  214.         }
  215.         try {
  216.             ExtractCallback callback = new ExtractCallback(inArchive);
  217.             inArchive.extract(filesToExtract, false, callback);
  218.             callback.closeOutputStream();
  219.             ok = true;
  220.         } catch (SevenZipException e) {
  221.             StringBuilder stringBuilder = new StringBuilder();
  222.             stringBuilder.append("Error extracting archive '");
  223.             stringBuilder.append(archive);
  224.             stringBuilder.append("': ");
  225.             stringBuilder.append(e.getMessage());
  226.             if (e.getCause() != null) {
  227.                 stringBuilder.append(" (");
  228.                 stringBuilder.append(e.getCause().getMessage());
  229.                 stringBuilder.append(')');
  230.             }
  231.             throw new ExtractionException(stringBuilder.toString(), e);
  232.         } finally {
  233.             try {
  234.                 inArchive.close();
  235.             } catch (SevenZipException e) {
  236.                 if (ok) {
  237.                     throw new ExtractionException("Error closing archive", e);
  238.                 }
  239.             }
  240.         }
  241.     }
  242. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement