1 package org.codehaus.plexus.redback.users.jdo;
4 * Copyright 2001-2006 The Apache Software Foundation.
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
10 * http://www.apache.org/licenses/LICENSE-2.0
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
19 import org.codehaus.plexus.jdo.JdoFactory;
20 import org.codehaus.plexus.jdo.PlexusJdoUtils;
21 import org.codehaus.plexus.jdo.PlexusObjectNotFoundException;
22 import org.codehaus.plexus.jdo.PlexusStoreException;
23 import org.codehaus.plexus.redback.policy.UserSecurityPolicy;
24 import org.codehaus.plexus.redback.users.AbstractUserManager;
25 import org.codehaus.plexus.redback.users.PermanentUserException;
26 import org.codehaus.plexus.redback.users.User;
27 import org.codehaus.plexus.redback.users.UserManagerException;
28 import org.codehaus.plexus.redback.users.UserNotFoundException;
29 import org.codehaus.plexus.redback.users.UserQuery;
30 import org.codehaus.plexus.util.StringUtils;
31 import org.jpox.JDOClassLoaderResolver;
32 import org.springframework.stereotype.Service;
34 import javax.annotation.PostConstruct;
35 import javax.annotation.Resource;
36 import javax.inject.Inject;
37 import javax.inject.Named;
38 import javax.jdo.Extent;
39 import javax.jdo.PersistenceManager;
40 import javax.jdo.PersistenceManagerFactory;
41 import javax.jdo.Query;
42 import javax.jdo.Transaction;
44 import java.util.Date;
45 import java.util.List;
50 * @author <a href="mailto:joakim@erdfelt.com">Joakim Erdfelt</a>
53 @Service("userManager#jdo")
54 public class JdoUserManager
55 extends AbstractUserManager
57 @Inject @Named(value="jdoFactory#users")
58 private JdoFactory jdoFactory;
61 private UserSecurityPolicy userSecurityPolicy;
63 private PersistenceManagerFactory pmf;
67 return "JDO UserManager - " + this.getClass().getName();
71 public boolean isReadOnly()
76 public UserQuery createUserQuery()
78 return new JdoUserQuery();
81 // ------------------------------------------------------------------
83 public User createUser( String username, String fullname, String email )
85 User user = new JdoUser();
86 user.setUsername( username );
87 user.setFullName( fullname );
88 user.setEmail( email );
89 user.setAccountCreationDate( new Date() );
94 public List<User> getUsers()
96 return getAllObjectsDetached( null );
99 public List<User> getUsers( boolean orderAscending )
101 String ordering = orderAscending ? "username ascending" : "username descending";
103 return getAllObjectsDetached( ordering );
106 @SuppressWarnings("unchecked")
107 private List<User> getAllObjectsDetached( String ordering )
109 return PlexusJdoUtils.getAllObjectsDetached( getPersistenceManager(), JdoUser.class, ordering, (String) null );
112 public List<User> findUsersByUsernameKey( String usernameKey, boolean orderAscending )
114 return findUsers( "username", usernameKey, orderAscending );
117 public List<User> findUsersByFullNameKey( String fullNameKey, boolean orderAscending )
119 return findUsers( "fullName", fullNameKey, orderAscending );
122 public List<User> findUsersByEmailKey( String emailKey, boolean orderAscending )
124 return findUsers( "email", emailKey, orderAscending );
127 @SuppressWarnings("unchecked")
128 public List<User> findUsersByQuery( UserQuery userQuery )
130 JdoUserQuery uq = (JdoUserQuery) userQuery;
132 PersistenceManager pm = getPersistenceManager();
134 Transaction tx = pm.currentTransaction();
140 Extent extent = pm.getExtent( JdoUser.class, true );
142 Query query = pm.newQuery( extent );
144 String ordering = uq.getOrdering();
146 query.setOrdering( ordering );
148 query.declareImports( "import java.lang.String" );
150 query.declareParameters( uq.getParameters() );
152 query.setFilter( uq.getFilter() );
154 query.setRange( uq.getFirstResult(),
155 uq.getMaxResults() < 0 ? Long.MAX_VALUE : uq.getFirstResult() + uq.getMaxResults() );
157 List<User> result = (List<User>) query.executeWithArray( uq.getSearchKeys() );
159 result = (List<User>) pm.detachCopyAll( result );
171 @SuppressWarnings("unchecked")
172 private List<User> findUsers( String searchField, String searchKey, boolean ascendingUsername )
174 PersistenceManager pm = getPersistenceManager();
176 Transaction tx = pm.currentTransaction();
182 Extent extent = pm.getExtent( JdoUser.class, true );
184 Query query = pm.newQuery( extent );
186 String ordering = ascendingUsername ? "username ascending" : "username descending";
188 query.setOrdering( ordering );
190 query.declareImports( "import java.lang.String" );
192 query.declareParameters( "String searchKey" );
194 query.setFilter( "this." + searchField + ".toLowerCase().indexOf(searchKey.toLowerCase()) > -1" );
196 List<User> result = (List<User>) query.execute( searchKey );
198 result = (List<User>) pm.detachCopyAll( result );
210 public User addUser( User user )
212 if ( !( user instanceof JdoUser ) )
214 throw new UserManagerException( "Unable to Add User. User object " + user.getClass().getName() +
215 " is not an instance of " + JdoUser.class.getName() );
218 if ( StringUtils.isEmpty( user.getUsername() ) )
220 throw new IllegalStateException(
221 Messages.getString( "user.manager.cannot.add.user.without.username" ) ); //$NON-NLS-1$
224 userSecurityPolicy.extensionChangePassword( user );
226 fireUserManagerUserAdded( user );
228 // TODO: find a better solution
229 // workaround for avoiding the admin from providing another password on the next login after the
230 // admin account has been created
231 // extensionChangePassword by default sets the password change status to false
232 if ( "admin".equals( user.getUsername() ) )
234 user.setPasswordChangeRequired( false );
238 user.setPasswordChangeRequired( true );
241 return (User) addObject( user );
244 public void deleteUser( Object principal )
248 User user = findUser( principal );
250 if ( user.isPermanent() )
252 throw new PermanentUserException( "Cannot delete permanent user [" + user.getUsername() + "]." );
255 fireUserManagerUserRemoved( user );
257 removeObject( user );
259 catch ( UserNotFoundException e )
261 log.warn( "Unable to delete user " + principal + ", user not found.", e );
265 public void deleteUser( String username )
269 User user = findUser( username );
271 if ( user.isPermanent() )
273 throw new PermanentUserException( "Cannot delete permanent user [" + user.getUsername() + "]." );
276 fireUserManagerUserRemoved( user );
278 PlexusJdoUtils.removeObject( getPersistenceManager(), user );
280 catch ( UserNotFoundException e )
282 log.warn( "Unable to delete user " + username + ", user not found.", e );
286 public void addUserUnchecked( User user )
288 if ( !( user instanceof JdoUser ) )
290 throw new UserManagerException( "Unable to Add User. User object " + user.getClass().getName() +
291 " is not an instance of " + JdoUser.class.getName() );
294 if ( StringUtils.isEmpty( user.getUsername() ) )
296 throw new IllegalStateException(
297 Messages.getString( "user.manager.cannot.add.user.without.username" ) ); //$NON-NLS-1$
303 public void eraseDatabase()
305 PlexusJdoUtils.removeAll( getPersistenceManager(), JdoUser.class );
306 PlexusJdoUtils.removeAll( getPersistenceManager(), UsersManagementModelloMetadata.class );
309 public User findUser( Object principal )
310 throws UserNotFoundException
312 if ( principal == null )
314 throw new UserNotFoundException( "Unable to find user based on null principal." );
319 return (User) PlexusJdoUtils.getObjectById( getPersistenceManager(), JdoUser.class, principal.toString(),
322 catch ( PlexusObjectNotFoundException e )
324 throw new UserNotFoundException( "Unable to find user: " + e.getMessage(), e );
326 catch ( PlexusStoreException e )
328 throw new UserNotFoundException( "Unable to find user: " + e.getMessage(), e );
332 public User findUser( String username )
333 throws UserNotFoundException
335 if ( StringUtils.isEmpty( username ) )
337 throw new UserNotFoundException( "User with empty username not found." );
340 return (User) getObjectById( username, null );
343 public boolean userExists( Object principal )
347 findUser( principal );
350 catch ( UserNotFoundException ne )
356 public User updateUser( User user )
357 throws UserNotFoundException
359 return updateUser( user, false );
362 public User updateUser( User user, boolean passwordChangeRequired )
363 throws UserNotFoundException
365 if ( !( user instanceof JdoUser ) )
367 throw new UserManagerException( "Unable to Update User. User object " + user.getClass().getName() +
368 " is not an instance of " + JdoUser.class.getName() );
371 // If password is supplied, assume changing of password.
372 // TODO: Consider adding a boolean to the updateUser indicating a password change or not.
373 if ( StringUtils.isNotEmpty( user.getPassword() ) )
375 userSecurityPolicy.extensionChangePassword( user, passwordChangeRequired );
378 updateObject( user );
380 fireUserManagerUserUpdated( user );
386 public void initialize()
388 JDOClassLoaderResolver d;
389 pmf = jdoFactory.getPersistenceManagerFactory();
392 public PersistenceManager getPersistenceManager()
394 PersistenceManager pm = pmf.getPersistenceManager();
396 pm.getFetchPlan().setMaxFetchDepth( -1 );
403 // ----------------------------------------------------------------------
404 // jdo utility methods
405 // ----------------------------------------------------------------------
407 private Object addObject( Object object )
409 return PlexusJdoUtils.addObject( getPersistenceManager(), object );
412 private Object getObjectById( String id, String fetchGroup )
413 throws UserNotFoundException, UserManagerException
417 return PlexusJdoUtils.getObjectById( getPersistenceManager(), JdoUser.class, id, fetchGroup );
419 catch ( PlexusObjectNotFoundException e )
421 throw new UserNotFoundException( e.getMessage() );
423 catch ( PlexusStoreException e )
425 throw new UserManagerException( "Unable to get object '" + JdoUser.class.getName() + "', id '" + id +
426 "', fetch-group '" + fetchGroup + "' from jdo store." );
430 private Object removeObject( Object o )
434 throw new UserManagerException( "Unable to remove null object" );
437 PlexusJdoUtils.removeObject( getPersistenceManager(), o );
441 private Object updateObject( Object object )
442 throws UserNotFoundException, UserManagerException
446 return PlexusJdoUtils.updateObject( getPersistenceManager(), object );
448 catch ( PlexusStoreException e )
450 throw new UserManagerException(
451 "Unable to update the '" + object.getClass().getName() + "' object in the jdo database.", e );
455 private void rollback( Transaction tx )
457 PlexusJdoUtils.rollbackIfActive( tx );
460 private boolean hasTriggeredInit = false;
462 public void triggerInit()
464 if ( !hasTriggeredInit )
466 hasTriggeredInit = true;
467 List<User> users = getAllObjectsDetached( null );
469 fireUserManagerInit( users.isEmpty() );
473 public JdoFactory getJdoFactory()
478 public void setJdoFactory( JdoFactory jdoFactory )
480 this.jdoFactory = jdoFactory;
483 public UserSecurityPolicy getUserSecurityPolicy()
485 return userSecurityPolicy;