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}