public MethodVisitor visitMethod()

in modules/privilizer/weaver/src/main/java/org/apache/commons/weaver/privilizer/PrivilizingVisitor.java [89:196]


    public MethodVisitor visitMethod(final int access, final String name, final String desc, final String signature,
        final String[] exceptions) {
        annotate();
        final MethodVisitor originalMethod = super.visitMethod(access, name, desc, signature, exceptions);
        final Method methd = new Method(name, desc);

        return new GeneratorAdapter(Privilizer.ASM_VERSION, originalMethod, access, name, desc) {

            @Override
            public AnnotationVisitor visitAnnotation(final String desc, final boolean visible) {
                if (Type.getType(Privileged.class).getDescriptor().equals(desc)) {
                    final AccessLevel localAccessLevel = AccessLevel.of(access);
                    if (accessLevel.compareTo(localAccessLevel) > 0) {
                        throw new IllegalStateException(new IllegalAccessException("Method " + className + "#" + methd
                            + " must have maximum access level '" + accessLevel + "' but is defined wider ('"
                            + localAccessLevel + "')"));
                    }
                    if (AccessLevel.PACKAGE.compareTo(accessLevel) > 0) {
                        privilizer().env.warn("Possible security leak: granting privileges to %s method %s.%s",
                            localAccessLevel, className, methd);
                    }
                    privilegedMethods.put(methd, privilizer().generateName(name));
                }
                return super.visitAnnotation(desc, visible);
            }

            @Override
            public void visitCode() {
                super.visitCode();
                if (!privilegedMethods.containsKey(methd)) {
                    return;
                }
                final String impl = privilegedMethods.get(methd);
                final boolean instanceMethod = !Modifier.isStatic(access);

                if (policy.isConditional()) {
                    privilizer().env.debug("setting up conditional execution due to policy %s", policy);
                    // test, loading boolean
                    if (policy == Policy.ON_INIT) {
                        getStatic(target, privilizer().generateName("hasSecurityManager"), Type.BOOLEAN_TYPE);
                    } else if (policy == Policy.DYNAMIC) {
                        checkSecurityManager(this);
                    }
                    final Label doPrivileged = new Label();

                    // if true, goto doPrivileged:
                    ifZCmp(NE, doPrivileged);

                    final Method implMethod = new Method(impl, desc);
                    if (instanceMethod) {
                        loadThis();
                        loadArgs();
                        invokeVirtual(target, implMethod);
                    } else {
                        loadArgs();
                        invokeStatic(target, implMethod);
                    }
                    returnValue();
                    mark(doPrivileged);
                } else {
                    privilizer().env.debug("setting up unconditional privileged execution due to policy %s", policy);
                }
                // generate action:
                final Type[] ctorArgs =
                    instanceMethod ? ArrayUtils.insert(0, methd.getArgumentTypes(), target) : methd.getArgumentTypes();
                final Type actionType = new ActionGenerator(access, methd, exceptions, PrivilizingVisitor.this).build();
                newInstance(actionType);
                dup();
                if (instanceMethod) {
                    loadThis();
                }
                loadArgs();
                invokeConstructor(actionType, new Method("<init>", Type.VOID_TYPE, ctorArgs));

                final boolean exc = ArrayUtils.isNotEmpty(exceptions);
                // mark try if needed
                final Label privTry = exc ? mark() : null;

                // execute action
                final Type arg =
                    exc ? Type.getType(PrivilegedExceptionAction.class) : Type.getType(PrivilegedAction.class);
                final Method doPrivileged = new Method("doPrivileged", Type.getType(Object.class), new Type[] { arg });
                invokeStatic(Type.getType(AccessController.class), doPrivileged);

                unbox(methd.getReturnType());
                returnValue();

                if (exc) {
                    final Type caught = Type.getType(PrivilegedActionException.class);
                    // end try
                    final Label privCatch = mark();
                    // catch
                    catchException(privTry, privCatch, caught);
                    // unwrap
                    invokeVirtual(caught, new Method("getException", Type.getType(Exception.class),
                        Privilizer.EMPTY_TYPE_ARRAY));
                    // throw
                    throwException();
                }
                // end original method
                endMethod();

                // substitute an impl visitor and continue
                mv = cv.visitMethod(AccessLevel.PRIVATE.merge(access), impl, desc, signature, exceptions);
                mv.visitCode();
            }
        };
    }