Version 1.7.4
[gae.git] / java / src / main / com / google / appengine / tools / development / agent / impl / ObjectAccessVisitor.java
blob564fcfa8cd603fe2457fe98515730991aa922e77
1 // Copyright 2009 Google Inc. All Rights Reserved.
3 package com.google.appengine.tools.development.agent.impl;
5 import org.objectweb.asm.ClassVisitor;
6 import org.objectweb.asm.MethodVisitor;
7 import org.objectweb.asm.Opcodes;
9 import java.net.URL;
10 import java.util.HashSet;
11 import java.util.Set;
13 /**
14 * Visits method and field instructions, checking for references to
15 * blacklisted classes.
18 public class ObjectAccessVisitor extends ClassVisitor {
20 private static final String REJECT = "reject";
22 private static final String REJECT_DESCRIPTOR = "(Ljava/lang/String;)V";
24 private static final String CHECK_RESTRICTED = "checkRestricted";
26 private static final String CHECK_RESTRICTED_DESCRIPTOR =
27 "(ZLjava/lang/String;Ljava/lang/String;Ljava/lang/String;)V";
29 private final boolean isUserCode;
30 private final boolean treatRestrictedListViolationsAsErrors;
31 private final String callingClassName;
32 private final String callingClassCodeSource;
33 private final Set<String> referencedClasses = new HashSet<String>();
35 public ObjectAccessVisitor(
36 ClassVisitor classVisitor, boolean isUserCode,
37 boolean treatRestrictedListViolationsAsErrors, String callingClassName, URL callingClassCodeSource) {
38 super(Opcodes.ASM4, classVisitor);
39 this.isUserCode = isUserCode;
40 this.treatRestrictedListViolationsAsErrors = treatRestrictedListViolationsAsErrors;
41 this.callingClassName = callingClassName;
42 this.callingClassCodeSource =
43 callingClassCodeSource == null ? "unknown location" : callingClassCodeSource.toString();
46 @Override
47 public MethodVisitor visitMethod(int access, String name, String desc, String signature,
48 String[] exceptions) {
49 MethodVisitor mv = super.visitMethod(access, name, desc, signature, exceptions);
50 return (mv == null) ? null : new MethodTranslator(mv, access, name, desc);
53 private class MethodTranslator extends NonRecordingGeneratorAdapter {
54 MethodTranslator(MethodVisitor methodVisitor, int access, String name, String desc) {
55 super(methodVisitor, access, name, desc);
58 @Override
59 public void visitFieldInsn(int opcode, String owner, String name, String desc) {
60 maybeReject(owner);
61 super.visitFieldInsn(opcode, owner, name, desc);
64 @Override
65 public void visitMethodInsn(int opcode, String owner, String name, String desc) {
66 maybeReject(owner);
67 super.visitMethodInsn(opcode, owner, name, desc);
70 private void maybeReject(String klass) {
71 if (BlackList.getBlackList().contains(klass)) {
72 super.push(klass.replace('/', '.'));
73 super.visitMethodInsn(Opcodes.INVOKESTATIC, AgentImpl.AGENT_RUNTIME,
74 REJECT, REJECT_DESCRIPTOR);
75 } else if (isUserCode && !referencedClasses.contains(klass)) {
76 referencedClasses.add(klass);
77 super.push(treatRestrictedListViolationsAsErrors);
78 super.push(klass.replace('/', '.'));
79 super.push(callingClassName);
80 super.push(callingClassCodeSource);
81 super.visitMethodInsn(Opcodes.INVOKESTATIC, AgentImpl.AGENT_RUNTIME,
82 CHECK_RESTRICTED, CHECK_RESTRICTED_DESCRIPTOR);