Demo applications

Simple demo:

This is a very simple app, only demonstrates the usage of Interceptor, Mixin and Pointcut of each type. Please refer to the tutorial

Role based access control:

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.