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>