Home | History | Annotate | Download | only in report
      1 /*******************************************************************************
      2  * Copyright (c) 2009, 2018 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  *******************************************************************************/
     12 package org.jacoco.report;
     13 
     14 import java.io.IOException;
     15 import java.io.OutputStream;
     16 import java.util.zip.ZipEntry;
     17 import java.util.zip.ZipOutputStream;
     18 
     19 /**
     20  * Implementation of {@link IMultiReportOutput} that writes files into a
     21  * {@link ZipOutputStream}.
     22  */
     23 public class ZipMultiReportOutput implements IMultiReportOutput {
     24 
     25 	private final ZipOutputStream zip;
     26 
     27 	private OutputStream currentEntry;
     28 
     29 	/**
     30 	 * Creates a new instance based on the given {@link ZipOutputStream}.
     31 	 *
     32 	 * @param zip
     33 	 *            stream to write file entries to
     34 	 */
     35 	public ZipMultiReportOutput(final ZipOutputStream zip) {
     36 		this.zip = zip;
     37 	}
     38 
     39 	/**
     40 	 * Creates a new instance based on the given {@link OutputStream}.
     41 	 *
     42 	 * @param out
     43 	 *            stream to write file entries to
     44 	 */
     45 	public ZipMultiReportOutput(final OutputStream out) {
     46 		this(new ZipOutputStream(out));
     47 	}
     48 
     49 	public OutputStream createFile(final String path) throws IOException {
     50 		if (currentEntry != null) {
     51 			currentEntry.close();
     52 		}
     53 		final ZipEntry entry = new ZipEntry(path);
     54 		zip.putNextEntry(entry);
     55 		currentEntry = new EntryOutput();
     56 		return currentEntry;
     57 	}
     58 
     59 	public void close() throws IOException {
     60 		zip.close();
     61 	}
     62 
     63 	private final class EntryOutput extends OutputStream {
     64 
     65 		private boolean closed = false;
     66 
     67 		@Override
     68 		public void write(final byte[] b, final int off, final int len)
     69 				throws IOException {
     70 			ensureNotClosed();
     71 			zip.write(b, off, len);
     72 		}
     73 
     74 		@Override
     75 		public void write(final byte[] b) throws IOException {
     76 			ensureNotClosed();
     77 			zip.write(b);
     78 		}
     79 
     80 		@Override
     81 		public void write(final int b) throws IOException {
     82 			ensureNotClosed();
     83 			zip.write(b);
     84 		}
     85 
     86 		@Override
     87 		public void flush() throws IOException {
     88 			ensureNotClosed();
     89 			zip.flush();
     90 		}
     91 
     92 		@Override
     93 		public void close() throws IOException {
     94 			if (!closed) {
     95 				closed = true;
     96 				zip.closeEntry();
     97 			}
     98 		}
     99 
    100 		private void ensureNotClosed() throws IOException {
    101 			if (closed) {
    102 				throw new IOException("Zip entry already closed.");
    103 			}
    104 		}
    105 
    106 	}
    107 
    108 }
    109