001package org.apache.fulcrum.security.hibernate;
002
003/*
004 * Licensed to the Apache Software Foundation (ASF) under one
005 * or more contributor license agreements.  See the NOTICE file
006 * distributed with this work for additional information
007 * regarding copyright ownership.  The ASF licenses this file
008 * to you under the Apache License, Version 2.0 (the
009 * "License"); you may not use this file except in compliance
010 * with the License.  You may obtain a copy of the License at
011 *
012 *   http://www.apache.org/licenses/LICENSE-2.0
013 *
014 * Unless required by applicable law or agreed to in writing,
015 * software distributed under the License is distributed on an
016 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
017 * KIND, either express or implied.  See the License for the
018 * specific language governing permissions and limitations
019 * under the License.
020 */
021import java.util.List;
022
023import org.apache.fulcrum.security.entity.User;
024import org.apache.fulcrum.security.spi.AbstractUserManager;
025import org.apache.fulcrum.security.util.DataBackendException;
026import org.apache.fulcrum.security.util.EntityExistsException;
027import org.apache.fulcrum.security.util.UnknownEntityException;
028import org.apache.fulcrum.security.util.UserSet;
029import org.hibernate.HibernateException;
030
031/**
032 * This implementation persists to a database via Hibernate.
033 * 
034 * @author <a href="mailto:epugh@upstate.com">Eric Pugh</a>
035 * @version $Id$
036 */
037@SuppressWarnings("unchecked")
038public class HibernateUserManagerImpl extends AbstractUserManager
039{
040    private PersistenceHelper persistenceHelper;
041
042    /**
043     * Check whether a specified user's account exists.
044     * 
045     * The login name is used for looking up the account.
046     * 
047     * @param userName
048     *            The name of the user to be checked.
049     * @return true if the specified account exists
050     * @throws DataBackendException
051     *             if there was an error accessing the data backend.
052     */
053    public boolean checkExists(String userName) throws DataBackendException
054    {
055        List<User> users = null;
056        try
057        {
058            users = getPersistenceHelper().retrieveSession().createQuery("from " + User.class.getName() + " su where su.name=:name")
059                    .setString("name", userName.toLowerCase()).list();
060        }
061        catch (HibernateException e)
062        {
063            throw new DataBackendException("Error retrieving user information", e);
064        }
065        if (users.size() > 1)
066        {
067            throw new DataBackendException("Multiple Users with same username '" + userName + "'");
068        }
069        return (users.size() == 1);
070    }
071
072    /**
073     * Retrieve a user from persistent storage using username as the key.
074     * 
075     * @param userName
076     *            the name of the user.
077     * @return an User object.
078     * @exception UnknownEntityException
079     *                if the user's account does not exist in the database.
080     * @exception DataBackendException
081     *                if there is a problem accessing the storage.
082     */
083    @Override
084    public User getUser(String userName) throws UnknownEntityException, DataBackendException
085    {
086        List<User> users = null;
087        try
088        {
089            users = getPersistenceHelper().retrieveSession().createQuery("from " + User.class.getName() + " su where su.name=:name")
090                    .setString("name", userName.toLowerCase()).list();
091        }
092        catch (HibernateException e)
093        {
094            throw new DataBackendException("Error retrieving user information", e);
095        }
096        if (users.size() > 1)
097        {
098            throw new DataBackendException("Multiple Users with same username '" + userName + "'");
099        }
100        if (users.size() == 1)
101        {
102            return users.get(0);
103        }
104        throw new UnknownEntityException("Unknown user '" + userName + "'");
105    }
106
107    /**
108     * Retrieves all users defined in the system.
109     * 
110     * @return the names of all users defined in the system.
111     * @throws DataBackendException
112     *             if there was an error accessing the data backend.
113     */
114    public UserSet getAllUsers() throws DataBackendException
115    {
116        UserSet userSet = new UserSet();
117        try
118        {
119            List<User> users = getPersistenceHelper().retrieveSession().createQuery("from " + User.class.getName()).list();
120            userSet.add(users);
121        }
122        catch (HibernateException e)
123        {
124            throw new DataBackendException("Error retrieving all users", e);
125        }
126        return userSet;
127    }
128
129    /**
130     * Removes an user account from the system.
131     * 
132     * @param user
133     *            the object describing the account to be removed.
134     * @throws DataBackendException
135     *             if there was an error accessing the data backend.
136     * @throws UnknownEntityException
137     *             if the user account is not present.
138     */
139    public void removeUser(User user) throws DataBackendException, UnknownEntityException
140    {
141        getPersistenceHelper().removeEntity(user);
142    }
143
144    /**
145     * Creates new user account with specified attributes.
146     * 
147     * @param user
148     *            the object describing account to be created.
149     * 
150     * @throws DataBackendException
151     *             if there was an error accessing the data backend.
152     */
153    @Override
154    public User persistNewUser(User user) throws DataBackendException
155    {
156        getPersistenceHelper().addEntity(user);
157        return user;
158    }
159
160    /**
161     * Stores User attributes. The User is required to exist in the system.
162     * 
163     * @param user
164     *            The User to be stored.
165     * @throws DataBackendException
166     *             if there was an error accessing the data backend.
167     * @throws UnknownEntityException
168     *             if the role does not exist.
169     */
170    public void saveUser(User user) throws DataBackendException, UnknownEntityException
171    {
172        boolean userExists = false;
173        userExists = checkExists(user);
174        if (userExists)
175        {
176            getPersistenceHelper().updateEntity(user);
177        }
178        else
179        {
180            throw new UnknownEntityException("Unknown user '" + user + "'");
181        }
182    }
183
184    /**
185     * @return Returns the persistenceHelper.
186     */
187    public PersistenceHelper getPersistenceHelper()
188    {
189        if (persistenceHelper == null)
190        {
191            persistenceHelper = (PersistenceHelper) resolve(PersistenceHelper.ROLE);
192        }
193        return persistenceHelper;
194    }
195
196    /**
197     * Retrieve a User object with specified id.
198     * 
199     * @param id
200     *            the id of the User.
201     * @return an object representing the User with specified id.
202     * @throws DataBackendException
203     *             if there was an error accessing the data backend.
204     * @throws UnknownEntityException
205     *             if the user does not exist.
206     */
207    @Override
208    public User getUserById(Object id) throws DataBackendException, UnknownEntityException
209    {
210        User user = null;
211
212        if (id != null)
213        {
214            try
215            {
216                List<User> users = getPersistenceHelper().retrieveSession()
217                        .createQuery("from " + User.class.getName() + " su where su.id=:id").setLong("id", ((Long) id).longValue()).list();
218                if (users.size() == 0)
219                {
220                    throw new UnknownEntityException("Could not find user by id " + id);
221                }
222                user = users.get(0);
223                // session.close();
224            }
225            catch (HibernateException e)
226            {
227                throw new DataBackendException("Error retrieving user information", e);
228            }
229        }
230
231        return user;
232    }
233}