View Javadoc
1   package org.apache.fulcrum.security.torque.turbine;
2   /*
3    * Licensed to the Apache Software Foundation (ASF) under one
4    * or more contributor license agreements.  See the NOTICE file
5    * distributed with this work for additional information
6    * regarding copyright ownership.  The ASF licenses this file
7    * to you under the Apache License, Version 2.0 (the
8    * "License"); you may not use this file except in compliance
9    * with the License.  You may obtain a copy of the License at
10   *
11   *   http://www.apache.org/licenses/LICENSE-2.0
12   *
13   * Unless required by applicable law or agreed to in writing,
14   * software distributed under the License is distributed on an
15   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16   * KIND, either express or implied.  See the License for the
17   * specific language governing permissions and limitations
18   * under the License.
19   */
20  import java.sql.Connection;
21  import java.util.List;
22  
23  import org.apache.fulcrum.security.entity.User;
24  import org.apache.fulcrum.security.model.turbine.TurbineUserManager;
25  import org.apache.fulcrum.security.torque.om.TorqueTurbineUserPeer;
26  import org.apache.fulcrum.security.torque.peer.TorqueTurbinePeer;
27  import org.apache.fulcrum.security.torque.peer.TorqueTurbineUserGroupRolePeer;
28  import org.apache.fulcrum.security.torque.peer.TurbineUserGroupRoleModelPeerMapper;
29  import org.apache.fulcrum.security.torque.peer.managers.PeerUserManager;
30  import org.apache.fulcrum.security.torque.security.TorqueAbstractSecurityEntity;
31  import org.apache.fulcrum.security.torque.security.turbine.TorqueAbstractTurbineTurbineSecurityEntityDefault;
32  import org.apache.fulcrum.security.util.DataBackendException;
33  import org.apache.fulcrum.security.util.UnknownEntityException;
34  import org.apache.fulcrum.security.util.UserSet;
35  import org.apache.torque.NoRowsException;
36  import org.apache.torque.TooManyRowsException;
37  import org.apache.torque.TorqueException;
38  import org.apache.torque.criteria.Criteria;
39  import org.apache.torque.util.Transaction;
40  /**
41   * This implementation persists to a database via Torque.
42   * 
43   *
44   * @author <a href="mailto:tv@apache.org">Thomas Vandahl</a>
45   * @version $Id$
46   */
47  public class TorqueTurbineUserManagerImpl extends PeerUserManager implements TurbineUserManager
48  {
49  
50  	/** Serial version */
51  	private static final long serialVersionUID = 1L;
52  	private static final String ANON = "anon";
53  
54      /**
55       * Default implementation.
56       */
57      @Override
58      public <T extends User> T getAnonymousUser()
59          throws UnknownEntityException
60      {
61          try
62          {
63              T anonUser =  getUser( ANON );
64              // add more, if needed
65              return anonUser;
66          }
67          catch ( DataBackendException e )
68          {
69              throw new UnknownEntityException( "Failed to load anonymous user",e);
70          } 
71      }
72  
73      /**
74       * Default implementation.
75       */
76      @Override
77      public boolean isAnonymousUser( User u )
78      {
79          try
80          {
81              User anon = getAnonymousUser();
82              if (u.equals( anon )) 
83                  {
84                   return true;
85                  }
86          }
87          catch ( Exception e )
88          {
89              getLogger().error( "Failed to check user:" + e.getMessage(),e);
90          }
91          return false;
92      }
93      
94      /**
95       * @see org.apache.fulcrum.security.torque.TorqueAbstractUserManager#doSelectAllUsers(java.sql.Connection)
96       */
97     
98      @Override
99  	@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 }