SystemPropertiesRuntime.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.core.runtime;
   14
   15import java.util.Map;
   16
   17import org.objectweb.asm.MethodVisitor;
   18import org.objectweb.asm.Opcodes;
   19
   20/**
   21 * This {@link IRuntime} implementation makes the execution data available
   22 * through a special entry of the type {@link Map} in the
   23 * {@link System#getProperties()} hash table. The advantage is, that the
   24 * instrumented classes do not get dependencies to other classes than the JRE
   25 * library itself.
   26 * 
   27 * This runtime may cause problems in environments with security restrictions,
   28 * in applications that replace the system properties or in applications that
   29 * fail if non-String values are placed in the system properties.
   30 * 
   31 * @author Marc R. Hoffmann
   32 * @version $Revision: $
   33 */
   34public class SystemPropertiesRuntime extends AbstractRuntime {
   35
   36    private static final String KEYPREFIX = "jacoco-";
   37
   38    private final String key;
   39
   40    /**
   41     * Creates a new runtime.
   42     */
   43    public SystemPropertiesRuntime() {
   44        this.key = KEYPREFIX + hashCode();
   45    }
   46
   47    public int generateDataAccessor(final long classid, final String classname,
   48            final int probecount, final MethodVisitor mv) {
   49        mv.visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/System",
   50                "getProperties", "()Ljava/util/Properties;");
   51
   52        // Stack[0]: Ljava/util/Properties;
   53
   54        mv.visitLdcInsn(key);
   55
   56        // Stack[1]: Ljava/lang/String;
   57        // Stack[0]: Ljava/util/Properties;
   58
   59        mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/util/Properties",
   60                "get", "(Ljava/lang/Object;)Ljava/lang/Object;");
   61
   62        // Stack[0]: Ljava/lang/Object;
   63
   64        ExecutionDataAccess.generateAccessCall(classid, classname, probecount, mv);
   65
   66        // Stack[0]: [Z
   67
   68        return 6; // Maximum local stack size is 3
   69    }
   70
   71    public void startup() {
   72        System.getProperties().put(key, access);
   73    }
   74
   75    public void shutdown() {
   76        System.getProperties().remove(key);
   77    }
   78
   79}