Skip to main content
aboutsummaryrefslogtreecommitdiffstats
blob: 76704ffdfe0ddaa6c0edba8957a52d9003c5d561 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
/*******************************************************************************
 * Copyright (c) 2007 Innoopract Informationssysteme GmbH
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *    Innoopract - initial API and implementation
 *******************************************************************************/
package org.eclipse.epp.packaging.core.io;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

/**
 * Capsules creation of archives in ZIP format. Begin with constructor, add
 * content, finally end creation with close().
 */
public class Zip {

  private final ZipOutputStream zipOutputStream;

  /**
   * Opens a new zip archive in the location denoted by file and readies it for
   * writing.
   * 
   * @param file the zip archive file that is used for writing
   * @throws FileNotFoundException
   */
  public Zip( final File file ) throws FileNotFoundException {
    this.zipOutputStream = new ZipOutputStream( new FileOutputStream( file ) );
  }

  public Zip( final File sourceFolder, final String fileName )
    throws FileNotFoundException
  {
    this( new File( sourceFolder, fileName ) );
  }

  /**
   * Adds a file to the zip archive.
   * 
   * @param relativePath The relative path to the file to add.
   */
  public void addFile( final String relativePath ) throws IOException {
    File file = new File( relativePath );
    addFileAs( file, relativePath );
  }

  /**
   * Adds the contents of a folder to the zip archive.
   * 
   * @param folder The folder to add. If the file is not a folder, nothing
   *            happens.
   */
  public void addFolder( final File folder ) throws IOException {
    if( folder.isDirectory() ) {
      addDirectoryContents( folder, folder );
    }
  }

  /**
   * Adds a file or folder to the archive. *
   * 
   * @param file The file or folder to add.
   * @param rootContainer The parent directory. All files' paths are made
   *            relative to this folder.
   */
  private void addFile( final File file, final File rootContainer )
    throws IOException
  {
    if( file.isDirectory() ) {
      addDirectoryContents( file, rootContainer );
    } else {
      String path = file.getCanonicalPath();
      String entryName 
        = path.replace( rootContainer.getCanonicalPath(), "." );//$NON-NLS-1$
      addFileAs( file, entryName );
    }
  }

  /**
   * Adds the given file to the archive.
   * 
   * @param file The file to add.
   * @param entryName The path under which to store the file.
   */
  public void addFileAs( final File file, final String entryName )
    throws IOException, FileNotFoundException
  {
    String name = entryName;
    if( entryName.startsWith( "./" ) ) {//$NON-NLS-1$
      name = name.replaceFirst( "./", "" );//$NON-NLS-1$//$NON-NLS-2$
    }
    if( entryName.startsWith( ".\\" ) ) {//$NON-NLS-1$
      name = name.replaceFirst( ".\\\\", "" );//$NON-NLS-1$//$NON-NLS-2$
    }
    this.zipOutputStream.putNextEntry( new ZipEntry( name ) );
    writeFileToZip( new FileInputStream( file ) );
    this.zipOutputStream.closeEntry();
  }

  /**
   * Closes the zip file. No further additions are possible.
   * 
   * @throws IOException if the file couldn't be closed
   */
  public void close() throws IOException {
    this.zipOutputStream.close();
  }

  /**
   * Adds all subfiles of the given directory to the archive. Paths are made
   * relative to rootContainer.
   * 
   * @param file The directory to add.
   * @param rootContainer The parent directory. All files' paths are made
   *            relative to this folder.
   */
  private void addDirectoryContents( final File file, final File rootContainer )
    throws IOException
  {
    for( File subFile : file.listFiles() ) {
      addFile( subFile, rootContainer );
    }
  }

  /**
   * Writes the given InputStream to the ZipOutputStream
   */
  private void writeFileToZip( final InputStream inStream ) throws IOException {
    byte[] buffer = new byte[ 512 ];
    int lengthRead = 0;
    while( ( lengthRead = inStream.read( buffer ) ) != -1 ) {
      this.zipOutputStream.write( buffer, 0, lengthRead );
    }
    inStream.close();
  }
}

Back to the top