(no commit message)
[utils] / security / jpatest / src / main / java / org / wamblee / security / authorization / hibernate / PersistentAuthorizationService.java
1 /*
2  * Copyright 2005-2010 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 package org.wamblee.security.authorization.hibernate;
17
18 import java.util.List;
19
20 import org.springframework.orm.hibernate3.HibernateTemplate;
21 import org.wamblee.security.authorization.AuthorizationRule;
22 import org.wamblee.security.authorization.AuthorizationService;
23 import org.wamblee.security.authorization.DefaultAuthorizationService;
24 import org.wamblee.security.authorization.Operation;
25 import org.wamblee.usermgt.UserAccessor;
26
27 /**
28  * Authorization service with persistent storage. This is a wrapper for
29  * {@link org.wamblee.security.authorization.DefaultAuthorizationService} which
30  * refreshes the state of the service at certain time intervals.
31  * 
32  * @author Erik Brakkee
33  */
34 public class PersistentAuthorizationService extends AuthorizationService {
35     /**
36      * Name of query to find the service by name.
37      */
38     private static final String FIND_QUERY = "findAuthorizationServiceByName";
39
40     /**
41      * Name of the query parameter for the service name.
42      */
43     private static final String NAME_PARAM = "name";
44
45     /**
46      * Authorization service to use.
47      */
48     private DefaultAuthorizationService service;
49
50     /**
51      * Hibernate template to use.
52      */
53     private HibernateTemplate template;
54
55     /**
56      * User accessor.
57      */
58     private UserAccessor userAccessor;
59
60     /**
61      * Name of the service.
62      */
63     private String name;
64
65     /**
66      * Refresh interval in milliseconds.
67      */
68     private final long refreshInterval;
69
70     /**
71      * Last refresh time.
72      */
73     private long lastRefreshTime;
74
75     /**
76      * Constructs the persistent service.
77      * 
78      * @param aName
79      *            Name of the service.
80      * @param aTemplate
81      *            Hibernate template for hibernate usage.
82      * @param aAccessor
83      *            User accessor.
84      * @param aRefresh
85      *            Whether or not to refresh the state of the service at the
86      *            start of every operation.
87      */
88     public PersistentAuthorizationService(String aName,
89         HibernateTemplate aTemplate, UserAccessor aAccessor,
90         long aRefreshInterval) {
91         template = aTemplate;
92         refreshInterval = aRefreshInterval;
93         lastRefreshTime = System.currentTimeMillis();
94         userAccessor = aAccessor;
95         name = aName;
96     }
97     
98     @Override
99     public void setUserAccessor(UserAccessor aUserAccessor) {
100         userAccessor = aUserAccessor;   
101     }
102
103     /**
104      * Initialize service if needed.
105      * 
106      */
107     private void initialize() {
108         if (service == null) {
109             List<DefaultAuthorizationService> result = template
110                 .findByNamedQueryAndNamedParam(FIND_QUERY, NAME_PARAM, 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
132      * org.wamblee.security.authorization.AuthorizationService#isAllowed(java
133      * .lang.Object, org.wamblee.security.authorization.Operation)
134      */
135     public boolean isAllowed(Object aResource, Operation aOperation) {
136         initialize();
137         refresh();
138
139         return service.isAllowed(aResource, aOperation);
140     }
141
142     /*
143      * (non-Javadoc)
144      * 
145      * @see org.wamblee.security.authorization.AuthorizationService#check(T,
146      * org.wamblee.security.authorization.Operation)
147      */
148     public <T> T check(T aResource, Operation aOperation) {
149         initialize();
150         refresh();
151
152         return service.check(aResource, aOperation);
153     }
154
155     /*
156      * (non-Javadoc)
157      * 
158      * @see org.wamblee.security.authorization.AuthorizationService#getRules()
159      */
160     public AuthorizationRule[] getRules() {
161         initialize();
162         refresh();
163
164         return service.getRules();
165     }
166
167     /*
168      * (non-Javadoc)
169      * 
170      * @see
171      * org.wamblee.security.authorization.AuthorizationService#appendRule(org
172      * .wamblee.security.authorization.AuthorizationRule)
173      */
174     public void appendRule(AuthorizationRule aRule) {
175         initialize();
176         refresh();
177         service.appendRule(aRule);
178         save();
179     }
180
181     /*
182      * (non-Javadoc)
183      * 
184      * @see
185      * org.wamblee.security.authorization.AuthorizationService#removeRule(int)
186      */
187     public void removeRule(int aIndex) {
188         initialize();
189         refresh();
190         service.removeRule(aIndex);
191         save();
192     }
193
194     /*
195      * (non-Javadoc)
196      * 
197      * @see
198      * org.wamblee.security.authorization.AuthorizationService#insertRuleAfter
199      * (int, org.wamblee.security.authorization.AuthorizationRule)
200      */
201     public void insertRuleAfter(int aIndex, AuthorizationRule aRule) {
202         initialize();
203         refresh();
204         service.insertRuleAfter(aIndex, aRule);
205         save();
206     }
207
208     /**
209      * Refreshes the state of the service through hibernate.
210      */
211     private synchronized void refresh() {
212         long time = System.currentTimeMillis();
213
214         if ((time - lastRefreshTime) > refreshInterval) {
215             template.refresh(service);
216             lastRefreshTime = time;
217         }
218     }
219
220     /**
221      * Saves any changes to the service state if necessary.
222      */
223     private void save() {
224        // HibernateSupport.merge(template, service);
225     }
226 }