This is a very simple app, only demonstrates the usage of Interceptor, Mixin and Pointcut of each type. Please refer to the tutorial
This one is much more complex, here use JoyAop to re-implement a real RBAC system. Besides, it demonstrates the usage of the extension libraries, JoyAop could work with Hiberante(3), PicoContainer and JMock.
JDK5.0 annotation driven access control:
package net.sf.joyaop.demo.rbac;
import net.sf.joyaop.demo.rbac.annotation.Permission;
/**
* @author Shen Li
*/
public class Facade {
@Permission("create")
public void create() {
System.out.println("Create successfully.");
}
@Permission("delete")
public void delete() {
System.out.println("Delete successfully.");
}
}
Create the domain objects with the AOP mixins. (TODO UML)
Instantiate the interceptor using PicoContainer (Constructor Injection: because it's an abstract class here, the constructor should be declared as protected.
package net.sf.joyaop.demo.rbac;
import net.sf.joyaop.AbstractInterceptor;
import net.sf.joyaop.demo.rbac.annotation.Permission;
/**
* @author Shen Li
*/
public abstract class AcessControlInterceptor implements AbstractInterceptor {
private AccessController accessController;
protected AcessControlInterceptor(AccessController accessController) {
this.accessController = accessController;
}
public Object execute() throws Throwable {
Permission permissionAnnotation = getMethod().getAnnotation(Permission.class);
if (permissionAnnotation == null) {
throw new RuntimeException(
"Method " + getMethod().getName() + " doesn't have the permission annotation.");
} else {
accessController.checkPermission(permissionAnnotation.value());
}
return proceed();
}
}
Test abstract mixin (Mock the abstract methods with the the extension mock library of JoyAop):
package net.sf.joyaop.demo.rbac.model;
import net.sf.joyaop.extension.mock.MockObjectTestCase;
import org.jmock.Mock;
import java.util.HashSet;
import java.util.Set;
/**
* @author Shen Li
*/
public class RoleOwnerTest extends MockObjectTestCase {
public void testGetAllRoles() {
// mock the abstract mixin using the extension library.
// the usage is the same as JMock, except it only overrides the abstract methods.
Mock mockRoleOwner = mockAbstactMethods(RoleOwnerImpl.class);
Mock mockParentRoleOwner = mock(RoleOwnerImpl.class);
RoleOwner roleOwner = (RoleOwner) mockRoleOwner.proxy();
RoleOwner parentRoleOwner = (RoleOwner) mockParentRoleOwner.proxy();
Set parents = new HashSet();
parents.add(parentRoleOwner);
Set parentRoles = new HashSet();
Role parentRole = (Role) mock(Role.class).proxy();
parentRoles .add(parentRole);
mockRoleOwner.expects(atLeastOnce()).method("getParents").will(returnValue(parents));
mockParentRoleOwner.expects(atLeastOnce()).method("getAllRoles").will(returnValue(parentRoles));
Role role = (Role) mock(Role.class).proxy();
roleOwner.addRole(role);
assertEquals(2, roleOwner.getAllRoles().size());
assertTrue(roleOwner.getAllRoles().contains(role));
assertTrue(roleOwner.getAllRoles().contains(parentRole));
mockRoleOwner.verify();
mockParentRoleOwner.verify();
}
}
Very simple configuration file
<runtime>
<pointcut expr="interface(net.sf.joyaop.demo.rbac.model.Child)">
<mixin interface="net.sf.joyaop.demo.rbac.model.Child" class="net.sf.joyaop.demo.rbac.model.ChildImpl"/>
</pointcut>
<pointcut expr="interface(net.sf.joyaop.demo.rbac.model.Parent)">
<mixin interface="net.sf.joyaop.demo.rbac.model.Parent" class="net.sf.joyaop.demo.rbac.model.ParentImpl"/>
</pointcut>
<pointcut expr="interface(net.sf.joyaop.demo.rbac.model.RoleOwner) AND interface(net.sf.joyaop.demo.rbac.model.Child)">
<mixin interface="net.sf.joyaop.demo.rbac.model.RoleOwner" class="net.sf.joyaop.demo.rbac.model.RoleOwnerImpl"/>
</pointcut>
<pointcut expr="interface(net.sf.joyaop.demo.rbac.model.EntityInfo)">
<mixin interface="net.sf.joyaop.demo.rbac.model.EntityInfo" class="net.sf.joyaop.demo.rbac.model.EntityInfoImpl"/>
</pointcut>
<pointcut expr="interface(net.sf.joyaop.demo.rbac.model.UserInfo)">
<mixin interface="net.sf.joyaop.demo.rbac.model.UserInfo" class="net.sf.joyaop.demo.rbac.model.UserInfoImpl"/>
</pointcut>
<pointcut expr="interface(net.sf.joyaop.demo.rbac.model.PermissionOwner)">
<mixin interface="net.sf.joyaop.demo.rbac.model.PermissionOwner" class="net.sf.joyaop.demo.rbac.model.PermissionOwnerImpl"/>
</pointcut>
<pointcut expr="annotation(net.sf.joyaop.demo.rbac.annotation.Permission)">
<interceptor class="net.sf.joyaop.demo.rbac.AcessControlInterceptor"/>
</pointcut>
<pointcut expr="interface(net.sf.joyaop.demo.rbac.AccessController)">
<interceptor class="net.sf.joyaop.demo.rbac.LogDecorator"/>
</pointcut>
</runtime>
To run it, type "ant run:demo:rbac" in your console.