OpenConcerto

Dépôt officiel du code source de l'ERP OpenConcerto
sonarqube

svn://code.openconcerto.org/openconcerto

Rev

Rev 177 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 177 Rev 180
Line 11... Line 11...
11
 * When distributing the software, include this License Header Notice in each file.
11
 * When distributing the software, include this License Header Notice in each file.
12
 */
12
 */
13
 
13
 
14
 package org.openconcerto.utils;
14
 package org.openconcerto.utils;
15
 
15
 
-
 
16
import org.openconcerto.utils.cc.ITransformerExn;
-
 
17
 
16
import java.io.BufferedInputStream;
18
import java.io.BufferedInputStream;
17
import java.io.BufferedOutputStream;
19
import java.io.BufferedOutputStream;
18
import java.io.ByteArrayInputStream;
20
import java.io.ByteArrayInputStream;
19
import java.io.ByteArrayOutputStream;
21
import java.io.ByteArrayOutputStream;
-
 
22
import java.io.Closeable;
20
import java.io.File;
23
import java.io.File;
21
import java.io.FileInputStream;
24
import java.io.FileInputStream;
22
import java.io.FileNotFoundException;
25
import java.io.FileNotFoundException;
23
import java.io.FileOutputStream;
26
import java.io.FileOutputStream;
24
import java.io.IOException;
27
import java.io.IOException;
25
import java.io.InputStream;
28
import java.io.InputStream;
26
import java.io.OutputStream;
29
import java.io.OutputStream;
27
import java.nio.ByteBuffer;
30
import java.nio.ByteBuffer;
28
import java.util.Enumeration;
31
import java.util.Enumeration;
29
import java.util.Set;
32
import java.util.Set;
-
 
33
import java.util.function.Function;
-
 
34
import java.util.jar.JarEntry;
-
 
35
import java.util.jar.JarOutputStream;
30
import java.util.zip.CRC32;
36
import java.util.zip.CRC32;
31
import java.util.zip.DeflaterOutputStream;
37
import java.util.zip.DeflaterOutputStream;
32
import java.util.zip.InflaterInputStream;
38
import java.util.zip.InflaterInputStream;
33
import java.util.zip.ZipEntry;
39
import java.util.zip.ZipEntry;
34
import java.util.zip.ZipException;
40
import java.util.zip.ZipException;
Line 38... Line 44...
38
 * Permet d'écrire dans un fichier zip.
44
 * Permet d'écrire dans un fichier zip.
39
 * 
45
 * 
40
 * @author ILM Informatique
46
 * @author ILM Informatique
41
 * @see org.openconcerto.utils.Unzip
47
 * @see org.openconcerto.utils.Unzip
42
 */
48
 */
43
public class Zip {
49
public class Zip implements Closeable {
44
 
50
 
45
    static public byte[] deflate(final String s) throws IOException {
51
    static public byte[] deflate(final String s) throws IOException {
46
        return deflate(s.getBytes(StringUtils.UTF8));
52
        return deflate(s.getBytes(StringUtils.UTF8));
47
    }
53
    }
48
 
54
 
Line 119... Line 125...
119
        if (dest.exists())
125
        if (dest.exists())
120
            dest.delete();
126
            dest.delete();
121
        createFrom(src, dest, entriesName).close();
127
        createFrom(src, dest, entriesName).close();
122
    }
128
    }
123
 
129
 
-
 
130
    static public Zip createJar(final OutputStream out) {
-
 
131
        return new Zip(out, JarOutputStream::new, JarEntry::new);
-
 
132
    }
-
 
133
 
124
    // *** Instance
134
    // *** Instance
125
 
135
 
126
    private final OutputStream outstream;
136
    private final OutputStream outstream;
-
 
137
    private final ITransformerExn<OutputStream, ZipOutputStream, IOException> createZipStream;
127
    private ZipOutputStream zos;
138
    private ZipOutputStream zos;
-
 
139
    private final Function<String, ZipEntry> createEntry;
128
    // is an entry open, ie addEntry() has been called but closeEntry() not yet
140
    // is an entry open, ie addEntry() has been called but closeEntry() not yet
129
    private boolean entryOpen;
141
    private boolean entryOpen;
130
 
142
 
131
    /**
143
    /**
132
     * Construit un fichier zip. ATTN Le fichier passé sera écrasé lors de la première écriture.
144
     * Construit un fichier zip. ATTN Le fichier passé sera écrasé lors de la première écriture.
Line 142... Line 154...
142
     * Construit un fichier zip.
154
     * Construit un fichier zip.
143
     * 
155
     * 
144
     * @param out un stream dans lequel écrire.
156
     * @param out un stream dans lequel écrire.
145
     */
157
     */
146
    public Zip(OutputStream out) {
158
    public Zip(OutputStream out) {
-
 
159
        this(out, ZipOutputStream::new, ZipEntry::new);
-
 
160
    }
-
 
161
 
-
 
162
    public Zip(OutputStream out, final ITransformerExn<OutputStream, ZipOutputStream, IOException> createZipStream, final Function<String, ZipEntry> createEntry) {
147
        this.outstream = out;
163
        this.outstream = out;
-
 
164
        this.createZipStream = createZipStream;
148
        this.zos = null;
165
        this.zos = null;
-
 
166
        this.createEntry = createEntry;
149
        this.entryOpen = false;
167
        this.entryOpen = false;
150
    }
168
    }
151
 
169
 
-
 
170
    @Override
152
    public synchronized void close() throws IOException {
171
    public synchronized void close() throws IOException {
153
        if (this.zos != null) {
172
        if (this.zos != null) {
154
            // ferme aussi le FileOutputStream
173
            // ferme aussi le FileOutputStream
155
            this.zos.close();
174
            this.zos.close();
-
 
175
        } else {
-
 
176
            this.outstream.close();
156
        }
177
        }
157
    }
178
    }
158
 
179
 
159
    // *** Ecriture
180
    // *** Ecriture
160
 
181
 
161
    private synchronized ZipOutputStream getOutStream() {
182
    private synchronized ZipOutputStream getOutStream() throws IOException {
162
        if (this.zos == null) {
183
        if (this.zos == null) {
163
            this.zos = new ZipOutputStream(this.outstream);
184
            this.zos = this.createZipStream.transformChecked(this.outstream);
164
        }
185
        }
165
        return this.zos;
186
        return this.zos;
166
    }
187
    }
167
 
188
 
-
 
189
    public ZipEntry createEntry(String name) {
-
 
190
        return this.createEntry.apply(name);
-
 
191
    }
-
 
192
 
168
    /**
193
    /**
169
     * Ajoute newFile dans ce fichier. Il sera enregistré dans le zip directement à la racine.
194
     * Ajoute newFile dans ce fichier. Il sera enregistré dans le zip directement à la racine.
170
     * 
195
     * 
171
     * @param newFile le fichier à ajouter.
196
     * @param newFile le fichier à ajouter.
172
     * @throws IOException si le fichier ne peut etre zippé.
197
     * @throws IOException si le fichier ne peut etre zippé.
173
     */
198
     */
174
    public void zip(File newFile) throws IOException {
199
    public void zip(File newFile) throws IOException {
175
        // on ne garde que la derniere partie du chemin
200
        // on ne garde que la derniere partie du chemin
-
 
201
        this.zip(newFile.getName(), newFile);
-
 
202
    }
-
 
203
 
-
 
204
    public void zip(final String entryName, final File newFile) throws IOException {
-
 
205
        final ZipEntry entry = this.createEntry(entryName);
-
 
206
        // TODO call ZipEntry.setCreationTime()
-
 
207
        entry.setTime(newFile.lastModified());
176
        try (final BufferedInputStream ins = new BufferedInputStream(new FileInputStream(newFile))) {
208
        try (final BufferedInputStream ins = new BufferedInputStream(new FileInputStream(newFile))) {
177
            this.zip(newFile.getName(), ins);
209
            this.zip(entry, ins);
178
        }
210
        }
179
    }
211
    }
180
 
212
 
181
    /**
213
    /**
182
     * Zippe le contenu de <code>in</code>.
214
     * Zippe le contenu de <code>in</code>.
183
     * 
215
     * 
184
     * @param name le nom de l'entrée.
216
     * @param name le nom de l'entrée.
185
     * @param in l'ajout.
217
     * @param in l'ajout.
186
     * @throws IOException si in ne peut etre zippé.
218
     * @throws IOException si in ne peut etre zippé.
187
     */
219
     */
188
    public synchronized void zip(String name, InputStream in) throws IOException {
220
    public void zip(String name, InputStream in) throws IOException {
-
 
221
        this.zip(this.createEntry(name), in);
-
 
222
    }
-
 
223
 
-
 
224
    public synchronized void zip(final ZipEntry entry, InputStream in) throws IOException {
189
        this.putNextEntry(name);
225
        this.putNextEntry(entry);
190
 
226
 
191
        byte b[] = new byte[512];
227
        byte b[] = new byte[512];
192
        int len = 0;
228
        int len = 0;
193
        while ((len = in.read(b)) != -1) {
229
        while ((len = in.read(b)) != -1) {
194
            this.getOutStream().write(b, 0, len);
230
            this.getOutStream().write(b, 0, len);
Line 213... Line 249...
213
     * @param name the entry name.
249
     * @param name the entry name.
214
     * @param in what to zip.
250
     * @param in what to zip.
215
     * @throws IOException if an error occurs.
251
     * @throws IOException if an error occurs.
216
     */
252
     */
217
    public synchronized void zipNonCompressed(String name, byte[] in) throws IOException {
253
    public synchronized void zipNonCompressed(String name, byte[] in) throws IOException {
218
        final ZipEntry entry = new ZipEntry(name);
254
        final ZipEntry entry = createEntry(name);
219
        entry.setMethod(ZipEntry.STORED);
255
        entry.setMethod(ZipEntry.STORED);
220
        final CRC32 crc = new CRC32();
256
        final CRC32 crc = new CRC32();
221
        crc.update(in);
257
        crc.update(in);
222
        entry.setCrc(crc.getValue());
258
        entry.setCrc(crc.getValue());
223
        entry.setSize(in.length);
259
        entry.setSize(in.length);
Line 233... Line 269...
233
     * 
269
     * 
234
     * @param name the name of the entry.
270
     * @param name the name of the entry.
235
     * @return a stream to write to the entry.
271
     * @return a stream to write to the entry.
236
     * @throws IOException if a pb occurs.
272
     * @throws IOException if a pb occurs.
237
     */
273
     */
238
    public synchronized OutputStream createEntry(String name) throws IOException {
274
    public synchronized OutputStream createEntryStream(String name) throws IOException {
239
        this.putNextEntry(name);
275
        this.putNextEntry(name);
240
        return new BufferedOutputStream(this.getOutStream()) {
276
        return new BufferedOutputStream(this.getOutStream()) {
241
            public void close() throws IOException {
277
            public void close() throws IOException {
242
                this.flush();
278
                this.flush();
243
                Zip.this.closeEntry();
279
                Zip.this.closeEntry();
244
            }
280
            }
245
        };
281
        };
246
    }
282
    }
247
 
283
 
248
    private final synchronized void putNextEntry(String name) throws IOException, FileNotFoundException {
284
    private final synchronized void putNextEntry(String name) throws IOException, FileNotFoundException {
249
        this.putNextEntry(new ZipEntry(name));
285
        this.putNextEntry(createEntry(name));
250
    }
286
    }
251
 
287
 
252
    private final synchronized void putNextEntry(ZipEntry entry) throws IOException, FileNotFoundException {
288
    private final synchronized void putNextEntry(ZipEntry entry) throws IOException, FileNotFoundException {
253
        if (this.entryOpen)
289
        if (this.entryOpen)
254
            throw new IllegalStateException("previous entry not closed");
290
            throw new IllegalStateException("previous entry not closed");