045eda00623141e7d7489b7ed32cd8f1f6cc3dee
[utils] / security / impl / src / main / java / org / wamblee / usermgt / jpa / JpaUserSet.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.usermgt.jpa;
17
18 import java.util.List;
19 import java.util.Set;
20 import java.util.TreeSet;
21
22 import javax.persistence.EntityManager;
23 import javax.persistence.NoResultException;
24 import javax.persistence.TypedQuery;
25
26 import org.wamblee.cache.Cache;
27 import org.wamblee.persistence.JpaMergeSupport;
28 import org.wamblee.security.encryption.MessageDigester;
29 import org.wamblee.usermgt.AbstractUserSet;
30 import org.wamblee.usermgt.Group;
31 import org.wamblee.usermgt.NameValidator;
32 import org.wamblee.usermgt.User;
33
34 /**
35  * User set backed by the database.
36  * 
37  * @author Erik Brakkee
38  */
39 public class JpaUserSet extends AbstractUserSet {
40
41     /**
42      * Cache of users. Every user in the cache has its password validator and
43      * encoder set.
44      */
45     private Cache<String, User> cache;
46
47     private EntityManager entityManager;
48
49     /**
50      * Constructs a user set backed by the database.
51      * 
52      * @param aCache
53      *            User cache to use.
54      */
55     public JpaUserSet(Cache<String, User> aCache,
56         NameValidator aPasswordValidator, MessageDigester aPasswordEncoder,
57         EntityManager aEntityManager) {
58         super(aPasswordValidator, aPasswordEncoder);
59         cache = aCache;
60         entityManager = aEntityManager;
61     }
62
63     /*
64      * (non-Javadoc)
65      * 
66      * @see org.wamblee.usermgt.UserSet#userModified(org.wamblee.usermgt.User)
67      */
68     public void userModified(User aUser) {
69         assert aUser.getPrimaryKey() != null;
70         User merged = entityManager.merge(aUser);
71         // Need to flush the entity manager to make sure the version is updated. 
72         entityManager.flush();
73         JpaMergeSupport.merge(merged, aUser);
74         cache.remove(aUser.getName());
75         setPasswordInfo(aUser);
76         cache.put(aUser.getName(), new User(aUser));
77     }
78
79     /*
80      * (non-Javadoc)
81      * 
82      * @see org.wamblee.usermgt.UserSet#find(java.lang.String)
83      */
84     public User find(String aName) {
85         User user = cache.get(aName);
86
87         if (user != null) {
88             return user;
89         }
90
91         TypedQuery<User> query = entityManager.createNamedQuery(
92             User.QUERY_FIND_BY_NAME, User.class);
93         query.setParameter(User.NAME_PARAM, aName);
94         try {
95             user = query.getSingleResult();
96             user = new User(user);
97             setPasswordInfo(user);
98             cache.put(aName, user);
99             return user;
100         } catch (NoResultException e) {
101             return null;
102         }
103     }
104
105     /*
106      * (non-Javadoc)
107      * 
108      * @see org.wamblee.usermgt.UserSet#contains(org.wamblee.usermgt.User)
109      */
110     public boolean contains(User aUser) {
111         return find(aUser.getName()) != null;
112     }
113
114     /*
115      * (non-Javadoc)
116      * 
117      * @see org.wamblee.usermgt.UserSet#add(org.wamblee.usermgt.User)
118      */
119     public boolean add(User aUser) {
120         assert aUser.getPrimaryKey() == null;
121
122         if (contains(aUser)) {
123             return false;
124         }
125
126         entityManager.persist(aUser);
127         setPasswordInfo(aUser);
128         cache.put(aUser.getName(), aUser);
129
130         return true;
131     }
132
133     /*
134      * (non-Javadoc)
135      * 
136      * @see org.wamblee.usermgt.UserSet#remove(org.wamblee.usermgt.User)
137      */
138     public boolean remove(User aUser) {
139         if (!contains(aUser)) {
140             return false;
141         }
142
143         User user = entityManager.merge(aUser);
144         entityManager.remove(user);
145         cache.remove(aUser.getName());
146
147         return true;
148     }
149
150     /*
151      * (non-Javadoc)
152      * 
153      * @see org.wamblee.usermgt.UserSet#list()
154      */
155     public Set<User> list() {
156         Set<User> users = new TreeSet<User>();
157         List<User> list = entityManager.createNamedQuery(User.QUERY_ALL_USERS,
158             User.class).getResultList();
159
160         for (User user : list) {
161             setPasswordInfo(user);
162             users.add(new User(user));
163         }
164
165         return users;
166     }
167
168     /*
169      * (non-Javadoc)
170      * 
171      * @see org.wamblee.usermgt.UserSet#list(org.wamblee.usermgt.Group)
172      */
173     public Set<User> list(Group aGroup) {
174         Set<User> users = new TreeSet<User>();
175         TypedQuery<User> query = entityManager.createNamedQuery(
176             User.QUERY_FIND_BY_GROUP_NAME, User.class);
177         query.setParameter(User.NAME_PARAM, aGroup.getName());
178         
179         List<User> list = query.getResultList();
180
181         for (User user : list) {
182             setPasswordInfo(user);
183             users.add(new User(user));
184         }
185
186         return users;
187     }
188
189     /*
190      * (non-Javadoc)
191      * 
192      * @see org.wamblee.usermgt.UserSet#size()
193      */
194     public int size() {
195         Long result = entityManager.createNamedQuery(User.QUERY_COUNT_USERS, Long.class).getSingleResult();
196         return result.intValue();
197     }
198 }