You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by mb...@apache.org on 2013/04/05 20:38:39 UTC
svn commit: r1465091 - in /commons/sandbox/weaver/trunk: ./ example/
example/src/main/java/org/apache/commons/weaver/privilizer/example/
example/src/test/java/org/apache/commons/weaver/privilizer/example/
example/src/test/resources/ modules/privilizer/...
Author: mbenson
Date: Fri Apr 5 18:38:39 2013
New Revision: 1465091
URL: http://svn.apache.org/r1465091
Log:
reintegrate fields branch
Added:
commons/sandbox/weaver/trunk/processor/src/main/java/org/apache/commons/weaver/utils/Assistant.java
- copied unchanged from r1465080, commons/sandbox/weaver/branches/fields/processor/src/main/java/org/apache/commons/weaver/utils/Assistant.java
Modified:
commons/sandbox/weaver/trunk/ (props changed)
commons/sandbox/weaver/trunk/example/pom.xml
commons/sandbox/weaver/trunk/example/src/main/java/org/apache/commons/weaver/privilizer/example/UsingBlueprints.java
commons/sandbox/weaver/trunk/example/src/main/java/org/apache/commons/weaver/privilizer/example/Utils.java
commons/sandbox/weaver/trunk/example/src/test/java/org/apache/commons/weaver/privilizer/example/UsingBlueprintsTest.java
commons/sandbox/weaver/trunk/example/src/test/resources/java.policy
commons/sandbox/weaver/trunk/modules/privilizer/weaver/pom.xml
commons/sandbox/weaver/trunk/modules/privilizer/weaver/src/main/java/org/apache/commons/weaver/privilizer/Privilizer.java
commons/sandbox/weaver/trunk/modules/privilizer/weaver/src/main/java/org/apache/commons/weaver/privilizer/PrivilizerWeaver.java
commons/sandbox/weaver/trunk/pom.xml
commons/sandbox/weaver/trunk/processor/pom.xml
Propchange: commons/sandbox/weaver/trunk/
------------------------------------------------------------------------------
Merged /commons/sandbox/weaver/branches/fields:r1460191-1460199,1460201-1465080
Modified: commons/sandbox/weaver/trunk/example/pom.xml
URL: http://svn.apache.org/viewvc/commons/sandbox/weaver/trunk/example/pom.xml?rev=1465091&r1=1465090&r2=1465091&view=diff
==============================================================================
--- commons/sandbox/weaver/trunk/example/pom.xml (original)
+++ commons/sandbox/weaver/trunk/example/pom.xml Fri Apr 5 18:38:39 2013
@@ -27,12 +27,18 @@
<name>Commons Weaver Privilizer Example</name>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+ <privilizer.policy>ON_INIT</privilizer.policy>
</properties>
<dependencies>
<dependency>
<groupId>org.apache.commons</groupId>
+ <artifactId>commons-lang3</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.commons</groupId>
<artifactId>commons-weaver-privilizer-api</artifactId>
<version>${project.version}</version>
+ <scope>provided</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
@@ -49,7 +55,7 @@
<configuration>
<weaverConfig>
<privilizer.accessLevel>PACKAGE</privilizer.accessLevel>
- <privilizer.policy>ON_INIT</privilizer.policy>
+ <privilizer.policy>${privilizer.policy}</privilizer.policy>
</weaverConfig>
</configuration>
<executions>
@@ -104,6 +110,11 @@
</lifecycleMappingMetadata>
</configuration>
</plugin>
+ <plugin>
+ <groupId>org.codehaus.mojo</groupId>
+ <artifactId>exec-maven-plugin</artifactId>
+ <version>1.2.1</version>
+ </plugin>
</plugins>
</pluginManagement>
</build>
Modified: commons/sandbox/weaver/trunk/example/src/main/java/org/apache/commons/weaver/privilizer/example/UsingBlueprints.java
URL: http://svn.apache.org/viewvc/commons/sandbox/weaver/trunk/example/src/main/java/org/apache/commons/weaver/privilizer/example/UsingBlueprints.java?rev=1465091&r1=1465090&r2=1465091&view=diff
==============================================================================
--- commons/sandbox/weaver/trunk/example/src/main/java/org/apache/commons/weaver/privilizer/example/UsingBlueprints.java (original)
+++ commons/sandbox/weaver/trunk/example/src/main/java/org/apache/commons/weaver/privilizer/example/UsingBlueprints.java Fri Apr 5 18:38:39 2013
@@ -21,6 +21,10 @@ import org.apache.commons.weaver.privili
@Privilizing({ @CallTo(Utils.class), @CallTo(value = Utils.More.class, methods = "getProperty") })
public class UsingBlueprints {
+ public String utilsReadPublicConstant() {
+ return Utils.readPublicConstant();
+ }
+
public String utilsGetProperty() {
return Utils.getProperty();
}
@@ -40,7 +44,4 @@ public class UsingBlueprints {
public String moreGetTopStackElementClassName() {
return Utils.More.getTopStackElementClassName();
}
-
- private void foo() {
- }
}
Modified: commons/sandbox/weaver/trunk/example/src/main/java/org/apache/commons/weaver/privilizer/example/Utils.java
URL: http://svn.apache.org/viewvc/commons/sandbox/weaver/trunk/example/src/main/java/org/apache/commons/weaver/privilizer/example/Utils.java?rev=1465091&r1=1465090&r2=1465091&view=diff
==============================================================================
--- commons/sandbox/weaver/trunk/example/src/main/java/org/apache/commons/weaver/privilizer/example/Utils.java (original)
+++ commons/sandbox/weaver/trunk/example/src/main/java/org/apache/commons/weaver/privilizer/example/Utils.java Fri Apr 5 18:38:39 2013
@@ -32,6 +32,12 @@ public class Utils {
private Utils() {
}
+ public static final String FOO = "foo".intern();
+
+ public static String readPublicConstant() {
+ return FOO;
+ }
+
public static String getProperty() {
return getProperty("foo");
}
Modified: commons/sandbox/weaver/trunk/example/src/test/java/org/apache/commons/weaver/privilizer/example/UsingBlueprintsTest.java
URL: http://svn.apache.org/viewvc/commons/sandbox/weaver/trunk/example/src/test/java/org/apache/commons/weaver/privilizer/example/UsingBlueprintsTest.java?rev=1465091&r1=1465090&r2=1465091&view=diff
==============================================================================
--- commons/sandbox/weaver/trunk/example/src/test/java/org/apache/commons/weaver/privilizer/example/UsingBlueprintsTest.java (original)
+++ commons/sandbox/weaver/trunk/example/src/test/java/org/apache/commons/weaver/privilizer/example/UsingBlueprintsTest.java Fri Apr 5 18:38:39 2013
@@ -42,6 +42,11 @@ public class UsingBlueprintsTest {
}
@Test
+ public void testUtilsReadPublicConstant() {
+ assertEquals(Utils.FOO, usingBlueprints.utilsReadPublicConstant());
+ }
+
+ @Test
public void testUtilsGetProperty() {
assertEquals("foo-value", usingBlueprints.utilsGetProperty());
}
Modified: commons/sandbox/weaver/trunk/example/src/test/resources/java.policy
URL: http://svn.apache.org/viewvc/commons/sandbox/weaver/trunk/example/src/test/resources/java.policy?rev=1465091&r1=1465090&r2=1465091&view=diff
==============================================================================
--- commons/sandbox/weaver/trunk/example/src/test/resources/java.policy (original)
+++ commons/sandbox/weaver/trunk/example/src/test/resources/java.policy Fri Apr 5 18:38:39 2013
@@ -42,4 +42,5 @@ grant codeBase "file:${user.dir}/target/
permission java.util.PropertyPermission "foo", "read";
permission java.util.PropertyPermission "bar", "read";
permission java.util.PropertyPermission "baz", "read";
+ #permission java.lang.RuntimePermission "getClassLoader";
};
Modified: commons/sandbox/weaver/trunk/modules/privilizer/weaver/pom.xml
URL: http://svn.apache.org/viewvc/commons/sandbox/weaver/trunk/modules/privilizer/weaver/pom.xml?rev=1465091&r1=1465090&r2=1465091&view=diff
==============================================================================
--- commons/sandbox/weaver/trunk/modules/privilizer/weaver/pom.xml (original)
+++ commons/sandbox/weaver/trunk/modules/privilizer/weaver/pom.xml Fri Apr 5 18:38:39 2013
@@ -47,7 +47,6 @@
<dependency>
<groupId>org.javassist</groupId>
<artifactId>javassist</artifactId>
- <version>3.17.1-GA</version>
</dependency>
</dependencies>
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=1465091&r1=1465090&r2=1465091&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 Fri Apr 5 18:38:39 2013
@@ -41,17 +41,27 @@ import javassist.CtPrimitiveType;
import javassist.NotFoundException;
import javassist.bytecode.Descriptor;
import javassist.expr.ExprEditor;
+import javassist.expr.FieldAccess;
import javassist.expr.MethodCall;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.Validate;
+import org.apache.commons.lang3.mutable.MutableBoolean;
import org.apache.commons.lang3.text.StrBuilder;
import org.apache.commons.weaver.privilizer.Privilizing.CallTo;
+import org.apache.commons.weaver.utils.Assistant;
import org.apache.commons.weaver.utils.Body;
/**
- * Handles weaving of methods annotated with {@link Privileged}.
+ * Handles:
+ * <ul>
+ * <li>weaving of methods annotated with {@link Privileged}</li>
+ * <li>weaving of blueprint annotation methods</li>
+ * </ul>
+ *
+ * @see Privileged
+ * @see Privilizing
*/
public abstract class Privilizer {
public interface ClassFileWriter {
@@ -150,6 +160,8 @@ public abstract class Privilizer {
return result;
}
+ private final Assistant assistant;
+
public Privilizer(ClassPool classPool) {
this(Policy.DYNAMIC, classPool);
}
@@ -157,10 +169,12 @@ public abstract class Privilizer {
public Privilizer(Policy policy, ClassPool classPool) {
this.policy = Validate.notNull(policy, "policy");
this.classPool = Validate.notNull(classPool, "classPool");
+ this.assistant = new Assistant(classPool, "__privilizer_");
}
/**
- * Weave all {@link Privileged} methods found.
+ * Weave the specified class. Handles all {@link Privileged} methods as well as calls described by
+ * {@code privilizing}.
*
* @param privilizing
*
@@ -170,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);
}
@@ -186,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));
@@ -205,7 +219,8 @@ public abstract class Privilizer {
}
if (policy == Policy.ON_INIT) {
- debug("Initializing field %s to %s", policy.condition, HAS_SECURITY_MANAGER_CONDITION);
+ debug("Initializing field %s.%s to %s", type.getName(), policy.condition,
+ HAS_SECURITY_MANAGER_CONDITION);
CtField securityManager = new CtField(CtClass.booleanType, policy.condition, type);
securityManager.setModifiers(Modifier.STATIC | Modifier.PRIVATE | Modifier.FINAL);
@@ -227,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;
@@ -243,11 +258,11 @@ public abstract class Privilizer {
}
private boolean privilizeBlueprints(final CtClass type, final CtMethod method, final CallTo[] blueprintCalls)
- throws CannotCompileException, ClassNotFoundException, NotFoundException, IOException, IllegalAccessException {
- boolean result = false;
+ throws CannotCompileException, ClassNotFoundException, NotFoundException, IOException,
+ IllegalAccessException {
+ final MutableBoolean result = new MutableBoolean();
- final List<CtMethod> blueprints = new ArrayList<CtMethod>();
- class CollectBlueprints extends ExprEditor {
+ method.instrument(new ExprEditor() {
@Override
public void edit(MethodCall call) throws CannotCompileException {
super.edit(call);
@@ -257,49 +272,63 @@ public abstract class Privilizer {
if (!Modifier.isStatic(called.getModifiers())) {
return;
}
- } catch (NotFoundException e) {
+ }
+ catch (NotFoundException e) {
return;
}
+ boolean found = false;
for (CallTo callTo : blueprintCalls) {
final Class<?> owner = callTo.value();
if (owner.getName().equals(call.getClassName())) {
- if (callTo.methods().length > 0) {
- boolean found = false;
- for (String m : callTo.methods()) {
- found = StringUtils.equals(call.getMethodName(), m);
- if (found) {
- break;
- }
- }
- if (!found) {
- continue;
+ if (callTo.methods().length == 0) {
+ found = true;
+ break;
+ }
+ for (String m : callTo.methods()) {
+ found = StringUtils.equals(call.getMethodName(), m);
+ if (found) {
+ break;
}
}
- blueprints.add(called);
- break;
}
}
- }
- }
- method.instrument(new CollectBlueprints());
+ if (found) {
+ final String name = importedMethodName(called);
- for (CtMethod blueprint : blueprints) {
- final String name = importedMethodName(blueprint);
-
- CtMethod copy = copyBlueprintTo(type, name, blueprint, blueprintCalls);
- method.instrument(redirect(blueprint, copy));
- result = true;
- }
- return result;
+ CtMethod copy;
+ try {
+ copy = copyBlueprintTo(type, name, called, blueprintCalls);
+ }
+ catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ if (copy == null) {
+ debug("Unable to use %s as blueprint method in %s", Privilizer.this.toString(called), Privilizer.this.toString(method));
+ return;
+ }
+ Body redirect = new Body(Privilizer.this, "call %s", Privilizer.this.toString(called));
+ if (Privilizer.this.policy.isConditional()) {
+ redirect.startBlock("if (%s)", Privilizer.this.policy.condition);
+ }
+ redirect.appendLine("$_ = %s($$);", copy.getName());
+ if (Privilizer.this.policy.isConditional()) {
+ redirect.endBlock().startBlock("else").appendLine("$_ = $proceed($$);").endBlock();
+ }
+ call.replace(redirect.complete().toString());
+ result.setValue(Boolean.TRUE);
+ }
+ }
+ });
+ return result.booleanValue();
}
private static String importedMethodName(CtMethod blueprint) {
return new StringBuilder(blueprint.getDeclaringClass().getName().replace('.', '_')).append('$')
- .append(blueprint.getName()).toString();
+ .append(blueprint.getName()).toString();
}
/*
- * This design is almost certainly non-optimal. Basically, we have:
+ * This design is almost certainly suboptimal. Basically, we have:
*
* for a declared method, look for calls to blueprint methods for each blueprint method, copy it when copying,
* inspect blueprint method's code and recursively copy in methods from the source class of *that particular method*
@@ -310,8 +339,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 {
+ final CallTo[] blueprintCalls) throws ClassNotFoundException, NotFoundException, IOException,
+ IllegalAccessException, CannotCompileException {
if (!Modifier.isStatic(method.getModifiers())) {
return null;
}
@@ -319,59 +348,97 @@ 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();
+ final List<CtField> referencedFields = new ArrayList<CtField>();
final List<CtMethod> ownBlueprints = new ArrayList<CtMethod>();
- class CollectBlueprints extends ExprEditor {
+ class CollectOwnReferences extends ExprEditor {
@Override
public void edit(MethodCall m) throws CannotCompileException {
super.edit(m);
CtMethod called;
try {
called = m.getMethod();
- } catch (NotFoundException e) {
+ }
+ catch (NotFoundException e) {
return;
}
if (called.getDeclaringClass().equals(declaring)) {
ownBlueprints.add(called);
}
}
+
+ @Override
+ public void edit(FieldAccess f) throws CannotCompileException {
+ super.edit(f);
+ try {
+ referencedFields.add(f.getField());
+ }
+ catch (NotFoundException e) {
+ }
+ }
}
- try {
- method.instrument(new CollectBlueprints());
+ method.instrument(new CollectOwnReferences());
- boolean isRecursive = false;
+ boolean isRecursive = false;
- for (CtMethod blueprint : ownBlueprints) {
- if (blueprint.equals(method)) {
- // recursive method call identified:
- isRecursive = true;
- continue;
- }
- CtMethod local = copyBlueprintTo(target, importedMethodName(blueprint), blueprint, blueprintCalls);
- if (local != null) {
- method.instrument(redirect(blueprint, local));
- }
- }
- final CtMethod result = CtNewMethod.copy(method, toName, target, null);
- result.setModifiers(Modifier.PRIVATE | Modifier.STATIC);
- target.addMethod(result);
- if (isRecursive) {
- CodeConverter redirect = new CodeConverter();
- redirect.redirectMethodCall(method.getName(), result);
- result.instrument(redirect);
- }
- // privilize other classes' blueprint methods recursively:
- privilizeBlueprints(target, result, blueprintCalls);
- // privilize:
- weave(target, result);
+ for (CtMethod blueprint : ownBlueprints) {
+ if (blueprint.equals(method)) {
+ // recursive method call identified:
+ isRecursive = true;
+ continue;
+ }
+ CtMethod local = copyBlueprintTo(target, importedMethodName(blueprint), blueprint, blueprintCalls);
+ if (local != null) {
+ method.instrument(redirect(blueprint, local));
+ }
+ }
- return result;
- } catch (CannotCompileException e) {
+ // we have code to handle non-public fields, but the generated code gets VerifyErrors at runtime;
+ // for now we must skip blueprinting such methods.
+ boolean referencesPublicFieldsOnly = true;
+ for (CtField refd : referencedFields) {
+ if (!Modifier.isPublic(refd.getModifiers())) {
+ warn("Method %s references non-public field %s.%s", toString(method), refd.getDeclaringClass().getName(), refd.getName());
+ referencesPublicFieldsOnly = false;
+ }
+ }
+ if (!referencesPublicFieldsOnly) {
return null;
}
+
+ final CtMethod result = CtNewMethod.copy(method, toName, target, null);
+ result.setModifiers(Modifier.PRIVATE | Modifier.STATIC);
+ target.addMethod(result);
+
+ if (!referencedFields.isEmpty()) {
+ handleReferencedFields(target, result, method, referencedFields);
+ }
+ if (isRecursive) {
+ CodeConverter redirectRecursive = new CodeConverter();
+ redirectRecursive.redirectMethodCall(method.getName(), result);
+ result.instrument(redirectRecursive);
+ }
+ // 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
+ // TODO? only privilize methods the instrumented class called originally, directly
+ if (Modifier.isPublic(method.getModifiers())) {
+ weave(target, result);
+ }
+
+ return result;
}
private static CodeConverter redirect(CtMethod origMethod, CtMethod substMethod) throws CannotCompileException {
@@ -380,6 +447,95 @@ public abstract class Privilizer {
return result;
}
+ private void handleReferencedFields(final CtClass target, final CtMethod method, final CtMethod source,
+ 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
+ public void edit(FieldAccess f) throws CannotCompileException {
+ super.edit(f);
+ CtField fld;
+ boolean primitive;
+ try {
+ fld = f.getField();
+ primitive = fld.getType().isPrimitive();
+ }
+ 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
+
+ fld = null;
+ primitive = false;
+ CtClass host = source.getDeclaringClass();
+ while (host != null) {
+ try {
+ fld = host.getDeclaredField(f.getFieldName());
+ primitive = fld.getType().isPrimitive();
+ break;
+ }
+ catch (NotFoundException e1) {
+ }
+ try {
+ host = host.getSuperclass();
+ }
+ catch (NotFoundException e1) {
+ break;
+ }
+ }
+ if (fld == null) {
+ throw new RuntimeException(e);
+ }
+ }
+ final String replacement;
+ if (f.isReader()) {
+ if (Modifier.isPublic(fld.getModifiers())) {
+ replacement = String.format("$_ = %s.%s;", fld.getDeclaringClass().getName(), f.getFieldName());
+ } else {
+ replacement =
+ String.format("$_ = ($%s) %s(%s.class, \"%s\", null);", primitive ? "w" : "r", assistant
+ .fieldReader(target).getName(), fld.getDeclaringClass().getName(), f.getFieldName());
+ }
+ } else {
+ if (Modifier.isPublic(fld.getModifiers())) {
+ replacement = String.format("%s.%s = $1;", 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());
+ 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) {
+ if (!Modifier.isPublic(ctField.getModifiers())) {
+ allPublic = false;
+ break;
+ }
+ }
+ 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) {
log.fine(String.format(message, args));
}
@@ -407,7 +563,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());
@@ -420,7 +576,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);
@@ -445,13 +602,13 @@ 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());
body.appendLine("this.%1$s = %1$s;", fld.getName());
}
-
result.addConstructor(CtNewConstructor.make(sig.append(") ").append(body.complete()).toString(), result));
}
{
@@ -466,12 +623,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) {
@@ -479,12 +637,7 @@ public abstract class Privilizer {
}
}
- run.append(body.complete());
-
- final String r = run.toString();
- debug("Creating run method:");
- debug(r);
- result.addMethod(CtNewMethod.make(r, result));
+ result.addMethod(CtNewMethod.make(run.append(body.complete()).toString(), result));
}
getClassFileWriter().write(result);
debug("Returning action type %s", result);
@@ -495,8 +648,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();
}
@@ -506,16 +659,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());
@@ -523,9 +676,10 @@ 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));
+
if (policy.isConditional()) {
body.startBlock("if (%s)", policy.condition);
}
@@ -544,14 +698,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));
@@ -567,7 +723,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
@@ -594,8 +751,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();
}
Modified: commons/sandbox/weaver/trunk/modules/privilizer/weaver/src/main/java/org/apache/commons/weaver/privilizer/PrivilizerWeaver.java
URL: http://svn.apache.org/viewvc/commons/sandbox/weaver/trunk/modules/privilizer/weaver/src/main/java/org/apache/commons/weaver/privilizer/PrivilizerWeaver.java?rev=1465091&r1=1465090&r2=1465091&view=diff
==============================================================================
--- commons/sandbox/weaver/trunk/modules/privilizer/weaver/src/main/java/org/apache/commons/weaver/privilizer/PrivilizerWeaver.java (original)
+++ commons/sandbox/weaver/trunk/modules/privilizer/weaver/src/main/java/org/apache/commons/weaver/privilizer/PrivilizerWeaver.java Fri Apr 5 18:38:39 2013
@@ -23,10 +23,8 @@ public class PrivilizerWeaver implements
public static final String CONFIG_ACCESS_LEVEL = CONFIG_WEAVER + "accessLevel";
public static final String CONFIG_POLICY = CONFIG_WEAVER + "policy";
- private FilesystemPrivilizer privilizer;
-
+ private Privilizer privilizer;
private Privilizer.Policy policy;
-
private AccessLevel targetAccessLevel;
@Override
Modified: commons/sandbox/weaver/trunk/pom.xml
URL: http://svn.apache.org/viewvc/commons/sandbox/weaver/trunk/pom.xml?rev=1465091&r1=1465090&r2=1465091&view=diff
==============================================================================
--- commons/sandbox/weaver/trunk/pom.xml (original)
+++ commons/sandbox/weaver/trunk/pom.xml Fri Apr 5 18:38:39 2013
@@ -25,7 +25,6 @@
<version>10-SNAPSHOT</version>
</parent>
- <groupId>org.apache.commons</groupId>
<artifactId>commons-weaver</artifactId>
<version>0.1-SNAPSHOT</version>
<packaging>pom</packaging>
@@ -95,6 +94,11 @@
<version>3.1</version>
</dependency>
<dependency>
+ <groupId>org.javassist</groupId>
+ <artifactId>javassist</artifactId>
+ <version>3.17.1-GA</version>
+ </dependency>
+ <dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
Modified: commons/sandbox/weaver/trunk/processor/pom.xml
URL: http://svn.apache.org/viewvc/commons/sandbox/weaver/trunk/processor/pom.xml?rev=1465091&r1=1465090&r2=1465091&view=diff
==============================================================================
--- commons/sandbox/weaver/trunk/processor/pom.xml (original)
+++ commons/sandbox/weaver/trunk/processor/pom.xml Fri Apr 5 18:38:39 2013
@@ -43,6 +43,11 @@ under the License.
<artifactId>commons-lang3</artifactId>
</dependency>
<dependency>
+ <groupId>org.javassist</groupId>
+ <artifactId>javassist</artifactId>
+ <optional>true</optional>
+ </dependency>
+ <dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>