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