This project has retired. For details please refer to its Attic page.
JdoUserManager xref
View Javadoc

1   package org.apache.archiva.redback.users.jdo;
2   
3   /*
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   * http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing,
15   * software distributed under the License is distributed on an
16   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17   * KIND, either express or implied.  See the License for the
18   * specific language governing permissions and limitations
19   * under the License.
20   */
21  
22  import org.apache.archiva.redback.components.jdo.JdoFactory;
23  import org.apache.archiva.redback.components.jdo.RedbackJdoUtils;
24  import org.apache.archiva.redback.components.jdo.RedbackObjectNotFoundException;
25  import org.apache.archiva.redback.components.jdo.RedbackStoreException;
26  import org.apache.archiva.redback.policy.UserSecurityPolicy;
27  import org.apache.archiva.redback.users.AbstractUserManager;
28  import org.apache.archiva.redback.users.PermanentUserException;
29  import org.apache.archiva.redback.users.User;
30  import org.apache.archiva.redback.users.UserManagerException;
31  import org.apache.archiva.redback.users.UserNotFoundException;
32  import org.apache.archiva.redback.users.UserQuery;
33  import org.codehaus.plexus.util.StringUtils;
34  import org.jpox.JDOClassLoaderResolver;
35  import org.springframework.stereotype.Service;
36  
37  import javax.annotation.PostConstruct;
38  import javax.inject.Inject;
39  import javax.inject.Named;
40  import javax.jdo.Extent;
41  import javax.jdo.PersistenceManager;
42  import javax.jdo.PersistenceManagerFactory;
43  import javax.jdo.Query;
44  import javax.jdo.Transaction;
45  import java.util.Date;
46  import java.util.List;
47  
48  /**
49   * JdoUserManager
50   *
51   * @author <a href="mailto:joakim@erdfelt.com">Joakim Erdfelt</a>
52   */
53  @Service("userManager#jdo")
54  public class JdoUserManager
55      extends AbstractUserManager
56  {
57      @Inject
58      @Named(value = "jdoFactory#users")
59      private JdoFactory jdoFactory;
60  
61      @Inject
62      private UserSecurityPolicy userSecurityPolicy;
63  
64      private PersistenceManagerFactory pmf;
65  
66      public String getId()
67      {
68          return "jdo";
69      }
70  
71  
72      public boolean isReadOnly()
73      {
74          return false;
75      }
76  
77      public UserQuery createUserQuery()
78      {
79          return new JdoUserQuery();
80      }
81  
82      // ------------------------------------------------------------------
83  
84      public User createUser( String username, String fullname, String email )
85      {
86          User user = new JdoUser();
87          user.setUsername( username );
88          user.setFullName( fullname );
89          user.setEmail( email );
90          user.setAccountCreationDate( new Date() );
91  
92          return user;
93      }
94  
95      public List<User> getUsers()
96      {
97          return getAllObjectsDetached( null );
98      }
99  
100     public List<User> getUsers( boolean orderAscending )
101     {
102         String ordering = orderAscending ? "username ascending" : "username descending";
103 
104         return getAllObjectsDetached( ordering );
105     }
106 
107     @SuppressWarnings("unchecked")
108     private List<User> getAllObjectsDetached( String ordering )
109     {
110         return RedbackJdoUtils.getAllObjectsDetached( getPersistenceManager(), JdoUser.class, ordering, (String) null );
111     }
112 
113     public List<User> findUsersByUsernameKey( String usernameKey, boolean orderAscending )
114     {
115         return findUsers( "username", usernameKey, orderAscending );
116     }
117 
118     public List<User> findUsersByFullNameKey( String fullNameKey, boolean orderAscending )
119     {
120         return findUsers( "fullName", fullNameKey, orderAscending );
121     }
122 
123     public List<User> findUsersByEmailKey( String emailKey, boolean orderAscending )
124     {
125         return findUsers( "email", emailKey, orderAscending );
126     }
127 
128     @SuppressWarnings("unchecked")
129     public List<User> findUsersByQuery( UserQuery userQuery )
130     {
131         JdoUserQuery uq = (JdoUserQuery) userQuery;
132 
133         PersistenceManager pm = getPersistenceManager();
134 
135         Transaction tx = pm.currentTransaction();
136 
137         try
138         {
139             tx.begin();
140 
141             Extent extent = pm.getExtent( JdoUser.class, true );
142 
143             Query query = pm.newQuery( extent );
144 
145             String ordering = uq.getOrdering();
146 
147             query.setOrdering( ordering );
148 
149             query.declareImports( "import java.lang.String" );
150 
151             query.declareParameters( uq.getParameters() );
152 
153             query.setFilter( uq.getFilter() );
154 
155             query.setRange( uq.getFirstResult(),
156                             uq.getMaxResults() < 0 ? Long.MAX_VALUE : uq.getFirstResult() + uq.getMaxResults() );
157 
158             List<User> result = (List<User>) query.executeWithArray( uq.getSearchKeys() );
159 
160             result = (List<User>) pm.detachCopyAll( result );
161 
162             tx.commit();
163 
164             return result;
165         }
166         finally
167         {
168             rollback( tx );
169         }
170     }
171 
172     @SuppressWarnings("unchecked")
173     private List<User> findUsers( String searchField, String searchKey, boolean ascendingUsername )
174     {
175         PersistenceManager pm = getPersistenceManager();
176 
177         Transaction tx = pm.currentTransaction();
178 
179         try
180         {
181             tx.begin();
182 
183             Extent extent = pm.getExtent( JdoUser.class, true );
184 
185             Query query = pm.newQuery( extent );
186 
187             String ordering = ascendingUsername ? "username ascending" : "username descending";
188 
189             query.setOrdering( ordering );
190 
191             query.declareImports( "import java.lang.String" );
192 
193             query.declareParameters( "String searchKey" );
194 
195             query.setFilter( "this." + searchField + ".toLowerCase().indexOf(searchKey.toLowerCase()) > -1" );
196 
197             List<User> result = (List<User>) query.execute( searchKey );
198 
199             result = (List<User>) pm.detachCopyAll( result );
200 
201             tx.commit();
202 
203             return result;
204         }
205         finally
206         {
207             rollback( tx );
208         }
209     }
210 
211     public User addUser( User user )
212         throws UserManagerException
213     {
214         if ( !( user instanceof JdoUser ) )
215         {
216             throw new UserManagerException( "Unable to Add User. User object " + user.getClass().getName() +
217                                                 " is not an instance of " + JdoUser.class.getName() );
218         }
219 
220         if ( StringUtils.isEmpty( user.getUsername() ) )
221         {
222             throw new IllegalStateException(
223                 Messages.getString( "user.manager.cannot.add.user.without.username" ) ); //$NON-NLS-1$
224         }
225 
226         userSecurityPolicy.extensionChangePassword( user );
227 
228         fireUserManagerUserAdded( user );
229 
230         // TODO: find a better solution
231         // workaround for avoiding the admin from providing another password on the next login after the
232         // admin account has been created
233         // extensionChangePassword by default sets the password change status to false
234         if ( "admin".equals( user.getUsername() ) )
235         {
236             user.setPasswordChangeRequired( false );
237         }
238         else
239         {
240             user.setPasswordChangeRequired( true );
241         }
242 
243         return (User) addObject( user );
244     }
245 
246     public void deleteUser( String username )
247         throws UserManagerException
248     {
249         try
250         {
251             User user = findUser( username );
252 
253             if ( user.isPermanent() )
254             {
255                 throw new PermanentUserException( "Cannot delete permanent user [" + user.getUsername() + "]." );
256             }
257 
258             fireUserManagerUserRemoved( user );
259 
260             RedbackJdoUtils.removeObject( getPersistenceManager(), user );
261         }
262         catch ( UserNotFoundException e )
263         {
264             log.warn( "Unable to delete user " + username + ", user not found.", e );
265         }
266     }
267 
268     public void addUserUnchecked( User user )
269         throws UserManagerException
270     {
271         if ( !( user instanceof JdoUser ) )
272         {
273             throw new UserManagerException( "Unable to Add User. User object " + user.getClass().getName() +
274                                                 " is not an instance of " + JdoUser.class.getName() );
275         }
276 
277         if ( StringUtils.isEmpty( user.getUsername() ) )
278         {
279             throw new IllegalStateException(
280                 Messages.getString( "user.manager.cannot.add.user.without.username" ) ); //$NON-NLS-1$
281         }
282 
283         addObject( user );
284     }
285 
286     public void eraseDatabase()
287     {
288         RedbackJdoUtils.removeAll( getPersistenceManager(), JdoUser.class );
289         RedbackJdoUtils.removeAll( getPersistenceManager(), UsersManagementModelloMetadata.class );
290     }
291 
292     public User findUser( String username )
293         throws UserNotFoundException, UserManagerException
294     {
295         if ( StringUtils.isEmpty( username ) )
296         {
297             throw new UserNotFoundException( "User with empty username not found." );
298         }
299 
300         return (User) getObjectById( username, null );
301     }
302 
303     public boolean userExists( String principal )
304         throws UserManagerException
305     {
306         try
307         {
308             findUser( principal );
309             return true;
310         }
311         catch ( UserNotFoundException ne )
312         {
313             return false;
314         }
315     }
316 
317     public User updateUser( User user )
318         throws UserNotFoundException, UserManagerException
319     {
320         return updateUser( user, false );
321     }
322 
323     public User updateUser( User user, boolean passwordChangeRequired )
324         throws UserNotFoundException, UserManagerException
325     {
326         if ( !( user instanceof JdoUser ) )
327         {
328             throw new UserManagerException( "Unable to Update User. User object " + user.getClass().getName() +
329                                                 " is not an instance of " + JdoUser.class.getName() );
330         }
331 
332         // If password is supplied, assume changing of password.
333         // TODO: Consider adding a boolean to the updateUser indicating a password change or not.
334         if ( StringUtils.isNotEmpty( user.getPassword() ) )
335         {
336             userSecurityPolicy.extensionChangePassword( user, passwordChangeRequired );
337         }
338 
339         user = (User) updateObject( user );
340 
341         fireUserManagerUserUpdated( user );
342 
343         return user;
344     }
345 
346     @PostConstruct
347     public void initialize()
348     {
349         JDOClassLoaderResolver d;
350         pmf = jdoFactory.getPersistenceManagerFactory();
351     }
352 
353     public PersistenceManager getPersistenceManager()
354     {
355         PersistenceManager pm = pmf.getPersistenceManager();
356 
357         pm.getFetchPlan().setMaxFetchDepth( -1 );
358 
359         triggerInit();
360 
361         return pm;
362     }
363 
364     // ----------------------------------------------------------------------
365     // jdo utility methods
366     // ----------------------------------------------------------------------
367 
368     private Object addObject( Object object )
369     {
370         return RedbackJdoUtils.addObject( getPersistenceManager(), object );
371     }
372 
373     private Object getObjectById( String id, String fetchGroup )
374         throws UserNotFoundException, UserManagerException
375     {
376         try
377         {
378             return RedbackJdoUtils.getObjectById( getPersistenceManager(), JdoUser.class, id, fetchGroup );
379         }
380         catch ( RedbackObjectNotFoundException e )
381         {
382             throw new UserNotFoundException( e.getMessage() );
383         }
384         catch ( RedbackStoreException e )
385         {
386             throw new UserManagerException( "Unable to get object '" + JdoUser.class.getName() + "', id '" + id +
387                                                 "', fetch-group '" + fetchGroup + "' from jdo store.", e );
388         }
389     }
390 
391     private Object removeObject( Object o )
392         throws UserManagerException
393     {
394         if ( o == null )
395         {
396             throw new UserManagerException( "Unable to remove null object" );
397         }
398 
399         RedbackJdoUtils.removeObject( getPersistenceManager(), o );
400         return o;
401     }
402 
403     private Object updateObject( Object object )
404         throws UserNotFoundException, UserManagerException
405     {
406         try
407         {
408             return RedbackJdoUtils.updateObject( getPersistenceManager(), object );
409         }
410         catch ( RedbackStoreException e )
411         {
412             throw new UserManagerException(
413                 "Unable to update the '" + object.getClass().getName() + "' object in the jdo database.", e );
414         }
415     }
416 
417     private void rollback( Transaction tx )
418     {
419         RedbackJdoUtils.rollbackIfActive( tx );
420     }
421 
422     private boolean hasTriggeredInit = false;
423 
424     public void triggerInit()
425     {
426         if ( !hasTriggeredInit )
427         {
428             hasTriggeredInit = true;
429             List<User> users = getAllObjectsDetached( null );
430 
431             fireUserManagerInit( users.isEmpty() );
432         }
433     }
434 
435     public JdoFactory getJdoFactory()
436     {
437         return jdoFactory;
438     }
439 
440     public void setJdoFactory( JdoFactory jdoFactory )
441     {
442         this.jdoFactory = jdoFactory;
443     }
444 
445     public UserSecurityPolicy getUserSecurityPolicy()
446     {
447         return userSecurityPolicy;
448     }
449 
450     public boolean isFinalImplementation()
451     {
452         return true;
453     }
454 
455     public String getDescriptionKey()
456     {
457         return "archiva.redback.usermanager.jdo";
458     }
459 }