Author: mbenson
Date: Sun Mar 31 08:10:09 2013
New Revision: 1462892

URL: http://svn.apache.org/r1462892
Log:
split out accessibility setup to reduce the amount of code that gets inspected 
for recursive blueprinting

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

Modified: 
commons/sandbox/weaver/branches/fields/modules/privilizer/weaver/src/main/java/org/apache/commons/weaver/privilizer/Privilizer.java
URL: 
http://svn.apache.org/viewvc/commons/sandbox/weaver/branches/fields/modules/privilizer/weaver/src/main/java/org/apache/commons/weaver/privilizer/Privilizer.java?rev=1462892&r1=1462891&r2=1462892&view=diff
==============================================================================
--- 
commons/sandbox/weaver/branches/fields/modules/privilizer/weaver/src/main/java/org/apache/commons/weaver/privilizer/Privilizer.java
 (original)
+++ 
commons/sandbox/weaver/branches/fields/modules/privilizer/weaver/src/main/java/org/apache/commons/weaver/privilizer/Privilizer.java
 Sun Mar 31 08:10:09 2013
@@ -184,7 +184,7 @@ public abstract class Privilizer {
      * @throws ClassNotFoundException
      */
     public boolean weaveClass(Class<?> clazz, Privilizing privilizing) throws 
NotFoundException, IOException,
-        CannotCompileException, ClassNotFoundException, IllegalAccessException 
{
+            CannotCompileException, ClassNotFoundException, 
IllegalAccessException {
         return weave(classPool.get(clazz.getName()), privilizing);
     }
 
@@ -200,7 +200,7 @@ public abstract class Privilizer {
      * @throws ClassNotFoundException
      */
     private boolean weave(CtClass type, Privilizing privilizing) throws 
NotFoundException, IOException,
-        CannotCompileException, ClassNotFoundException, IllegalAccessException 
{
+            CannotCompileException, ClassNotFoundException, 
IllegalAccessException {
         reportSettings();
         final String policyName = generateName(POLICY_NAME);
         final String policyValue = toString(type.getAttribute(policyName));
@@ -220,7 +220,7 @@ public abstract class Privilizer {
 
             if (policy == Policy.ON_INIT) {
                 debug("Initializing field %s.%s to %s", type.getName(), 
policy.condition,
-                    HAS_SECURITY_MANAGER_CONDITION);
+                        HAS_SECURITY_MANAGER_CONDITION);
 
                 CtField securityManager = new CtField(CtClass.booleanType, 
policy.condition, type);
                 securityManager.setModifiers(Modifier.STATIC | 
Modifier.PRIVATE | Modifier.FINAL);
@@ -242,13 +242,13 @@ public abstract class Privilizer {
     }
 
     private boolean privilizeBlueprints(CtClass type, Privilizing annotation) 
throws CannotCompileException,
-        ClassNotFoundException, NotFoundException, IOException, 
IllegalAccessException {
+            ClassNotFoundException, NotFoundException, IOException, 
IllegalAccessException {
         boolean result = false;
         if (annotation != null) {
             final CallTo[] blueprintCalls = annotation.value();
             for (CallTo callTo : blueprintCalls) {
                 Validate.isTrue(!callTo.value().equals(type.getName()),
-                    "Type %s cannot use itself as a privilizer blueprint", 
callTo.value());
+                        "Type %s cannot use itself as a privilizer blueprint", 
callTo.value());
             }
             for (CtMethod method : type.getDeclaredMethods()) {
                 result = privilizeBlueprints(type, method, blueprintCalls) | 
result;
@@ -258,7 +258,8 @@ public abstract class Privilizer {
     }
 
     private boolean privilizeBlueprints(final CtClass type, final CtMethod 
method, final CallTo[] blueprintCalls)
-        throws CannotCompileException, ClassNotFoundException, 
NotFoundException, IOException, IllegalAccessException {
+            throws CannotCompileException, ClassNotFoundException, 
NotFoundException, IOException,
+            IllegalAccessException {
         final MutableBoolean result = new MutableBoolean();
 
         method.instrument(new ExprEditor() {
@@ -271,7 +272,8 @@ public abstract class Privilizer {
                     if (!Modifier.isStatic(called.getModifiers())) {
                         return;
                     }
-                } catch (NotFoundException e) {
+                }
+                catch (NotFoundException e) {
                     return;
                 }
                 boolean found = false;
@@ -296,7 +298,8 @@ public abstract class Privilizer {
                     CtMethod copy;
                     try {
                         copy = copyBlueprintTo(type, name, called, 
blueprintCalls);
-                    } catch (Exception e) {
+                    }
+                    catch (Exception e) {
                         throw new RuntimeException(e);
                     }
                     Body redirect = new Body(Privilizer.this, "call %s", 
Privilizer.this.toString(called));
@@ -317,7 +320,7 @@ public abstract class Privilizer {
 
     private static String importedMethodName(CtMethod blueprint) {
         return new 
StringBuilder(blueprint.getDeclaringClass().getName().replace('.', 
'_')).append('$')
-            .append(blueprint.getName()).toString();
+                .append(blueprint.getName()).toString();
     }
 
     /*
@@ -332,8 +335,8 @@ public abstract class Privilizer {
      * my head around it right now. -MJB
      */
     private CtMethod copyBlueprintTo(final CtClass target, final String 
toName, final CtMethod method,
-        final CallTo[] blueprintCalls) throws ClassNotFoundException, 
NotFoundException, IOException,
-        IllegalAccessException, CannotCompileException {
+            final CallTo[] blueprintCalls) throws ClassNotFoundException, 
NotFoundException, IOException,
+            IllegalAccessException, CannotCompileException {
         if (!Modifier.isStatic(method.getModifiers())) {
             return null;
         }
@@ -341,7 +344,8 @@ public abstract class Privilizer {
         try {
             final CtMethod done = target.getDeclaredMethod(toName, 
method.getParameterTypes());
             return done;
-        } catch (NotFoundException e1) {
+        }
+        catch (NotFoundException e1) {
         }
         final CtClass declaring = method.getDeclaringClass();
 
@@ -354,7 +358,8 @@ public abstract class Privilizer {
                 CtMethod called;
                 try {
                     called = m.getMethod();
-                } catch (NotFoundException e) {
+                }
+                catch (NotFoundException e) {
                     return;
                 }
                 if (called.getDeclaringClass().equals(declaring)) {
@@ -367,7 +372,8 @@ public abstract class Privilizer {
                 super.edit(f);
                 try {
                     referencedFields.add(f.getField());
-                } catch (NotFoundException e) {
+                }
+                catch (NotFoundException e) {
                 }
             }
         }
@@ -401,6 +407,11 @@ public abstract class Privilizer {
         // privilize other classes' blueprint methods recursively:
         privilizeBlueprints(target, result, blueprintCalls);
 
+        if (!referencedFields.isEmpty()) {
+            // more referenced fields handling, but reduces the amount of 
generated code we read through
+            // when blueprinting recursively
+            makeAccessible(target, result, referencedFields);
+        }
         // not really possible to check for what truly may throw a 
SecurityException and thus requires privilizing,
         // but we'll assume any public method must be. As anything else, once 
copied,
         // can only be called from something we have already privilized
@@ -419,7 +430,12 @@ public abstract class Privilizer {
     }
 
     private void handleReferencedFields(final CtClass target, final CtMethod 
method, final CtMethod source,
-        List<CtField> referencedFields) throws CannotCompileException, 
NotFoundException {
+            final List<CtField> referencedFields) throws 
CannotCompileException, NotFoundException {
+
+        for (CtField ctField : referencedFields) {
+            Validate.validState(!ctField.getDeclaringClass().equals(target),
+                    "Circular reference; cannot blueprint method %s", 
toString(source));
+        }
 
         method.instrument(new ExprEditor() {
             @Override
@@ -430,7 +446,8 @@ public abstract class Privilizer {
                 try {
                     fld = f.getField();
                     primitive = fld.getType().isPrimitive();
-                } catch (NotFoundException e) {
+                }
+                catch (NotFoundException e) {
                     // no such field implies a reference copied such that the 
field doesn't exist, probably the usual
                     // case with blueprinted methods containing field refs
 
@@ -442,11 +459,13 @@ public abstract class Privilizer {
                             fld = host.getDeclaredField(f.getFieldName());
                             primitive = fld.getType().isPrimitive();
                             break;
-                        } catch (NotFoundException e1) {
+                        }
+                        catch (NotFoundException e1) {
                         }
                         try {
                             host = host.getSuperclass();
-                        } catch (NotFoundException e1) {
+                        }
+                        catch (NotFoundException e1) {
                             break;
                         }
                     }
@@ -460,36 +479,40 @@ public abstract class Privilizer {
 
                 final String replacement;
                 if (f.isReader()) {
-                    replacement =
-                        String.format("$_ = ($%s) %s(%s.class, \"%s\", 
null);", primitive ? "w" : "r", assistant
-                            .fieldReader(target).getName(), 
fld.getDeclaringClass().getName(), f.getFieldName());
-                } else {
-                    replacement =
-                        String.format("%s(%s.class, \"%s\", null, %s);", 
assistant.fieldWriter(target).getName(), fld
-                            .getDeclaringClass().getName(), f.getFieldName(), 
primitive ? "($w) $1" : "$1");
+                    replacement = String.format("$_ = ($%s) %s(%s.class, 
\"%s\", null);", primitive ? "w" : "r",
+                            assistant.fieldReader(target).getName(), 
fld.getDeclaringClass().getName(),
+                            f.getFieldName());
+                }
+                else {
+                    replacement = String.format("%s(%s.class, \"%s\", null, 
%s);", assistant.fieldWriter(target)
+                            .getName(), fld.getDeclaringClass().getName(), 
f.getFieldName(), primitive ? "($w) $1"
+                            : "$1");
                 }
                 debug("Replacing %s access of %s.%s", f.isReader() ? "read" : 
"write", fld.getDeclaringClass()
-                    .getName(), f.getFieldName());
+                        .getName(), f.getFieldName());
                 debug(replacement);
                 f.replace(replacement);
             }
         });
+    }
 
+    private void makeAccessible(final CtClass target, final CtMethod method, 
final List<CtField> referencedFields)
+            throws CannotCompileException {
         boolean allPublic = true;
         for (CtField ctField : referencedFields) {
-            Validate.validState(!ctField.getDeclaringClass().equals(target),
-                "Circular reference; cannot blueprint method %s", 
toString(source));
             if (!Modifier.isPublic(ctField.getModifiers())) {
                 allPublic = false;
                 break;
             }
         }
-        if (!allPublic) {
-            method.insertBefore(assistant.callPushFieldAccess(target, 
referencedFields));
-            final boolean asFinally = true;
-            method.insertAfter(new 
StringBuilder(assistant.popFieldAccess(target).getName()).append("();").toString(),
+        if (allPublic) {
+            // no need to fiddle with access
+            return;
+        }
+        method.insertBefore(assistant.callPushFieldAccess(target, 
referencedFields));
+        final boolean asFinally = true;
+        method.insertAfter(new 
StringBuilder(assistant.popFieldAccess(target).getName()).append("();").toString(),
                 asFinally);
-        }
     }
 
     protected void debug(String message, Object... args) {
@@ -519,7 +542,7 @@ public abstract class Privilizer {
     }
 
     private CtClass createAction(CtClass type, CtMethod impl, Class<?> iface) 
throws NotFoundException,
-        CannotCompileException, IOException {
+            CannotCompileException, IOException {
         final boolean exc = impl.getExceptionTypes().length > 0;
 
         final CtClass actionType = classPool.get(iface.getName());
@@ -532,7 +555,8 @@ public abstract class Privilizer {
         final CtField owner;
         if (Modifier.isStatic(impl.getModifiers())) {
             owner = null;
-        } else {
+        }
+        else {
             owner = new CtField(type, generateName("owner"), result);
             owner.setModifiers(Modifier.PRIVATE | Modifier.FINAL);
             debug("Adding owner field %s to %s", owner.getName(), simpleName);
@@ -557,7 +581,8 @@ public abstract class Privilizer {
             for (final CtField fld : result.getDeclaredFields()) {
                 if (sep) {
                     sig.append(", ");
-                } else {
+                }
+                else {
                     sep = true;
                 }
                 sig.append(fld.getType().getName()).append(' 
').append(fld.getName());
@@ -577,12 +602,13 @@ public abstract class Privilizer {
                 body.append("return ");
             }
             final String deref = Modifier.isStatic(impl.getModifiers()) ? 
type.getName() : owner.getName();
-            final String call =
-                String.format("%s.%s(%s)", deref, impl.getName(), 
StringUtils.join(propagatedParameters, ", "));
+            final String call = String.format("%s.%s(%s)", deref, 
impl.getName(),
+                    StringUtils.join(propagatedParameters, ", "));
 
             if (!isVoid && rt.isPrimitive()) {
                 body.appendLine("%2$s.valueOf(%1$s);", call, 
((CtPrimitiveType) rt).getWrapperName());
-            } else {
+            }
+            else {
                 body.append(call).append(';').appendNewLine();
 
                 if (isVoid) {
@@ -601,8 +627,8 @@ public abstract class Privilizer {
         final StringBuilder b = new StringBuilder(m.getName());
         if (m.getParameterTypes().length > 0) {
             b.append("$$").append(
-                
StringUtils.strip(Descriptor.getParamDescriptor(m.getSignature()), 
"(;)").replace("[", "ARRAYOF_")
-                    .replace('/', '_').replace(';', '$'));
+                    
StringUtils.strip(Descriptor.getParamDescriptor(m.getSignature()), 
"(;)").replace("[", "ARRAYOF_")
+                            .replace('/', '_').replace(';', '$'));
         }
         return b.append(ACTION_SUFFIX).toString();
     }
@@ -612,16 +638,16 @@ public abstract class Privilizer {
     }
 
     private boolean weave(CtClass type, CtMethod method) throws 
ClassNotFoundException, CannotCompileException,
-        NotFoundException, IOException, IllegalAccessException {
+            NotFoundException, IOException, IllegalAccessException {
         final AccessLevel accessLevel = AccessLevel.of(method.getModifiers());
         if (!permitMethodWeaving(accessLevel)) {
             throw new IllegalAccessException("Method " + type.getName() + "#" 
+ toString(method)
-                + " must have maximum access level '" + getTargetAccessLevel() 
+ "' but is defined wider ('"
-                + accessLevel + "')");
+                    + " must have maximum access level '" + 
getTargetAccessLevel() + "' 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(),
-                toString(method));
+                    toString(method));
         }
         final String implName = generateName(method.getName());
 
@@ -629,7 +655,7 @@ public abstract class Privilizer {
         impl.setModifiers(AccessLevel.PRIVATE.merge(method.getModifiers()));
         type.addMethod(impl);
         debug("Copied %2$s %1$s.%3$s to %4$s %1$s.%5$s", type.getName(), 
accessLevel, toString(method),
-            AccessLevel.PRIVATE, toString(impl));
+                AccessLevel.PRIVATE, toString(impl));
 
         final Body body = new Body(this, "new body of %s", toString(method));
 
@@ -651,14 +677,16 @@ public abstract class Privilizer {
         boolean firstParam;
         if (Modifier.isStatic(impl.getModifiers())) {
             firstParam = true;
-        } else {
+        }
+        else {
             body.append("$0");
             firstParam = false;
         }
         for (int i = 1, sz = impl.getParameterTypes().length; i <= sz; i++) {
             if (firstParam) {
                 firstParam = false;
-            } else {
+            }
+            else {
                 body.append(", ");
             }
             body.append('$').append(Integer.toString(i));
@@ -674,7 +702,8 @@ public abstract class Privilizer {
             if (policy.isConditional()) {
                 body.appendLine("return;");
             }
-        } else {
+        }
+        else {
             final String cast = rt.isPrimitive() ? ((CtPrimitiveType) 
rt).getWrapperName() : rt.getName();
             // don't worry about wrapper NPEs because we should be simply
             // passing back an autoboxed value, then unboxing again
@@ -701,8 +730,8 @@ public abstract class Privilizer {
                 body.endBlock();
             }
             body.appendLine(
-                "throw %1$s instanceof RuntimeException ? (RuntimeException) 
%1$s : new RuntimeException(%1$s);",
-                wrapped);
+                    "throw %1$s instanceof RuntimeException ? 
(RuntimeException) %1$s : new RuntimeException(%1$s);",
+                    wrapped);
             body.endBlock();
         }
 


Reply via email to