| package ${package}.fulcrum.security.torque; |
| |
| #* |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you 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. |
| *# |
| |
| import java.sql.Connection; |
| import java.util.List; |
| |
| import org.apache.avalon.framework.configuration.Configuration; |
| import org.apache.avalon.framework.configuration.ConfigurationException; |
| import org.apache.fulcrum.security.entity.User; |
| import org.apache.fulcrum.security.spi.AbstractUserManager; |
| import org.apache.fulcrum.security.util.DataBackendException; |
| import org.apache.fulcrum.security.util.EntityExistsException; |
| import org.apache.fulcrum.security.util.UnknownEntityException; |
| import org.apache.fulcrum.security.util.UserSet; |
| import org.apache.torque.NoRowsException; |
| import org.apache.torque.TooManyRowsException; |
| import org.apache.torque.TorqueException; |
| import org.apache.torque.util.Transaction; |
| |
| import org.apache.fulcrum.security.torque.TorqueAbstractSecurityEntity; |
| /** |
| * This implementation persists to a database via Torque. |
| * |
| * @author <a href="mailto:tv@apache.org">Thomas Vandahl</a> |
| * @version $Id:$ |
| */ |
| public abstract class TorqueAbstractUserManager extends AbstractUserManager |
| { |
| private Boolean customPeer = false; // used for torque which uses per object peer classes |
| |
| private String peerClassName; |
| private static final String PEER_CLASS_NAME_KEY = "peerClassName"; |
| |
| /** |
| * Avalon Service lifecycle method |
| */ |
| public void configure(Configuration conf) throws ConfigurationException |
| { |
| super.configure( conf ); |
| |
| peerClassName = conf.getChild( PEER_CLASS_NAME_KEY).getValue( null ); |
| if (peerClassName != null) { |
| setPeerClassName( peerClassName ); |
| setCustomPeer(true); |
| } |
| } |
| |
| public Boolean getCustomPeer() |
| { |
| return customPeer; |
| } |
| |
| public void setCustomPeer( Boolean customPeer ) |
| { |
| this.customPeer = customPeer; |
| } |
| |
| public String getPeerClassName() |
| { |
| return peerClassName; |
| } |
| |
| public void setPeerClassName( String peerClassName ) |
| { |
| this.peerClassName = peerClassName; |
| } |
| /** |
| * Get all specialized Users |
| * |
| * @param con a database connection |
| * |
| * @return a List of User instances |
| * |
| * @throws TorqueException if any database error occurs |
| */ |
| protected abstract <T extends User> List<T> doSelectAllUsers(Connection con) |
| throws TorqueException; |
| |
| /** |
| * Get a specialized User by name |
| * |
| * @param name the name of the group |
| * @param con a database connection |
| * |
| * @return a User instance |
| * |
| * @throws NoRowsException if no such group exists |
| * @throws TooManyRowsException if multiple groups with the given name exist |
| * @throws TorqueException if any other database error occurs |
| */ |
| protected abstract <T extends User> T doSelectByName(String name, Connection con) |
| throws NoRowsException, TooManyRowsException, TorqueException; |
| |
| /** |
| * Get a specialized User by id |
| * |
| * @param id the id of the group |
| * @param con a database connection |
| * |
| * @return a User instance |
| * |
| * @throws NoRowsException if no such group exists |
| * @throws TooManyRowsException if multiple groups with the given id exist |
| * @throws TorqueException if any other database error occurs |
| */ |
| protected abstract <T extends User> T doSelectById(Integer id, Connection con) |
| throws NoRowsException, TooManyRowsException, TorqueException; |
| |
| /** |
| * Removes an user account from the system. |
| * |
| * @param user the object describing the account to be removed. |
| * @throws DataBackendException if there was an error accessing the data |
| * backend. |
| * @throws UnknownEntityException if the user account is not present. |
| */ |
| public synchronized void removeUser(User user) throws DataBackendException, UnknownEntityException |
| { |
| try |
| { |
| ((TorqueAbstractSecurityEntity)user).delete(); |
| } |
| catch (TorqueException e) |
| { |
| throw new DataBackendException("Removing User '" + user.getName() + "' failed", e); |
| } |
| } |
| |
| /** |
| * Creates new user account with specified attributes. |
| * |
| * @param user the object describing account to be created. |
| * |
| * @throws DataBackendException if there was an error accessing the |
| * data backend. |
| * @throws EntityExistsException if the user account already exists. |
| */ |
| protected synchronized <T extends User> T persistNewUser(T user) throws DataBackendException |
| { |
| try |
| { |
| ((TorqueAbstractSecurityEntity)user).save(); |
| } |
| catch (Exception e) |
| { |
| throw new DataBackendException("Adding User '" + user.getName() + "' failed", e); |
| } |
| |
| return user; |
| } |
| |
| /** |
| * Stores User attributes. The User is required to exist in the system. |
| * |
| * @param user The User to be stored. |
| * @throws DataBackendException if there was an error accessing the data |
| * backend. |
| * @throws UnknownEntityException if the role does not exist. |
| */ |
| public synchronized void saveUser(User user) throws DataBackendException, UnknownEntityException |
| { |
| if (checkExists(user)) |
| { |
| try |
| { |
| TorqueAbstractSecurityEntity u = (TorqueAbstractSecurityEntity)user; |
| u.setNew(false); |
| u.save(); |
| } |
| catch (Exception e) |
| { |
| throw new DataBackendException("Saving User '" + user.getName() + "' failed", e); |
| } |
| } |
| else |
| { |
| throw new UnknownEntityException("Unknown user '" + user + "'"); |
| } |
| } |
| |
| /** |
| * Check whether a specified user's account exists. |
| * |
| * The login name is used for looking up the account. |
| * |
| * @param userName The name of the user to be checked. |
| * @return true if the specified account exists |
| * @throws DataBackendException if there was an error accessing |
| * the data backend. |
| */ |
| public boolean checkExists(String userName) throws DataBackendException |
| { |
| boolean exists = false; |
| |
| Connection con = null; |
| |
| try |
| { |
| con = Transaction.begin(((TorqueAbstractSecurityEntity)getUserInstance()).getDatabaseName()); |
| |
| doSelectByName(userName, con); |
| |
| Transaction.commit(con); |
| con = null; |
| |
| exists = true; |
| } |
| catch (NoRowsException e) |
| { |
| exists = false; |
| } |
| catch (TooManyRowsException e) |
| { |
| throw new DataBackendException("Multiple Users with same username '" + userName + "'"); |
| } |
| catch (TorqueException e) |
| { |
| throw new DataBackendException("Error retrieving user information", e); |
| } |
| finally |
| { |
| if (con != null) |
| { |
| Transaction.safeRollback(con); |
| } |
| } |
| |
| return exists; |
| } |
| |
| /** |
| * Retrieve a user from persistent storage using username as the |
| * key. |
| * |
| * @param userName the name of the user. |
| * @return an User object. |
| * @exception UnknownEntityException if the user's account does not |
| * exist in the database. |
| * @exception DataBackendException if there is a problem accessing the |
| * storage. |
| */ |
| public <T extends User> T getUser(String userName) throws UnknownEntityException, DataBackendException |
| { |
| T user = null; |
| Connection con = null; |
| |
| try |
| { |
| System.out.println("transaction for database: " +((TorqueAbstractSecurityEntity)getUserInstance()).getDatabaseName()); |
| con = Transaction.begin(((TorqueAbstractSecurityEntity)getUserInstance()).getDatabaseName()); |
| |
| user = doSelectByName(userName.toLowerCase(), con); |
| |
| // Add attached objects if they exist |
| ((TorqueAbstractSecurityEntity)user).retrieveAttachedObjects(con); |
| |
| Transaction.commit(con); |
| con = null; |
| } |
| catch (NoRowsException e) |
| { |
| throw new UnknownEntityException("Unknown user '" + userName + "'",e); |
| } |
| catch (TooManyRowsException e) |
| { |
| throw new DataBackendException("Multiple Users with same username '" + userName + "'"); |
| } |
| catch (TorqueException e) |
| { |
| throw new DataBackendException("Error retrieving user information", e); |
| } |
| finally |
| { |
| if (con != null) |
| { |
| Transaction.safeRollback(con); |
| } |
| } |
| |
| return user; |
| } |
| |
| /** |
| * Retrieves all users defined in the system. |
| * |
| * @return the names of all users defined in the system. |
| * @throws DataBackendException if there was an error accessing the data |
| * backend. |
| */ |
| public UserSet getAllUsers() throws DataBackendException |
| { |
| UserSet userSet = new UserSet(); |
| Connection con = null; |
| |
| try |
| { |
| con = Transaction.begin(((TorqueAbstractSecurityEntity)getUserInstance()).getDatabaseName()); |
| |
| List<User> users = doSelectAllUsers(con); |
| |
| for (User user : users) |
| { |
| // Add attached objects if they exist |
| ((TorqueAbstractSecurityEntity)user).retrieveAttachedObjects(con); |
| |
| userSet.add(user); |
| } |
| |
| Transaction.commit(con); |
| con = null; |
| } |
| catch (TorqueException e) |
| { |
| throw new DataBackendException("Error retrieving all users", e); |
| } |
| finally |
| { |
| if (con != null) |
| { |
| Transaction.safeRollback(con); |
| } |
| } |
| |
| return userSet; |
| } |
| |
| /** |
| * Retrieve a User object with specified id. |
| * |
| * @param id |
| * the id of the User. |
| * @return an object representing the User with specified id. |
| * @throws DataBackendException |
| * if there was an error accessing the data backend. |
| * @throws UnknownEntityException |
| * if the user does not exist. |
| */ |
| public <T extends User> T getUserById(Object id) throws DataBackendException, UnknownEntityException |
| { |
| T user; |
| |
| if (id != null && id instanceof Integer) |
| { |
| Connection con = null; |
| |
| try |
| { |
| con = Transaction.begin(((TorqueAbstractSecurityEntity)getUserInstance()).getDatabaseName()); |
| |
| user = doSelectById((Integer)id, con); |
| |
| // Add attached objects if they exist |
| ((TorqueAbstractSecurityEntity)user).retrieveAttachedObjects(con); |
| |
| Transaction.commit(con); |
| con = null; |
| } |
| catch (NoRowsException e) |
| { |
| throw new UnknownEntityException("User with id '" + id + "' does not exist.", e); |
| } |
| catch (TorqueException e) |
| { |
| throw new DataBackendException("Error retrieving user information", e); |
| } |
| finally |
| { |
| if (con != null) |
| { |
| Transaction.safeRollback(con); |
| } |
| } |
| } |
| else |
| { |
| throw new UnknownEntityException("Invalid user id '" + id + "'"); |
| } |
| |
| return user; |
| } |
| |
| } |