]> source.dussan.org Git - archiva.git/blob
c04ef0c659ef98e8b1fd847b6d57322636777f65
[archiva.git] /
1 package org.codehaus.plexus.redback.users.jdo;
2
3 /*
4  * Copyright 2001-2006 The Apache Software Foundation.
5  *
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
9  *
10  *      http://www.apache.org/licenses/LICENSE-2.0
11  *
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.
17  */
18
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;
33
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;
43
44 import java.util.Date;
45 import java.util.List;
46
47 /**
48  * JdoUserManager
49  *
50  * @author <a href="mailto:joakim@erdfelt.com">Joakim Erdfelt</a>
51  * @version $Id$
52  */
53 @Service("userManager#jdo")
54 public class JdoUserManager
55     extends AbstractUserManager
56 {
57     @Inject @Named(value="jdoFactory#users")
58     private JdoFactory jdoFactory;
59
60     @Inject
61     private UserSecurityPolicy userSecurityPolicy;
62
63     private PersistenceManagerFactory pmf;
64
65     public String getId()
66     {
67         return "JDO UserManager - " + this.getClass().getName();
68     }
69
70
71     public boolean isReadOnly()
72     {
73         return false;
74     }
75
76     public UserQuery createUserQuery()
77     {
78         return new JdoUserQuery();
79     }
80
81     // ------------------------------------------------------------------
82
83     public User createUser( String username, String fullname, String email )
84     {
85         User user = new JdoUser();
86         user.setUsername( username );
87         user.setFullName( fullname );
88         user.setEmail( email );
89         user.setAccountCreationDate( new Date() );
90
91         return user;
92     }
93
94     public List<User> getUsers()
95     {
96         return getAllObjectsDetached( null );
97     }
98
99     public List<User> getUsers( boolean orderAscending )
100     {
101         String ordering = orderAscending ? "username ascending" : "username descending";
102
103         return getAllObjectsDetached( ordering );
104     }
105
106     @SuppressWarnings("unchecked")
107     private List<User> getAllObjectsDetached( String ordering )
108     {
109         return PlexusJdoUtils.getAllObjectsDetached( getPersistenceManager(), JdoUser.class, ordering, (String) null );
110     }
111
112     public List<User> findUsersByUsernameKey( String usernameKey, boolean orderAscending )
113     {
114         return findUsers( "username", usernameKey, orderAscending );
115     }
116
117     public List<User> findUsersByFullNameKey( String fullNameKey, boolean orderAscending )
118     {
119         return findUsers( "fullName", fullNameKey, orderAscending );
120     }
121
122     public List<User> findUsersByEmailKey( String emailKey, boolean orderAscending )
123     {
124         return findUsers( "email", emailKey, orderAscending );
125     }
126
127     @SuppressWarnings("unchecked")
128     public List<User> findUsersByQuery( UserQuery userQuery )
129     {
130         JdoUserQuery uq = (JdoUserQuery) userQuery;
131
132         PersistenceManager pm = getPersistenceManager();
133
134         Transaction tx = pm.currentTransaction();
135
136         try
137         {
138             tx.begin();
139
140             Extent extent = pm.getExtent( JdoUser.class, true );
141
142             Query query = pm.newQuery( extent );
143
144             String ordering = uq.getOrdering();
145
146             query.setOrdering( ordering );
147
148             query.declareImports( "import java.lang.String" );
149
150             query.declareParameters( uq.getParameters() );
151
152             query.setFilter( uq.getFilter() );
153
154             query.setRange( uq.getFirstResult(),
155                             uq.getMaxResults() < 0 ? Long.MAX_VALUE : uq.getFirstResult() + uq.getMaxResults() );
156
157             List<User> result = (List<User>) query.executeWithArray( uq.getSearchKeys() );
158
159             result = (List<User>) pm.detachCopyAll( result );
160
161             tx.commit();
162
163             return result;
164         }
165         finally
166         {
167             rollback( tx );
168         }
169     }
170
171     @SuppressWarnings("unchecked")
172     private List<User> findUsers( String searchField, String searchKey, boolean ascendingUsername )
173     {
174         PersistenceManager pm = getPersistenceManager();
175
176         Transaction tx = pm.currentTransaction();
177
178         try
179         {
180             tx.begin();
181
182             Extent extent = pm.getExtent( JdoUser.class, true );
183
184             Query query = pm.newQuery( extent );
185
186             String ordering = ascendingUsername ? "username ascending" : "username descending";
187
188             query.setOrdering( ordering );
189
190             query.declareImports( "import java.lang.String" );
191
192             query.declareParameters( "String searchKey" );
193
194             query.setFilter( "this." + searchField + ".toLowerCase().indexOf(searchKey.toLowerCase()) > -1" );
195
196             List<User> result = (List<User>) query.execute( searchKey );
197
198             result = (List<User>) pm.detachCopyAll( result );
199
200             tx.commit();
201
202             return result;
203         }
204         finally
205         {
206             rollback( tx );
207         }
208     }
209
210     public User addUser( User user )
211     {
212         if ( !( user instanceof JdoUser ) )
213         {
214             throw new UserManagerException( "Unable to Add User. User object " + user.getClass().getName() +
215                 " is not an instance of " + JdoUser.class.getName() );
216         }
217
218         if ( StringUtils.isEmpty( user.getUsername() ) )
219         {
220             throw new IllegalStateException(
221                 Messages.getString( "user.manager.cannot.add.user.without.username" ) ); //$NON-NLS-1$
222         }
223
224         userSecurityPolicy.extensionChangePassword( user );
225
226         fireUserManagerUserAdded( user );
227
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() ) )
233         {
234             user.setPasswordChangeRequired( false );
235         }
236         else
237         {
238             user.setPasswordChangeRequired( true );
239         }
240
241         return (User) addObject( user );
242     }
243
244     public void deleteUser( Object principal )
245     {
246         try
247         {
248             User user = findUser( principal );
249
250             if ( user.isPermanent() )
251             {
252                 throw new PermanentUserException( "Cannot delete permanent user [" + user.getUsername() + "]." );
253             }
254
255             fireUserManagerUserRemoved( user );
256
257             removeObject( user );
258         }
259         catch ( UserNotFoundException e )
260         {
261             log.warn( "Unable to delete user " + principal + ", user not found.", e );
262         }
263     }
264
265     public void deleteUser( String username )
266     {
267         try
268         {
269             User user = findUser( username );
270
271             if ( user.isPermanent() )
272             {
273                 throw new PermanentUserException( "Cannot delete permanent user [" + user.getUsername() + "]." );
274             }
275
276             fireUserManagerUserRemoved( user );
277
278             PlexusJdoUtils.removeObject( getPersistenceManager(), user );
279         }
280         catch ( UserNotFoundException e )
281         {
282             log.warn( "Unable to delete user " + username + ", user not found.", e );
283         }
284     }
285
286     public void addUserUnchecked( User user )
287     {
288         if ( !( user instanceof JdoUser ) )
289         {
290             throw new UserManagerException( "Unable to Add User. User object " + user.getClass().getName() +
291                 " is not an instance of " + JdoUser.class.getName() );
292         }
293
294         if ( StringUtils.isEmpty( user.getUsername() ) )
295         {
296             throw new IllegalStateException(
297                 Messages.getString( "user.manager.cannot.add.user.without.username" ) ); //$NON-NLS-1$
298         }
299
300         addObject( user );
301     }
302
303     public void eraseDatabase()
304     {
305         PlexusJdoUtils.removeAll( getPersistenceManager(), JdoUser.class );
306         PlexusJdoUtils.removeAll( getPersistenceManager(), UsersManagementModelloMetadata.class );
307     }
308
309     public User findUser( Object principal )
310         throws UserNotFoundException
311     {
312         if ( principal == null )
313         {
314             throw new UserNotFoundException( "Unable to find user based on null principal." );
315         }
316
317         try
318         {
319             return (User) PlexusJdoUtils.getObjectById( getPersistenceManager(), JdoUser.class, principal.toString(),
320                                                         null );
321         }
322         catch ( PlexusObjectNotFoundException e )
323         {
324             throw new UserNotFoundException( "Unable to find user: " + e.getMessage(), e );
325         }
326         catch ( PlexusStoreException e )
327         {
328             throw new UserNotFoundException( "Unable to find user: " + e.getMessage(), e );
329         }
330     }
331
332     public User findUser( String username )
333         throws UserNotFoundException
334     {
335         if ( StringUtils.isEmpty( username ) )
336         {
337             throw new UserNotFoundException( "User with empty username not found." );
338         }
339
340         return (User) getObjectById( username, null );
341     }
342
343     public boolean userExists( Object principal )
344     {
345         try
346         {
347             findUser( principal );
348             return true;
349         }
350         catch ( UserNotFoundException ne )
351         {
352             return false;
353         }
354     }
355
356     public User updateUser( User user )
357         throws UserNotFoundException
358     {
359         return updateUser( user, false );
360     }
361
362     public User updateUser( User user, boolean passwordChangeRequired )
363         throws UserNotFoundException
364     {
365         if ( !( user instanceof JdoUser ) )
366         {
367             throw new UserManagerException( "Unable to Update User. User object " + user.getClass().getName() +
368                 " is not an instance of " + JdoUser.class.getName() );
369         }
370
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() ) )
374         {
375             userSecurityPolicy.extensionChangePassword( user, passwordChangeRequired );
376         }
377
378         updateObject( user );
379
380         fireUserManagerUserUpdated( user );
381
382         return user;
383     }
384
385     @PostConstruct
386     public void initialize()
387     {
388         JDOClassLoaderResolver d;
389         pmf = jdoFactory.getPersistenceManagerFactory();
390     }
391
392     public PersistenceManager getPersistenceManager()
393     {
394         PersistenceManager pm = pmf.getPersistenceManager();
395
396         pm.getFetchPlan().setMaxFetchDepth( -1 );
397
398         triggerInit();
399
400         return pm;
401     }
402
403     // ----------------------------------------------------------------------
404     // jdo utility methods
405     // ----------------------------------------------------------------------
406
407     private Object addObject( Object object )
408     {
409         return PlexusJdoUtils.addObject( getPersistenceManager(), object );
410     }
411
412     private Object getObjectById( String id, String fetchGroup )
413         throws UserNotFoundException, UserManagerException
414     {
415         try
416         {
417             return PlexusJdoUtils.getObjectById( getPersistenceManager(), JdoUser.class, id, fetchGroup );
418         }
419         catch ( PlexusObjectNotFoundException e )
420         {
421             throw new UserNotFoundException( e.getMessage() );
422         }
423         catch ( PlexusStoreException e )
424         {
425             throw new UserManagerException( "Unable to get object '" + JdoUser.class.getName() + "', id '" + id +
426                 "', fetch-group '" + fetchGroup + "' from jdo store." );
427         }
428     }
429
430     private Object removeObject( Object o )
431     {
432         if ( o == null )
433         {
434             throw new UserManagerException( "Unable to remove null object" );
435         }
436
437         PlexusJdoUtils.removeObject( getPersistenceManager(), o );
438         return o;
439     }
440
441     private Object updateObject( Object object )
442         throws UserNotFoundException, UserManagerException
443     {
444         try
445         {
446             return PlexusJdoUtils.updateObject( getPersistenceManager(), object );
447         }
448         catch ( PlexusStoreException e )
449         {
450             throw new UserManagerException(
451                 "Unable to update the '" + object.getClass().getName() + "' object in the jdo database.", e );
452         }
453     }
454
455     private void rollback( Transaction tx )
456     {
457         PlexusJdoUtils.rollbackIfActive( tx );
458     }
459
460     private boolean hasTriggeredInit = false;
461
462     public void triggerInit()
463     {
464         if ( !hasTriggeredInit )
465         {
466             hasTriggeredInit = true;
467             List<User> users = getAllObjectsDetached( null );
468
469             fireUserManagerInit( users.isEmpty() );
470         }
471     }
472
473     public JdoFactory getJdoFactory()
474     {
475         return jdoFactory;
476     }
477
478     public void setJdoFactory( JdoFactory jdoFactory )
479     {
480         this.jdoFactory = jdoFactory;
481     }
482
483     public UserSecurityPolicy getUserSecurityPolicy()
484     {
485         return userSecurityPolicy;
486     }
487 }