(no commit message)
authorerik <erik@77661180-640e-0410-b3a8-9f9b13e6d0e0>
Fri, 30 Apr 2010 22:07:49 +0000 (22:07 +0000)
committererik <erik@77661180-640e-0410-b3a8-9f9b13e6d0e0>
Fri, 30 Apr 2010 22:07:49 +0000 (22:07 +0000)
security/impl/src/main/java/org/wamblee/security/authorization/jpa/JpaAuthorizationService.java [new file with mode: 0644]

diff --git a/security/impl/src/main/java/org/wamblee/security/authorization/jpa/JpaAuthorizationService.java b/security/impl/src/main/java/org/wamblee/security/authorization/jpa/JpaAuthorizationService.java
new file mode 100644 (file)
index 0000000..e1b71d7
--- /dev/null
@@ -0,0 +1,223 @@
+/*
+ * Copyright 2005-2010 the original author or authors.
+ * 
+ * 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.
+ */
+package org.wamblee.security.authorization.jpa;
+
+import javax.persistence.EntityManager;
+import javax.persistence.NoResultException;
+import javax.persistence.NonUniqueResultException;
+
+import org.wamblee.persistence.JpaMergeSupport;
+import org.wamblee.security.authorization.AbstractAuthorizationService;
+import org.wamblee.security.authorization.AbstractAuthorizationRule;
+import org.wamblee.security.authorization.AuthorizationRule;
+import org.wamblee.security.authorization.AuthorizationService;
+import org.wamblee.security.authorization.DefaultAuthorizationService;
+import org.wamblee.security.authorization.Operation;
+import org.wamblee.usermgt.UserAccessor;
+
+/**
+ * Authorization service with persistent storage. This is a wrapper for
+ * {@link org.wamblee.security.authorization.DefaultAuthorizationService} which
+ * refreshes the state of the service at certain time intervals.
+ * 
+ * @author Erik Brakkee
+ */
+public class JpaAuthorizationService implements AuthorizationService {
+
+    /**
+     * Authorization service to use.
+     */
+    private AuthorizationService service;
+
+    /**
+     * Hibernate template to use.
+     */
+    private EntityManager entityManager;
+
+    /**
+     * User accessor.
+     */
+    private UserAccessor userAccessor;
+
+    /**
+     * Name of the service.
+     */
+    private String name;
+
+    /**
+     * Refresh interval in milliseconds.
+     */
+    private final long refreshInterval;
+
+    /**
+     * Last refresh time.
+     */
+    private long lastRefreshTime;
+
+    /**
+     * Constructs the persistent service.
+     * 
+     * @param aName
+     *            Name of the service.
+     * @param aEntityManager
+     *            Entity manager.
+     * @param aAccessor
+     *            User accessor.
+     * @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) {
+        entityManager = aEntityManager;
+        refreshInterval = aRefreshInterval;
+        lastRefreshTime = System.currentTimeMillis();
+        userAccessor = aAccessor;
+        name = aName;
+    }
+    
+    @Override
+    public void setUserAccessor(UserAccessor aUserAccessor) {
+        userAccessor = aUserAccessor;   
+    }
+
+    /**
+     * Initialize service if needed.
+     * 
+     */
+    private void initialize() {
+        if (service == null) {
+            refreshByReload();
+        }
+    }
+
+    private void refreshByReload() {
+        try {
+            service = entityManager.createNamedQuery(
+                AbstractAuthorizationService.QUERY_FIND_BY_NAME,
+                AbstractAuthorizationService.class).setParameter(
+                    AbstractAuthorizationService.NAME_PARAM, name).getSingleResult();
+            service.setUserAccessor(userAccessor);
+        } 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);
+        }
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see
+     * org.wamblee.security.authorization.AuthorizationService#isAllowed(java
+     * .lang.Object, org.wamblee.security.authorization.Operation)
+     */
+    public boolean isAllowed(Object aResource, Operation aOperation) {
+        initialize();
+        refresh();
+
+        return service.isAllowed(aResource, aOperation);
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see org.wamblee.security.authorization.AuthorizationService#check(T,
+     * org.wamblee.security.authorization.Operation)
+     */
+    public <T> T check(T aResource, Operation aOperation) {
+        initialize();
+        refresh();
+
+        return service.check(aResource, aOperation);
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see org.wamblee.security.authorization.AuthorizationService#getRules()
+     */
+    public AuthorizationRule[] getRules() {
+        initialize();
+        refresh();
+
+        return service.getRules();
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see
+     * org.wamblee.security.authorization.AuthorizationService#appendRule(org
+     * .wamblee.security.authorization.AuthorizationRule)
+     */
+    public void appendRule(AuthorizationRule aRule) {
+        initialize();
+        refresh();
+        service.appendRule(aRule);
+        save();
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see
+     * org.wamblee.security.authorization.AuthorizationService#removeRule(int)
+     */
+    public void removeRule(int aIndex) {
+        initialize();
+        refresh();
+        service.removeRule(aIndex);
+        save();
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see
+     * org.wamblee.security.authorization.AuthorizationService#insertRuleAfter
+     * (int, org.wamblee.security.authorization.AuthorizationRule)
+     */
+    public void insertRuleAfter(int aIndex, AuthorizationRule aRule) {
+        initialize();
+        refresh();
+        service.insertRuleAfter(aIndex, aRule);
+        save();
+    }
+
+    /**
+     * Refreshes the state of the service through hibernate.
+     */
+    private synchronized void refresh() {
+        long time = System.currentTimeMillis();
+
+        if ((time - lastRefreshTime) > refreshInterval) {
+            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);
+    }
+}