/* * Copyright 2005-2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.wamblee.security.authentication.jpa; import java.util.List; import java.util.Set; import java.util.TreeSet; import javax.persistence.EntityManager; import javax.persistence.NoResultException; import javax.persistence.TypedQuery; import org.wamblee.cache.Cache; import org.wamblee.persistence.JpaMergeSupport; import org.wamblee.security.authentication.AbstractUserSet; import org.wamblee.security.authentication.Group; import org.wamblee.security.authentication.MessageDigester; import org.wamblee.security.authentication.NameValidator; import org.wamblee.security.authentication.User; /** * User set backed by the database. * * @author Erik Brakkee */ public class JpaUserSet extends AbstractUserSet { /** * Cache of users. Every user in the cache has its password validator and * encoder set. */ private Cache cache; private EntityManager entityManager; /** * Constructs a user set backed by the database. * * @param aCache * User cache to use. */ public JpaUserSet(Cache aCache, NameValidator aPasswordValidator, MessageDigester aPasswordEncoder, EntityManager aEntityManager) { super(aPasswordValidator, aPasswordEncoder); cache = aCache; entityManager = aEntityManager; } @Override public void userModified(User aUser) { assert aUser.getPrimaryKey() != null; User merged = entityManager.merge(aUser); // Need to flush the entity manager to make sure the version is updated. entityManager.flush(); JpaMergeSupport.merge(merged, aUser); cache.remove(aUser.getName()); setPasswordInfo(aUser); cache.put(aUser.getName(), new User(aUser)); } @Override public User find(String aName) { User user = cache.get(aName); if (user != null) { return user; } TypedQuery query = entityManager.createNamedQuery( User.QUERY_FIND_BY_NAME, User.class); query.setParameter(User.NAME_PARAM, aName); try { user = query.getSingleResult(); setPasswordInfo(user); cache.put(aName, user); return user; } catch (NoResultException e) { return null; } } @Override public boolean contains(User aUser) { return find(aUser.getName()) != null; } @Override public boolean add(User aUser) { assert aUser.getPrimaryKey() == null; if (contains(aUser)) { return false; } entityManager.persist(aUser); entityManager.flush(); // to make sure the version is updated. setPasswordInfo(aUser); cache.put(aUser.getName(), aUser); return true; } @Override public boolean remove(User aUser) { if (!contains(aUser)) { return false; } User user = entityManager.merge(aUser); entityManager.remove(user); cache.remove(aUser.getName()); return true; } @Override public Set list() { Set users = new TreeSet(); List list = entityManager.createNamedQuery(User.QUERY_ALL_USERS, User.class).getResultList(); for (User user : list) { setPasswordInfo(user); users.add(user); } return users; } @Override public Set list(Group aGroup) { Set users = new TreeSet(); TypedQuery query = entityManager.createNamedQuery( User.QUERY_FIND_BY_GROUP_NAME, User.class); query.setParameter(User.NAME_PARAM, aGroup.getName()); List list = query.getResultList(); users.addAll(list); for (User user : users) { setPasswordInfo(user); } return users; } @Override public int size() { Long result = entityManager.createNamedQuery(User.QUERY_COUNT_USERS, Long.class).getSingleResult(); return result.intValue(); } @Override public void clearCache() { cache.clear(); } }