895e77e642d9129bcb24478ddebd6695179c15ca
[utils] / security / src / main / java / org / wamblee / security / authorization / hibernate / PersistentAuthorizationService.java
1 /*
2  * Copyright 2005 the original author or authors.
3  * 
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  * 
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  * 
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 package org.wamblee.security.authorization.hibernate;
18
19 import java.util.List;
20
21 import org.springframework.orm.hibernate3.HibernateTemplate;
22 import org.wamblee.persistence.AbstractPersistent;
23 import org.wamblee.persistence.hibernate.HibernateSupport;
24 import org.wamblee.security.authorization.AuthorizationRule;
25 import org.wamblee.security.authorization.AuthorizationService;
26 import org.wamblee.security.authorization.DefaultAuthorizationService;
27 import org.wamblee.security.authorization.Operation;
28 import org.wamblee.usermgt.UserAccessor;
29
30 /**
31  * Authorization service with persistent storage.
32  * This is a wrapper for {@link org.wamblee.security.authorization.DefaultAuthorizationService}
33  * which refreshes the state of the service at certain time intervals. 
34  *
35  * @author Erik Brakkee
36  */
37 public class PersistentAuthorizationService extends AbstractPersistent
38         implements AuthorizationService {
39
40     /**
41      * Name of query to find the service by name.
42      */
43     private static final String FIND_QUERY = "findAuthorizationServiceByName";
44
45     /**
46      * Name of the query parameter for the service name.
47      */
48     private static final String NAME_PARAM = "name";
49
50     /**
51      * Authorization service to use.
52      */
53     private DefaultAuthorizationService service;
54
55     /**
56      * Hibernate template to use.
57      */
58     private HibernateTemplate template;
59
60     /**
61      * User accessor.
62      */
63     private UserAccessor userAccessor;
64     
65     /**
66      * Name of the service. 
67      */
68     private String name; 
69
70     /**
71      * Refresh interval in milliseconds. 
72      */
73     private final long refreshInterval;
74     
75     /**
76      * Last refresh time. 
77      */
78     private long lastRefreshTime; 
79
80     /**
81      * Constructs the persistent service.
82      * 
83      * @param aName
84      *            Name of the service.
85      * @param aTemplate
86      *            Hibernate template for hibernate usage.
87      * @param aAccessor
88      *            User accessor.
89      * @param aRefresh
90      *            Whether or not to refresh the state of the service at the
91      *            start of every operation.
92      */
93     public PersistentAuthorizationService(String aName,
94             HibernateTemplate aTemplate, UserAccessor aAccessor,
95             long aRefreshInterval) {
96         template = aTemplate;
97         refreshInterval = aRefreshInterval;
98         lastRefreshTime = System.currentTimeMillis(); 
99         userAccessor = aAccessor;
100         name = aName; 
101     }
102
103     /**
104      * Initialize service if needed. 
105      */
106     private void initialize() {
107         if (service == null) {
108             List<DefaultAuthorizationService> result = template
109                     .findByNamedQueryAndNamedParam(FIND_QUERY, NAME_PARAM,
110                             name);
111
112             if (result.size() > 1) {
113                 throw new IllegalArgumentException(
114                         "Returned more than one service for name '" + name
115                                 + "' (" + result.size() + ")");
116             }
117
118             if (result.size() == 0) {
119                 service = new DefaultAuthorizationService(userAccessor, name);
120                 template.persist(service);
121             } else {
122                 service = result.get(0);
123                 service.setUserAccessor(userAccessor);
124             }
125         }
126     }
127
128     /*
129      * (non-Javadoc)
130      * 
131      * @see org.wamblee.security.authorization.AuthorizationService#isAllowed(java.lang.Object,
132      *      org.wamblee.security.authorization.Operation)
133      */
134     public boolean isAllowed(Object aResource, Operation aOperation) {
135         initialize();
136         refresh();
137         return service.isAllowed(aResource, aOperation);
138     }
139     
140     /* (non-Javadoc)
141      * @see org.wamblee.security.authorization.AuthorizationService#check(T, org.wamblee.security.authorization.Operation)
142      */
143     public <T> T check(T aResource, Operation aOperation) {
144         initialize();
145         refresh();
146         return service.check(aResource, aOperation);
147     }
148
149     /*
150      * (non-Javadoc)
151      * 
152      * @see org.wamblee.security.authorization.AuthorizationService#getRules()
153      */
154     public AuthorizationRule[] getRules() {
155         initialize();
156         refresh();
157         return service.getRules();
158     }
159
160     /*
161      * (non-Javadoc)
162      * 
163      * @see org.wamblee.security.authorization.AuthorizationService#appendRule(org.wamblee.security.authorization.AuthorizationRule)
164      */
165     public void appendRule(AuthorizationRule aRule) {
166         initialize();
167         refresh();
168         service.appendRule(aRule);
169         save();
170     }
171
172     /*
173      * (non-Javadoc)
174      * 
175      * @see org.wamblee.security.authorization.AuthorizationService#removeRule(int)
176      */
177     public void removeRule(int aIndex) {
178         initialize();
179         refresh();
180         service.removeRule(aIndex);
181         save();
182     }
183
184     /*
185      * (non-Javadoc)
186      * 
187      * @see org.wamblee.security.authorization.AuthorizationService#insertRuleAfter(int,
188      *      org.wamblee.security.authorization.AuthorizationRule)
189      */
190     public void insertRuleAfter(int aIndex, AuthorizationRule aRule) {
191         initialize();
192         refresh();
193         service.insertRuleAfter(aIndex, aRule);
194         save();
195     }
196
197     /**
198      * Refreshes the state of the service through hibernate.
199      * 
200      */
201     private synchronized void refresh() {
202         long time = System.currentTimeMillis(); 
203         if ( time - lastRefreshTime > refreshInterval ) { 
204             template.refresh(service);
205             lastRefreshTime = time; 
206         }
207     }
208
209     /**
210      * Saves any changes to the service state if necessary.
211      */
212     private void save() {
213         HibernateSupport.merge(template, service);
214     }
215 }