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