ZipMultiReportOutput.java revision 1b885c7bc666c215c3947ad4d12099273a5f533f
1/*******************************************************************************
2 * Copyright (c) 2009, 2010 Mountainminds GmbH & Co. KG and Contributors
3 * All rights reserved. This program and the accompanying materials
4 * are made available under the terms of the Eclipse Public License v1.0
5 * which accompanies this distribution, and is available at
6 * http://www.eclipse.org/legal/epl-v10.html
7 *
8 * Contributors:
9 *    Marc R. Hoffmann - initial API and implementation
10 *
11 *******************************************************************************/
12package org.jacoco.report;
13
14import java.io.IOException;
15import java.io.OutputStream;
16import java.util.zip.ZipEntry;
17import java.util.zip.ZipOutputStream;
18
19/**
20 * Implementation of {@link IMultiReportOutput} that writes files into a
21 * {@link ZipOutputStream}.
22 *
23 * @author Marc R. Hoffmann
24 * @version $qualified.bundle.version$
25 */
26public class ZipMultiReportOutput implements IMultiReportOutput {
27
28	private final ZipOutputStream zip;
29
30	private OutputStream currentEntry;
31
32	/**
33	 * Creates a new instance based on the given {@link ZipOutputStream}.
34	 *
35	 * @param zip
36	 *            stream to write file entries to
37	 */
38	public ZipMultiReportOutput(final ZipOutputStream zip) {
39		this.zip = zip;
40	}
41
42	public OutputStream createFile(final String path) throws IOException {
43		if (currentEntry != null) {
44			currentEntry.close();
45		}
46		final ZipEntry entry = new ZipEntry(path);
47		zip.putNextEntry(entry);
48		currentEntry = new EntryOutput();
49		return currentEntry;
50	}
51
52	private final class EntryOutput extends OutputStream {
53
54		private boolean closed = false;
55
56		@Override
57		public void write(final byte[] b, final int off, final int len)
58				throws IOException {
59			ensureNotClosed();
60			zip.write(b, off, len);
61		}
62
63		@Override
64		public void write(final byte[] b) throws IOException {
65			ensureNotClosed();
66			zip.write(b);
67		}
68
69		@Override
70		public void write(final int b) throws IOException {
71			ensureNotClosed();
72			zip.write(b);
73		}
74
75		@Override
76		public void flush() throws IOException {
77			ensureNotClosed();
78			zip.flush();
79		}
80
81		@Override
82		public void close() throws IOException {
83			if (!closed) {
84				closed = true;
85				zip.closeEntry();
86			}
87		}
88
89		private void ensureNotClosed() throws IOException {
90			if (closed) {
91				throw new IOException("Zip entry already closed.");
92			}
93		}
94
95	}
96
97}
98