001package org.apache.fulcrum.security.torque.turbine; 002/* 003 * Licensed to the Apache Software Foundation (ASF) under one 004 * or more contributor license agreements. See the NOTICE file 005 * distributed with this work for additional information 006 * regarding copyright ownership. The ASF licenses this file 007 * to you under the Apache License, Version 2.0 (the 008 * "License"); you may not use this file except in compliance 009 * with the License. You may obtain a copy of the License at 010 * 011 * http://www.apache.org/licenses/LICENSE-2.0 012 * 013 * Unless required by applicable law or agreed to in writing, 014 * software distributed under the License is distributed on an 015 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 016 * KIND, either express or implied. See the License for the 017 * specific language governing permissions and limitations 018 * under the License. 019 */ 020import java.sql.Connection; 021import java.util.List; 022 023import org.apache.fulcrum.security.entity.User; 024import org.apache.fulcrum.security.model.turbine.TurbineUserManager; 025import org.apache.fulcrum.security.torque.om.TorqueTurbineUserPeer; 026import org.apache.fulcrum.security.torque.peer.TorqueTurbinePeer; 027import org.apache.fulcrum.security.torque.peer.TorqueTurbineUserGroupRolePeer; 028import org.apache.fulcrum.security.torque.peer.TurbineUserGroupRoleModelPeerMapper; 029import org.apache.fulcrum.security.torque.peer.managers.PeerUserManager; 030import org.apache.fulcrum.security.torque.security.TorqueAbstractSecurityEntity; 031import org.apache.fulcrum.security.torque.security.turbine.TorqueAbstractTurbineTurbineSecurityEntityDefault; 032import org.apache.fulcrum.security.util.DataBackendException; 033import org.apache.fulcrum.security.util.UnknownEntityException; 034import org.apache.fulcrum.security.util.UserSet; 035import org.apache.torque.NoRowsException; 036import org.apache.torque.TooManyRowsException; 037import org.apache.torque.TorqueException; 038import org.apache.torque.criteria.Criteria; 039import org.apache.torque.util.Transaction; 040/** 041 * This implementation persists to a database via Torque. 042 * 043 * 044 * @author <a href="mailto:tv@apache.org">Thomas Vandahl</a> 045 * @version $Id$ 046 */ 047public class TorqueTurbineUserManagerImpl extends PeerUserManager implements TurbineUserManager 048{ 049 050 /** Serial version */ 051 private static final long serialVersionUID = 1L; 052 private static final String ANON = "anon"; 053 054 /** 055 * Default implementation. 056 */ 057 @Override 058 public <T extends User> T getAnonymousUser() 059 throws UnknownEntityException 060 { 061 try 062 { 063 T anonUser = getUser( ANON ); 064 // add more, if needed 065 return anonUser; 066 } 067 catch ( DataBackendException e ) 068 { 069 throw new UnknownEntityException( "Failed to load anonymous user",e); 070 } 071 } 072 073 /** 074 * Default implementation. 075 */ 076 @Override 077 public boolean isAnonymousUser( User u ) 078 { 079 try 080 { 081 User anon = getAnonymousUser(); 082 if (u.equals( anon )) 083 { 084 return true; 085 } 086 } 087 catch ( Exception e ) 088 { 089 getLogger().error( "Failed to check user:" + e.getMessage(),e); 090 } 091 return false; 092 } 093 094 /** 095 * @see org.apache.fulcrum.security.torque.TorqueAbstractUserManager#doSelectAllUsers(java.sql.Connection) 096 */ 097 098 @Override 099 @SuppressWarnings("unchecked") 100 protected <T extends User> List<T> doSelectAllUsers(Connection con) throws TorqueException 101 { 102 Criteria criteria = new Criteria(); 103 104 if ( (getCustomPeer())) { 105 try 106 { 107 TorqueTurbinePeer<T> peerInstance = (TorqueTurbinePeer<T>)getPeerInstance(); 108 return peerInstance.doSelect( criteria, con ); 109 } 110 catch ( DataBackendException e ) 111 { 112 throw new TorqueException( e ); 113 } 114 } else { 115 return (List<T>) TorqueTurbineUserPeer.doSelect(criteria, con); 116 } 117 } 118 119 /** 120 * @see org.apache.fulcrum.security.torque.TorqueAbstractUserManager#doSelectById(java.lang.Integer, java.sql.Connection) 121 */ 122 @Override 123 @SuppressWarnings("unchecked") 124 protected <T extends User> T doSelectById(Integer id, Connection con) throws NoRowsException, TooManyRowsException, TorqueException 125 { 126 if ( (getCustomPeer())) { 127 try 128 { 129 TorqueTurbinePeer<T> peerInstance = (TorqueTurbinePeer<T>)getPeerInstance(); 130 return peerInstance.retrieveByPK( id, con ); 131 } 132 catch ( DataBackendException e ) 133 { 134 throw new TorqueException( e ); 135 } 136 } else { 137 return (T) TorqueTurbineUserPeer.retrieveByPK(id, con); 138 } 139 } 140 141 /** 142 * @see org.apache.fulcrum.security.torque.TorqueAbstractUserManager#doSelectByName(java.lang.String, java.sql.Connection) 143 */ 144 @Override 145 @SuppressWarnings("unchecked") 146 protected <T extends User> T doSelectByName(String name, Connection con) throws NoRowsException, TooManyRowsException, TorqueException 147 { 148 Criteria criteria = new Criteria(); 149 150 criteria.setIgnoreCase(true); 151 criteria.setSingleRecord(true); 152 153 List<T> users = null; 154 if ( (getCustomPeer())) { 155 try 156 { 157 TorqueTurbinePeer<T> peerInstance = (TorqueTurbinePeer<T>)getPeerInstance(); 158 criteria.where(peerInstance.getTableMap().getColumn(getColumnName() ), name); 159 users = peerInstance.doSelect( criteria, con ); 160 } 161 catch ( DataBackendException e ) 162 { 163 throw new TorqueException( e ); 164 } 165 } else { 166 criteria.where(TorqueTurbineUserPeer.LOGIN_NAME, name); 167 users = (List<T>) TorqueTurbineUserPeer.doSelect(criteria, con); 168 } 169 170 171 if (users.isEmpty()) 172 { 173 throw new NoRowsException(name); 174 } 175 176 return users.get(0); 177 } 178 179 /** 180 * Retrieve a user from persistent storage using username as the 181 * key. Also retrieves all attached objects (user group role relationships). 182 * 183 * @param userName the name of the user. 184 * @return an User object. 185 * @exception UnknownEntityException if the user's account does not 186 * exist in the database. 187 * @exception DataBackendException if there is a problem accessing the 188 * storage. 189 */ 190 @Override 191 public <T extends User> T getUser(String userName) throws UnknownEntityException, DataBackendException 192 { 193 T user = null; 194 Connection con = null; 195 196 try 197 { 198 con = Transaction.begin(); 199 200 user = doSelectByName(userName.toLowerCase(), con); 201 202 // Add attached objects if they exist 203 attachRelatedObjects( user, con ); 204 205 Transaction.commit(con); 206 con = null; 207 } 208 catch (NoRowsException e) 209 { 210 throw new UnknownEntityException("Unknown user '" + userName + "'"); 211 } 212 catch (TooManyRowsException e) 213 { 214 throw new DataBackendException("Multiple Users with same username '" + userName + "'"); 215 } 216 catch (TorqueException e) 217 { 218 throw new DataBackendException("Error retrieving user information", e); 219 } 220 finally 221 { 222 if (con != null) 223 { 224 Transaction.safeRollback(con); 225 } 226 } 227 228 return user; 229 } 230 231 /** 232 * Retrieves all users with attached related objects (user group role relationships) defined in the system. 233 * 234 * @return the names of all users defined in the system. 235 * @throws DataBackendException if there was an error accessing the data 236 * backend. 237 */ 238 @Override 239 public <T extends User> UserSet<T> getAllUsers() throws DataBackendException 240 { 241 UserSet<T> userSet = new UserSet<T>(); 242 Connection con = null; 243 244 try 245 { 246 con = Transaction.begin(); 247 248 List<User> users = doSelectAllUsers(con); 249 250 for (User user : users) 251 { 252 // Add attached objects if they exist 253 attachRelatedObjects( user, con ); 254 255 userSet.add(user); 256 } 257 258 Transaction.commit(con); 259 con = null; 260 } 261 catch (TorqueException e) 262 { 263 throw new DataBackendException("Error retrieving all users", e); 264 } 265 finally 266 { 267 if (con != null) 268 { 269 Transaction.safeRollback(con); 270 } 271 } 272 273 return userSet; 274 } 275 276 /** 277 * Retrieve a User object with specified id and all attached objects (user group role relationships). 278 * 279 * @param id 280 * the id of the User. 281 * @return an object representing the User with specified id. 282 * @throws DataBackendException 283 * if there was an error accessing the data backend. 284 * @throws UnknownEntityException 285 * if the user does not exist. 286 */ 287 @Override 288 public <T extends User> T getUserById(Object id) throws DataBackendException, UnknownEntityException 289 { 290 T user; 291 292 if (id != null && id instanceof Integer) 293 { 294 Connection con = null; 295 296 try 297 { 298 con = Transaction.begin(); 299 300 user = doSelectById((Integer)id, con); 301 302 // Add attached objects if they exist 303 attachRelatedObjects( user, con ); 304 305 Transaction.commit(con); 306 con = null; 307 } 308 catch (NoRowsException e) 309 { 310 throw new UnknownEntityException("User with id '" + id + "' does not exist.", e); 311 } 312 catch (TorqueException e) 313 { 314 throw new DataBackendException("Error retrieving user information", e); 315 } 316 finally 317 { 318 if (con != null) 319 { 320 Transaction.safeRollback(con); 321 } 322 } 323 } 324 else 325 { 326 throw new UnknownEntityException("Invalid user id '" + id + "'"); 327 } 328 329 return user; 330 } 331 332 /** 333 * Retrieves all related objects (user group roles). If the objects not exists {@link DataBackendException} is wrapped in a new TorqueException. 334 * 335 * @param user 336 * @param con 337 * @throws TorqueException 338 */ 339 private <T extends User> void attachRelatedObjects( T user, Connection con ) throws TorqueException 340 { 341 if (user instanceof TorqueAbstractSecurityEntity) { 342 if (getCustomPeer()) { 343 try 344 { 345 TorqueTurbineUserGroupRolePeer<TurbineUserGroupRoleModelPeerMapper> peerInstance = 346 (TorqueTurbineUserGroupRolePeer<TurbineUserGroupRoleModelPeerMapper>) getUserGroupRolePeerInstance(); 347 Criteria criteria = new Criteria(); 348 // expecting the same name in any custom implementation 349 criteria.where(peerInstance.getTableMap().getColumn(getColumnName4UserGroupRole() ), ( (TorqueAbstractSecurityEntity) user ).getEntityId() ); 350 List<TurbineUserGroupRoleModelPeerMapper> ugrs = peerInstance.doSelectJoinTurbineGroup( criteria, con ); 351 352 if (user instanceof TorqueAbstractTurbineTurbineSecurityEntityDefault) { 353 ((TorqueAbstractTurbineTurbineSecurityEntityDefault)user).retrieveAttachedObjects(con, false, ugrs); 354 } 355 } 356 catch ( DataBackendException e ) 357 { 358 throw new TorqueException( e ); 359 } 360 } else { 361 try 362 { 363 ((TorqueAbstractSecurityEntity)user).retrieveAttachedObjects(con); 364 } 365 catch ( DataBackendException e ) 366 { 367 throw new TorqueException( e ); 368 } 369 } 370 } 371 } 372 373}