From: erik Date: Fri, 30 Apr 2010 22:07:49 +0000 (+0000) Subject: (no commit message) X-Git-Tag: wamblee-utils-0.2.2^2~11 X-Git-Url: http://wamblee.org/gitweb/?a=commitdiff_plain;h=a484e5ed22abd827236f61aed3ecf25853fcfc18;p=utils --- 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 index 00000000..e1b71d7d --- /dev/null +++ b/security/impl/src/main/java/org/wamblee/security/authorization/jpa/JpaAuthorizationService.java @@ -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 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); + } +}