You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@archiva.apache.org by ol...@apache.org on 2012/04/06 11:59:32 UTC

svn commit: r1310268 [33/42] - in /archiva/redback/redback-core/trunk: ./ redback-authentication/ redback-authentication/redback-authentication-api/ redback-authentication/redback-authentication-api/src/ redback-authentication/redback-authentication-ap...

Added: archiva/redback/redback-core/trunk/redback-rbac/redback-rbac-providers/redback-rbac-jdo/src/main/java/org/codehaus/plexus/redback/rbac/jdo/JdoRbacManager.java
URL: http://svn.apache.org/viewvc/archiva/redback/redback-core/trunk/redback-rbac/redback-rbac-providers/redback-rbac-jdo/src/main/java/org/codehaus/plexus/redback/rbac/jdo/JdoRbacManager.java?rev=1310268&view=auto
==============================================================================
--- archiva/redback/redback-core/trunk/redback-rbac/redback-rbac-providers/redback-rbac-jdo/src/main/java/org/codehaus/plexus/redback/rbac/jdo/JdoRbacManager.java (added)
+++ archiva/redback/redback-core/trunk/redback-rbac/redback-rbac-providers/redback-rbac-jdo/src/main/java/org/codehaus/plexus/redback/rbac/jdo/JdoRbacManager.java Fri Apr  6 09:58:14 2012
@@ -0,0 +1,694 @@
+package org.codehaus.plexus.redback.rbac.jdo;
+
+/*
+ * Copyright 2005 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import org.codehaus.plexus.redback.rbac.AbstractRBACManager;
+import org.codehaus.plexus.redback.rbac.Operation;
+import org.codehaus.plexus.redback.rbac.Permission;
+import org.codehaus.plexus.redback.rbac.RBACManagerListener;
+import org.codehaus.plexus.redback.rbac.RBACObjectAssertions;
+import org.codehaus.plexus.redback.rbac.RbacManagerException;
+import org.codehaus.plexus.redback.rbac.RbacObjectInvalidException;
+import org.codehaus.plexus.redback.rbac.RbacObjectNotFoundException;
+import org.codehaus.plexus.redback.rbac.RbacPermanentException;
+import org.codehaus.plexus.redback.rbac.Resource;
+import org.codehaus.plexus.redback.rbac.Role;
+import org.codehaus.plexus.redback.rbac.UserAssignment;
+import org.springframework.stereotype.Service;
+
+import javax.annotation.PostConstruct;
+import javax.inject.Inject;
+import javax.jdo.JDOHelper;
+import javax.jdo.PersistenceManager;
+import javax.jdo.Transaction;
+import java.util.Collection;
+import java.util.List;
+
+/**
+ * JdoRbacManager:
+ *
+ * @author <a href="mailto:joakim@erdfelt.com">Joakim Erdfelt</a>
+ * @author Jesse McConnell <jm...@apache.org>
+ * @version $Id$
+ */
+@Service( "rBACManager#jdo" )
+public class JdoRbacManager
+    extends AbstractRBACManager
+    implements RBACManagerListener
+{
+    @Inject
+    private JdoTool jdo;
+
+    private boolean enableCache = true;
+
+    // private static final String ROLE_DETAIL = "role-child-detail";
+    private static final String ROLE_DETAIL = null;
+
+    // ----------------------------------------------------------------------
+    // Role methods
+    // ----------------------------------------------------------------------
+
+    /**
+     * Creates an implementation specific {@link Role}.
+     * <p/>
+     * Note: this method does not add the {@link Role} to the underlying store.
+     * a call to {@link #saveRole(Role)} is required to track the role created with this
+     * method call.
+     *
+     * @param name the name.
+     * @return the new {@link Role} object with an empty (non-null) {@link Role#getChildRoleNames()} object.
+     * @throws RbacManagerException
+     */
+    public Role createRole( String name )
+    {
+        Role role;
+
+        try
+        {
+            role = getRole( name );
+        }
+        catch ( RbacManagerException e )
+        {
+            role = new JdoRole();
+            role.setName( name );
+        }
+
+        return role;
+    }
+
+    /**
+     * Method addRole
+     *
+     * @param role
+     */
+    public Role saveRole( Role role )
+        throws RbacObjectInvalidException, RbacManagerException
+    {
+        RBACObjectAssertions.assertValid( role );
+
+        return (Role) jdo.saveObject( role, new String[]{ ROLE_DETAIL } );
+    }
+
+    public boolean roleExists( Role role )
+    {
+        return jdo.objectExists( role );
+    }
+
+    public boolean roleExists( String name )
+    {
+        try
+        {
+            return jdo.objectExistsById( JdoRole.class, name );
+        }
+        catch ( RbacManagerException e )
+        {
+            return false;
+        }
+    }
+
+    /**
+     * @param roleName
+     * @return
+     * @throws RbacObjectNotFoundException
+     * @throws RbacManagerException
+     */
+    public Role getRole( String roleName )
+        throws RbacObjectNotFoundException, RbacManagerException
+    {
+        return (Role) jdo.getObjectById( JdoRole.class, roleName, ROLE_DETAIL );
+    }
+
+    /**
+     * Method getRoles
+     */
+    @SuppressWarnings( "unchecked" )
+    public List<Role> getAllRoles()
+        throws RbacManagerException
+    {
+        return (List<Role>) jdo.getAllObjects( JdoRole.class );
+    }
+
+    public void removeRole( Role role )
+        throws RbacObjectNotFoundException, RbacObjectInvalidException, RbacManagerException
+    {
+        RBACObjectAssertions.assertValid( role );
+
+        if ( role.isPermanent() )
+        {
+            throw new RbacPermanentException( "Unable to delete permanent role [" + role.getName() + "]" );
+        }
+
+        jdo.removeObject( role );
+    }
+
+    public void saveRoles( Collection<Role> roles )
+        throws RbacObjectInvalidException, RbacManagerException
+    {
+        if ( roles == null )
+        {
+            // Nothing to do.
+            return;
+        }
+
+        // This is done in JdoRbacManager as opposed to JdoTool as we need to assertValid() on each role and
+        // also wrap the entire collection into a single atomic save/makePersistent.
+
+        PersistenceManager pm = jdo.getPersistenceManager();
+        Transaction tx = pm.currentTransaction();
+
+        try
+        {
+            tx.begin();
+
+            for ( Role role : roles )
+            {
+                if ( ( JDOHelper.getObjectId( role ) != null ) && !JDOHelper.isDetached( role ) )
+                {
+                    // This is a fatal error that means we need to fix our code.
+                    // Leave it as a JDOUserException, it's intentional.
+                    throw new RbacManagerException( "Existing Role is not detached: " + role );
+                }
+
+                RBACObjectAssertions.assertValid( role );
+
+                pm.makePersistent( role );
+            }
+
+            tx.commit();
+        }
+        finally
+        {
+            jdo.rollbackIfActive( tx );
+        }
+    }
+
+    // ----------------------------------------------------------------------
+    // Permission methods
+    // ----------------------------------------------------------------------
+
+    /**
+     * Creates an implementation specific {@link Permission}.
+     * <p/>
+     * Note: this method does not add the {@link Permission} to the underlying store.
+     * a call to {@link #savePermission(Permission)} is required to track the permission created
+     * with this method call.
+     *
+     * @param name the name.
+     * @return the new Permission.
+     * @throws RbacManagerException
+     */
+    public Permission createPermission( String name )
+        throws RbacManagerException
+    {
+        Permission permission;
+
+        try
+        {
+            permission = getPermission( name );
+            log.debug( "Create Permission [{}] Returning Existing.", name );
+        }
+        catch ( RbacObjectNotFoundException e )
+        {
+            permission = new JdoPermission();
+            permission.setName( name );
+            log.debug( "Create Permission [{}] New JdoPermission.", name );
+        }
+
+        return permission;
+    }
+
+    /**
+     * Creates an implementation specific {@link Permission} with specified {@link Operation},
+     * and {@link Resource} identifiers.
+     * <p/>
+     * Note: this method does not add the Permission, Operation, or Resource to the underlying store.
+     * a call to {@link #savePermission(Permission)} is required to track the permission, operation,
+     * or resource created with this method call.
+     *
+     * @param name               the name.
+     * @param operationName      the {@link Operation#setName(String)} value
+     * @param resourceIdentifier the {@link Resource#setIdentifier(String)} value
+     * @return the new Permission.
+     * @throws RbacManagerException
+     */
+    public Permission createPermission( String name, String operationName, String resourceIdentifier )
+        throws RbacManagerException
+    {
+        Permission permission = new JdoPermission();
+        permission.setName( name );
+
+        Operation operation;
+        try
+        {
+            operation = getOperation( operationName );
+        }
+        catch ( RbacObjectNotFoundException e )
+        {
+            operation = new JdoOperation();
+            operation.setName( operationName );
+        }
+        permission.setOperation( operation );
+
+        Resource resource;
+        try
+        {
+            resource = getResource( resourceIdentifier );
+        }
+        catch ( RbacObjectNotFoundException e )
+        {
+            resource = new JdoResource();
+            resource.setIdentifier( resourceIdentifier );
+        }
+        permission.setResource( resource );
+
+        return permission;
+    }
+
+    public Permission savePermission( Permission permission )
+        throws RbacObjectInvalidException, RbacManagerException
+    {
+        RBACObjectAssertions.assertValid( permission );
+
+        return (Permission) jdo.saveObject( permission, null );
+    }
+
+    public boolean permissionExists( Permission permission )
+    {
+        return jdo.objectExists( permission );
+    }
+
+    public boolean permissionExists( String name )
+    {
+        try
+        {
+            return jdo.objectExistsById( JdoPermission.class, name );
+        }
+        catch ( RbacManagerException e )
+        {
+            return false;
+        }
+    }
+
+    public Permission getPermission( String permissionName )
+        throws RbacObjectNotFoundException, RbacManagerException
+    {
+        return (Permission) jdo.getObjectById( JdoPermission.class, permissionName, null );
+    }
+
+    @SuppressWarnings( "unchecked" )
+    public List<Permission> getAllPermissions()
+        throws RbacManagerException
+    {
+        return (List<Permission>) jdo.getAllObjects( JdoPermission.class );
+    }
+
+    public void removePermission( Permission permission )
+        throws RbacObjectNotFoundException, RbacObjectInvalidException, RbacManagerException
+    {
+        RBACObjectAssertions.assertValid( permission );
+
+        if ( permission.isPermanent() )
+        {
+            throw new RbacPermanentException( "Unable to delete permanent permission [" + permission.getName() + "]" );
+        }
+
+        jdo.removeObject( permission );
+    }
+
+    // ----------------------------------------------------------------------
+    // Operation methods
+    // ----------------------------------------------------------------------
+
+    /**
+     * Creates an implementation specific {@link Operation}.
+     * <p/>
+     * Note: this method does not add the {@link Operation} to the underlying store.
+     * a call to {@link #saveOperation(Operation)} is required to track the operation created
+     * with this method call.
+     *
+     * @param name the name.
+     * @return the new Operation.
+     * @throws RbacManagerException
+     */
+    public Operation createOperation( String name )
+        throws RbacManagerException
+    {
+        Operation operation;
+
+        try
+        {
+            operation = getOperation( name );
+        }
+        catch ( RbacObjectNotFoundException e )
+        {
+            operation = new JdoOperation();
+            operation.setName( name );
+        }
+
+        return operation;
+    }
+
+    public Operation saveOperation( Operation operation )
+        throws RbacObjectInvalidException, RbacManagerException
+    {
+        RBACObjectAssertions.assertValid( operation );
+        return (Operation) jdo.saveObject( operation, null );
+    }
+
+    public boolean operationExists( Operation operation )
+    {
+        return jdo.objectExists( operation );
+    }
+
+    public boolean operationExists( String name )
+    {
+        try
+        {
+            return jdo.objectExistsById( JdoOperation.class, name );
+        }
+        catch ( RbacManagerException e )
+        {
+            return false;
+        }
+    }
+
+    public Operation getOperation( String operationName )
+        throws RbacObjectNotFoundException, RbacManagerException
+    {
+        return (Operation) jdo.getObjectById( JdoOperation.class, operationName, null );
+    }
+
+    @SuppressWarnings( "unchecked" )
+    public List<Operation> getAllOperations()
+        throws RbacManagerException
+    {
+        return (List<Operation>) jdo.getAllObjects( JdoOperation.class );
+    }
+
+    public void removeOperation( Operation operation )
+        throws RbacObjectNotFoundException, RbacObjectInvalidException, RbacManagerException
+    {
+        RBACObjectAssertions.assertValid( operation );
+
+        if ( operation.isPermanent() )
+        {
+            throw new RbacPermanentException( "Unable to delete permanent operation [" + operation.getName() + "]" );
+        }
+
+        jdo.removeObject( operation );
+    }
+
+    // ----------------------------------------------------------------------
+    // Resource methods
+    // ----------------------------------------------------------------------
+
+    /**
+     * Creates an implementation specific {@link Resource}.
+     * <p/>
+     * Note: this method does not add the {@link Resource} to the underlying store.
+     * a call to {@link #saveResource(Resource)} is required to track the resource created
+     * with this method call.
+     *
+     * @param identifier the identifier.
+     * @return the new Resource.
+     * @throws RbacManagerException
+     */
+    public Resource createResource( String identifier )
+        throws RbacManagerException
+    {
+        Resource resource;
+
+        try
+        {
+            resource = getResource( identifier );
+            log.debug( "Create Resource [ {} ] Returning Existing.", identifier );
+        }
+        catch ( RbacObjectNotFoundException e )
+        {
+            resource = new JdoResource();
+            resource.setIdentifier( identifier );
+            log.debug( "Create Resource [ {} ] New JdoResource.", identifier );
+        }
+
+        return resource;
+    }
+
+    public Resource saveResource( Resource resource )
+        throws RbacObjectInvalidException, RbacManagerException
+    {
+        RBACObjectAssertions.assertValid( resource );
+        return (Resource) jdo.saveObject( resource, null );
+    }
+
+    public boolean resourceExists( Resource resource )
+    {
+        return jdo.objectExists( resource );
+    }
+
+    public boolean resourceExists( String identifier )
+    {
+        try
+        {
+            return jdo.objectExistsById( JdoResource.class, identifier );
+        }
+        catch ( RbacManagerException e )
+        {
+            return false;
+        }
+    }
+
+    public Resource getResource( String resourceIdentifier )
+        throws RbacObjectNotFoundException, RbacManagerException
+    {
+        return (Resource) jdo.getObjectById( JdoResource.class, resourceIdentifier, null );
+    }
+
+    @SuppressWarnings( "unchecked" )
+    public List<Resource> getAllResources()
+        throws RbacManagerException
+    {
+        return (List<Resource>) jdo.getAllObjects( JdoResource.class );
+    }
+
+    public void removeResource( Resource resource )
+        throws RbacObjectNotFoundException, RbacObjectInvalidException, RbacManagerException
+    {
+        RBACObjectAssertions.assertValid( resource );
+
+        if ( resource.isPermanent() )
+        {
+            throw new RbacPermanentException(
+                "Unable to delete permanent resource [" + resource.getIdentifier() + "]" );
+        }
+
+        jdo.removeObject( resource );
+    }
+
+    // ----------------------------------------------------------------------
+    // User Assignment methods
+    // ----------------------------------------------------------------------
+
+    /**
+     * Creates an implementation specific {@link UserAssignment}.
+     * <p/>
+     * Note: this method does not add the {@link UserAssignment} to the underlying store.
+     * a call to {@link #saveUserAssignment(UserAssignment)} is required to track the user
+     * assignment created with this method call.
+     *
+     * @param principal the principal reference to the user.
+     * @return the new UserAssignment with an empty (non-null) {@link UserAssignment#getRoleNames()} object.
+     * @throws RbacManagerException
+     */
+    public UserAssignment createUserAssignment( String principal )
+    {
+        UserAssignment ua;
+
+        try
+        {
+            ua = getUserAssignment( principal );
+        }
+        catch ( RbacManagerException e )
+        {
+            ua = new JdoUserAssignment();
+            ua.setPrincipal( principal );
+        }
+
+        return ua;
+    }
+
+    /**
+     * Method addUserAssignment
+     *
+     * @param userAssignment
+     */
+    public UserAssignment saveUserAssignment( UserAssignment userAssignment )
+        throws RbacObjectInvalidException, RbacManagerException
+    {
+        RBACObjectAssertions.assertValid( "Save User Assignment", userAssignment );
+
+        fireRbacUserAssignmentSaved( userAssignment );
+
+        return (UserAssignment) jdo.saveObject( userAssignment, new String[]{ ROLE_DETAIL } );
+    }
+
+    public boolean userAssignmentExists( String principal )
+    {
+        try
+        {
+            return jdo.objectExistsById( JdoUserAssignment.class, principal );
+        }
+        catch ( RbacManagerException e )
+        {
+            return false;
+        }
+    }
+
+    public boolean userAssignmentExists( UserAssignment assignment )
+    {
+        return jdo.objectExists( assignment );
+    }
+
+    public UserAssignment getUserAssignment( String principal )
+        throws RbacObjectNotFoundException, RbacManagerException
+    {
+        return (UserAssignment) jdo.getObjectById( JdoUserAssignment.class, principal, ROLE_DETAIL );
+    }
+
+    /**
+     * Method getAssignments
+     */
+    @SuppressWarnings( "unchecked" )
+    public List<UserAssignment> getAllUserAssignments()
+        throws RbacManagerException
+    {
+        return (List<UserAssignment>) jdo.getAllObjects( JdoUserAssignment.class );
+    }
+
+    /**
+     * Method getUserAssignmentsForRoles
+     */
+    @SuppressWarnings( "unchecked" )
+    public List<UserAssignment> getUserAssignmentsForRoles( Collection<String> roleNames )
+        throws RbacManagerException
+    {
+        return (List<UserAssignment>) jdo.getUserAssignmentsForRoles( JdoUserAssignment.class, null, roleNames );
+    }
+
+    /**
+     * Method removeAssignment
+     *
+     * @param userAssignment
+     */
+    public void removeUserAssignment( UserAssignment userAssignment )
+        throws RbacObjectNotFoundException, RbacObjectInvalidException, RbacManagerException
+    {
+        RBACObjectAssertions.assertValid( userAssignment );
+
+        if ( userAssignment.isPermanent() )
+        {
+            throw new RbacPermanentException(
+                "Unable to delete permanent user assignment [" + userAssignment.getPrincipal() + "]" );
+        }
+
+        fireRbacUserAssignmentRemoved( userAssignment );
+
+        jdo.removeObject( userAssignment );
+    }
+
+    public void eraseDatabase()
+    {
+        // Must delete in order so that FK constraints don't get violated
+        jdo.removeAll( JdoRole.class );
+        jdo.removeAll( JdoPermission.class );
+        jdo.removeAll( JdoOperation.class );
+        jdo.removeAll( JdoResource.class );
+        jdo.removeAll( JdoUserAssignment.class );
+        jdo.removeAll( RbacJdoModelModelloMetadata.class );
+    }
+
+    @PostConstruct
+    public void initialize()
+    {
+        super.initialize();
+
+        jdo.setListener( this );
+        if ( enableCache )
+        {
+            jdo.enableCache( JdoRole.class );
+            jdo.enableCache( JdoOperation.class );
+            jdo.enableCache( JdoResource.class );
+            jdo.enableCache( JdoUserAssignment.class );
+            jdo.enableCache( JdoPermission.class );
+        }
+    }
+
+    public void rbacInit( boolean freshdb )
+    {
+        fireRbacInit( freshdb );
+    }
+
+    public void rbacPermissionRemoved( Permission permission )
+    {
+        fireRbacPermissionRemoved( permission );
+    }
+
+    public void rbacPermissionSaved( Permission permission )
+    {
+        fireRbacPermissionSaved( permission );
+    }
+
+    public void rbacRoleRemoved( Role role )
+    {
+        fireRbacRoleRemoved( role );
+    }
+
+    public void rbacRoleSaved( Role role )
+    {
+        fireRbacRoleSaved( role );
+    }
+
+
+    public void rbacUserAssignmentSaved( UserAssignment userAssignment )
+    {
+        fireRbacUserAssignmentSaved( userAssignment );
+    }
+
+    public void rbacUserAssignmentRemoved( UserAssignment userAssignment )
+    {
+        fireRbacUserAssignmentRemoved( userAssignment );
+    }
+
+    public JdoTool getJdo()
+    {
+        return jdo;
+    }
+
+    public void setJdo( JdoTool jdo )
+    {
+        this.jdo = jdo;
+    }
+
+    public boolean isEnableCache()
+    {
+        return enableCache;
+    }
+
+    public void setEnableCache( boolean enableCache )
+    {
+        this.enableCache = enableCache;
+    }
+}

Propchange: archiva/redback/redback-core/trunk/redback-rbac/redback-rbac-providers/redback-rbac-jdo/src/main/java/org/codehaus/plexus/redback/rbac/jdo/JdoRbacManager.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: archiva/redback/redback-core/trunk/redback-rbac/redback-rbac-providers/redback-rbac-jdo/src/main/java/org/codehaus/plexus/redback/rbac/jdo/JdoRbacManager.java
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision

Added: archiva/redback/redback-core/trunk/redback-rbac/redback-rbac-providers/redback-rbac-jdo/src/main/java/org/codehaus/plexus/redback/rbac/jdo/JdoTool.java
URL: http://svn.apache.org/viewvc/archiva/redback/redback-core/trunk/redback-rbac/redback-rbac-providers/redback-rbac-jdo/src/main/java/org/codehaus/plexus/redback/rbac/jdo/JdoTool.java?rev=1310268&view=auto
==============================================================================
--- archiva/redback/redback-core/trunk/redback-rbac/redback-rbac-providers/redback-rbac-jdo/src/main/java/org/codehaus/plexus/redback/rbac/jdo/JdoTool.java (added)
+++ archiva/redback/redback-core/trunk/redback-rbac/redback-rbac-providers/redback-rbac-jdo/src/main/java/org/codehaus/plexus/redback/rbac/jdo/JdoTool.java Fri Apr  6 09:58:14 2012
@@ -0,0 +1,497 @@
+package org.codehaus.plexus.redback.rbac.jdo;
+
+/*
+ * Copyright 2001-2006 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import org.codehaus.plexus.jdo.JdoFactory;
+import org.codehaus.plexus.redback.rbac.Permission;
+import org.codehaus.plexus.redback.rbac.RBACManagerListener;
+import org.codehaus.plexus.redback.rbac.RbacManagerException;
+import org.codehaus.plexus.redback.rbac.RbacObjectNotFoundException;
+import org.codehaus.plexus.redback.rbac.Role;
+import org.codehaus.plexus.util.StringUtils;
+import org.springframework.stereotype.Service;
+
+import javax.annotation.PostConstruct;
+import javax.annotation.Resource;
+import javax.jdo.Extent;
+import javax.jdo.JDOException;
+import javax.jdo.JDOHelper;
+import javax.jdo.JDOObjectNotFoundException;
+import javax.jdo.JDOUserException;
+import javax.jdo.PersistenceManager;
+import javax.jdo.PersistenceManagerFactory;
+import javax.jdo.Query;
+import javax.jdo.Transaction;
+import javax.jdo.datastore.DataStoreCache;
+import javax.jdo.listener.DeleteLifecycleListener;
+import javax.jdo.listener.InstanceLifecycleEvent;
+import javax.jdo.listener.StoreLifecycleListener;
+import javax.jdo.spi.Detachable;
+import javax.jdo.spi.PersistenceCapable;
+import java.io.PrintStream;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+
+/**
+ * JdoTool - RBAC JDO Tools.
+ *
+ * @author <a href="mailto:joakim@erdfelt.com">Joakim Erdfelt</a>
+ * @version $Id$
+ */
+@Service("jdoTool")
+public class JdoTool
+    implements DeleteLifecycleListener, StoreLifecycleListener
+{
+
+    @Resource(name="jdoFactory#users")
+    private JdoFactory jdoFactory;
+
+    private PersistenceManagerFactory pmf;
+
+    private RBACManagerListener listener;
+
+    @PostConstruct
+    public void initialize()
+    {
+        pmf = jdoFactory.getPersistenceManagerFactory();
+
+        pmf.addInstanceLifecycleListener( this, null );
+    }
+
+    public static void dumpObjectState( PrintStream out, Object o )
+    {
+        final String STATE = "[STATE] ";
+        final String INDENT = "        ";
+
+        if ( o == null )
+        {
+            out.println( STATE + "Object is null." );
+            return;
+        }
+
+        out.println( STATE + "Object " + o.getClass().getName() );
+
+        if ( !( o instanceof PersistenceCapable ) )
+        {
+            out.println( INDENT + "is NOT PersistenceCapable (not a jdo object?)" );
+            return;
+        }
+
+        out.println( INDENT + "is PersistenceCapable." );
+        if ( o instanceof Detachable )
+        {
+            out.println( INDENT + "is Detachable" );
+        }
+
+        out.println( INDENT + "is new : " + Boolean.toString( JDOHelper.isNew( o ) ) );
+        out.println( INDENT + "is transactional : " + Boolean.toString( JDOHelper.isTransactional( o ) ) );
+        out.println( INDENT + "is deleted : " + Boolean.toString( JDOHelper.isDeleted( o ) ) );
+        out.println( INDENT + "is detached : " + Boolean.toString( JDOHelper.isDetached( o ) ) );
+        out.println( INDENT + "is dirty : " + Boolean.toString( JDOHelper.isDirty( o ) ) );
+        out.println( INDENT + "is persistent : " + Boolean.toString( JDOHelper.isPersistent( o ) ) );
+
+        out.println( INDENT + "object id : " + JDOHelper.getObjectId( o ) );
+    }
+
+    public PersistenceManager getPersistenceManager()
+    {
+        PersistenceManager pm = pmf.getPersistenceManager();
+
+        pm.getFetchPlan().setMaxFetchDepth( -1 );
+
+        triggerInit();
+
+        return pm;
+    }
+
+    private boolean hasTriggeredInit = false;
+
+    @SuppressWarnings("unchecked")
+    public void triggerInit()
+    {
+        if ( !hasTriggeredInit )
+        {
+            hasTriggeredInit = true;
+
+            List<Role> roles = (List<Role>) getAllObjects( JdoRole.class );
+
+            listener.rbacInit( roles.isEmpty() );
+        }
+    }
+
+    public void enableCache( Class<?> clazz )
+    {
+        DataStoreCache cache = pmf.getDataStoreCache();
+        if ( cache.getClass().getName().equals( "org.jpox.cache.EhcacheClassBasedLevel2Cache" )
+            || cache.getClass().getName().equals( "org.jpox.cache.EhcacheLevel2Cache" ) )
+        {
+            /* Ehcache adapters don't support pinAll, the caching is handled in the configuration */
+            return;
+        }
+        cache.pinAll( clazz, false ); // Pin all objects of type clazz from now on
+    }
+
+    public Object saveObject( Object object )
+    {
+        return saveObject( object, null );
+    }
+
+    public Object saveObject( Object object, String[] fetchGroups )
+    {
+        PersistenceManager pm = getPersistenceManager();
+        Transaction tx = pm.currentTransaction();
+
+        try
+        {
+            tx.begin();
+
+            if ( ( JDOHelper.getObjectId( object ) != null ) && !JDOHelper.isDetached( object ) )
+            {
+                // This is a fatal error that means we need to fix our code.
+                // Leave it as a JDOUserException, it's intentional.
+                throw new JDOUserException( "Existing object is not detached: " + object, object );
+            }
+
+            if ( fetchGroups != null )
+            {
+                for ( int i = 0; i >= fetchGroups.length; i++ )
+                {
+                    pm.getFetchPlan().addGroup( fetchGroups[i] );
+                }
+            }
+
+            pm.makePersistent( object );
+
+            object = pm.detachCopy( object );
+
+            tx.commit();
+
+            return object;
+        }
+        finally
+        {
+            rollbackIfActive( tx );
+        }
+    }
+
+    public List<?> getAllObjects( Class<?> clazz )
+    {
+        return getAllObjects( clazz, null, null );
+    }
+
+    public List<?> getAllObjects( Class<?> clazz, String ordering )
+    {
+        return getAllObjects( clazz, ordering, null );
+    }
+
+    public List<?> getAllObjects( Class<?> clazz, String ordering, String fetchGroup )
+    {
+        PersistenceManager pm = getPersistenceManager();
+        Transaction tx = pm.currentTransaction();
+
+        try
+        {
+            tx.begin();
+
+            Extent extent = pm.getExtent( clazz, true );
+
+            Query query = pm.newQuery( extent );
+
+            if ( ordering != null )
+            {
+                query.setOrdering( ordering );
+            }
+
+            if ( fetchGroup != null )
+            {
+                pm.getFetchPlan().addGroup( fetchGroup );
+            }
+
+            List<?> result = (List<?>) query.execute();
+
+            result = (List<?>) pm.detachCopyAll( result );
+
+            tx.commit();
+
+            return result;
+        }
+        finally
+        {
+            rollbackIfActive( tx );
+        }
+    }
+
+    public List<?> getUserAssignmentsForRoles( Class<?> clazz, String ordering, Collection<String> roleNames )
+    {
+        PersistenceManager pm = getPersistenceManager();
+        Transaction tx = pm.currentTransaction();
+
+        try
+        {
+            tx.begin();
+
+            Extent extent = pm.getExtent( clazz, true );
+
+            Query query = pm.newQuery( extent );
+
+            if ( ordering != null )
+            {
+                query.setOrdering( ordering );
+            }
+
+            query.declareImports( "import java.lang.String" );
+
+            StringBuffer filter = new StringBuffer();
+
+            if ( roleNames.size() > 0 )
+            {
+                Iterator<String> i = roleNames.iterator();
+
+                filter.append( "this.roleNames.contains(\"" ).append( i.next() ).append( "\")" );
+
+                while ( i.hasNext() )
+                {
+                    filter.append( " || this.roleNames.contains(\"" ).append( i.next() ).append( "\")" );
+                }
+
+                query.setFilter( filter.toString() );
+            }
+
+            List<?> result = (List<?>) query.execute();
+
+            result = (List<?>) pm.detachCopyAll( result );
+
+            tx.commit();
+
+            return result;
+        }
+        finally
+        {
+            rollbackIfActive( tx );
+        }
+    }
+
+    public Object getObjectById( Class<?> clazz, String id, String fetchGroup )
+        throws RbacObjectNotFoundException, RbacManagerException
+    {
+        if ( StringUtils.isEmpty( id ) )
+        {
+            throw new RbacObjectNotFoundException(
+                "Unable to get object '" + clazz.getName() + "' from jdo using null/empty id." );
+        }
+
+        PersistenceManager pm = getPersistenceManager();
+        Transaction tx = pm.currentTransaction();
+
+        try
+        {
+            tx.begin();
+
+            if ( fetchGroup != null )
+            {
+                pm.getFetchPlan().addGroup( fetchGroup );
+            }
+
+            Object objectId = pm.newObjectIdInstance( clazz, id );
+
+            Object object = pm.getObjectById( objectId );
+
+            object = pm.detachCopy( object );
+
+            tx.commit();
+
+            return object;
+        }
+        catch ( JDOObjectNotFoundException e )
+        {
+            throw new RbacObjectNotFoundException( "Unable to find RBAC Object '" + id + "' of type " +
+                clazz.getName() + " using fetch-group '" + fetchGroup + "'", e, id );
+        }
+        catch ( JDOException e )
+        {
+            throw new RbacManagerException( "Error in JDO during get of RBAC object id '" + id + "' of type " +
+                clazz.getName() + " using fetch-group '" + fetchGroup + "'", e );
+        }
+        finally
+        {
+            rollbackIfActive( tx );
+        }
+    }
+
+    public boolean objectExists( Object object )
+    {
+        return ( JDOHelper.getObjectId( object ) != null );
+    }
+
+    public boolean objectExistsById( Class<?> clazz, String id )
+        throws RbacManagerException
+    {
+        try
+        {
+            Object o = getObjectById( clazz, id, null );
+            return ( o != null );
+        }
+        catch ( RbacObjectNotFoundException e )
+        {
+            return false;
+        }
+    }
+
+    public Object removeObject( Object o )
+        throws RbacManagerException
+    {
+        if ( o == null )
+        {
+            throw new RbacManagerException( "Unable to remove null object" );
+        }
+
+        PersistenceManager pm = getPersistenceManager();
+        Transaction tx = pm.currentTransaction();
+
+        try
+        {
+            tx.begin();
+
+            o = pm.getObjectById( pm.getObjectId( o ) );
+
+            pm.deletePersistent( o );
+
+            tx.commit();
+
+            return o;
+        }
+        finally
+        {
+            rollbackIfActive( tx );
+        }
+    }
+
+    public void rollbackIfActive( Transaction tx )
+    {
+        PersistenceManager pm = tx.getPersistenceManager();
+
+        try
+        {
+            if ( tx.isActive() )
+            {
+                tx.rollback();
+            }
+        }
+        finally
+        {
+            closePersistenceManager( pm );
+        }
+    }
+
+    public void closePersistenceManager( PersistenceManager pm )
+    {
+        try
+        {
+            pm.close();
+        }
+        catch ( JDOUserException e )
+        {
+            // ignore
+        }
+    }
+
+    public RBACManagerListener getListener()
+    {
+        return listener;
+    }
+
+    public void setListener( RBACManagerListener listener )
+    {
+        this.listener = listener;
+    }
+
+    public void postDelete( InstanceLifecycleEvent evt )
+    {
+        PersistenceCapable obj = ( (PersistenceCapable) evt.getSource() );
+
+        if ( obj == null )
+        {
+            // Do not track null objects.
+            // These events are typically a product of an internal lifecycle event.
+            return;
+        }
+
+        if ( obj instanceof Role )
+        {
+            listener.rbacRoleRemoved( (Role) obj );
+        }
+        else if ( obj instanceof Permission )
+        {
+            listener.rbacPermissionRemoved( (Permission) obj );
+        }
+    }
+
+    public void preDelete( InstanceLifecycleEvent evt )
+    {
+        // ignore
+    }
+
+    public void postStore( InstanceLifecycleEvent evt )
+    {
+        PersistenceCapable obj = ( (PersistenceCapable) evt.getSource() );
+
+        if ( obj instanceof Role )
+        {
+            listener.rbacRoleSaved( (Role) obj );
+        }
+        else if ( obj instanceof Permission )
+        {
+            listener.rbacPermissionSaved( (Permission) obj );
+        }
+    }
+
+    public void preStore( InstanceLifecycleEvent evt )
+    {
+        // ignore
+    }
+
+    public void removeAll( Class<?> aClass )
+    {
+        PersistenceManager pm = getPersistenceManager();
+        Transaction tx = pm.currentTransaction();
+
+        try
+        {
+            tx.begin();
+
+            Query query = pm.newQuery( aClass );
+            query.deletePersistentAll();
+
+            tx.commit();
+        }
+        finally
+        {
+            rollbackIfActive( tx );
+        }
+    }
+
+    public JdoFactory getJdoFactory()
+    {
+        return jdoFactory;
+    }
+
+    public void setJdoFactory( JdoFactory jdoFactory )
+    {
+        this.jdoFactory = jdoFactory;
+    }
+}

Propchange: archiva/redback/redback-core/trunk/redback-rbac/redback-rbac-providers/redback-rbac-jdo/src/main/java/org/codehaus/plexus/redback/rbac/jdo/JdoTool.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: archiva/redback/redback-core/trunk/redback-rbac/redback-rbac-providers/redback-rbac-jdo/src/main/java/org/codehaus/plexus/redback/rbac/jdo/JdoTool.java
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision

Added: archiva/redback/redback-core/trunk/redback-rbac/redback-rbac-providers/redback-rbac-jdo/src/main/mdo/rbac-jdo.mdo
URL: http://svn.apache.org/viewvc/archiva/redback/redback-core/trunk/redback-rbac/redback-rbac-providers/redback-rbac-jdo/src/main/mdo/rbac-jdo.mdo?rev=1310268&view=auto
==============================================================================
--- archiva/redback/redback-core/trunk/redback-rbac/redback-rbac-providers/redback-rbac-jdo/src/main/mdo/rbac-jdo.mdo (added)
+++ archiva/redback/redback-core/trunk/redback-rbac/redback-rbac-providers/redback-rbac-jdo/src/main/mdo/rbac-jdo.mdo Fri Apr  6 09:58:14 2012
@@ -0,0 +1,323 @@
+<?xml version="1.0"?>
+<model jpox.mapping-in-package="true"
+       jpox.table-prefix="SECURITY_">
+  <!-- TODO: there is no reason this model is JDO specific. Shouldn't it be the basis for the various providers? It would dramatically reduce the code in -memory, for example -->
+  <id>rbac-jdo</id>
+  <name>RbacJdoModel</name>
+  <version>1.0.1</version>
+  <defaults>
+    <default>
+      <key>package</key>
+      <value>org.codehaus.plexus.redback.rbac.jdo</value>
+    </default>
+  </defaults>
+  <classes>
+    <class rootElement="true"
+           jpox.stashable="false">
+      <name>RbacDatabase</name>
+      <version>1.0.1+</version>
+      <fields>
+        <field jpox.column="RBAC_ROLES">
+          <name>roles</name>
+          <version>1.0.1+</version>
+          <association>
+            <type>JdoRole</type>
+            <multiplicity>*</multiplicity>
+          </association>
+        </field>
+        <field>
+          <name>permissions</name>
+          <version>1.0.1+</version>
+          <association>
+            <type>JdoPermission</type>
+            <multiplicity>*</multiplicity>
+          </association>
+        </field>
+        <field>
+          <name>operations</name>
+          <version>1.0.1+</version>
+          <association>
+            <type>JdoOperation</type>
+            <multiplicity>*</multiplicity>
+          </association>
+        </field>
+        <field>
+          <name>resources</name>
+          <version>1.0.1+</version>
+          <association>
+            <type>JdoResource</type>
+            <multiplicity>*</multiplicity>
+          </association>
+        </field>
+        <field>
+          <name>userAssignments</name>
+          <version>1.0.1+</version>
+          <association>
+            <type>JdoUserAssignment</type>
+            <multiplicity>*</multiplicity>
+          </association>
+        </field>
+      </fields>
+    </class>
+
+    <class jpox.stashable="true" 
+           jpox.table="ROLES"
+           jpox.not-persisted-fields="modelEncoding">
+      <name>JdoRole</name>
+      <version>1.0.0+</version>
+      <interfaces>
+        <interface>org.codehaus.plexus.redback.rbac.Role</interface>
+      </interfaces>
+      <superClass>org.codehaus.plexus.redback.rbac.AbstractRole</superClass>
+      <fields>
+        <field jpox.primary-key="true" jpox.value-strategy="off">
+          <name>name</name>
+          <version>1.0.0+</version>
+          <type>String</type>
+          <identifier>true</identifier>
+        </field>
+        <field>
+          <name>description</name>
+          <version>1.0.0+</version>
+          <type>String</type>
+        </field>
+        <field>
+          <name>assignable</name>
+          <version>1.0.0+</version>
+          <type>boolean</type>
+          <description>
+            true if this role is available to be assigned to a user
+          </description>
+        </field>
+        <field>
+          <name>permanent</name>
+          <version>1.0.0+</version>
+          <type>boolean</type>
+          <description>
+            true if this object is permanent.
+          </description>
+        </field>
+        <field jpox.persistence-modifier="persistent" 
+               jpox.fetch-groups="role-child-detail"
+               jpox.join-table="ROLE_CHILDROLE_MAP">
+          <name>childRoleNames</name>
+          <version>1.0.0+</version>
+          <association stash.part="true" 
+                       jpox.join="true"
+                       java.init="field" 
+                       jpox.dependent="false"
+                       java.generate-break="false" 
+                       java.generate-create="false"
+                       zjava.use-interface="org.codehaus.plexus.redback.rbac.Role">
+            <type>String</type>
+            <multiplicity>*</multiplicity>
+          </association>
+          <description>
+            roles that will inherit the permissions of this role
+          </description>
+        </field>
+        <field jpox.fetch-groups="role-child-detail"
+               jpox.join-table="ROLE_PERMISSION_MAP">
+          <name>permissions</name>
+          <version>1.0.0+</version>
+          <association stash.part="true"
+                       xml.reference="true"
+                       jpox.join="true"
+                       jpox.dependent="false"
+                       java.init="field"
+                       java.generate-break="false"
+                       java.generate-create="false"
+                       java.use-interface="org.codehaus.plexus.redback.rbac.Permission">
+            <type>JdoPermission</type>
+            <multiplicity>*</multiplicity>
+          </association>
+        </field>
+      </fields>
+    </class>
+
+    <class jpox.stashable="true" 
+           jpox.table="PERMISSIONS"
+           jpox.not-persisted-fields="modelEncoding">
+      <name>JdoPermission</name>
+      <version>1.0.0+</version>
+      <interfaces>
+        <interface>org.codehaus.plexus.redback.rbac.Permission</interface>
+      </interfaces>
+      <fields>
+        <field jpox.primary-key="true" jpox.value-strategy="off">
+          <name>name</name>
+          <version>1.0.0+</version>
+          <type>String</type>
+          <identifier>true</identifier>
+        </field>
+        <field>
+          <name>description</name>
+          <version>1.0.0+</version>
+          <type>String</type>
+        </field>
+        <field>
+          <name>permanent</name>
+          <version>1.0.0+</version>
+          <type>boolean</type>
+          <description>
+            true if this object is permanent.
+          </description>
+        </field>
+        <field jpox.indexed="true" 
+               jpox.persistence-modifier="persistent"
+               jpox.column="RBAC_OPERATION">
+          <name>operation</name>
+          <version>1.0.0+</version>
+          <association stash.part="true" 
+                       xml.reference="true"
+                       java.use-interface="org.codehaus.plexus.redback.rbac.Operation"
+                       jpox.dependent="false">
+            <type>JdoOperation</type>
+            <multiplicity>1</multiplicity>
+          </association>
+        </field>
+        <field jpox.indexed="true" 
+               jpox.persistence-modifier="persistent"
+               jpox.column="RBAC_RESOURCE">
+          <name>resource</name>
+          <version>1.0.0+</version>
+          <association stash.part="true" 
+                       xml.reference="true"
+                       java.use-interface="org.codehaus.plexus.redback.rbac.Resource"
+                       jpox.dependent="false">
+            <type>JdoResource</type>
+            <multiplicity>1</multiplicity>
+          </association>
+        </field>
+      </fields>
+    </class>
+
+    <class jpox.stashable="true" 
+           jpox.table="OPERATIONS"
+           jpox.not-persisted-fields="modelEncoding">
+      <name>JdoOperation</name>
+      <version>1.0.0+</version>
+      <interfaces>
+        <interface>org.codehaus.plexus.redback.rbac.Operation</interface>
+      </interfaces>
+      <fields>
+        <field jpox.primary-key="true" jpox.value-strategy="off">
+          <name>name</name>
+          <version>1.0.0+</version>
+          <type>String</type>
+          <identifier>true</identifier>
+        </field>
+        <field>
+          <name>description</name>
+          <version>1.0.0+</version>
+          <type>String</type>
+        </field>
+        <field>
+          <name>permanent</name>
+          <version>1.0.0+</version>
+          <type>boolean</type>
+          <description>
+            true if this object is permanent.
+          </description>
+        </field>
+        <field>
+          <name>resourceRequired</name>
+          <version>1.0.0+</version>
+          <type>boolean</type>
+          <description>
+            true if the resource is required for authorization to be granted
+          </description>
+        </field>
+      </fields>
+    </class>
+
+    <class jpox.stashable="true" 
+           jpox.table="RESOURCES"
+           jpox.not-persisted-fields="modelEncoding">
+      <name>JdoResource</name>
+      <version>1.0.0+</version>
+      <description>
+        In RBAC terms, this is the entity which an operation is associated with that which permissions are based on.
+      </description>
+      <interfaces>
+        <interface>org.codehaus.plexus.redback.rbac.Resource</interface>
+      </interfaces>
+      <fields>
+        <field jpox.primary-key="true" jpox.value-strategy="off">
+          <name>identifier</name>
+          <version>1.0.0+</version>
+          <type>String</type>
+          <description>
+            The string identifier for a resource.
+          </description>
+          <identifier>true</identifier>
+        </field>
+        <field>
+          <name>pattern</name>
+          <version>1.0.0+</version>
+          <type>boolean</type>
+          <description>
+            true if the identifer is a pattern that is to be evaluated, for example x.* could match x.a or x.b and x.**
+            could match x.foo
+          </description>
+        </field>
+        <field>
+          <name>permanent</name>
+          <version>1.0.0+</version>
+          <type>boolean</type>
+          <description>
+            true if this object is permanent.
+          </description>
+        </field>
+      </fields>
+    </class>
+
+    <class jpox.stashable="true" 
+           jpox.table="USER_ASSIGNMENTS"
+           jpox.not-persisted-fields="modelEncoding">
+      <name>JdoUserAssignment</name>
+      <description>binding of a principal to a role</description>
+      <version>1.0.0+</version>
+      <interfaces>
+        <interface>org.codehaus.plexus.redback.rbac.UserAssignment</interface>
+      </interfaces>
+      <superClass>org.codehaus.plexus.redback.rbac.AbstractUserAssignment</superClass>
+      <fields>
+        <field jpox.primary-key="true" jpox.value-strategy="off">
+          <name>principal</name>
+          <version>1.0.0+</version>
+          <type>String</type>
+          <identifier>true</identifier>
+        </field>
+        <field jpox.column="LAST_UPDATED">
+          <name>timestamp</name>
+          <version>1.0.0+</version>
+          <type>Date</type>
+        </field>
+        <field>
+          <name>permanent</name>
+          <version>1.0.0+</version>
+          <type>boolean</type>
+          <description>
+            true if this object is permanent.
+          </description>
+        </field>
+        <field java.adder="false"
+               jpox.persistence-modifier="persistent" 
+               jpox.indexed="false"
+               jpox.join-table="USERASSIGNMENT_ROLENAMES">
+          <name>roleNames</name>
+          <version>1.0.0+</version>
+          <association stash.part="true" 
+                       jpox.join="true"
+                       java.init="field"
+                       java.generate-break="false"
+                       java.generate-create="false">
+            <type>String</type>
+            <multiplicity>*</multiplicity>
+          </association>
+        </field>
+      </fields>
+    </class>
+  </classes>
+</model>

Propchange: archiva/redback/redback-core/trunk/redback-rbac/redback-rbac-providers/redback-rbac-jdo/src/main/mdo/rbac-jdo.mdo
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: archiva/redback/redback-core/trunk/redback-rbac/redback-rbac-providers/redback-rbac-jdo/src/main/mdo/rbac-jdo.mdo
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision

Added: archiva/redback/redback-core/trunk/redback-rbac/redback-rbac-providers/redback-rbac-jdo/src/main/resources/META-INF/spring-context.xml
URL: http://svn.apache.org/viewvc/archiva/redback/redback-core/trunk/redback-rbac/redback-rbac-providers/redback-rbac-jdo/src/main/resources/META-INF/spring-context.xml?rev=1310268&view=auto
==============================================================================
--- archiva/redback/redback-core/trunk/redback-rbac/redback-rbac-providers/redback-rbac-jdo/src/main/resources/META-INF/spring-context.xml (added)
+++ archiva/redback/redback-core/trunk/redback-rbac/redback-rbac-providers/redback-rbac-jdo/src/main/resources/META-INF/spring-context.xml Fri Apr  6 09:58:14 2012
@@ -0,0 +1,37 @@
+<?xml version="1.0"?>
+
+<!--
+  ~ Licensed to the Apache Software Foundation (ASF) under one
+  ~ or more contributor license agreements.  See the NOTICE file
+  ~ distributed with this work for additional information
+  ~ regarding copyright ownership.  The ASF licenses this file
+  ~ to you under the Apache License, Version 2.0 (the
+  ~ "License"); you may not use this file except in compliance
+  ~ with the License.  You may obtain a copy of the License at
+  ~
+  ~   http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing,
+  ~ software distributed under the License is distributed on an
+  ~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+  ~ KIND, either express or implied.  See the License for the
+  ~ specific language governing permissions and limitations
+  ~ under the License.
+  -->
+<beans xmlns="http://www.springframework.org/schema/beans"
+       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+       xmlns:context="http://www.springframework.org/schema/context"
+       xsi:schemaLocation="http://www.springframework.org/schema/beans
+           http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
+           http://www.springframework.org/schema/context 
+           http://www.springframework.org/schema/context/spring-context-3.0.xsd"
+       default-lazy-init="true">
+
+  <bean name="rBACManager#jdo" class="org.codehaus.plexus.redback.rbac.jdo.JdoRbacManager" init-method="initialize">
+    <property name="jdo" ref="jdoTool"/>
+  </bean>
+
+  <bean id="jdoTool" class="org.codehaus.plexus.redback.rbac.jdo.JdoTool" init-method="initialize" lazy-init="true">
+    <property name="jdoFactory" ref="jdoFactory#users"/>
+  </bean>
+</beans>
\ No newline at end of file

Propchange: archiva/redback/redback-core/trunk/redback-rbac/redback-rbac-providers/redback-rbac-jdo/src/main/resources/META-INF/spring-context.xml
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: archiva/redback/redback-core/trunk/redback-rbac/redback-rbac-providers/redback-rbac-jdo/src/main/resources/META-INF/spring-context.xml
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision

Added: archiva/redback/redback-core/trunk/redback-rbac/redback-rbac-providers/redback-rbac-jdo/src/site/db-schema.dot
URL: http://svn.apache.org/viewvc/archiva/redback/redback-core/trunk/redback-rbac/redback-rbac-providers/redback-rbac-jdo/src/site/db-schema.dot?rev=1310268&view=auto
==============================================================================
--- archiva/redback/redback-core/trunk/redback-rbac/redback-rbac-providers/redback-rbac-jdo/src/site/db-schema.dot (added)
+++ archiva/redback/redback-core/trunk/redback-rbac/redback-rbac-providers/redback-rbac-jdo/src/site/db-schema.dot Fri Apr  6 09:58:14 2012
@@ -0,0 +1,196 @@
+// Graph of desired database structure.
+//   Use GraphViz (available from www.graphviz.org) to generate the image.
+// 
+// Command line: dot -Tpng db-schema.dot -o db-schema.png
+
+digraph structs {
+  // Graph Defaults
+  graph [
+    rankdir="RL"
+    bgcolor="#f7f7f7"
+    label="\nGenerated by GraphViz"
+    labeljust="l"
+  ];
+
+  // Node Defaults.
+  node [
+    fontname="Helvetica"
+    fontsize="11"
+    shape="plaintext"
+  ];
+
+  // Edge Defaults.  
+  edge [
+    arrowsize="0.8"
+  ];
+
+  // The Nodes
+  "KEY" [
+    label=<
+    <TABLE BORDER="1" CELLBORDER="0" CELLSPACING="0" CELLPADDING="5" BGCOLOR="#EEEEEE">
+    <TR><TD>KEY</TD></TR>
+    <TR><TD>
+    <TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0" BGCOLOR="#ffffff">
+      <TR><TD BGCOLOR="#9bab96" ALIGN="CENTER">
+        [TABLE NAME]
+      </TD></TR>
+      <TR><TD ALIGN="LEFT" BGCOLOR="#def1b8">
+        [COLUMN / PRIMARY KEY]
+      </TD></TR>
+      <TR><TD ALIGN="LEFT" BGCOLOR="#fffacd">
+        [COLUMN / INDEXED]
+      </TD></TR>
+      <TR><TD ALIGN="LEFT">
+        [COLUMN]
+      </TD></TR>
+    </TABLE>
+    </TD></TR>
+    </TABLE>>
+  ];
+
+  "ROLES" [
+    label=<
+    <TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0" BGCOLOR="#ffffff">
+      <TR><TD PORT="ROLES.heading" BGCOLOR="#9bab96" ALIGN="CENTER">
+        ROLES
+      </TD></TR>
+      <TR><TD PORT="NAME" ALIGN="LEFT" BGCOLOR="#def1b8">
+        NAME
+      </TD></TR>
+      <TR><TD PORT="DESCRIPTION" ALIGN="LEFT">
+        DESCRIPTION
+      </TD></TR>
+      <TR><TD PORT="ASSIGNABLE" ALIGN="LEFT">
+        ASSIGNABLE
+      </TD></TR>
+    </TABLE>>
+  ];
+
+  "ROLE_PERMISSION_MAP" [
+    label=<
+    <TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0" BGCOLOR="#ffffff">
+      <TR><TD PORT="ROLE_PERMISSION_MAP.heading" BGCOLOR="#9bab96" ALIGN="CENTER">
+        ROLE_PERMISSION_MAP
+      </TD></TR>
+      <TR><TD PORT="ROLE_NAME" ALIGN="LEFT" BGCOLOR="#fffacd">
+        ROLE_NAME
+      </TD></TR>
+      <TR><TD PORT="PERMISSION_NAME" ALIGN="LEFT" BGCOLOR="#fffacd">
+        PERMISSION_NAME
+      </TD></TR>
+    </TABLE>>
+  ];
+
+  "ROLE_ROLE_MAP" [
+    label=<
+    <TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0" BGCOLOR="#ffffff">
+      <TR><TD PORT="ROLE_ROLE_MAP.heading" BGCOLOR="#9bab96" ALIGN="CENTER">
+        ROLE_ROLE_MAP
+      </TD></TR>
+      <TR><TD PORT="PARENT_ROLE_NAME" ALIGN="LEFT" BGCOLOR="#fffacd">
+        PARENT_ROLE_NAME
+      </TD></TR>
+      <TR><TD PORT="CHILD_ROLE_NAME" ALIGN="LEFT" BGCOLOR="#fffacd">
+        CHILD_ROLE_NAME
+      </TD></TR>
+    </TABLE>>
+  ];
+
+  "PERMISSIONS" [
+    label=<
+    <TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0" BGCOLOR="#ffffff">
+      <TR><TD PORT="PERMISSIONS.heading" BGCOLOR="#9bab96" ALIGN="CENTER">
+        PERMISSIONS
+      </TD></TR>
+      <TR><TD PORT="NAME" ALIGN="LEFT" BGCOLOR="#def1b8">
+        NAME
+      </TD></TR>
+      <TR><TD PORT="DESCRIPTION" ALIGN="LEFT">
+        DESCRIPTION
+      </TD></TR>
+      <TR><TD PORT="OPERATION_NAME" ALIGN="LEFT" BGCOLOR="#fffacd">
+        OPERATION_NAME
+      </TD></TR>
+      <TR><TD PORT="RESOURCE_IDENTIFIER" ALIGN="LEFT" BGCOLOR="#fffacd">
+        RESOURCE_IDENTIFIER
+      </TD></TR>
+    </TABLE>>
+  ];
+
+  "OPERATIONS" [
+    label=<
+    <TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0" BGCOLOR="#ffffff">
+      <TR><TD PORT="OPERATIONS.heading" BGCOLOR="#9bab96" ALIGN="CENTER">
+        OPERATIONS
+      </TD></TR>
+      <TR><TD PORT="NAME" ALIGN="LEFT" BGCOLOR="#def1b8">
+        NAME
+      </TD></TR>
+      <TR><TD PORT="DESCRIPTION" ALIGN="LEFT">
+        DESCRIPTION
+      </TD></TR>
+      <TR><TD PORT="RESOURCE_REQUIRED" ALIGN="LEFT">
+        RESOURCE_REQUIRED
+      </TD></TR>
+    </TABLE>>
+  ];
+
+  "RESOURCES" [
+    label=<
+    <TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0" BGCOLOR="#ffffff">
+      <TR><TD PORT="RESOURCES.heading" BGCOLOR="#9bab96" ALIGN="CENTER">
+        RESOURCES
+      </TD></TR>
+      <TR><TD PORT="IDENTIFIER" ALIGN="LEFT" BGCOLOR="#def1b8">
+        IDENTIFIER
+      </TD></TR>
+      <TR><TD PORT="PATTERN" ALIGN="LEFT">
+        PATTERN
+      </TD></TR>
+    </TABLE>>
+  ];
+
+  "USER_ASSIGNMENTS" [
+    label=<
+    <TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0" BGCOLOR="#ffffff">
+      <TR><TD PORT="USER_ASSIGNMENTS.heading" BGCOLOR="#9bab96" ALIGN="CENTER">
+        USER_ASSIGNMENTS
+      </TD></TR>
+      <TR><TD PORT="PRINCIPAL" ALIGN="LEFT" BGCOLOR="#fffacd">
+        PRINCIPAL
+      </TD></TR>
+      <TR><TD PORT="ROLE_NAME" ALIGN="LEFT" BGCOLOR="#fffacd">
+        ROLE_NAME
+      </TD></TR>
+    </TABLE>>
+  ];
+
+  // The Connections
+  "PERMISSIONS":"NAME" ->
+    "ROLE_PERMISSION_MAP":"PERMISSION_NAME"
+    [arrowtail=none arrowhead=dot];
+
+  "PERMISSIONS":"OPERATION_NAME":w ->
+    "OPERATIONS":"NAME":e
+    [arrowtail=none arrowhead=normal];
+
+  "PERMISSIONS":"RESOURCE_IDENTIFIER" ->
+    "RESOURCES":"IDENTIFIER"
+    [arrowtail=none arrowhead=normal];
+
+  "USER_ASSIGNMENTS":"ROLE_NAME" ->
+    "ROLES":"NAME"
+    [arrowtail=none arrowhead=normal];
+
+  "ROLES":"NAME":w ->
+    "ROLE_PERMISSION_MAP":"ROLE_NAME":e
+    [arrowtail=none arrowhead=dot];
+
+  "ROLES":"NAME" ->
+    "ROLE_ROLE_MAP":"PARENT_ROLE_NAME"
+    [arrowtail=none arrowhead=dot];
+
+  "ROLE_ROLE_MAP":"CHILD_ROLE_NAME" ->
+    "ROLES":"NAME"
+    [arrowtail=none arrowhead=dot];
+}

Added: archiva/redback/redback-core/trunk/redback-rbac/redback-rbac-providers/redback-rbac-jdo/src/site/db-schema.png
URL: http://svn.apache.org/viewvc/archiva/redback/redback-core/trunk/redback-rbac/redback-rbac-providers/redback-rbac-jdo/src/site/db-schema.png?rev=1310268&view=auto
==============================================================================
Binary file - no diff available.

Propchange: archiva/redback/redback-core/trunk/redback-rbac/redback-rbac-providers/redback-rbac-jdo/src/site/db-schema.png
------------------------------------------------------------------------------
    svn:mime-type = image/png

Added: archiva/redback/redback-core/trunk/redback-rbac/redback-rbac-providers/redback-rbac-jdo/src/test/java/org/codehaus/plexus/redback/rbac/jdo/JdoRbacManagerTest.java
URL: http://svn.apache.org/viewvc/archiva/redback/redback-core/trunk/redback-rbac/redback-rbac-providers/redback-rbac-jdo/src/test/java/org/codehaus/plexus/redback/rbac/jdo/JdoRbacManagerTest.java?rev=1310268&view=auto
==============================================================================
--- archiva/redback/redback-core/trunk/redback-rbac/redback-rbac-providers/redback-rbac-jdo/src/test/java/org/codehaus/plexus/redback/rbac/jdo/JdoRbacManagerTest.java (added)
+++ archiva/redback/redback-core/trunk/redback-rbac/redback-rbac-providers/redback-rbac-jdo/src/test/java/org/codehaus/plexus/redback/rbac/jdo/JdoRbacManagerTest.java Fri Apr  6 09:58:14 2012
@@ -0,0 +1,212 @@
+package org.codehaus.plexus.redback.rbac.jdo;
+
+/*
+ * Copyright 2005 The Codehaus
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import net.sf.ehcache.CacheManager;
+import org.codehaus.plexus.jdo.DefaultConfigurableJdoFactory;
+import org.codehaus.plexus.redback.common.jdo.test.StoreManagerDebug;
+import org.codehaus.plexus.redback.rbac.RBACManager;
+import org.codehaus.plexus.redback.rbac.RbacManagerException;
+import org.codehaus.plexus.redback.tests.AbstractRbacManagerTestCase;
+import org.jpox.AbstractPersistenceManagerFactory;
+import org.jpox.SchemaTool;
+import org.junit.Before;
+
+import javax.inject.Inject;
+import javax.inject.Named;
+import javax.jdo.PersistenceManager;
+import javax.jdo.PersistenceManagerFactory;
+import java.io.File;
+import java.net.URL;
+import java.util.Map;
+import java.util.Properties;
+
+/**
+ * JdoRbacManagerTest:
+ *
+ * @author Jesse McConnell <jm...@apache.org>
+ * @author <a href="mailto:joakim@erdfelt.com">Joakim Erdfelt</a>
+ * @version $Id$
+ */
+public class JdoRbacManagerTest
+    extends AbstractRbacManagerTestCase
+{
+    private StoreManagerDebug storeManager;
+
+    @Inject
+    @Named( value = "jdoFactory#users" )
+    DefaultConfigurableJdoFactory jdoFactory;
+
+    @Inject
+    @Named( value = "rBACManager#jdo" )
+    RBACManager rbacManager;
+
+    /**
+     * Creates a new RbacStore which contains no data.
+     */
+    @Before
+    public void setUp()
+        throws Exception
+    {
+
+        super.setUp();
+
+        assertEquals( DefaultConfigurableJdoFactory.class.getName(), jdoFactory.getClass().getName() );
+
+        jdoFactory.setPersistenceManagerFactoryClass( "org.jpox.PersistenceManagerFactoryImpl" ); //$NON-NLS-1$
+
+        jdoFactory.setDriverName(
+            System.getProperty( "jdo.test.driver", "org.hsqldb.jdbcDriver" ) ); //$NON-NLS-1$  //$NON-NLS-2$
+
+        jdoFactory.setUrl(
+            System.getProperty( "jdo.test.url", "jdbc:hsqldb:mem:" + getName() ) ); //$NON-NLS-1$  //$NON-NLS-2$
+
+        jdoFactory.setUserName( System.getProperty( "jdo.test.user", "sa" ) ); //$NON-NLS-1$
+
+        jdoFactory.setPassword( System.getProperty( "jdo.test.pass", "" ) ); //$NON-NLS-1$
+
+        jdoFactory.setProperty( "org.jpox.transactionIsolation", "READ_COMMITTED" ); //$NON-NLS-1$ //$NON-NLS-2$
+
+        jdoFactory.setProperty( "org.jpox.poid.transactionIsolation", "READ_COMMITTED" ); //$NON-NLS-1$ //$NON-NLS-2$
+
+        jdoFactory.setProperty( "org.jpox.autoCreateSchema", "true" ); //$NON-NLS-1$ //$NON-NLS-2$
+
+        jdoFactory.setProperty( "org.jpox.autoCreateTables", "true" );
+
+        jdoFactory.setProperty( "javax.jdo.option.RetainValues", "true" );
+
+        jdoFactory.setProperty( "javax.jdo.option.RestoreValues", "true" );
+
+        // jdoFactory.setProperty( "org.jpox.autoCreateColumns", "true" );
+
+        jdoFactory.setProperty( "org.jpox.validateTables", "true" );
+
+        jdoFactory.setProperty( "org.jpox.validateColumns", "true" );
+
+        jdoFactory.setProperty( "org.jpox.validateConstraints", "true" );
+
+        /* Enable the level 2 Ehcache class-based cache */
+        jdoFactory.setProperty( "org.jpox.cache.level2", "true" );
+        jdoFactory.setProperty( "org.jpox.cache.level2.type", "ehcacheclassbased" );
+        jdoFactory.setProperty( "org.jpox.cache.level2.configurationFile", "/ehcache.xml" ); // ehcache config
+        jdoFactory.setProperty( "org.jpox.cache.level2.cacheName", "default" ); // default cache name
+
+        Properties properties = jdoFactory.getProperties();
+
+        for ( Map.Entry<Object, Object> entry : properties.entrySet() )
+        {
+            System.setProperty( (String) entry.getKey(), (String) entry.getValue() );
+        }
+
+        URL[] jdoFileUrls =
+            new URL[]{ getClass().getResource( "/org/codehaus/plexus/redback/rbac/jdo/package.jdo" ) }; //$NON-NLS-1$
+
+
+
+        if ( ( jdoFileUrls == null ) || ( jdoFileUrls[0] == null ) )
+        {
+            fail( "Unable to process test " + getName() + " - missing package.jdo." );
+        }
+
+        File propsFile = null; // intentional
+        boolean verbose = true;
+
+        PersistenceManagerFactory pmf = jdoFactory.getPersistenceManagerFactory();
+
+        assertNotNull( pmf );
+
+        /* set our own Store Manager to allow counting SQL statements */
+        StoreManagerDebug.setup( (AbstractPersistenceManagerFactory) pmf );
+
+        /* clean up the db */
+        SchemaTool.deleteSchemaTables( jdoFileUrls, new URL[]{ }, propsFile, verbose );
+        SchemaTool.createSchemaTables( jdoFileUrls, new URL[]{ }, propsFile, verbose, null );
+
+        PersistenceManager pm = pmf.getPersistenceManager();
+
+        pm.close();
+
+        setRbacManager( rbacManager );
+
+        /* save the store manager to access the queries executed */
+        JdoRbacManager rbacManager = (JdoRbacManager) getRbacManager();
+        storeManager = StoreManagerDebug.getConfiguredStoreManager( rbacManager.getJdo().getPersistenceManager() );
+    }
+
+
+    @Override
+    public void testGetAssignedRoles()
+        throws RbacManagerException
+    {
+        storeManager.resetCounter();
+        super.testGetAssignedRoles();
+        int counter = storeManager.counter();
+        /* without Level 2 cache: 15 queries */
+        /* with    Level 2 cache:  8 queries */
+        assertEquals( "Number of SQL queries", 8, counter );
+    }
+
+    @Override
+    public void testGetAssignedPermissionsDeep()
+        throws RbacManagerException
+    {
+        super.testGetAssignedPermissionsDeep();
+        int counter = storeManager.counter();
+        /* without Level 2 cache: 26 queries */
+        /* with    Level 2 cache: 10 queries */
+        assertEquals( "Number of SQL queries", 10, counter );
+    }
+
+    @Override
+    protected void afterSetup()
+    {
+        super.afterSetup();
+        storeManager.resetCounter();
+    }
+
+    @Override
+    public void testLargeApplicationInit()
+        throws RbacManagerException
+    {
+        for (String cacheName : CacheManager.getInstance().getCacheNames())
+        {
+            CacheManager.getInstance().getCache( cacheName ).removeAll();
+        }
+        super.testLargeApplicationInit();
+    }
+
+    @Override
+    public void testGetRolesDeep()
+        throws RbacManagerException
+    {
+        for (String cacheName : CacheManager.getInstance().getCacheNames())
+        {
+            CacheManager.getInstance().getCache( cacheName ).removeAll();
+        }
+        super.testGetRolesDeep();
+    }
+
+
+    @Override
+    public void testStoreInitialization()
+        throws Exception
+    {
+        rbacManager.eraseDatabase();
+        eventTracker.rbacInit( true );
+        super.testStoreInitialization();
+    }
+}

Propchange: archiva/redback/redback-core/trunk/redback-rbac/redback-rbac-providers/redback-rbac-jdo/src/test/java/org/codehaus/plexus/redback/rbac/jdo/JdoRbacManagerTest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: archiva/redback/redback-core/trunk/redback-rbac/redback-rbac-providers/redback-rbac-jdo/src/test/java/org/codehaus/plexus/redback/rbac/jdo/JdoRbacManagerTest.java
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision

Added: archiva/redback/redback-core/trunk/redback-rbac/redback-rbac-providers/redback-rbac-jdo/src/test/java/org/codehaus/plexus/redback/rbac/jdo/RbacJdoModelStaxTest.java
URL: http://svn.apache.org/viewvc/archiva/redback/redback-core/trunk/redback-rbac/redback-rbac-providers/redback-rbac-jdo/src/test/java/org/codehaus/plexus/redback/rbac/jdo/RbacJdoModelStaxTest.java?rev=1310268&view=auto
==============================================================================
--- archiva/redback/redback-core/trunk/redback-rbac/redback-rbac-providers/redback-rbac-jdo/src/test/java/org/codehaus/plexus/redback/rbac/jdo/RbacJdoModelStaxTest.java (added)
+++ archiva/redback/redback-core/trunk/redback-rbac/redback-rbac-providers/redback-rbac-jdo/src/test/java/org/codehaus/plexus/redback/rbac/jdo/RbacJdoModelStaxTest.java Fri Apr  6 09:58:14 2012
@@ -0,0 +1,193 @@
+package org.codehaus.plexus.redback.rbac.jdo;
+
+/*
+ * Copyright 2006 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import java.io.IOException;
+import java.io.StringReader;
+import java.io.StringWriter;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.List;
+import java.util.Locale;
+
+import javax.xml.stream.XMLStreamException;
+
+import junit.framework.TestCase;
+
+import org.codehaus.plexus.redback.rbac.Operation;
+import org.codehaus.plexus.redback.rbac.Resource;
+import org.codehaus.plexus.redback.rbac.jdo.io.stax.RbacJdoModelStaxReader;
+import org.codehaus.plexus.redback.rbac.jdo.io.stax.RbacJdoModelStaxWriter;
+
+/**
+ * Test the StAX reader and writer generated.
+ */
+public class RbacJdoModelStaxTest
+    extends TestCase
+{
+    @SuppressWarnings("unchecked")
+    public void testStax()
+        throws IOException, XMLStreamException
+    {
+        RbacDatabase database = new RbacDatabase();
+
+        JdoRole role = new JdoRole();
+        role.setAssignable( true );
+        role.setDescription( "descriptor" );
+        role.setName( "name" );
+        role.setPermanent( true );
+        role.addChildRoleName( "childRole1" );
+        role.addChildRoleName( "childRole2" );
+
+        JdoPermission permission = new JdoPermission();
+        permission.setDescription( "permDesc" );
+        permission.setName( "permName" );
+
+        JdoOperation operation = new JdoOperation();
+        operation.setDescription( "opDesc" );
+        operation.setName( "opName" );
+        operation.setPermanent( true );
+        operation.setResourceRequired( true );
+        permission.setOperation( operation );
+        database.addOperation( operation );
+
+        JdoResource resource = new JdoResource();
+        resource.setIdentifier( "resId" );
+        resource.setPattern( true );
+        resource.setPermanent( true );
+        permission.setResource( resource );
+        database.addResource( resource );
+        permission.setPermanent( true );
+        role.addPermission( permission );
+        database.addPermission( permission );
+
+        database.addRole( role );
+
+        JdoUserAssignment assignment = new JdoUserAssignment();
+        assignment.setPermanent( false );
+        assignment.setPrincipal( "principal" );
+        assignment.setTimestamp( new Date() );
+        assignment.addRoleName( "name" );
+
+        database.addUserAssignment( assignment );
+
+        StringWriter w = new StringWriter();
+        new RbacJdoModelStaxWriter().write( w, database );
+
+        RbacDatabase newDatabase = new RbacJdoModelStaxReader().read( new StringReader( w.toString() ) );
+
+        List<JdoRole> expectedRoles = database.getRoles();
+        List<JdoRole> roles = newDatabase.getRoles();
+        assertEquals( expectedRoles.size(), roles.size() );
+        for ( JdoRole r : roles )
+        {
+            boolean found = false;
+            for ( JdoRole expectedRole : expectedRoles )
+            {
+                if ( expectedRole.getName().equals( r.getName() ) )
+                {
+                    found = true;
+
+                    assertRole( expectedRole, r );
+                }
+            }
+            if ( !found )
+            {
+                fail( "Couldn't find role: " + r.getName() );
+            }
+        }
+
+        List<JdoUserAssignment> expectedUserAssignments = database.getUserAssignments();
+        List<JdoUserAssignment> userAssignments = newDatabase.getUserAssignments();
+        assertEquals( expectedUserAssignments.size(), userAssignments.size() );
+        for ( JdoUserAssignment a : userAssignments )
+        {
+            boolean found = false;
+            for ( JdoUserAssignment expectedAssignment : expectedUserAssignments )
+            {
+                if ( expectedAssignment.getPrincipal().equals( a.getPrincipal() ) )
+                {
+                    found = true;
+
+                    assertUserAssignment( expectedAssignment, a );
+                }
+            }
+            if ( !found )
+            {
+                fail( "Couldn't find assignment: " + a.getPrincipal() );
+            }
+        }
+    }
+
+    @SuppressWarnings("unchecked")
+    private void assertRole( JdoRole expectedRole, JdoRole role )
+    {
+        assertEquals( expectedRole.getDescription(), role.getDescription() );
+        assertPermissions( expectedRole.getPermissions(), role.getPermissions() );
+        assertEquals( expectedRole.getChildRoleNames(), role.getChildRoleNames() );
+    }
+
+    private void assertUserAssignment( JdoUserAssignment expectedAssignment, JdoUserAssignment assignment )
+    {
+        SimpleDateFormat sdf = new SimpleDateFormat( "EEE, d MMM yyyy HH:mm:ss Z", Locale.US );
+        assertNotNull( expectedAssignment.getTimestamp() );
+        assertNotNull( assignment.getTimestamp() );
+
+        assertEquals( sdf.format( expectedAssignment.getTimestamp() ), sdf.format( assignment.getTimestamp() ) );
+        assertEquals( expectedAssignment.getRoleNames(), assignment.getRoleNames() );
+    }
+
+    private void assertPermissions( List<JdoPermission> expectedPermissions, List<JdoPermission> permissions )
+    {
+        assertEquals( expectedPermissions.size(), permissions.size() );
+        for ( JdoPermission permission : permissions )
+        {
+            boolean found = false;
+            for ( JdoPermission expectedPermission : expectedPermissions )
+            {
+                if ( expectedPermission.getName().equals( permission.getName() ) )
+                {
+                    found = true;
+
+                    assertPermission( expectedPermission, permission );
+                }
+            }
+            if ( !found )
+            {
+                fail( "Couldn't find permission: " + permission.getName() );
+            }
+        }
+    }
+
+    private void assertPermission( JdoPermission expectedPermission, JdoPermission permission )
+    {
+        assertEquals( expectedPermission.getDescription(), permission.getDescription() );
+        assertOperation( expectedPermission.getOperation(), permission.getOperation() );
+        assertResource( expectedPermission.getResource(), permission.getResource() );
+    }
+
+    private void assertResource( Resource expectedResource, Resource resource )
+    {
+        assertEquals( expectedResource.getIdentifier(), resource.getIdentifier() );
+    }
+
+    private void assertOperation( Operation expectedOperation, Operation operation )
+    {
+        assertEquals( expectedOperation.getName(), operation.getName() );
+        assertEquals( expectedOperation.getDescription(), operation.getDescription() );
+    }
+}

Propchange: archiva/redback/redback-core/trunk/redback-rbac/redback-rbac-providers/redback-rbac-jdo/src/test/java/org/codehaus/plexus/redback/rbac/jdo/RbacJdoModelStaxTest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: archiva/redback/redback-core/trunk/redback-rbac/redback-rbac-providers/redback-rbac-jdo/src/test/java/org/codehaus/plexus/redback/rbac/jdo/RbacJdoModelStaxTest.java
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision

Added: archiva/redback/redback-core/trunk/redback-rbac/redback-rbac-providers/redback-rbac-jdo/src/test/resources/ehcache.xml
URL: http://svn.apache.org/viewvc/archiva/redback/redback-core/trunk/redback-rbac/redback-rbac-providers/redback-rbac-jdo/src/test/resources/ehcache.xml?rev=1310268&view=auto
==============================================================================
--- archiva/redback/redback-core/trunk/redback-rbac/redback-rbac-providers/redback-rbac-jdo/src/test/resources/ehcache.xml (added)
+++ archiva/redback/redback-core/trunk/redback-rbac/redback-rbac-providers/redback-rbac-jdo/src/test/resources/ehcache.xml Fri Apr  6 09:58:14 2012
@@ -0,0 +1,70 @@
+<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+    xsi:noNamespaceSchemaLocation="http://ehcache.org/ehcache.xsd">
+  <diskStore path="java.io.tmpdir" />
+
+  <!--
+    Redback EHCACHE config file that can be used with JPOX-Ehcache integration
+
+    For reference http://ehcache.sourceforge.net/documentation/configuration.html
+  -->
+
+  <!-- make default cache very short lived -->
+  <defaultCache
+    maxElementsInMemory="100"
+    maxElementsOnDisk="0"
+    eternal="false"
+    overflowToDisk="false"
+    timeToIdleSeconds="300"
+    timeToLiveSeconds="600"
+    memoryStoreEvictionPolicy="LFU" />
+
+  <!--
+    cache Redback classes longer to avoid a lot of SQL queries
+    See REDBACK-227
+  -->
+  <cache name="org.codehaus.plexus.redback.rbac.jdo.JdoOperation"
+    maxElementsInMemory="10000"
+    maxElementsOnDisk="0"
+    eternal="false"
+    overflowToDisk="false"
+    timeToIdleSeconds="3000"
+    timeToLiveSeconds="6000"
+    memoryStoreEvictionPolicy="LFU" />
+
+  <cache name="org.codehaus.plexus.redback.rbac.jdo.JdoPermission"
+    maxElementsInMemory="10000"
+    maxElementsOnDisk="0"
+    eternal="false"
+    overflowToDisk="false"
+    timeToIdleSeconds="3000"
+    timeToLiveSeconds="6000"
+    memoryStoreEvictionPolicy="LFU" />
+
+  <cache name="org.codehaus.plexus.redback.rbac.jdo.JdoResource"
+    maxElementsInMemory="10000"
+    maxElementsOnDisk="0"
+    eternal="false"
+    overflowToDisk="false"
+    timeToIdleSeconds="3000"
+    timeToLiveSeconds="6000"
+    memoryStoreEvictionPolicy="LFU" />
+
+  <cache name="org.codehaus.plexus.redback.rbac.jdo.JdoRole"
+    maxElementsInMemory="10000"
+    maxElementsOnDisk="0"
+    eternal="false"
+    overflowToDisk="false"
+    timeToIdleSeconds="3000"
+    timeToLiveSeconds="6000"
+    memoryStoreEvictionPolicy="LFU" />
+
+  <cache name="org.codehaus.plexus.redback.rbac.jdo.JdoUserAssignment"
+    maxElementsInMemory="10000"
+    maxElementsOnDisk="0"
+    eternal="false"
+    overflowToDisk="false"
+    timeToIdleSeconds="3000"
+    timeToLiveSeconds="6000"
+    memoryStoreEvictionPolicy="LFU" />
+
+</ehcache>

Propchange: archiva/redback/redback-core/trunk/redback-rbac/redback-rbac-providers/redback-rbac-jdo/src/test/resources/ehcache.xml
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: archiva/redback/redback-core/trunk/redback-rbac/redback-rbac-providers/redback-rbac-jdo/src/test/resources/ehcache.xml
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision

Added: archiva/redback/redback-core/trunk/redback-rbac/redback-rbac-providers/redback-rbac-jdo/src/test/resources/spring-context.xml
URL: http://svn.apache.org/viewvc/archiva/redback/redback-core/trunk/redback-rbac/redback-rbac-providers/redback-rbac-jdo/src/test/resources/spring-context.xml?rev=1310268&view=auto
==============================================================================
--- archiva/redback/redback-core/trunk/redback-rbac/redback-rbac-providers/redback-rbac-jdo/src/test/resources/spring-context.xml (added)
+++ archiva/redback/redback-core/trunk/redback-rbac/redback-rbac-providers/redback-rbac-jdo/src/test/resources/spring-context.xml Fri Apr  6 09:58:14 2012
@@ -0,0 +1,56 @@
+<?xml version="1.0"?>
+
+<!--
+  ~ Licensed to the Apache Software Foundation (ASF) under one
+  ~ or more contributor license agreements.  See the NOTICE file
+  ~ distributed with this work for additional information
+  ~ regarding copyright ownership.  The ASF licenses this file
+  ~ to you under the Apache License, Version 2.0 (the
+  ~ "License"); you may not use this file except in compliance
+  ~ with the License.  You may obtain a copy of the License at
+  ~
+  ~   http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing,
+  ~ software distributed under the License is distributed on an
+  ~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+  ~ KIND, either express or implied.  See the License for the
+  ~ specific language governing permissions and limitations
+  ~ under the License.
+  -->
+<beans xmlns="http://www.springframework.org/schema/beans"
+       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+       xmlns:context="http://www.springframework.org/schema/context"
+       xsi:schemaLocation="http://www.springframework.org/schema/beans
+           http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
+           http://www.springframework.org/schema/context 
+           http://www.springframework.org/schema/context/spring-context-3.0.xsd">
+
+  <bean name="jdoFactory#users" class="org.codehaus.plexus.jdo.DefaultConfigurableJdoFactory">
+    <property name="driverName" value="org.hsqldb.jdbcDriver"/>
+    <property name="url" value="jdbc:hsqldb:mem:redback-users-tests" />
+    <property name="userName" value="sa"/>
+    <property name="password" value=""/>
+    <property name="persistenceManagerFactoryClass" value="org.jpox.PersistenceManagerFactoryImpl"/>
+    <property name="otherProperties">
+      <props>
+        <prop key="org.jpox.rdbms.dateTimezone">JDK_DEFAULT_TIMEZONE</prop>
+        <prop key="org.jpox.autoCreateTables">true</prop>
+        <prop key="org.jpox.cache.level2">true</prop>
+        <prop key="org.jpox.cache.level2.type">ehcacheclassbased</prop>
+        <prop key="org.jpox.cache.level2.configurationFile">/ehcache.xml</prop>
+        <prop key="org.jpox.cache.level2.cacheName">defaultfake</prop>
+      </props>
+    </property>
+  </bean>
+
+  <bean name="userConfiguration" class="org.codehaus.plexus.redback.configuration.UserConfiguration">
+    <property name="registry" ref="test-conf"/>
+  </bean>
+
+  <bean name="commons-configuration" class="org.codehaus.redback.components.registry.commons.CommonsConfigurationRegistry">
+  </bean>
+
+  <alias name="commons-configuration" alias="test-conf"/>
+
+</beans>
\ No newline at end of file

Propchange: archiva/redback/redback-core/trunk/redback-rbac/redback-rbac-providers/redback-rbac-jdo/src/test/resources/spring-context.xml
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: archiva/redback/redback-core/trunk/redback-rbac/redback-rbac-providers/redback-rbac-jdo/src/test/resources/spring-context.xml
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision

Added: archiva/redback/redback-core/trunk/redback-rbac/redback-rbac-providers/redback-rbac-memory/pom.xml
URL: http://svn.apache.org/viewvc/archiva/redback/redback-core/trunk/redback-rbac/redback-rbac-providers/redback-rbac-memory/pom.xml?rev=1310268&view=auto
==============================================================================
--- archiva/redback/redback-core/trunk/redback-rbac/redback-rbac-providers/redback-rbac-memory/pom.xml (added)
+++ archiva/redback/redback-core/trunk/redback-rbac/redback-rbac-providers/redback-rbac-memory/pom.xml Fri Apr  6 09:58:14 2012
@@ -0,0 +1,47 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+  <parent>
+    <groupId>org.codehaus.redback</groupId>
+    <artifactId>redback-rbac-providers</artifactId>
+    <version>1.5-SNAPSHOT</version>
+  </parent>
+  <artifactId>redback-rbac-memory</artifactId>
+  <name>Redback :: RBAC Provider :: Memory</name>
+  <dependencies>
+    <dependency>
+      <groupId>org.codehaus.redback</groupId>
+      <artifactId>redback-system</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.codehaus.redback</groupId>
+      <artifactId>redback-authorization-api</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.codehaus.redback</groupId>
+      <artifactId>redback-rbac-model</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.springframework</groupId>
+      <artifactId>spring-context-support</artifactId>
+    </dependency>   
+    <dependency>
+      <groupId>javax.annotation</groupId>
+      <artifactId>jsr250-api</artifactId>
+    </dependency>    
+    <dependency>
+      <groupId>org.codehaus.redback</groupId>
+      <artifactId>redback-rbac-tests</artifactId>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.hsqldb</groupId>
+      <artifactId>hsqldb</artifactId>
+      <scope>test</scope>
+    </dependency>    
+    <dependency>
+      <groupId>org.slf4j</groupId>
+      <artifactId>slf4j-simple</artifactId>
+      <scope>test</scope>
+    </dependency>
+  </dependencies>
+</project>

Propchange: archiva/redback/redback-core/trunk/redback-rbac/redback-rbac-providers/redback-rbac-memory/pom.xml
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: archiva/redback/redback-core/trunk/redback-rbac/redback-rbac-providers/redback-rbac-memory/pom.xml
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision

Added: archiva/redback/redback-core/trunk/redback-rbac/redback-rbac-providers/redback-rbac-memory/src/main/java/org/codehaus/plexus/redback/rbac/memory/MemoryAuthorizationDataSource.java
URL: http://svn.apache.org/viewvc/archiva/redback/redback-core/trunk/redback-rbac/redback-rbac-providers/redback-rbac-memory/src/main/java/org/codehaus/plexus/redback/rbac/memory/MemoryAuthorizationDataSource.java?rev=1310268&view=auto
==============================================================================
--- archiva/redback/redback-core/trunk/redback-rbac/redback-rbac-providers/redback-rbac-memory/src/main/java/org/codehaus/plexus/redback/rbac/memory/MemoryAuthorizationDataSource.java (added)
+++ archiva/redback/redback-core/trunk/redback-rbac/redback-rbac-providers/redback-rbac-memory/src/main/java/org/codehaus/plexus/redback/rbac/memory/MemoryAuthorizationDataSource.java Fri Apr  6 09:58:14 2012
@@ -0,0 +1,56 @@
+package org.codehaus.plexus.redback.rbac.memory;
+
+import org.codehaus.plexus.redback.users.User;
+
+/**
+ * MemoryAuthorizationDataSource:
+ *
+ * @author Jesse McConnell <jm...@apache.org>
+ * @version $Id$
+ */
+public class MemoryAuthorizationDataSource
+//    implements AuthorizationDataSource
+{
+    Object principal;
+
+    User user;
+
+    Object permission;
+
+    public MemoryAuthorizationDataSource( Object principal, User user, Object permission )
+    {
+        this.principal = principal;
+        this.user = user;
+        this.permission = permission;
+    }
+
+    public Object getPrincipal()
+    {
+        return principal;
+    }
+
+    public void setPrincipal( String principal )
+    {
+        this.principal = principal;
+    }
+
+    public User getUser()
+    {
+        return user;
+    }
+
+    public void setUser( User user )
+    {
+        this.user = user;
+    }
+
+    public Object getPermission()
+    {
+        return permission;
+    }
+
+    public void setPermission( Object permission )
+    {
+        this.permission = permission;
+    }
+}