now using the simplified user management interface.
[utils] / security / impl / src / main / java / org / wamblee / security / authorization / jpa / JpaAuthorizationService.java
index 9683888f93df6420f8daabd2189a0a331b79e4f4..4bce7aef3e60a55d3c7ed80afdafc4d81a556d96 100644 (file)
@@ -21,6 +21,7 @@ import javax.persistence.NonUniqueResultException;
 
 import org.wamblee.persistence.JpaMergeSupport;
 import org.wamblee.security.authentication.UserAccessor;
+import org.wamblee.security.authentication.UserAdministration;
 import org.wamblee.security.authorization.AbstractAuthorizationService;
 import org.wamblee.security.authorization.AbstractAuthorizationRule;
 import org.wamblee.security.authorization.AuthorizationRule;
@@ -51,6 +52,11 @@ public class JpaAuthorizationService implements AuthorizationService {
      * User accessor.
      */
     private UserAccessor userAccessor;
+    
+    /**
+     * User administration.
+     */
+    private UserAdministration userAdmin;
 
     /**
      * Name of the service.
@@ -76,16 +82,18 @@ public class JpaAuthorizationService implements AuthorizationService {
      *            Entity manager.
      * @param aAccessor
      *            User accessor.
+     * @param aUserAdmin  User administration.
      * @param aRefresh
      *            Whether or not to refresh the state of the service at the
      *            start of every operation.
      */
     public JpaAuthorizationService(String aName, EntityManager aEntityManager,
-        UserAccessor aAccessor, long aRefreshInterval) {
+        UserAccessor aAccessor, UserAdministration aUserAdmin, long aRefreshInterval) {
         entityManager = aEntityManager;
         refreshInterval = aRefreshInterval;
         lastRefreshTime = System.currentTimeMillis();
         userAccessor = aAccessor;
+        userAdmin = aUserAdmin;
         name = aName;
     }
     
@@ -93,33 +101,32 @@ public class JpaAuthorizationService implements AuthorizationService {
     public void setUserAccessor(UserAccessor aUserAccessor) {
         userAccessor = aUserAccessor;   
     }
-
-    /**
-     * Initialize service if needed.
-     * 
-     */
-    private void initialize() {
-        if (service == null) {
-            service = refreshByReload();
-        }
+    
+    @Override
+    public void setUserAdministration(UserAdministration aUserAdmin) {
+        userAdmin = aUserAdmin;   
     }
 
     private AuthorizationService refreshByReload() {
-        AuthorizationService service; 
+        if ( userAdmin == null ) { 
+            throw new IllegalArgumentException("useradmin is null");
+        }
+        AuthorizationService svc; 
         try {
-            service = entityManager.createNamedQuery(
+            svc = entityManager.createNamedQuery(
                 AbstractAuthorizationService.QUERY_FIND_BY_NAME,
                 AbstractAuthorizationService.class).setParameter(
                     DefaultAuthorizationService.NAME_PARAM, name).getSingleResult();
-            service.setUserAccessor(userAccessor);
+            svc.setUserAccessor(userAccessor);
+            svc.setUserAdministration(userAdmin);
         } catch (NonUniqueResultException e) {
             throw new IllegalArgumentException(
                 "Returned more than one service for name '" + name + "'");
         } catch (NoResultException e) {
-            service = new DefaultAuthorizationService(userAccessor, name);
-            entityManager.persist(service);
+            svc = new DefaultAuthorizationService(userAccessor, userAdmin, name);
+            entityManager.persist(svc);
         }
-        return service;
+        return svc;
     }
 
     /*
@@ -130,7 +137,6 @@ public class JpaAuthorizationService implements AuthorizationService {
      * .lang.Object, org.wamblee.security.authorization.Operation)
      */
     public boolean isAllowed(Object aResource, Operation aOperation) {
-        initialize();
         refresh();
 
         return service.isAllowed(aResource, aOperation);
@@ -143,7 +149,6 @@ public class JpaAuthorizationService implements AuthorizationService {
      * org.wamblee.security.authorization.Operation)
      */
     public <T> T check(T aResource, Operation aOperation) {
-        initialize();
         refresh();
 
         return service.check(aResource, aOperation);
@@ -155,7 +160,6 @@ public class JpaAuthorizationService implements AuthorizationService {
      * @see org.wamblee.security.authorization.AuthorizationService#getRules()
      */
     public AuthorizationRule[] getRules() {
-        initialize();
         refresh();
 
         return service.getRules();
@@ -169,12 +173,22 @@ public class JpaAuthorizationService implements AuthorizationService {
      * .wamblee.security.authorization.AuthorizationRule)
      */
     public void appendRule(AuthorizationRule aRule) {
-        initialize();
-        refresh();
-        service.appendRule(aRule);
-        save(); // service might still be detached as service is cached. 
+        AuthorizationService svc = refreshByReload();
+        svc.appendRule(aRule);
+        // Setting service to null will force reload the next time the 
+        // service is used. This deals effectively with the case where the 
+        // current transaction would roll back and the change would not have been made. 
+        setService(null);
     }
-
+    
+    private synchronized AuthorizationService getService() { 
+        return service; 
+    }
+    
+    private synchronized void setService(AuthorizationService aSvc) { 
+        service = aSvc; 
+    }
+    
     /*
      * (non-Javadoc)
      * 
@@ -182,10 +196,9 @@ public class JpaAuthorizationService implements AuthorizationService {
      * org.wamblee.security.authorization.AuthorizationService#removeRule(int)
      */
     public void removeRule(int aIndex) {
-        initialize();
-        refresh();
-        service.removeRule(aIndex);
-        save(); // service might still be detached as service is cached. 
+        AuthorizationService svc = refreshByReload(); 
+        svc.removeRule(aIndex);
+        setService(null); 
     }
 
     /*
@@ -196,10 +209,9 @@ public class JpaAuthorizationService implements AuthorizationService {
      * (int, org.wamblee.security.authorization.AuthorizationRule)
      */
     public void insertRuleAfter(int aIndex, AuthorizationRule aRule) {
-        initialize();
-        refresh();
-        service.insertRuleAfter(aIndex, aRule);
-        save(); // service might still be detached as service is cached.
+        AuthorizationService svc = refreshByReload(); 
+        svc.insertRuleAfter(aIndex, aRule);
+        setService(null);
     }
 
     /**
@@ -208,18 +220,9 @@ public class JpaAuthorizationService implements AuthorizationService {
     private synchronized void refresh() {
         long time = System.currentTimeMillis();
 
-        if ((time - lastRefreshTime) > refreshInterval) {
+        if (service == null || (time - lastRefreshTime) > refreshInterval) {
             service = refreshByReload();
             lastRefreshTime = time;
         }
     }
-
-    /**
-     * Saves any changes to the service state if necessary.
-     */
-    private void save() {
-        AuthorizationService merged = entityManager.merge(service);
-        entityManager.flush();
-        JpaMergeSupport.merge(merged, service);
-    }
 }