/* * Copyright 2005 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.hibernate; import java.util.List; import org.springframework.orm.hibernate3.HibernateTemplate; import org.wamblee.persistence.AbstractPersistent; import org.wamblee.persistence.hibernate.HibernateSupport; 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. */ public class PersistentAuthorizationService extends AbstractPersistent implements AuthorizationService { /** * Name of query to find the service by name. */ private static final String FIND_QUERY = "findAuthorizationServiceByName"; /** * Name of the query parameter for the service name. */ private static final String NAME_PARAM = "name"; /** * Authorization service to use. */ private DefaultAuthorizationService _service; /** * Hibernate template to use. */ private HibernateTemplate _template; /** * 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 aTemplate * Hibernate template for hibernate usage. * @param aAccessor * User accessor. * @param aRefresh * Whether or not to refresh the state of the service at the * start of every operation. */ public PersistentAuthorizationService(String aName, HibernateTemplate aTemplate, UserAccessor aAccessor, long aRefreshInterval) { _template = aTemplate; _refreshInterval = aRefreshInterval; _lastRefreshTime = System.currentTimeMillis(); _userAccessor = aAccessor; _name = aName; } /** * Initialize service if needed. */ private void initialize() { if (_service == null) { List result = _template .findByNamedQueryAndNamedParam(FIND_QUERY, NAME_PARAM, _name); if (result.size() > 1) { throw new IllegalArgumentException( "Returned more than one service for name '" + _name + "' (" + result.size() + ")"); } if (result.size() == 0) { _service = new DefaultAuthorizationService(_userAccessor, _name); _template.persist(_service); } else { _service = result.get(0); _service.setUserAccessor(_userAccessor); } } } /* * (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 ) { _template.refresh(_service); _lastRefreshTime = time; } } /** * Saves any changes to the service state if necessary. */ private void save() { HibernateSupport.merge(_template, _service); } }