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