AgentJar.java

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