KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > sape > carbon > services > security > management > rdbms > RdbmsUserManagerImpl


1 /*
2  * The contents of this file are subject to the Sapient Public License
3  * Version 1.0 (the "License"); you may not use this file except in compliance
4  * with the License. You may obtain a copy of the License at
5  * http://carbon.sf.net/License.html.
6  *
7  * Software distributed under the License is distributed on an "AS IS" basis,
8  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
9  * the specific language governing rights and limitations under the License.
10  *
11  * The Original Code is The Carbon Component Framework.
12  *
13  * The Initial Developer of the Original Code is Sapient Corporation
14  *
15  * Copyright (C) 2003 Sapient Corporation. All Rights Reserved.
16  */

17
18 package org.sape.carbon.services.security.management.rdbms;
19
20 import java.security.Principal JavaDoc;
21 import java.security.acl.Group JavaDoc;
22 import java.sql.Connection JavaDoc;
23 import java.sql.PreparedStatement JavaDoc;
24 import java.sql.ResultSet JavaDoc;
25 import java.sql.SQLException JavaDoc;
26 import java.util.HashMap JavaDoc;
27 import java.util.HashSet JavaDoc;
28 import java.util.Iterator JavaDoc;
29 import java.util.Map JavaDoc;
30 import java.util.Set JavaDoc;
31
32 import org.sape.carbon.core.component.ComponentConfiguration;
33 import org.sape.carbon.core.component.lifecycle.Configurable;
34 import org.sape.carbon.core.config.InvalidConfigurationException;
35 import org.sape.carbon.core.exception.ExceptionUtility;
36 import org.sape.carbon.services.security.management.DefaultGroupImpl;
37 import org.sape.carbon.services.security.management.DefaultUserImpl;
38 import org.sape.carbon.services.security.management.DuplicateGroupException;
39 import org.sape.carbon.services.security.management.DuplicatePrincipalException;
40 import org.sape.carbon.services.security.management.LazyLoadGroup;
41 import org.sape.carbon.services.security.management.RuntimeSecurityManagementException;
42 import org.sape.carbon.services.security.management.UnknownGroupException;
43 import org.sape.carbon.services.security.management.UnknownPrincipalException;
44 import org.sape.carbon.services.security.management.UserManager;
45 import org.sape.carbon.services.sql.StatementFactoryException;
46
47 import org.apache.commons.logging.Log;
48 import org.apache.commons.logging.LogFactory;
49
50 /**
51  * Implementation of the UserManager against a RDBMS backing store. This
52  * implementation executes queries against the datastore as specified in
53  * the configuration file as well as the statement factory. Copyright
54  * 2002 Sapient
55  *
56  * @author Jordan Reed, September 2002
57  * @version $Revision: 1.14 $($Author: dvoet $ / $Date: 2003/10/28 19:02:01 $)
58  *
59  * @since carbon 1.2
60  */

61 public class RdbmsUserManagerImpl implements UserManager, Configurable {
62
63     /**
64      * Provides a handle to Apache-commons logger
65      */

66     private Log log = LogFactory.getLog(this.getClass());
67
68     /** Holds a reference to the configuration. */
69     protected RdbmsUserManagerConfiguration config;
70
71     /**
72      * Creates a new user object in the database and returns it.
73      *
74      * @param username the name of the user to create
75      * @param credential the credential for the user to authenticate
76      *
77      * @return the new instance of a principal generated
78      *
79      * @throws DuplicatePrincipalException indicates the a principal with
80      * the same name already exists in the database
81      * @throws RuntimeSecurityManagementException indicates an error
82      * communicating with the database
83      */

84     public Principal JavaDoc createUser(String JavaDoc username, Map JavaDoc userInfo)
85         throws DuplicatePrincipalException {
86
87         Principal JavaDoc resultUser = null;
88         Connection JavaDoc connection = null;
89
90         try {
91             connection = config.getConnectionFactory().getConnection();
92         } catch (SQLException JavaDoc sqle) {
93             log.trace("Caught exception: " + sqle
94                 + ExceptionUtility.captureStackTrace(sqle));
95
96             throw new RuntimeSecurityManagementException(
97                 this.getClass(), "Caught SQLException while opening connection",
98                 sqle);
99         }
100
101         try {
102             resultUser = createUser(connection, username, userInfo);
103         } finally {
104             try {
105                 if (connection != null) {
106                     connection.close();
107                 }
108             } catch (SQLException JavaDoc sqle) {
109                 log.info("Caught exception closing Connection: " + sqle
110                     + ExceptionUtility.captureStackTrace(sqle));
111             }
112         }
113
114         return resultUser;
115     }
116
117     /**
118      * Creates a new user object in the database and returns it using the
119      * given connection.
120      *
121      * <p>
122      * This method makes calls to two helper methods to delegate the two
123      * bits of functionality. <code>createUserEntry</code> to create the
124      * database entry for the user and <code>createCredentialEntry</code>
125      * to create the credential entry for the user.
126      * </p>
127      *
128      * @param connection connection to execute database calls against
129      * @param username the name of the user to create
130      * @param credential the credential for the user to authenticate
131      *
132      * @return the new instance of a principal generated
133      *
134      * @throws DuplicatePrincipalException indicates the a principal with
135      * the same name already exists in the database
136      * @throws RuntimeSecurityManagementException indicates an error
137      * communicating with the database
138      */

139     protected Principal JavaDoc createUser(
140         Connection JavaDoc connection, String JavaDoc username, Map JavaDoc userInfo)
141         throws DuplicatePrincipalException {
142
143         if (log.isTraceEnabled()) {
144             log.trace("Adding user with name [" + username
145                 + "] and additional info ["
146                 + userInfo + "]");
147         }
148
149         Principal JavaDoc currentUser = retreiveUser(connection, username);
150
151         if (currentUser != null) {
152             throw new DuplicatePrincipalException(
153                 this.getClass(), currentUser);
154         }
155
156         try {
157             connection.setAutoCommit(false);
158             createUserEntry(connection, username);
159             currentUser = retreiveUser(connection, username);
160             createCredentialEntry(connection, currentUser, userInfo);
161             connection.commit();
162             connection.setAutoCommit(true);
163         } catch (RuntimeSecurityManagementException rsme) {
164             try {
165                 if (connection != null) {
166                     connection.rollback();
167                     connection.setAutoCommit(true);
168                 }
169             } catch (SQLException JavaDoc se) {
170                 // Ignore exception.
171
}
172
173             throw rsme;
174         } catch (SQLException JavaDoc se) {
175             try {
176                 if (connection != null) {
177                     connection.rollback();
178                     connection.setAutoCommit(true);
179                 }
180             } catch (SQLException JavaDoc se2) {
181                 // Ignore exception.
182
}
183
184             throw new RuntimeSecurityManagementException(
185                 this.getClass(),
186                 "Caught SQLException while adding " + "new user named ["
187                 + username + "]", se);
188         }
189
190         return currentUser;
191     }
192
193     /**
194      * Creates the user row in the database. If the credential is created
195      * at the same time, the <code>createCredentialEntry</code> method
196      * should be overriden and set to empty.
197      *
198      * @param connection connection to execute database calls against
199      * @param username the name of the user to create
200      * @param credential the credential for the user to authenticate
201      *
202      * @throws RuntimeSecurityManagementException indicates an error
203      * communicating with the database or inconsistent state.
204      */

205     protected void createUserEntry(
206         Connection JavaDoc connection, String JavaDoc username) {
207         PreparedStatement JavaDoc createUserStatement = null;
208
209         try {
210             createUserStatement =
211                 config.getStatementFactory().createPreparedStatement(
212                     config.getCreateUserQueryName(), connection);
213             createUserStatement.setString(1, username);
214
215             int resultCount = createUserStatement.executeUpdate();
216
217             if (log.isInfoEnabled()) {
218                 log.info("Added user with name [" + username + "]");
219             }
220         } catch (StatementFactoryException sfe) {
221             log.trace("Caught exception: " + sfe
222                 + ExceptionUtility.captureStackTrace(sfe));
223
224             throw new RuntimeSecurityManagementException(
225                 this.getClass(),
226                 "Caught StatementFactoryException while adding "
227                 + "new user.", sfe);
228         } catch (SQLException JavaDoc sqle) {
229             log.trace("Caught exception: " + sqle
230                 + ExceptionUtility.captureStackTrace(sqle));
231
232             throw new RuntimeSecurityManagementException(
233                 this.getClass(), "Caught SQLException while adding "
234                     + "new user.",
235                 sqle);
236         } finally {
237             try {
238                 if (createUserStatement != null) {
239                     createUserStatement.close();
240                 }
241             } catch (SQLException JavaDoc sqle) {
242                 // Ignore exception.
243
}
244         }
245     }
246
247     /**
248      * Creates the credential row in the database. If the credential is
249      * created with the user this method should be overriden and set to
250      * empty.
251      *
252      * @param connection connection to execute database calls against
253      * @param currentUser the user to create a credential for
254      * @param credential the credential for the user to authenticate
255      *
256      * @throws RuntimeSecurityManagementException indicates an error
257      * communicating with the database or inconsistent state.
258      */

259     protected void createCredentialEntry(
260         Connection JavaDoc connection, Principal JavaDoc currentUser, Map JavaDoc userInfo) {
261         PreparedStatement JavaDoc createCredentialStatement = null;
262         Object JavaDoc userPrimaryKey = null;
263
264         try {
265             userPrimaryKey =
266                 retreivePrincipalPrimaryKey(connection, currentUser);
267         } catch (UnknownPrincipalException upe) {
268             throw new RuntimeSecurityManagementException(
269                 this.getClass(),
270                 "Caught UnknownPrincipalException while getting "
271                 + "primary key for [" + currentUser.getName() + "]", upe);
272         }
273
274         try {
275             Object JavaDoc credential =
276                 userInfo.get(this.config.getCreateUserBindParameters()[0]);
277                 
278             createCredentialStatement =
279                 config.getStatementFactory().createPreparedStatement(
280                     config.getCreateCredentialQueryName(), connection);
281
282             createCredentialStatement.setObject(1, userPrimaryKey);
283             createCredentialStatement.setObject(2, credential);
284
285             int resultCount = createCredentialStatement.executeUpdate();
286
287             if (log.isInfoEnabled()) {
288                 log.info("Added credential to user with name ["
289                     + currentUser.getName() + "] and credential of type ["
290                     + credential.getClass().getName() + "]");
291             }
292         } catch (StatementFactoryException sfe) {
293             log.trace("Caught exception: " + sfe
294                 + ExceptionUtility.captureStackTrace(sfe));
295
296             throw new RuntimeSecurityManagementException(
297                 this.getClass(),
298                 "Caught StatementFactoryException while adding "
299                 + "new user.", sfe);
300         } catch (SQLException JavaDoc sqle) {
301             log.trace("Caught exception: " + sqle
302                 + ExceptionUtility.captureStackTrace(sqle));
303
304             throw new RuntimeSecurityManagementException(
305                 this.getClass(), "Caught SQLException while adding "
306                     + "new user.",
307                 sqle);
308         } finally {
309             try {
310                 if (createCredentialStatement != null) {
311                     createCredentialStatement.close();
312                 }
313             } catch (SQLException JavaDoc sqle) {
314                 // Ignore exception.
315
}
316         }
317     }
318
319     /**
320      * Removes the credential row from the database.
321      *
322      * @param connection connection to execute database calls against
323      * @param userPrimaryKey the primary key of the user.
324      *
325      * @throws RuntimeSecurityManagementException indicates an error
326      * communicating with the database or inconsistent state.
327      */

328     protected void removeCredential(
329         Connection JavaDoc connection, Object JavaDoc userPrimaryKey) {
330         PreparedStatement JavaDoc removeCredentialStatement = null;
331
332         try {
333             removeCredentialStatement =
334                 config.getStatementFactory().createPreparedStatement(
335                     config.getRemoveCredentialQueryName(), connection);
336
337             removeCredentialStatement.setObject(1, userPrimaryKey);
338
339             int resultCount = removeCredentialStatement.executeUpdate();
340
341             if (log.isInfoEnabled()) {
342                 log.info("Deleted credential to user with name ["
343                     + userPrimaryKey + "]");
344             }
345         } catch (StatementFactoryException sfe) {
346             log.trace("Caught exception: " + sfe
347                 + ExceptionUtility.captureStackTrace(sfe));
348
349             throw new RuntimeSecurityManagementException(
350                 this.getClass(),
351                 "Caught StatementFactoryException while deleting "
352                 + "credential.", sfe);
353         } catch (SQLException JavaDoc sqle) {
354             log.trace("Caught exception: " + sqle
355                 + ExceptionUtility.captureStackTrace(sqle));
356
357             throw new RuntimeSecurityManagementException(
358                 this.getClass(), "Caught SQLException while deleting "
359                     + "credential.",
360                 sqle);
361         } finally {
362             try {
363                 if (removeCredentialStatement != null) {
364                     removeCredentialStatement.close();
365                 }
366             } catch (SQLException JavaDoc sqle) {
367                 // Ignore exception.
368
}
369         }
370     }
371
372     /**
373      * Authenticates a user against a given credential.
374      *
375      * <p>
376      * This method will check the validity of a credential for a given
377      * user and return if the user is valid to log in of if some other
378      * status prevents them.
379      * </p>
380      *
381      * <p>
382      * This method does not provide business specific reasons why a user
383      * may be unable to log in (user does not exist, incorrect password,
384      * locked out, etc.). Projects must write project specific checks for
385      * business conditions preventing a user from logging in.
386      * </p>
387      *
388      * @param username The username identifying the user inside the user
389      * store.
390      * @param credential The credential object a user needs to prove they
391      * can be referenced by the principal.
392      *
393      * @return if this is the valid credential for the given user
394      *
395      * @throws RuntimeSecurityManagementException indicates an error
396      * communicating with the database or inconsistent state.
397      */

398     public boolean authenticate(String JavaDoc username, Object JavaDoc credential) {
399         Connection JavaDoc connection = null;
400         boolean authenticated = false;
401
402         try {
403             connection = config.getConnectionFactory().getConnection();
404         } catch (SQLException JavaDoc sqle) {
405             log.trace("Caught exception: " + sqle
406                 + ExceptionUtility.captureStackTrace(sqle));
407
408             throw new RuntimeSecurityManagementException(
409                 this.getClass(), "Caught SQLException while opening "
410                     + "connection",
411                 sqle);
412         }
413
414         try {
415             authenticated = authenticate(connection, username, credential);
416         } finally {
417             try {
418                 if (connection != null) {
419                     connection.close();
420                 }
421             } catch (SQLException JavaDoc sqle) {
422                 log.info("Caught exception closing Connection: " + sqle
423                     + ExceptionUtility.captureStackTrace(sqle));
424             }
425         }
426
427         return authenticated;
428     }
429
430     /**
431      * Authenticates a user against a given credential.
432      *
433      * <p>
434      * This method will check the validity of a credential for a given
435      * user and return if the user is valid to log in of if some other
436      * status prevents them.
437      * </p>
438      *
439      * <p>
440      * This method does not provide business specific reasons why a user
441      * may be unable to log in (user does not exist, incorrect password,
442      * locked out, etc.). Projects must write project specific checks for
443      * business conditions preventing a user from logging in.
444      * </p>
445      *
446      * @param connection connection to execute database calls against
447      * @param username The username identifying the user inside the user
448      * store.
449      * @param credential The credential object a user needs to prove they
450      * can be referenced by the principal.
451      *
452      * @return if this is the valid credential for the given user
453      *
454      * @throws RuntimeSecurityManagementException indicates an error
455      * communicating with the database or inconsistent state.
456      */

457     public boolean authenticate(
458         Connection JavaDoc connection, String JavaDoc username, Object JavaDoc credential) {
459         PreparedStatement JavaDoc authenticateUserStatement = null;
460         ResultSet JavaDoc authenticateUserResultSet = null;
461         boolean authenticated = false;
462
463         if (log.isTraceEnabled()) {
464             log.trace("Searching for user with principal name [" + username
465                 + "]");
466         }
467
468         try {
469             authenticateUserStatement =
470                 config.getStatementFactory().createPreparedStatement(
471                     config.getAuthenticateUserQueryName(), connection);
472             authenticateUserStatement.setString(1, username);
473             authenticateUserStatement.setObject(2, credential);
474             authenticateUserResultSet =
475                 authenticateUserStatement.executeQuery();
476
477             if (authenticateUserResultSet.next()) {
478                 authenticated = true;
479
480                 if (log.isTraceEnabled()) {
481                     log.trace("User with principal name [" + username
482                         + "] was successfully authenticated");
483                 }
484             } else {
485                 authenticated = false;
486
487                 if (log.isTraceEnabled()) {
488                     log.trace("User with principal name [" + username
489                         + "] failed authentication");
490                 }
491             }
492         } catch (StatementFactoryException sfe) {
493             log.trace("Caught exception: " + sfe
494                 + ExceptionUtility.captureStackTrace(sfe));
495
496             throw new RuntimeSecurityManagementException(
497                 this.getClass(),
498                 "Caught StatementFactoryException while adding "
499                 + "new user.", sfe);
500         } catch (SQLException JavaDoc sqle) {
501             log.trace("Caught exception: " + sqle
502                 + ExceptionUtility.captureStackTrace(sqle));
503
504             throw new RuntimeSecurityManagementException(
505                 this.getClass(), "Caught SQLException while authenticating "
506                     + "user.",
507                 sqle);
508         } finally {
509             try {
510                 if (authenticateUserResultSet != null) {
511                     authenticateUserResultSet.close();
512                 }
513             } catch (SQLException JavaDoc sqle) {
514                 log.info("Caught exception closing ResultSet: " + sqle
515                     + ExceptionUtility.captureStackTrace(sqle));
516             }
517
518             try {
519                 if (authenticateUserStatement != null) {
520                     authenticateUserStatement.close();
521                 }
522             } catch (SQLException JavaDoc sqle) {
523                 log.info("Caught exception closing Statement: " + sqle
524                     + ExceptionUtility.captureStackTrace(sqle));
525             }
526         }
527
528         return authenticated;
529     }
530
531     /**
532      * Removes a principal from all groups it is in.
533      *
534      * <p>
535      * This is used when removing a user or group from the system to
536      * validate that no extraneous rows are leftover.
537      * </p>
538      *
539      * @param connection connection to execute database calls against
540      * @param principalPrimaryKey the principal (either user or group) to
541      * remove from all groups it is in
542      *
543      * @throws UnknownPrincipalException indicates the principal does not
544      * currently exists in the system
545      * @throws RuntimeSecurityManagementException indicates an error
546      * communicating with the database
547      */

548     protected void removeAllRelationships(
549         Connection JavaDoc connection, Object JavaDoc principalPrimaryKey)
550         throws UnknownPrincipalException {
551         PreparedStatement JavaDoc removeAllRelationshipsStatement = null;
552
553         if (log.isTraceEnabled()) {
554             log.trace("Removing principal [" + principalPrimaryKey
555                 + "] from all relationships");
556         }
557
558         try {
559             removeAllRelationshipsStatement =
560                 config.getStatementFactory().createPreparedStatement(
561                     config.getRemoveAllRelationshipsQueryName(), connection);
562             removeAllRelationshipsStatement.setObject(
563                 1, principalPrimaryKey);
564             removeAllRelationshipsStatement.setObject(
565                 2, principalPrimaryKey);
566
567             int resultCount =
568                 removeAllRelationshipsStatement.executeUpdate();
569
570             if (log.isInfoEnabled()) {
571                 log.info("Removed principal with name [" + principalPrimaryKey
572                     + "] from [" + resultCount + "] relationships");
573             }
574         } catch (StatementFactoryException sfe) {
575             log.trace("Caught exception: " + sfe
576                 + ExceptionUtility.captureStackTrace(sfe));
577
578             throw new RuntimeSecurityManagementException(
579                 this.getClass(),
580                 "Caught StatementFactoryException while removing "
581                 + "user.", sfe);
582         } catch (SQLException JavaDoc sqle) {
583             log.trace("Caught exception: " + sqle
584                 + ExceptionUtility.captureStackTrace(sqle));
585
586             throw new RuntimeSecurityManagementException(
587                 this.getClass(), "Caught SQLException while removing "
588                     + "user.",
589                 sqle);
590         } finally {
591             try {
592                 if (removeAllRelationshipsStatement != null) {
593                     removeAllRelationshipsStatement.close();
594                 }
595             } catch (SQLException JavaDoc sqle) {
596                 log.info("Caught exception closing Statement: " + sqle
597                     + ExceptionUtility.captureStackTrace(sqle));
598             }
599         }
600     }
601
602     /**
603      * Removes a user from the database.
604      *
605      * <p>
606      * This will first remove the user from any groups it may be in, and
607      * then proceed to delete the user. These two steps are done in a
608      * transaction against the database that will rollback if there is an
609      * error on either step.
610      * </p>
611      *
612      * @param user The user to remove from the database
613      *
614      * @throws UnknownPrincipalException indicates the principal does not
615      * currently exists in the system
616      * @throws RuntimeSecurityManagementException indicates an error
617      * communicating with the database
618      */

619     public void removeUser(Principal JavaDoc user)
620         throws UnknownPrincipalException {
621
622         Connection JavaDoc connection = null;
623
624         try {
625             connection = config.getConnectionFactory().getConnection();
626         } catch (SQLException JavaDoc sqle) {
627             log.trace("Caught exception: " + sqle
628                 + ExceptionUtility.captureStackTrace(sqle));
629
630             throw new RuntimeSecurityManagementException(
631                 this.getClass(), "Caught SQLException while opening "
632                     + "connection",
633                 sqle);
634         }
635
636         try {
637             removeUser(connection, user);
638         } finally {
639             try {
640                 if (connection != null) {
641                     connection.close();
642                 }
643             } catch (SQLException JavaDoc sqle) {
644                 log.info("Caught exception closing Connection: " + sqle
645                     + ExceptionUtility.captureStackTrace(sqle));
646             }
647         }
648     }
649
650     /**
651      * Removes a user from the database.
652      *
653      * <p>
654      * This will first remove the user from any groups it may be in, and
655      * then proceed to delete the user. These two steps are done in a
656      * transaction against the database that will rollback if there is an
657      * error on either step.
658      * </p>
659      *
660      * @param connection connection to execute database calls against
661      * @param user The user to remove from the database
662      *
663      * @throws UnknownPrincipalException indicates the principal does not
664      * currently exists in the system
665      * @throws RuntimeSecurityManagementException indicates an error
666      * communicating with the database
667      */

668     protected void removeUser(Connection JavaDoc connection, Principal JavaDoc user)
669         throws UnknownPrincipalException {
670
671         Principal JavaDoc currentUser = retreiveUser(connection, user.getName());
672
673         if (currentUser == null) {
674             throw new UnknownPrincipalException(
675                 this.getClass(), user.getName());
676         }
677
678         Object JavaDoc userPrimaryKey =
679             retreivePrincipalPrimaryKey(connection, user);
680
681         if (log.isTraceEnabled()) {
682             log.trace("Removing user with principal ["
683                 + user.getName()
684                 + "]");
685         }
686
687         try {
688             connection.setAutoCommit(false);
689
690             removeAllRelationships(connection, userPrimaryKey);
691             removeCredential(connection, userPrimaryKey);
692             removeUserEntry(connection, userPrimaryKey);
693
694             connection.commit();
695             connection.setAutoCommit(true);
696
697             if (log.isInfoEnabled()) {
698                 log.info("Removed user with name [" + user.getName() + "]");
699             }
700         } catch (RuntimeSecurityManagementException rsme) {
701             try {
702                 if (connection != null) {
703                     connection.rollback();
704                     connection.setAutoCommit(true);
705                 }
706             } catch (SQLException JavaDoc se) {
707                 // Ignore exception.
708
}
709
710             throw rsme;
711         } catch (SQLException JavaDoc se) {
712             try {
713                 if (connection != null) {
714                     connection.rollback();
715                     connection.setAutoCommit(true);
716                 }
717             } catch (SQLException JavaDoc se2) {
718                 // Ignore exception.
719
}
720
721             throw new RuntimeSecurityManagementException(
722                 this.getClass(),
723                 "Caught SQLException while deleting " + "user named ["
724                 + user.getName() + "]", se);
725         }
726     }
727
728     /**
729      * Removes the user row from the database.
730      *
731      * <p>
732      * This method should not normally be called until all other values
733      * relating to the user have been removed from the database unless
734      * this is an Oracle database with cascading contraints.
735      * </p>
736      *
737      * @param connection connection to execute database calls against
738      * @param userPrimaryKey the primary key of the user.
739      *
740      * @throws RuntimeSecurityManagementException indicates an error
741      * communicating with the database or inconsistent state.
742      */

743     protected void removeUserEntry(
744         Connection JavaDoc connection, Object JavaDoc userPrimaryKey) {
745         PreparedStatement JavaDoc removeUserStatement = null;
746
747         try {
748             removeUserStatement =
749                 config.getStatementFactory().createPreparedStatement(
750                     config.getRemoveUserQueryName(), connection);
751             removeUserStatement.setObject(1, userPrimaryKey);
752
753             int resultCount = removeUserStatement.executeUpdate();
754         } catch (StatementFactoryException sfe) {
755             log.trace("Caught exception and rolled back transaction: " + sfe
756                 + ExceptionUtility.captureStackTrace(sfe));
757
758             throw new RuntimeSecurityManagementException(
759                 this.getClass(),
760                 "Caught StatementFactoryException while removing "
761                 + "user.", sfe);
762         } catch (SQLException JavaDoc sqle) {
763             log.trace("Caught exception and rolled back transaction: " + sqle
764                 + ExceptionUtility.captureStackTrace(sqle));
765
766             throw new RuntimeSecurityManagementException(
767                 this.getClass(), "Caught SQLException while removing "
768                     + "user.",
769                 sqle);
770         } finally {
771             try {
772                 if (removeUserStatement != null) {
773                     removeUserStatement.close();
774                 }
775             } catch (SQLException JavaDoc sqle) {
776                 log.info("Caught exception closing Statement: " + sqle
777                     + ExceptionUtility.captureStackTrace(sqle));
778             }
779         }
780     }
781
782     /**
783      * Updates the credential for the user in the database.
784      *
785      * @param user the user to update in the database
786      * @param credential the new credential to assign to the user
787      *
788      * @throws UnknownPrincipalException indicates the principal does not
789      * currently exists in the system
790      * @throws RuntimeSecurityManagementException indicates an error
791      * communicating with the database
792      */

793     public void updateCredential(Principal JavaDoc user, Object JavaDoc credential)
794         throws UnknownPrincipalException {
795         Connection JavaDoc connection = null;
796
797         try {
798             connection = config.getConnectionFactory().getConnection();
799         } catch (SQLException JavaDoc sqle) {
800             log.trace("Caught exception: " + sqle
801                 + ExceptionUtility.captureStackTrace(sqle));
802
803             throw new RuntimeSecurityManagementException(
804                 this.getClass(), "Caught SQLException while opening "
805                     + "connection",
806                 sqle);
807         }
808
809         try {
810             updateCredential(connection, user, credential);
811         } finally {
812             try {
813                 if (connection != null) {
814                     connection.close();
815                 }
816             } catch (SQLException JavaDoc sqle) {
817                 log.info("Caught exception closing Connection: " + sqle
818                     + ExceptionUtility.captureStackTrace(sqle));
819             }
820         }
821     }
822
823     /**
824      * Updates the credential for the user in the database.
825      *
826      * @param connection the user to update in the database
827      * @param user the user to update in the database
828      * @param credential the new credential to assign to the user
829      *
830      * @throws UnknownPrincipalException indicates the principal does not
831      * currently exists in the system
832      * @throws RuntimeSecurityManagementException indicates an error
833      * communicating with the database
834      */

835     protected void updateCredential(
836         Connection JavaDoc connection, Principal JavaDoc user, Object JavaDoc credential)
837         throws UnknownPrincipalException {
838         PreparedStatement JavaDoc updateCredentialStatement = null;
839
840         if (log.isTraceEnabled()) {
841             log.trace("Updating user with principal [" + user
842                 + "] and credential of type ["
843                 + credential.getClass().getName() + "]");
844         }
845
846         Object JavaDoc userPrimaryKey =
847             retreivePrincipalPrimaryKey(connection, user);
848
849         try {
850             updateCredentialStatement =
851                 config.getStatementFactory().createPreparedStatement(
852                     config.getUpdateCredentialQueryName(), connection);
853             updateCredentialStatement.setObject(1, credential);
854             updateCredentialStatement.setObject(2, userPrimaryKey);
855
856             int resultCount = updateCredentialStatement.executeUpdate();
857
858             if (log.isDebugEnabled()) {
859                 log.debug("Updated credential for user with name ["
860                     + user.getName() + "]");
861             }
862         } catch (StatementFactoryException sfe) {
863             log.trace("Caught exception: " + sfe
864                 + ExceptionUtility.captureStackTrace(sfe));
865
866             throw new RuntimeSecurityManagementException(
867                 this.getClass(),
868                 "Caught StatementFactoryException while updating "
869                 + "user.", sfe);
870         } catch (SQLException JavaDoc sqle) {
871             log.trace("Caught exception: " + sqle
872                 + ExceptionUtility.captureStackTrace(sqle));
873
874             throw new RuntimeSecurityManagementException(
875                 this.getClass(), "Caught SQLException while updating "
876                     + "user.",
877                 sqle);
878         } finally {
879             try {
880                 updateCredentialStatement.close();
881             } catch (SQLException JavaDoc sqle) {
882                 log.info("Caught exception closing Statement: " + sqle
883                     + ExceptionUtility.captureStackTrace(sqle));
884             }
885         }
886     }
887
888     /**
889      * Creates a new entry for Group in the database.
890      *
891      * @param groupName name of the group add to the database
892      *
893      * @return a new group object in the database
894      *
895      * @throws DuplicateGroupException indicates that a group with the
896      * same name already exists in the database
897      * @throws RuntimeSecurityManagementException indicates an error
898      * communicating with the database
899      */

900     public Group JavaDoc createGroup(String JavaDoc groupName)
901         throws DuplicateGroupException {
902         Group JavaDoc result = null;
903         Connection JavaDoc connection = null;
904
905         try {
906             connection = config.getConnectionFactory().getConnection();
907         } catch (SQLException JavaDoc sqle) {
908             log.trace("Caught exception: " + sqle
909                 + ExceptionUtility.captureStackTrace(sqle));
910
911             throw new RuntimeSecurityManagementException(
912                 this.getClass(), "Caught SQLException while opening "
913                     + "connection",
914                 sqle);
915         }
916
917         try {
918             result = createGroup(connection, groupName);
919         } finally {
920             try {
921                 if (connection != null) {
922                     connection.close();
923                 }
924             } catch (SQLException JavaDoc sqle) {
925                 log.info("Caught exception closing Connection: " + sqle
926                     + ExceptionUtility.captureStackTrace(sqle));
927             }
928         }
929
930         return result;
931     }
932
933     /**
934      * Creates a new entry for Group in the database.
935      *
936      * @param connection connection to execute database calls against
937      * @param groupName name of the group add to the database
938      *
939      * @return a new group object in the database
940      *
941      * @throws DuplicateGroupException indicates that a group with the
942      * same name already exists in the database
943      * @throws RuntimeSecurityManagementException indicates an error
944      * communicating with the database
945      */

946     protected Group JavaDoc createGroup(Connection JavaDoc connection, String JavaDoc groupName)
947         throws DuplicateGroupException {
948         PreparedStatement JavaDoc createGroupStatement = null;
949
950         if (log.isTraceEnabled()) {
951             log.trace("Adding group [" + groupName + "]");
952         }
953
954         Group JavaDoc currentGroup = retreiveGroup(connection, groupName);
955
956         if (currentGroup != null) {
957             throw new DuplicateGroupException(
958                 this.getClass(), currentGroup);
959         }
960
961         try {
962             createGroupStatement =
963                 config.getStatementFactory().createPreparedStatement(
964                     config.getCreateGroupQueryName(), connection);
965             createGroupStatement.setString(1, groupName);
966
967             int resultCount = createGroupStatement.executeUpdate();
968
969             if (log.isInfoEnabled()) {
970                 log.info("Added group with name [" + groupName + "]");
971             }
972         } catch (StatementFactoryException sfe) {
973             log.trace("Caught exception: " + sfe
974                 + ExceptionUtility.captureStackTrace(sfe));
975
976             throw new RuntimeSecurityManagementException(
977                 this.getClass(),
978                 "Caught StatementFactoryException while adding "
979                 + "new group.", sfe);
980         } catch (SQLException JavaDoc sqle) {
981             log.trace("Caught exception: " + sqle
982                 + ExceptionUtility.captureStackTrace(sqle));
983
984             throw new RuntimeSecurityManagementException(
985                 this.getClass(), "Caught SQLException while adding "
986                     + "new group.",
987                 sqle);
988         } finally {
989             try {
990                 createGroupStatement.close();
991             } catch (SQLException JavaDoc sqle) {
992                 log.info("Caught exception closing Statement: " + sqle
993                     + ExceptionUtility.captureStackTrace(sqle));
994             }
995         }
996
997         Group JavaDoc newGroup = retreiveGroup(connection, groupName);
998
999         return newGroup;
1000    }
1001
1002    /**
1003     * Removes a group from the database.
1004     *
1005     * @param group group to remove from the database
1006     *
1007     * @throws UnknownGroupException indicates the group does not
1008     * currently exists in the system
1009     * @throws RuntimeSecurityManagementException indicates an error
1010     * communicating with the database
1011     */

1012    public void removeGroup(Group JavaDoc group) throws UnknownGroupException {
1013        Connection JavaDoc connection = null;
1014
1015        try {
1016            connection = config.getConnectionFactory().getConnection();
1017        } catch (SQLException JavaDoc sqle) {
1018            log.trace("Caught exception: " + sqle
1019                + ExceptionUtility.captureStackTrace(sqle));
1020
1021            throw new RuntimeSecurityManagementException(
1022                this.getClass(), "Caught SQLException while opening "
1023                    + "connection",
1024                sqle);
1025        }
1026
1027        try {
1028            removeGroup(connection, group);
1029        } finally {
1030            try {
1031                if (connection != null) {
1032                    connection.close();
1033                }
1034            } catch (SQLException JavaDoc sqle) {
1035                log.info("Caught exception closing Connection: " + sqle
1036                    + ExceptionUtility.captureStackTrace(sqle));
1037            }
1038        }
1039    }
1040
1041    /**
1042     * Removes a group from the database.
1043     *
1044     * @param connection connection to execute database calls against
1045     * @param group group to remove from the database
1046     *
1047     * @throws UnknownGroupException indicates the group does not
1048     * currently exists in the system
1049     * @throws RuntimeSecurityManagementException indicates an error
1050     * communicating with the database
1051     */

1052    protected void removeGroup(Connection JavaDoc connection, Group JavaDoc group)
1053        throws UnknownGroupException {
1054        PreparedStatement JavaDoc removeGroupStatement = null;
1055        Object JavaDoc groupPrimaryKey;
1056
1057        Group JavaDoc currentGroup = retreiveGroup(connection, group.getName());
1058
1059        if (currentGroup == null) {
1060            throw new UnknownGroupException(
1061                this.getClass(), group.getName());
1062        }
1063
1064        try {
1065            groupPrimaryKey =
1066                retreivePrincipalPrimaryKey(connection, group);
1067        } catch (UnknownPrincipalException upe) {
1068            throw new UnknownGroupException(
1069                this.getClass(), group.getName(),
1070                upe);
1071        }
1072
1073        if (log.isTraceEnabled()) {
1074            log.trace("Removing group [" + group.getName() + "]");
1075        }
1076
1077        try {
1078            connection.setAutoCommit(false);
1079
1080            removeAllRelationships(connection, groupPrimaryKey);
1081
1082            removeGroupStatement =
1083                config.getStatementFactory().createPreparedStatement(
1084                    config.getRemoveGroupQueryName(), connection);
1085            removeGroupStatement.setObject(1, groupPrimaryKey);
1086
1087            int resultCount = removeGroupStatement.executeUpdate();
1088
1089            connection.commit();
1090            connection.setAutoCommit(true);
1091
1092            if (log.isInfoEnabled()) {
1093                log.info("Removed group with name [" + group.getName() + "]");
1094            }
1095        } catch (UnknownPrincipalException upe) {
1096            try {
1097                if (connection != null) {
1098                    connection.rollback();
1099                    connection.setAutoCommit(true);
1100                }
1101            } catch (SQLException JavaDoc sqle) {
1102                log.info("Caught exception rolling back transaction: "
1103                    + sqle
1104                    + ExceptionUtility.captureStackTrace(sqle));
1105            }
1106
1107            // This can be thrown from the removeAllRelationships
1108
// statement. Repackage here.
1109
throw new UnknownGroupException(
1110                this.getClass(), group.getName(),
1111                upe);
1112        } catch (StatementFactoryException sfe) {
1113            log.trace("Caught exception: " + sfe
1114                + ExceptionUtility.captureStackTrace(sfe));
1115
1116            try {
1117                if (connection != null) {
1118                    connection.rollback();
1119                    connection.setAutoCommit(true);
1120                }
1121            } catch (SQLException JavaDoc sqle) {
1122                log.info("Caught exception rolling back transaction: "
1123                    + sqle
1124                    + ExceptionUtility.captureStackTrace(sqle));
1125            }
1126
1127            throw new RuntimeSecurityManagementException(
1128                this.getClass(),
1129                "Caught StatementFactoryException while removing "
1130                + "group.", sfe);
1131        } catch (SQLException JavaDoc sqle) {
1132            log.trace("Caught exception: " + sqle
1133                + ExceptionUtility.captureStackTrace(sqle));
1134
1135            try {
1136                if (connection != null) {
1137                    connection.rollback();
1138                    connection.setAutoCommit(true);
1139                }
1140            } catch (SQLException JavaDoc sqle2) {
1141                log.info("Caught exception rolling back transaction: "
1142                    + sqle2
1143                    + ExceptionUtility.captureStackTrace(sqle));
1144            }
1145
1146            throw new RuntimeSecurityManagementException(
1147                this.getClass(), "Caught SQLException while removing "
1148                    + "group.",
1149                sqle);
1150        } finally {
1151            try {
1152                if (removeGroupStatement != null) {
1153                    removeGroupStatement.close();
1154                }
1155            } catch (SQLException JavaDoc sqle) {
1156                log.info("Caught exception closing Statement: " + sqle
1157                    + ExceptionUtility.captureStackTrace(sqle));
1158            }
1159        }
1160    }
1161
1162    /**
1163     * Finds a user with the given name in the database.
1164     *
1165     * @param username the user in the database
1166     *
1167     * @return the principal associated with the username or null if there
1168     * is no user
1169     *
1170     * @throws RuntimeSecurityManagementException indicates an error
1171     * communicating with the database
1172     */

1173    public Principal JavaDoc retreiveUser(String JavaDoc username) {
1174
1175        Principal JavaDoc result = null;
1176        Connection JavaDoc connection = null;
1177
1178        try {
1179            connection = config.getConnectionFactory().getConnection();
1180        } catch (SQLException JavaDoc sqle) {
1181            log.trace("Caught exception: " + sqle
1182                + ExceptionUtility.captureStackTrace(sqle));
1183
1184            throw new RuntimeSecurityManagementException(
1185                this.getClass(), "Caught SQLException while opening "
1186                    + "connection",
1187                sqle);
1188        }
1189
1190        try {
1191            result = retreiveUser(connection, username);
1192        } finally {
1193            try {
1194                if (connection != null) {
1195                    connection.close();
1196                }
1197            } catch (SQLException JavaDoc sqle) {
1198                log.debug("Caught exception closing Connection: " + sqle
1199                    + ExceptionUtility.captureStackTrace(sqle));
1200            }
1201        }
1202
1203        return result;
1204    }
1205
1206    /**
1207     * Finds a user with the given name in the database.
1208     *
1209     * @param connection connection to execute database calls against
1210     * @param username the user in the database
1211     *
1212     * @return the principal associated with the username or null if there
1213     * is no user
1214     *
1215     * @throws RuntimeSecurityManagementException indicates an error
1216     * communicating with the database
1217     */

1218    protected Principal JavaDoc retreiveUser(
1219        Connection JavaDoc connection, String JavaDoc username) {
1220        PreparedStatement JavaDoc retreiveUserStatement = null;
1221        ResultSet JavaDoc retreiveUserResultSet = null;
1222        Principal JavaDoc resultPrincipal;
1223
1224        if (log.isTraceEnabled()) {
1225            log.trace("Searching for user with principal name [" + username
1226                + "]");
1227        }
1228
1229        try {
1230            retreiveUserStatement =
1231                config.getStatementFactory().createPreparedStatement(
1232                    config.getRetreiveUserQueryName(), connection);
1233            retreiveUserStatement.setString(1, username);
1234            retreiveUserResultSet = retreiveUserStatement.executeQuery();
1235
1236            if (retreiveUserResultSet.next()) {
1237                resultPrincipal =
1238                    createUserObject(retreiveUserResultSet.getString(1));
1239            } else {
1240                resultPrincipal = null;
1241            }
1242        } catch (StatementFactoryException sfe) {
1243            log.trace("Caught exception: " + sfe
1244                + ExceptionUtility.captureStackTrace(sfe));
1245
1246            throw new RuntimeSecurityManagementException(
1247                this.getClass(),
1248                "Caught StatementFactoryException while adding "
1249                + "new user.", sfe);
1250        } catch (SQLException JavaDoc sqle) {
1251            log.trace("Caught exception: " + sqle
1252                + ExceptionUtility.captureStackTrace(sqle));
1253
1254            throw new RuntimeSecurityManagementException(
1255                this.getClass(), "Caught SQLException while adding "
1256                    + "new user.",
1257                sqle);
1258        } finally {
1259            try {
1260                if (retreiveUserResultSet != null) {
1261                    retreiveUserResultSet.close();
1262                }
1263            } catch (SQLException JavaDoc sqle) {
1264                log.info("Caught exception closing ResultSet: " + sqle
1265                    + ExceptionUtility.captureStackTrace(sqle));
1266            }
1267
1268            try {
1269                if (retreiveUserStatement != null) {
1270                    retreiveUserStatement.close();
1271                }
1272            } catch (SQLException JavaDoc sqle) {
1273                log.info("Caught exception closing Statement: " + sqle
1274                    + ExceptionUtility.captureStackTrace(sqle));
1275            }
1276        }
1277
1278        return resultPrincipal;
1279    }
1280
1281    /**
1282     * Finds the group with the given name in the database.
1283     *
1284     * @param groupName the name of the group to get from the database
1285     *
1286     * @return the group with the given name or null if the group was not
1287     * in the database
1288     *
1289     * @throws RuntimeSecurityManagementException indicates an error
1290     * communicating with the database
1291     */

1292    public Group JavaDoc retreiveGroup(String JavaDoc groupName) {
1293
1294
1295        Group JavaDoc result = null;
1296        Connection JavaDoc connection = null;
1297
1298        try {
1299            connection = config.getConnectionFactory().getConnection();
1300        } catch (SQLException JavaDoc sqle) {
1301            log.trace("Caught exception: " + sqle
1302                + ExceptionUtility.captureStackTrace(sqle));
1303
1304            throw new RuntimeSecurityManagementException(
1305                this.getClass(), "Caught SQLException while opening "
1306                    + "connection",
1307                sqle);
1308        }
1309
1310        try {
1311            result = retreiveGroup(connection, groupName);
1312        } finally {
1313            try {
1314                if (connection != null) {
1315                    connection.close();
1316                }
1317            } catch (SQLException JavaDoc sqle) {
1318                log.info("Caught exception closing Connection: " + sqle
1319                    + ExceptionUtility.captureStackTrace(sqle));
1320            }
1321        }
1322
1323        return result;
1324    }
1325
1326    /**
1327     * Finds the group with the given name in the database.
1328     *
1329     * @param connection connection to execute database calls against
1330     * @param groupName the name of the group to get from the database
1331     *
1332     * @return the group with the given name or null if the group was not
1333     * in the database
1334     *
1335     * @throws RuntimeSecurityManagementException indicates an error
1336     * communicating with the database
1337     */

1338    protected Group JavaDoc retreiveGroup(Connection JavaDoc connection, String JavaDoc groupName) {
1339
1340        PreparedStatement JavaDoc retreiveGroupStatement = null;
1341        ResultSet JavaDoc retreiveGroupResultSet = null;
1342        Group JavaDoc resultGroup;
1343
1344        if (log.isTraceEnabled()) {
1345            log.trace("Searching for group with name [" + groupName + "]");
1346        }
1347
1348        try {
1349            retreiveGroupStatement =
1350                config.getStatementFactory().createPreparedStatement(
1351                    config.getRetreiveGroupQueryName(), connection);
1352            retreiveGroupStatement.setString(1, groupName);
1353            retreiveGroupResultSet = retreiveGroupStatement.executeQuery();
1354
1355            if (retreiveGroupResultSet.next()) {
1356                String JavaDoc resultGroupName =
1357                    retreiveGroupResultSet.getString(1);
1358                resultGroup = createGroupObject(resultGroupName, null);
1359
1360                if (resultGroup instanceof LazyLoadGroup) {
1361                    retreiveMembers(
1362                        connection, (LazyLoadGroup) resultGroup, null);
1363                } else {
1364                    // TODO: Create a more basic loading of 1-level deep
1365
if (log.isDebugEnabled()) {
1366                        log.debug("Group returned is not expected class ["
1367                            + LazyLoadGroup.class.getName()
1368                            + "] but is actually " + "instance of ["
1369                            + resultGroup.getClass().getName()
1370                            + "] and therefore members will not be loaded.");
1371                    }
1372                }
1373
1374                if (log.isTraceEnabled()) {
1375                    log.trace("Found group with name [" + groupName + "]");
1376                }
1377            } else {
1378                resultGroup = null;
1379
1380                if (log.isTraceEnabled()) {
1381                    log.trace(
1382                        "Did not find group with name [" + groupName + "]");
1383                }
1384            }
1385        } catch (StatementFactoryException sfe) {
1386            log.trace("Caught exception: " + sfe
1387                + ExceptionUtility.captureStackTrace(sfe));
1388
1389            throw new RuntimeSecurityManagementException(
1390                this.getClass(),
1391                "Caught StatementFactoryException while finding "
1392                + "group.", sfe);
1393        } catch (SQLException JavaDoc sqle) {
1394            log.trace("Caught exception: " + sqle
1395                + ExceptionUtility.captureStackTrace(sqle));
1396
1397            throw new RuntimeSecurityManagementException(
1398                this.getClass(), "Caught SQLException while finding "
1399                    + "group.",
1400                sqle);
1401        } finally {
1402            try {
1403                if (retreiveGroupResultSet != null) {
1404                    retreiveGroupResultSet.close();
1405                }
1406            } catch (SQLException JavaDoc sqle) {
1407                log.info("Caught exception closing ResultSet: " + sqle
1408                    + ExceptionUtility.captureStackTrace(sqle));
1409            }
1410
1411            try {
1412                if (retreiveGroupStatement != null) {
1413                    retreiveGroupStatement.close();
1414                }
1415            } catch (SQLException JavaDoc sqle) {
1416                log.info("Caught exception closing Statement: " + sqle
1417                    + ExceptionUtility.captureStackTrace(sqle));
1418            }
1419        }
1420
1421        return resultGroup;
1422    }
1423
1424    /**
1425     * Retreives the groups contain this particular principal.
1426     *
1427     * <p>
1428     * Only the first level into the group heirachy is queried.
1429     * </p>
1430     *
1431     * @param principal principal to retrieve the groups for
1432     *
1433     * @return groups which the principals is a direct member of
1434     *
1435     * @throws UnknownPrincipalException indicates the user does not exist
1436     * in the datastore
1437     * @throws RuntimeSecurityManagementException indicates an error
1438     * communicating with the database or inconsistent state.
1439     */

1440    public Set JavaDoc retreiveGroups(Principal JavaDoc principal)
1441        throws UnknownPrincipalException {
1442
1443        Set JavaDoc result = null;
1444        Connection JavaDoc connection = null;
1445
1446        try {
1447            connection = config.getConnectionFactory().getConnection();
1448        } catch (SQLException JavaDoc sqle) {
1449            log.trace("Caught exception: " + sqle
1450                + ExceptionUtility.captureStackTrace(sqle));
1451
1452            throw new RuntimeSecurityManagementException(
1453                this.getClass(), "Caught SQLException while opening "
1454                    + "connection",
1455                sqle);
1456        }
1457
1458        try {
1459            result = retreiveGroups(connection, principal);
1460        } finally {
1461            try {
1462                if (connection != null) {
1463                    connection.close();
1464                }
1465            } catch (SQLException JavaDoc sqle) {
1466                log.info("Caught exception closing Connection: " + sqle
1467                    + ExceptionUtility.captureStackTrace(sqle));
1468            }
1469        }
1470
1471        return result;
1472    }
1473
1474    /**
1475     * Retreives the groups contain this particular principal.
1476     *
1477     * <p>
1478     * Only the first level into the group heirachy is queried.
1479     * </p>
1480     *
1481     * @param connection connection to execute database calls against
1482     * @param principal principal to retrieve the groups for
1483     *
1484     * @return groups which the principals is a direct member of
1485     *
1486     * @throws UnknownPrincipalException indicates the user does not exist
1487     * in the datastore
1488     * @throws RuntimeSecurityManagementException indicates an error
1489     * communicating with the database or inconsistent state.
1490     */

1491    protected Set JavaDoc retreiveGroups(
1492        Connection JavaDoc connection, Principal JavaDoc principal)
1493        throws UnknownPrincipalException {
1494
1495        String JavaDoc queryname;
1496        Set JavaDoc membershipSet = new HashSet JavaDoc();
1497        PreparedStatement JavaDoc retreiveMembershipStatement = null;
1498        ResultSet JavaDoc retreiveMembershipResultSet = null;
1499
1500        if (principal instanceof Group JavaDoc) {
1501            Principal JavaDoc currentGroup =
1502                retreiveGroup(connection, principal.getName());
1503
1504            if (currentGroup == null) {
1505                throw new UnknownPrincipalException(
1506                    this.getClass(), principal);
1507            }
1508
1509            if (log.isTraceEnabled()) {
1510                log.trace("Get membership of group with name ["
1511                    + principal.getName() + "]");
1512            }
1513
1514            queryname = config.getRetreiveGroupsForGroupsQueryName();
1515        } else {
1516            Principal JavaDoc currentUser =
1517                retreiveUser(connection, principal.getName());
1518
1519            if (currentUser == null) {
1520                throw new UnknownPrincipalException(
1521                    this.getClass(), principal);
1522            }
1523
1524            if (log.isTraceEnabled()) {
1525                log.trace("Get membership of user with name ["
1526                    + principal.getName() + "]");
1527            }
1528
1529            queryname = config.getRetreiveGroupsForUserQueryName();
1530        }
1531
1532        try {
1533            retreiveMembershipStatement =
1534                config.getStatementFactory().createPreparedStatement(
1535                    queryname, connection);
1536            retreiveMembershipStatement.setString(1, principal.getName());
1537            retreiveMembershipResultSet =
1538                retreiveMembershipStatement.executeQuery();
1539
1540            while (retreiveMembershipResultSet.next()) {
1541                Group JavaDoc containingGroup =
1542                    retreiveGroup(
1543                        connection,
1544                        retreiveMembershipResultSet.getString(1));
1545
1546                if (log.isTraceEnabled()) {
1547                    log.trace("Adding membership group with name ["
1548                        + containingGroup.getName()
1549                        + "] to principals with name ["
1550                        + principal.getName() + "]");
1551                }
1552
1553                membershipSet.add(containingGroup);
1554            }
1555        } catch (StatementFactoryException sfe) {
1556            log.trace("Caught exception: " + sfe
1557                + ExceptionUtility.captureStackTrace(sfe));
1558
1559            throw new RuntimeSecurityManagementException(
1560                this.getClass(),
1561                "Caught StatementFactoryException while getting groups "
1562                + "for principal [" + principal.getName() + "]", sfe);
1563        } catch (SQLException JavaDoc sqle) {
1564            log.trace("Caught exception: " + sqle
1565                + ExceptionUtility.captureStackTrace(sqle));
1566
1567            throw new RuntimeSecurityManagementException(
1568                this.getClass(),
1569                "Caught SQLException while getting roups "
1570                + "for principal [" + principal.getName() + "]", sqle);
1571        } finally {
1572            try {
1573                if (retreiveMembershipResultSet != null) {
1574                    retreiveMembershipResultSet.close();
1575                }
1576            } catch (SQLException JavaDoc sqle) {
1577                log.info("Caught exception closing ResultSet: " + sqle
1578                    + ExceptionUtility.captureStackTrace(sqle));
1579            }
1580
1581            try {
1582                if (retreiveMembershipStatement != null) {
1583                    retreiveMembershipStatement.close();
1584                }
1585            } catch (SQLException JavaDoc sqle) {
1586                log.info("Caught exception closing Statement: " + sqle
1587                    + ExceptionUtility.captureStackTrace(sqle));
1588            }
1589        }
1590
1591        return membershipSet;
1592    }
1593
1594    /**
1595     * Retrieves all the members of the given group.
1596     *
1597     * <p>
1598     * This will recursively load all members of the given group loading
1599     * all groups under it.
1600     * </p>
1601     *
1602     * @param connection connection to execute database calls against
1603     * @param group group to get all members of
1604     * @param loadedGroups map of groups that are already loaded
1605     *
1606     * @throws RuntimeSecurityManagementException indicates an error
1607     * communicating with the database
1608     */

1609    protected void retreiveMembers(
1610        Connection JavaDoc connection, LazyLoadGroup group, Map JavaDoc loadedGroups) {
1611
1612        if (loadedGroups == null) {
1613            loadedGroups = new HashMap JavaDoc();
1614
1615            if (log.isTraceEnabled()) {
1616                log.trace("Retreiving members for top-level group named ["
1617                    + group.getName() + "]");
1618            }
1619        }
1620
1621        Set JavaDoc members = new HashSet JavaDoc();
1622
1623        PreparedStatement JavaDoc retreiveMembersStatement = null;
1624        ResultSet JavaDoc retreiveMembersResultSet = null;
1625
1626        try {
1627            retreiveMembersStatement =
1628                config.getStatementFactory().createPreparedStatement(
1629                    config.getRetreiveMemebersQueryName(), connection);
1630
1631            retreiveMembersStatement.setString(1, group.getName());
1632            retreiveMembersResultSet =
1633                retreiveMembersStatement.executeQuery();
1634
1635            while (retreiveMembersResultSet.next()) {
1636                members.add(
1637                    retreiveMember(retreiveMembersResultSet, loadedGroups));
1638            }
1639
1640            group.setMembers(members);
1641
1642            if (log.isTraceEnabled()) {
1643                log.trace("Added members to group named [" + group.getName()
1644                    + "] with total of [" + members.size()
1645                    + "] principals");
1646            }
1647        } catch (StatementFactoryException sfe) {
1648            log.trace("Caught exception: " + sfe
1649                + ExceptionUtility.captureStackTrace(sfe));
1650
1651            throw new RuntimeSecurityManagementException(
1652                this.getClass(),
1653                "Caught StatementFactoryException while adding "
1654                + "new user.", sfe);
1655        } catch (SQLException JavaDoc sqle) {
1656            log.trace("Caught exception: " + sqle
1657                + ExceptionUtility.captureStackTrace(sqle));
1658
1659            throw new RuntimeSecurityManagementException(
1660                this.getClass(), "Caught SQLException while adding "
1661                    + "new user.",
1662                sqle);
1663        } finally {
1664            try {
1665                retreiveMembersResultSet.close();
1666            } catch (SQLException JavaDoc sqle) {
1667                log.info("Caught exception closing ResultSet: " + sqle
1668                    + ExceptionUtility.captureStackTrace(sqle));
1669            }
1670
1671            try {
1672                retreiveMembersStatement.close();
1673            } catch (SQLException JavaDoc sqle) {
1674                log.info("Caught exception closing Statement: " + sqle
1675                    + ExceptionUtility.captureStackTrace(sqle));
1676            }
1677        }
1678
1679        // If the group object was constructed using the
1680
// LazyLoadGroup it is possible to load all
1681
// of the subgroups without errors.
1682
Iterator JavaDoc membersIterator = members.iterator();
1683
1684        while (membersIterator.hasNext()) {
1685            Object JavaDoc currentMember = membersIterator.next();
1686
1687            if (currentMember instanceof LazyLoadGroup) {
1688                LazyLoadGroup currentGroup = (LazyLoadGroup) currentMember;
1689
1690                if (currentGroup.isLoaded()) {
1691                    if (log.isTraceEnabled()) {
1692                        log.trace("In group named [" + group.getName()
1693                            + "] found loaded sub-group named ["
1694                            + currentGroup.getName() + "]");
1695                    }
1696                } else {
1697                    if (log.isTraceEnabled()) {
1698                        log.trace("In group named [" + group.getName()
1699                            + "] found UNLOADED sub-group named ["
1700                            + currentGroup.getName() + "]");
1701                    }
1702
1703                    retreiveMembers(
1704                        connection, currentGroup, loadedGroups);
1705                }
1706            }
1707        }
1708    }
1709
1710    /**
1711     * Method to create a new User object implementing the principal
1712     * interface. This method is meant to be overridden by a subclass
1713     * that needs to implement its own version.
1714     *
1715     * @param username name of the user to create an object for
1716     *
1717     * @return a new user object
1718     */

1719    protected Principal JavaDoc createUserObject(String JavaDoc username) {
1720        return new DefaultUserImpl(username);
1721    }
1722
1723    /**
1724     * Method to create a new Group object implementing the Group
1725     * interface. This method is meant to be overridden by a subclass
1726     * that needs to implement its own version.
1727     *
1728     * @param groupName name of the group to create an object for
1729     * @param members a set of members for this group
1730     *
1731     * @return a new group object
1732     */

1733    protected Group JavaDoc createGroupObject(String JavaDoc groupName, Set JavaDoc members) {
1734        return new DefaultGroupImpl(
1735            groupName, members, config.getConfigurationName());
1736    }
1737
1738    /**
1739     * Retreives a member from a given result.
1740     *
1741     * <p>
1742     * A map of groupname to already loaded groups is passed in as well.
1743     * This allows the method to either return a currently loaded group
1744     * if it exists. Otherwise it will create a new group with a call to
1745     * <code>createGroupObject</code>. It is possible to change the
1746     * group object returned by subclassing this implementation and
1747     * overriding that method.
1748     * </p>
1749     *
1750     * @param memberResultSet ResultSet to get the next user from. This
1751     * method expects the first column to be the name of the user.
1752     * The second column is the type of user identified by the
1753     * <code>PrincipalTypeEnum</code> object.
1754     * @param loadedGroups Map of already loaded groups. The key is the
1755     * name of the group. If the current row of the ResultSet
1756     * returns a group in this map, the already loaded group will
1757     * be returned instead of constructing a new one.
1758     *
1759     * @return a principal contained in the current row of the ResultSet
1760     *
1761     * @throws RuntimeSecurityManagementException indicates an error
1762     * communicating with the database
1763     */

1764    protected Principal JavaDoc retreiveMember(
1765        ResultSet JavaDoc memberResultSet, Map JavaDoc loadedGroups) {
1766
1767        Principal JavaDoc resultPrincipal = null;
1768
1769        try {
1770            String JavaDoc principalName = memberResultSet.getString(1);
1771            PrincipalTypeEnum principalTypeEnum =
1772                PrincipalTypeEnum.getByOrdinal(memberResultSet.getInt(2));
1773
1774            if (log.isTraceEnabled()) {
1775                log.trace("Instantiating new principal named ["
1776                    + principalName
1777                    + "] of enumeration type ["
1778                    + principalTypeEnum
1779                    + "]");
1780            }
1781
1782            if (principalTypeEnum.equals(PrincipalTypeEnum.USER)) {
1783                resultPrincipal = createUserObject(principalName);
1784            } else if (principalTypeEnum.equals(PrincipalTypeEnum.GROUP)) {
1785                if (loadedGroups.containsKey(principalName)) {
1786                    resultPrincipal =
1787                        (Principal JavaDoc) loadedGroups.get(principalName);
1788                } else {
1789                    resultPrincipal =
1790                        createGroupObject(principalName, null);
1791
1792                    loadedGroups.put(principalName, resultPrincipal);
1793                }
1794            }
1795        } catch (PrincipalTypeEnum.PrincipalTypeEnumNotFoundException ptenfe) {
1796            log.trace("Caught exception: " + ptenfe
1797                + ExceptionUtility.captureStackTrace(ptenfe));
1798
1799            throw new RuntimeSecurityManagementException(
1800                this.getClass(), "Invalid principal type encountered.", ptenfe);
1801        } catch (SQLException JavaDoc sqle) {
1802            log.trace("Caught exception: " + sqle
1803                + ExceptionUtility.captureStackTrace(sqle));
1804
1805            throw new RuntimeSecurityManagementException(
1806                this.getClass(), "Caught SQLException while adding "
1807                    + "new user.",
1808                sqle);
1809        }
1810
1811        return resultPrincipal;
1812    }
1813
1814    /**
1815     * Adds a principal (user or group) into the given group.
1816     *
1817     * @param principal the principal to add into the group
1818     * @param group the group to add a principal to
1819     *
1820     * @return if the database was altered by this call
1821     *
1822     * @throws UnknownPrincipalException indicates the principal does not
1823     * currently exists in the system
1824     * @throws UnknownGroupException indicates the group does not
1825     * currently exists in the system
1826     * @throws RuntimeSecurityManagementException indicates an error
1827     * communicating with the database
1828     */

1829    public boolean addPrincipalToGroup(Principal JavaDoc principal, Group JavaDoc group)
1830        throws UnknownPrincipalException, UnknownGroupException {
1831
1832        boolean isPrincipalAdded = false;
1833        Connection JavaDoc connection = null;
1834
1835        try {
1836            connection = config.getConnectionFactory().getConnection();
1837        } catch (SQLException JavaDoc sqle) {
1838            log.trace("Caught exception: " + sqle
1839                + ExceptionUtility.captureStackTrace(sqle));
1840
1841            throw new RuntimeSecurityManagementException(
1842                this.getClass(), "Caught SQLException while opening connection",
1843                sqle);
1844        }
1845
1846        try {
1847            isPrincipalAdded =
1848                addPrincipalToGroup(connection, principal, group);
1849        } finally {
1850            try {
1851                if (connection != null) {
1852                    connection.close();
1853                }
1854            } catch (SQLException JavaDoc sqle) {
1855                log.info("Caught exception closing Connection: " + sqle
1856                    + ExceptionUtility.captureStackTrace(sqle));
1857            }
1858        }
1859
1860        return isPrincipalAdded;
1861    }
1862
1863    /**
1864     * Adds a principal (user or group) into the given group.
1865     *
1866     * @param connection connection to execute database calls against
1867     * @param principal the principal to add into the group
1868     * @param group the group to add a principal to
1869     *
1870     * @return if the database was altered by this call
1871     *
1872     * @throws UnknownPrincipalException indicates the principal does not
1873     * currently exists in the system
1874     * @throws UnknownGroupException indicates the group does not
1875     * currently exists in the system
1876     * @throws RuntimeSecurityManagementException indicates an error
1877     * communicating with the database
1878     */

1879    protected boolean addPrincipalToGroup(
1880        Connection JavaDoc connection, Principal JavaDoc principal, Group JavaDoc group)
1881        throws UnknownPrincipalException, UnknownGroupException {
1882        PreparedStatement JavaDoc addPrincipalToGroupStatement = null;
1883        boolean result = false;
1884
1885        if (log.isTraceEnabled()) {
1886            log.trace("Adding principal [" + principal.getName()
1887                + "] to group [" + group.getName() + "]");
1888        }
1889
1890        Object JavaDoc principalPrimaryKey =
1891            retreivePrincipalPrimaryKey(connection, principal);
1892        Object JavaDoc groupPrimaryKey =
1893            retreivePrincipalPrimaryKey(connection, group);
1894
1895        if (group.isMember(principal)) {
1896            if (log.isTraceEnabled()) {
1897                log.trace("User [" + principal
1898                    + "] is already a member of group [" + group + "]");
1899            }
1900
1901            result = false;
1902        } else {
1903            try {
1904                addPrincipalToGroupStatement =
1905                    config.getStatementFactory().createPreparedStatement(
1906                        config.getAddPrincipalToGroupQueryName(),
1907                        connection);
1908
1909                addPrincipalToGroupStatement.setObject(
1910                    1, principalPrimaryKey);
1911                addPrincipalToGroupStatement.setObject(2, groupPrimaryKey);
1912
1913                int resultCount =
1914                    addPrincipalToGroupStatement.executeUpdate();
1915
1916                if (resultCount > 0) {
1917                    result = true;
1918
1919                    if (log.isDebugEnabled()) {
1920                        log.debug("Added principal [" + principal.getName()
1921                            + "] to group [" + group.getName() + "]");
1922                    }
1923                }
1924            } catch (StatementFactoryException sfe) {
1925                log.trace("Caught exception: " + sfe
1926                    + ExceptionUtility.captureStackTrace(sfe));
1927
1928                throw new RuntimeSecurityManagementException(
1929                    this.getClass(),
1930                    "Caught StatementFactoryException while adding "
1931                    + "new user.", sfe);
1932            } catch (SQLException JavaDoc sqle) {
1933                log.trace("Caught exception: " + sqle
1934                    + ExceptionUtility.captureStackTrace(sqle));
1935
1936                throw new RuntimeSecurityManagementException(
1937                    this.getClass(),
1938                    "Caught SQLException while adding " + "new user.", sqle);
1939            } finally {
1940                try {
1941                    if (addPrincipalToGroupStatement != null) {
1942                        addPrincipalToGroupStatement.close();
1943                    }
1944                } catch (SQLException JavaDoc sqle) {
1945                    log.info("Caught exception closing Statement: " + sqle
1946                        + ExceptionUtility.captureStackTrace(sqle));
1947                }
1948            }
1949        }
1950
1951        return result;
1952    }
1953
1954    /**
1955     * Removes the principal (user or group) from the given group.
1956     *
1957     * @param principal the principal (user or group) to remove from the
1958     * given group
1959     * @param group the group to remove the principal from
1960     *
1961     * @return if the database changed as a result of the call
1962     *
1963     * @throws UnknownPrincipalException indicates the principal does not
1964     * currently exists in the system
1965     * @throws UnknownGroupException indicates the group does not
1966     * currently exists in the system
1967     * @throws RuntimeSecurityManagementException indicates an error
1968     * communicating with the database
1969     */

1970    public boolean removePrincipalFromGroup(
1971        Principal JavaDoc principal, Group JavaDoc group)
1972        throws UnknownPrincipalException, UnknownGroupException {
1973        Connection JavaDoc connection = null;
1974        boolean isRemoved = false;
1975
1976        try {
1977            connection = config.getConnectionFactory().getConnection();
1978        } catch (SQLException JavaDoc sqle) {
1979            log.trace("Caught exception: " + sqle
1980                + ExceptionUtility.captureStackTrace(sqle));
1981
1982            throw new RuntimeSecurityManagementException(
1983                this.getClass(), "Caught SQLException while opening connection",
1984                sqle);
1985        }
1986
1987        try {
1988            isRemoved =
1989                removePrincipalFromGroup(connection, principal, group);
1990        } finally {
1991            try {
1992                if (connection != null) {
1993                    connection.close();
1994                }
1995            } catch (SQLException JavaDoc sqle) {
1996                log.info("Caught exception closing Connection: " + sqle
1997                    + ExceptionUtility.captureStackTrace(sqle));
1998            }
1999        }
2000
2001        return isRemoved;
2002    }
2003
2004    /**
2005     * Removes the principal (user or group) from the given group.
2006     *
2007     * @param connection connection to execute database calls against
2008     * @param principal the principal (user or group) to remove from the
2009     * given group
2010     * @param group the group to remove the principal from
2011     *
2012     * @return if the database changed as a result of the call
2013     *
2014     * @throws UnknownPrincipalException indicates the principal does not
2015     * currently exists in the system
2016     * @throws UnknownGroupException indicates the group does not
2017     * currently exists in the system
2018     * @throws RuntimeSecurityManagementException indicates an error
2019     * communicating with the database
2020     */

2021    protected boolean removePrincipalFromGroup(
2022        Connection JavaDoc connection, Principal JavaDoc principal, Group JavaDoc group)
2023        throws UnknownPrincipalException, UnknownGroupException {
2024        PreparedStatement JavaDoc removePrincipalFromGroupStatement = null;
2025        boolean result = false;
2026
2027        if (log.isTraceEnabled()) {
2028            log.trace("Removing principal [" + principal.getName()
2029                + "] from group [" + group.getName() + "]");
2030        }
2031
2032        Object JavaDoc principalPrimaryKey =
2033            retreivePrincipalPrimaryKey(connection, principal);
2034        Object JavaDoc groupPrimaryKey =
2035            retreivePrincipalPrimaryKey(connection, group);
2036
2037        if (!group.isMember(principal)) {
2038            result = false;
2039
2040            if (log.isTraceEnabled()) {
2041                log.trace("User [" + principal
2042                    + "] is already not a member of group [" + group + "]");
2043            }
2044        } else {
2045            try {
2046                removePrincipalFromGroupStatement =
2047                    config.getStatementFactory().createPreparedStatement(
2048                        config.getRemovePrincipalFromGroupQueryName(),
2049                        connection);
2050
2051                removePrincipalFromGroupStatement.setObject(
2052                    1, principalPrimaryKey);
2053                removePrincipalFromGroupStatement.setObject(
2054                    2, groupPrimaryKey);
2055
2056                int resultCount =
2057                    removePrincipalFromGroupStatement.executeUpdate();
2058
2059                if (resultCount > 0) {
2060                    result = true;
2061
2062                    if (log.isDebugEnabled()) {
2063                        log.debug("Removed principal [" + principal.getName()
2064                            + "] from group [" + group.getName() + "]");
2065                    }
2066                }
2067            } catch (StatementFactoryException sfe) {
2068                log.trace("Caught exception: " + sfe
2069                    + ExceptionUtility.captureStackTrace(sfe));
2070
2071                throw new RuntimeSecurityManagementException(
2072                    this.getClass(),
2073                    "Caught StatementFactoryException while removing "
2074                    + "user.", sfe);
2075            } catch (SQLException JavaDoc sqle) {
2076                log.trace("Caught exception: " + sqle
2077                    + ExceptionUtility.captureStackTrace(sqle));
2078
2079                throw new RuntimeSecurityManagementException(
2080                    this.getClass(), "Caught SQLException while removing "
2081                    + "user.", sqle);
2082            } finally {
2083                try {
2084                    removePrincipalFromGroupStatement.close();
2085                } catch (SQLException JavaDoc sqle) {
2086                    log.info("Caught exception closing Statement: " + sqle
2087                        + ExceptionUtility.captureStackTrace(sqle));
2088                }
2089            }
2090        }
2091
2092        return result;
2093    }
2094
2095    /**
2096     * Retreives all unique names of users from the store as a Set of
2097     * Strings.
2098     *
2099     * @return All unique user names as a Set of Strings. If there are no
2100     * users in the system and empty Set will be returned.
2101     *
2102     * @throws RuntimeSecurityManagementException indicates an error
2103     * communicating with the database or inconsistent state.
2104     */

2105    public Set JavaDoc retreiveAllUserNames() {
2106
2107        Connection JavaDoc connection = null;
2108        Set JavaDoc allUsers = null;
2109
2110        try {
2111            connection = config.getConnectionFactory().getConnection();
2112        } catch (SQLException JavaDoc sqle) {
2113            log.trace("Caught exception: " + sqle
2114                + ExceptionUtility.captureStackTrace(sqle));
2115
2116            throw new RuntimeSecurityManagementException(
2117                this.getClass(), "Caught SQLException while opening connection",
2118                sqle);
2119        }
2120
2121        try {
2122            allUsers = retreiveAllusernames(connection);
2123        } finally {
2124            try {
2125                if (connection != null) {
2126                    connection.close();
2127                }
2128            } catch (SQLException JavaDoc sqle) {
2129                log.info("Caught exception closing Connection: " + sqle
2130                    + ExceptionUtility.captureStackTrace(sqle));
2131            }
2132        }
2133
2134        return allUsers;
2135    }
2136
2137    /**
2138     * Retreives all unique names of users from the store as a Set of
2139     * Strings.
2140     *
2141     * @param connection connection to execute database calls against
2142     *
2143     * @return All unique user names as a Set of Strings. If there are no
2144     * users in the system and empty Set will be returned.
2145     *
2146     * @throws RuntimeSecurityManagementException indicates an error
2147     * communicating with the database or inconsistent state.
2148     */

2149    protected Set JavaDoc retreiveAllusernames(Connection JavaDoc connection) {
2150        Set JavaDoc allUsers = new HashSet JavaDoc();
2151        PreparedStatement JavaDoc retreiveAllUsersStatement = null;
2152        ResultSet JavaDoc retreiveAllUsersResultSet = null;
2153
2154        if (log.isTraceEnabled()) {
2155            log.trace("Searching for all users.");
2156        }
2157
2158        try {
2159            retreiveAllUsersStatement =
2160                config.getStatementFactory().createPreparedStatement(
2161                    config.getRetreiveAllUsersQuery(), connection);
2162
2163            retreiveAllUsersResultSet =
2164                retreiveAllUsersStatement.executeQuery();
2165
2166            while (retreiveAllUsersResultSet.next()) {
2167                allUsers.add(retreiveAllUsersResultSet.getString(1));
2168            }
2169        } catch (StatementFactoryException sfe) {
2170            log.trace("Caught exception: " + sfe
2171                + ExceptionUtility.captureStackTrace(sfe));
2172
2173            throw new RuntimeSecurityManagementException(
2174                this.getClass(),
2175                "Caught StatementFactoryException while retreiving "
2176                + "users.", sfe);
2177        } catch (SQLException JavaDoc sqle) {
2178            log.trace("Caught exception: " + sqle
2179                + ExceptionUtility.captureStackTrace(sqle));
2180
2181            throw new RuntimeSecurityManagementException(
2182                this.getClass(),
2183                "Caught SQLException while retreiving users.",
2184                sqle);
2185        } finally {
2186            try {
2187                if (retreiveAllUsersResultSet != null) {
2188                    retreiveAllUsersResultSet.close();
2189                }
2190            } catch (SQLException JavaDoc sqle) {
2191                log.info("Caught exception closing ResultSet: " + sqle
2192                    + ExceptionUtility.captureStackTrace(sqle));
2193            }
2194
2195            try {
2196                if (retreiveAllUsersStatement != null) {
2197                    retreiveAllUsersStatement.close();
2198                }
2199            } catch (SQLException JavaDoc sqle) {
2200                log.info("Caught exception closing Statement: " + sqle
2201                    + ExceptionUtility.captureStackTrace(sqle));
2202            }
2203        }
2204
2205        return allUsers;
2206    }
2207
2208    /**
2209     * Retreives all unique names of groups from the store as a Set of
2210     * Strings.
2211     *
2212     * @return All unique group names as a Set of Strings. If there are
2213     * no group in the system and empty Set will be returned.
2214     *
2215     * @throws RuntimeSecurityManagementException indicates an error
2216     * communicating with the database or inconsistent state.
2217     */

2218    public Set JavaDoc retreiveAllGroupNames() {
2219
2220        Connection JavaDoc connection = null;
2221        Set JavaDoc allGroups = null;
2222
2223        try {
2224            connection = config.getConnectionFactory().getConnection();
2225        } catch (SQLException JavaDoc sqle) {
2226            log.trace("Caught exception: " + sqle
2227                + ExceptionUtility.captureStackTrace(sqle));
2228
2229            throw new RuntimeSecurityManagementException(
2230                this.getClass(), "Caught SQLException while opening connection",
2231                sqle);
2232        }
2233
2234        try {
2235            allGroups = retreiveAllGroupNames(connection);
2236        } finally {
2237            try {
2238                if (connection != null) {
2239                    connection.close();
2240                }
2241            } catch (SQLException JavaDoc sqle) {
2242                log.info("Caught exception closing Connection: " + sqle
2243                    + ExceptionUtility.captureStackTrace(sqle));
2244            }
2245        }
2246
2247        return allGroups;
2248    }
2249
2250    /**
2251     * Retreives all unique names of groups from the store as a Set of
2252     * Strings.
2253     *
2254     * @param connection connection to execute database calls against
2255     *
2256     * @return All unique group names as a Set of Strings. If there are
2257     * no group in the system and empty Set will be returned.
2258     *
2259     * @throws RuntimeSecurityManagementException indicates an error
2260     * communicating with the database or inconsistent state.
2261     */

2262    protected Set JavaDoc retreiveAllGroupNames(Connection JavaDoc connection) {
2263        Set JavaDoc allGroups = new HashSet JavaDoc();
2264        PreparedStatement JavaDoc retreiveAllGroupsStatement = null;
2265        ResultSet JavaDoc retreiveAllGroupsResultSet = null;
2266
2267        if (log.isTraceEnabled()) {
2268            log.trace("Searching for all users.");
2269        }
2270
2271        try {
2272            retreiveAllGroupsStatement =
2273                config.getStatementFactory().createPreparedStatement(
2274                    config.getRetreiveAllGroupsQuery(), connection);
2275
2276            retreiveAllGroupsResultSet =
2277                retreiveAllGroupsStatement.executeQuery();
2278
2279            while (retreiveAllGroupsResultSet.next()) {
2280                allGroups.add(retreiveAllGroupsResultSet.getString(1));
2281            }
2282        } catch (StatementFactoryException sfe) {
2283            log.trace("Caught exception: " + sfe
2284                + ExceptionUtility.captureStackTrace(sfe));
2285
2286            throw new RuntimeSecurityManagementException(
2287                this.getClass(),
2288                "Caught StatementFactoryException while retreiving "
2289                + "groups.", sfe);
2290        } catch (SQLException JavaDoc sqle) {
2291            log.trace("Caught exception: " + sqle
2292                + ExceptionUtility.captureStackTrace(sqle));
2293
2294            throw new RuntimeSecurityManagementException(
2295                this.getClass(), "Caught SQLException while retreiving groups.",
2296                sqle);
2297        } finally {
2298            try {
2299                if (retreiveAllGroupsResultSet != null) {
2300                    retreiveAllGroupsResultSet.close();
2301                }
2302            } catch (SQLException JavaDoc sqle) {
2303                log.info("Caught exception closing ResultSet: " + sqle
2304                    + ExceptionUtility.captureStackTrace(sqle));
2305            }
2306
2307            try {
2308                if (retreiveAllGroupsStatement != null) {
2309                    retreiveAllGroupsStatement.close();
2310                }
2311            } catch (SQLException JavaDoc sqle) {
2312                log.info("Caught exception closing Statement: " + sqle
2313                    + ExceptionUtility.captureStackTrace(sqle));
2314            }
2315        }
2316
2317        return allGroups;
2318    }
2319
2320    /**
2321     * Gets back the primary key in the database for a given principal.
2322     *
2323     * <p>
2324     * This may execute a query to retreive it, or if the information is
2325     * contained within the Principal object it may return it from there.
2326     * </p>
2327     *
2328     * @param connection connection to execute database calls against
2329     * @param principal the principal to get the primary key for.
2330     *
2331     * @return primary key for the user. This may be a String, Integer,
2332     * etc.
2333     *
2334     * @throws UnknownPrincipalException indicates the principal does not
2335     * currently exists in the system
2336     * @throws UnknownGroupException indicates the group does not
2337     * currently exists in the system
2338     *
2339     * @see #retreiveUserPrimaryKey
2340     * @see #retreiveGroupPrimaryKey
2341     */

2342    protected Object JavaDoc retreivePrincipalPrimaryKey(
2343        Connection JavaDoc connection, Principal JavaDoc principal)
2344        throws UnknownPrincipalException, UnknownGroupException {
2345        Object JavaDoc primaryKey;
2346
2347        if (principal instanceof Group JavaDoc) {
2348            primaryKey =
2349                retreiveGroupPrimaryKey(connection, (Group JavaDoc) principal);
2350        } else {
2351            primaryKey = retreiveUserPrimaryKey(connection, principal);
2352        }
2353
2354        return primaryKey;
2355    }
2356
2357    /**
2358     * Gets back the primary key in the database for a given user.
2359     *
2360     * <p>
2361     * This may execute a query to retreive it, or if the information is
2362     * contained within the Principal object it may return it from there.
2363     * </p>
2364     *
2365     * @param connection connection to execute database calls against
2366     * @param principal the principal to get the primary key for.
2367     *
2368     * @return primary key for the user. This may be a String, Integer,
2369     * etc.
2370     *
2371     * @throws UnknownPrincipalException indicates the principal does not
2372     * currently exists in the system
2373     * @throws RuntimeSecurityManagementException indicates an error
2374     * communicating with the database or inconsistent state.
2375     */

2376    protected Object JavaDoc retreiveUserPrimaryKey(
2377        Connection JavaDoc connection, Principal JavaDoc principal)
2378        throws UnknownPrincipalException {
2379        PreparedStatement JavaDoc retreiveUserPrimaryKeyStatement = null;
2380        ResultSet JavaDoc retreiveUserPrimaryKeyResultSet = null;
2381        Object JavaDoc userPrimaryKey = null;
2382
2383        try {
2384            retreiveUserPrimaryKeyStatement =
2385                config.getStatementFactory().createPreparedStatement(
2386                    config.getRetreiveUserPrimaryKeyQueryName(), connection);
2387
2388            retreiveUserPrimaryKeyStatement.setObject(
2389                1, principal.getName());
2390
2391            retreiveUserPrimaryKeyResultSet =
2392                retreiveUserPrimaryKeyStatement.executeQuery();
2393
2394            if (retreiveUserPrimaryKeyResultSet.next()) {
2395                userPrimaryKey =
2396                    retreiveUserPrimaryKeyResultSet.getObject(1);
2397            } else {
2398                throw new UnknownPrincipalException(
2399                    this.getClass(), principal.getName());
2400            }
2401
2402            if (log.isTraceEnabled()) {
2403                log.trace("Retreived primary key for user with name ["
2404                    + principal.getName() + "] of value ["
2405                    + userPrimaryKey + "]");
2406            }
2407        } catch (StatementFactoryException sfe) {
2408            log.trace("Caught exception: " + sfe
2409                + ExceptionUtility.captureStackTrace(sfe));
2410
2411            throw new RuntimeSecurityManagementException(
2412                this.getClass(),
2413                "Caught StatementFactoryException while getting primary key "
2414                + "for user [" + principal.getName() + "]", sfe);
2415        } catch (SQLException JavaDoc sqle) {
2416            log.trace("Caught exception: " + sqle
2417                + ExceptionUtility.captureStackTrace(sqle));
2418
2419            throw new RuntimeSecurityManagementException(
2420                this.getClass(),
2421                "Caught SQLException while getting primary key "
2422                + "for user [" + principal.getName() + "]", sqle);
2423        } finally {
2424            try {
2425                if (retreiveUserPrimaryKeyResultSet != null) {
2426                    retreiveUserPrimaryKeyResultSet.close();
2427                }
2428            } catch (SQLException JavaDoc sqle) {
2429                // Ignore exception.
2430
}
2431
2432            try {
2433                if (retreiveUserPrimaryKeyStatement != null) {
2434                    retreiveUserPrimaryKeyStatement.close();
2435                }
2436            } catch (SQLException JavaDoc sqle) {
2437                // Ignore exception.
2438
}
2439        }
2440
2441        return userPrimaryKey;
2442    }
2443
2444    /**
2445     * Gets back the primary key in the database for a given group.
2446     *
2447     * <p>
2448     * This may execute a query to retreive it, or if the information is
2449     * contained within the Principal object it may return it from there.
2450     * </p>
2451     *
2452     * @param connection connection to execute database calls against
2453     * @param group the principal to get the primary key for.
2454     *
2455     * @return primary key for the user. This may be a String, Integer,
2456     * etc.
2457     *
2458     * @throws UnknownGroupException indicates the principal does not
2459     * currently exists in the system
2460     * @throws RuntimeSecurityManagementException indicates an error
2461     * communicating with the database or inconsistent state.
2462     */

2463    protected Object JavaDoc retreiveGroupPrimaryKey(
2464        Connection JavaDoc connection, Group JavaDoc group) throws UnknownGroupException {
2465        PreparedStatement JavaDoc retreiveGroupPrimaryKeyStatement = null;
2466        ResultSet JavaDoc retreiveGroupPrimaryKeyResultSet = null;
2467        Object JavaDoc groupPrimaryKey = null;
2468
2469        try {
2470            retreiveGroupPrimaryKeyStatement =
2471                config.getStatementFactory().createPreparedStatement(
2472                    config.getRetreiveGroupPrimaryKeyQueryName(),
2473                    connection);
2474
2475            retreiveGroupPrimaryKeyStatement.setObject(1, group.getName());
2476
2477            retreiveGroupPrimaryKeyResultSet =
2478                retreiveGroupPrimaryKeyStatement.executeQuery();
2479
2480            if (retreiveGroupPrimaryKeyResultSet.next()) {
2481                groupPrimaryKey =
2482                    retreiveGroupPrimaryKeyResultSet.getObject(1);
2483            } else {
2484                throw new UnknownGroupException(
2485                    this.getClass(), group.getName());
2486            }
2487
2488            if (log.isTraceEnabled()) {
2489                log.trace("Retreived primary key for group with name ["
2490                    + group.getName() + "] of value [" + groupPrimaryKey
2491                    + "]");
2492            }
2493        } catch (StatementFactoryException sfe) {
2494            log.trace("Caught exception: " + sfe
2495                + ExceptionUtility.captureStackTrace(sfe));
2496
2497            throw new RuntimeSecurityManagementException(
2498                this.getClass(),
2499                "Caught StatementFactoryException while getting primary key "
2500                + "for group [" + group.getName() + "]", sfe);
2501        } catch (SQLException JavaDoc sqle) {
2502            log.trace("Caught exception: " + sqle
2503                + ExceptionUtility.captureStackTrace(sqle));
2504
2505            throw new RuntimeSecurityManagementException(
2506                this.getClass(),
2507                "Caught SQLException while getting primary key "
2508                + "for group [" + group.getName() + "]", sqle);
2509        } finally {
2510            try {
2511                if (retreiveGroupPrimaryKeyResultSet != null) {
2512                    retreiveGroupPrimaryKeyResultSet.close();
2513                }
2514            } catch (SQLException JavaDoc sqle) {
2515                // Ignore exception.
2516
}
2517
2518            try {
2519                if (retreiveGroupPrimaryKeyStatement != null) {
2520                    retreiveGroupPrimaryKeyStatement.close();
2521                }
2522            } catch (SQLException JavaDoc sqle) {
2523                // Ignore exception.
2524
}
2525        }
2526
2527        return groupPrimaryKey;
2528    }
2529
2530    /**
2531     * Configures the service.
2532     *
2533     * @param configuration <code>RdbmsUserManagerConfiguration</code>
2534     * configuration object for the service
2535     *
2536     * @throws InvalidConfigurationException indicates an error loading
2537     * the configuration
2538     */

2539    public void configure(ComponentConfiguration configuration) {
2540
2541        try {
2542            this.config = (RdbmsUserManagerConfiguration) configuration;
2543        } catch (ClassCastException JavaDoc cce) {
2544            throw new InvalidConfigurationException(
2545                this.getClass(), configuration.getConfigurationName(),
2546                "ComponentConfiguration",
2547                "Specifed RdbmsUserManagerConfiguration does not implement "
2548                    + "correct interface.",
2549                cce);
2550        }
2551    }
2552}
2553
Popular Tags