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(),