Home | History | Annotate | Download | only in agent
      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.agent;
     13 
     14 import java.io.Closeable;
     15 import java.io.File;
     16 import java.io.FileOutputStream;
     17 import java.io.IOException;
     18 import java.io.InputStream;
     19 import java.io.OutputStream;
     20 import java.net.URL;
     21 
     22 /**
     23  * API to access the agent JAR file as a resource. While the agent is a JAR file
     24  * it is considered as a plain resource that must be configured for the
     25  * application under test (target JVM). The agent JAR does not provide any
     26  * public Java API.
     27  */
     28 public final class AgentJar {
     29 
     30 	/**
     31 	 * Name of the agent JAR file resource within this bundle.
     32 	 */
     33 	private static final String RESOURCE = "/jacocoagent.jar";
     34 
     35 	private AgentJar() {
     36 	}
     37 
     38 	/**
     39 	 * Returns a URL pointing to the JAR file.
     40 	 *
     41 	 * @return URL of the JAR file
     42 	 */
     43 	public static URL getResource() {
     44 		final URL url = AgentJar.class.getResource(RESOURCE);
     45 		if (url == null) {
     46 			throw new AssertionError(ERRORMSG);
     47 		}
     48 		return url;
     49 	}
     50 
     51 	/**
     52 	 * Returns the content of the JAR file as a stream.
     53 	 *
     54 	 * @return content of the JAR file
     55 	 */
     56 	public static InputStream getResourceAsStream() {
     57 		final InputStream stream = AgentJar.class.getResourceAsStream(RESOURCE);
     58 		if (stream == null) {
     59 			throw new AssertionError(ERRORMSG);
     60 		}
     61 		return stream;
     62 	}
     63 
     64 	/**
     65 	 * Extract the JaCoCo agent JAR and put it into a temporary location. This
     66 	 * file should be deleted on exit, but may not if the VM is terminated
     67 	 *
     68 	 * @return Location of the Agent Jar file in the local file system. The file
     69 	 *         should exist and be readable.
     70 	 * @throws IOException
     71 	 *             Unable to unpack agent jar
     72 	 */
     73 	public static File extractToTempLocation() throws IOException {
     74 		final File agentJar = File.createTempFile("jacocoagent", ".jar");
     75 		agentJar.deleteOnExit();
     76 
     77 		extractTo(agentJar);
     78 
     79 		return agentJar;
     80 	}
     81 
     82 	/**
     83 	 * Extract the JaCoCo agent JAR and put it into the specified location.
     84 	 *
     85 	 * @param destination
     86 	 *            Location to write JaCoCo Agent Jar to. Must be writeable
     87 	 * @throws IOException
     88 	 *             Unable to unpack agent jar
     89 	 */
     90 	public static void extractTo(File destination) throws IOException {
     91 		InputStream inputJarStream = getResourceAsStream();
     92 		OutputStream outputJarStream = null;
     93 
     94 		try {
     95 
     96 			outputJarStream = new FileOutputStream(destination);
     97 
     98 			final byte[] buffer = new byte[8192];
     99 
    100 			int bytesRead;
    101 			while ((bytesRead = inputJarStream.read(buffer)) != -1) {
    102 				outputJarStream.write(buffer, 0, bytesRead);
    103 			}
    104 		} finally {
    105 			safeClose(inputJarStream);
    106 			safeClose(outputJarStream);
    107 		}
    108 	}
    109 
    110 	/**
    111 	 * Close a stream ignoring any error
    112 	 *
    113 	 * @param closeable
    114 	 *            stream to be closed
    115 	 */
    116 	private static void safeClose(Closeable closeable) {
    117 		try {
    118 			if (closeable != null) {
    119 				closeable.close();
    120 			}
    121 		} catch (IOException e) {
    122 		}
    123 	}
    124 
    125 	private static final String ERRORMSG = String.format(
    126 			"The resource %s has not been found. Please see "
    127 					+ "/org.jacoco.agent/README.TXT for details.", RESOURCE);
    128 
    129 }
    130