Author: mbenson
Date: Sat Apr 27 22:36:03 2013
New Revision: 1476690

URL: http://svn.apache.org/r1476690
Log:
use an annotation instead of an attribute to mark privilized classes

Modified:
    
commons/sandbox/weaver/trunk/modules/privilizer/weaver/src/main/java/org/apache/commons/weaver/privilizer/Privilizer.java

Modified: 
commons/sandbox/weaver/trunk/modules/privilizer/weaver/src/main/java/org/apache/commons/weaver/privilizer/Privilizer.java
URL: 
http://svn.apache.org/viewvc/commons/sandbox/weaver/trunk/modules/privilizer/weaver/src/main/java/org/apache/commons/weaver/privilizer/Privilizer.java?rev=1476690&r1=1476689&r2=1476690&view=diff
==============================================================================
--- 
commons/sandbox/weaver/trunk/modules/privilizer/weaver/src/main/java/org/apache/commons/weaver/privilizer/Privilizer.java
 (original)
+++ 
commons/sandbox/weaver/trunk/modules/privilizer/weaver/src/main/java/org/apache/commons/weaver/privilizer/Privilizer.java
 Sat Apr 27 22:36:03 2013
@@ -16,6 +16,8 @@
 package org.apache.commons.weaver.privilizer;
 
 import java.io.IOException;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Target;
 import java.lang.reflect.Modifier;
 import java.nio.charset.Charset;
 import java.security.AccessController;
@@ -39,7 +41,10 @@ import javassist.CtNewConstructor;
 import javassist.CtNewMethod;
 import javassist.CtPrimitiveType;
 import javassist.NotFoundException;
+import javassist.bytecode.AnnotationsAttribute;
 import javassist.bytecode.Descriptor;
+import javassist.bytecode.annotation.Annotation;
+import javassist.bytecode.annotation.EnumMemberValue;
 import javassist.expr.ExprEditor;
 import javassist.expr.FieldAccess;
 import javassist.expr.MethodCall;
@@ -121,6 +126,14 @@ public class Privilizer {
     }
 
     /**
+     * Class-retention annotation to mark woven classes.
+     */
+    @Target(ElementType.TYPE)
+    public @interface Privilized {
+        Policy value();
+    }
+
+    /**
      * Privilizer builder.
      */
     public static class Builder {
@@ -254,22 +267,23 @@ public class Privilizer {
     private boolean weave(CtClass type, Privilizing privilizing) throws 
NotFoundException, IOException,
         CannotCompileException, ClassNotFoundException, IllegalAccessException 
{
         reportSettings();
-        final String policyName = generateName(POLICY_NAME);
-        final String policyValue = toString(type.getAttribute(policyName));
-        if (policyValue != null) {
-            verbose("%s already woven with policy %s", type.getName(), 
policyValue);
-            if (!policy.name().equals(policyValue)) {
-                throw new AlreadyWovenException(type.getName(), 
Policy.valueOf(policyValue));
+
+        AnnotationsAttribute invisibleAnnotations =
+            (AnnotationsAttribute) 
type.getClassFile().getAttribute(AnnotationsAttribute.invisibleTag);
+
+        if (invisibleAnnotations != null) {
+            Annotation privilized = 
invisibleAnnotations.getAnnotation(Privilized.class.getName());
+            if (privilized != null) {
+                final String policyValue = ((EnumMemberValue) 
privilized.getMemberValue("value")).getValue();
+                verbose("%s already woven with policy %s", type.getName(), 
policyValue);
+                if (!policy.name().equals(policyValue)) {
+                    throw new AlreadyWovenException(type.getName(), 
Policy.valueOf(policyValue));
+                }
+                return false;
             }
-            return false;
         }
         boolean result = false;
         if (policy.compareTo(Policy.NEVER) > 0) {
-            if (type.getAttribute(policyName) != null) {
-                // if this class already got enhanced then abort
-                return false;
-            }
-
             if (policy == Policy.ON_INIT) {
                 debug("Initializing field %s.%s to %s", type.getName(), 
policy.condition,
                     HAS_SECURITY_MANAGER_CONDITION);
@@ -285,7 +299,19 @@ public class Privilizer {
                 result = weave(type, m) | result;
             }
             if (result) {
-                type.setAttribute(policyName, 
policy.name().getBytes(Charset.forName("UTF-8")));
+                if (invisibleAnnotations == null) {
+                    invisibleAnnotations =
+                        new 
AnnotationsAttribute(type.getClassFile().getConstPool(), 
AnnotationsAttribute.invisibleTag);
+                    type.getClassFile().addAttribute(invisibleAnnotations);
+                }
+                final Annotation privilized =
+                    new Annotation(Privilized.class.getName(), 
type.getClassFile().getConstPool());
+                final EnumMemberValue policyMember = new 
EnumMemberValue(type.getClassFile().getConstPool());
+                policyMember.setType(Policy.class.getName());
+                policyMember.setValue(policy.name());
+                privilized.addMemberValue("value", policyMember);
+                invisibleAnnotations.addAnnotation(privilized);
+
                 modifiedClassWriter.write(type);
             }
         }
@@ -690,8 +716,8 @@ public class Privilizer {
         final AccessLevel accessLevel = AccessLevel.of(method.getModifiers());
         if (targetAccessLevel.compareTo(accessLevel) > 0) {
             throw new IllegalAccessException("Method " + type.getName() + "#" 
+ toString(method)
-                + " must have maximum access level '" + targetAccessLevel + "' 
but is defined wider ('"
-                + accessLevel + "')");
+                + " must have maximum access level '" + targetAccessLevel + "' 
but is defined wider ('" + accessLevel
+                + "')");
         }
         if (AccessLevel.PACKAGE.compareTo(accessLevel) > 0) {
             warn("Possible security leak: granting privileges to %s method 
%s.%s", accessLevel, type.getName(),


Reply via email to