be3ebcdf8976c22bf92a78c4e7d809b96d160689
[utils] / security / usermgt / src / main / java / org / wamblee / security / authentication / 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.security.authentication.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.authentication.AbstractUserSet;
29 import org.wamblee.security.authentication.Group;
30 import org.wamblee.security.authentication.MessageDigester;
31 import org.wamblee.security.authentication.NameValidator;
32 import org.wamblee.security.authentication.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     @Override
64     public void userModified(User aUser) {
65         assert aUser.getPrimaryKey() != null;
66         User merged = entityManager.merge(aUser);
67         // Need to flush the entity manager to make sure the version is updated. 
68         entityManager.flush();
69         JpaMergeSupport.merge(merged, aUser);
70         cache.remove(aUser.getName());
71         setPasswordInfo(aUser);
72         cache.put(aUser.getName(), new User(aUser));
73     }
74
75     @Override
76     public User find(String aName) {
77         User user = cache.get(aName);
78
79         if (user != null) {
80             return user;
81         }
82
83         TypedQuery<User> query = entityManager.createNamedQuery(
84             User.QUERY_FIND_BY_NAME, User.class);
85         query.setParameter(User.NAME_PARAM, aName);
86         try {
87             user = query.getSingleResult();
88             setPasswordInfo(user);
89             cache.put(aName, user);
90             return user;
91         } catch (NoResultException e) {
92             return null;
93         }
94     }
95
96     @Override
97     public boolean contains(User aUser) {
98         return find(aUser.getName()) != null;
99     }
100
101     @Override
102     public boolean add(User aUser) {
103         assert aUser.getPrimaryKey() == null;
104
105         if (contains(aUser)) {
106             return false;
107         }
108
109         entityManager.persist(aUser);
110         entityManager.flush(); // to make sure the version is updated. 
111         setPasswordInfo(aUser);
112         cache.put(aUser.getName(), aUser);
113
114         return true;
115     }
116
117     @Override
118     public boolean remove(User aUser) {
119         if (!contains(aUser)) {
120             return false;
121         }
122
123         User user = entityManager.merge(aUser);
124         entityManager.remove(user);
125         cache.remove(aUser.getName());
126
127         return true;
128     }
129
130     @Override
131     public Set<User> list() {
132         Set<User> users = new TreeSet<User>();
133         List<User> list = entityManager.createNamedQuery(User.QUERY_ALL_USERS,
134             User.class).getResultList();
135
136         for (User user : list) {
137             setPasswordInfo(user);
138             users.add(user);
139         }
140
141         return users;
142     }
143
144     @Override
145     public Set<User> list(Group aGroup) {
146         Set<User> users = new TreeSet<User>();
147         TypedQuery<User> query = entityManager.createNamedQuery(
148             User.QUERY_FIND_BY_GROUP_NAME, User.class);
149         query.setParameter(User.NAME_PARAM, aGroup.getName());
150         
151         List<User> list = query.getResultList();
152         users.addAll(list);
153         for (User user : users) {
154             setPasswordInfo(user);
155         }
156
157         return users;
158     }
159
160     @Override
161     public int size() {
162         Long result = entityManager.createNamedQuery(User.QUERY_COUNT_USERS, Long.class).getSingleResult();
163         return result.intValue();
164     }
165     
166     @Override
167     public void clearCache() {
168         cache.clear();   
169     }
170 }