Source Code Cross Referenced for RdbmsUserManagerImpl.java in  » Inversion-of-Control » carbon » org » sape » carbon » services » security » management » rdbms » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Inversion of Control » carbon » org.sape.carbon.services.security.management.rdbms 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*
0002:         * The contents of this file are subject to the Sapient Public License
0003:         * Version 1.0 (the "License"); you may not use this file except in compliance
0004:         * with the License. You may obtain a copy of the License at
0005:         * http://carbon.sf.net/License.html.
0006:         *
0007:         * Software distributed under the License is distributed on an "AS IS" basis,
0008:         * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
0009:         * the specific language governing rights and limitations under the License.
0010:         *
0011:         * The Original Code is The Carbon Component Framework.
0012:         *
0013:         * The Initial Developer of the Original Code is Sapient Corporation
0014:         *
0015:         * Copyright (C) 2003 Sapient Corporation. All Rights Reserved.
0016:         */
0017:
0018:        package org.sape.carbon.services.security.management.rdbms;
0019:
0020:        import java.security.Principal;
0021:        import java.security.acl.Group;
0022:        import java.sql.Connection;
0023:        import java.sql.PreparedStatement;
0024:        import java.sql.ResultSet;
0025:        import java.sql.SQLException;
0026:        import java.util.HashMap;
0027:        import java.util.HashSet;
0028:        import java.util.Iterator;
0029:        import java.util.Map;
0030:        import java.util.Set;
0031:
0032:        import org.sape.carbon.core.component.ComponentConfiguration;
0033:        import org.sape.carbon.core.component.lifecycle.Configurable;
0034:        import org.sape.carbon.core.config.InvalidConfigurationException;
0035:        import org.sape.carbon.core.exception.ExceptionUtility;
0036:        import org.sape.carbon.services.security.management.DefaultGroupImpl;
0037:        import org.sape.carbon.services.security.management.DefaultUserImpl;
0038:        import org.sape.carbon.services.security.management.DuplicateGroupException;
0039:        import org.sape.carbon.services.security.management.DuplicatePrincipalException;
0040:        import org.sape.carbon.services.security.management.LazyLoadGroup;
0041:        import org.sape.carbon.services.security.management.RuntimeSecurityManagementException;
0042:        import org.sape.carbon.services.security.management.UnknownGroupException;
0043:        import org.sape.carbon.services.security.management.UnknownPrincipalException;
0044:        import org.sape.carbon.services.security.management.UserManager;
0045:        import org.sape.carbon.services.sql.StatementFactoryException;
0046:
0047:        import org.apache.commons.logging.Log;
0048:        import org.apache.commons.logging.LogFactory;
0049:
0050:        /**
0051:         * Implementation of the UserManager against a RDBMS backing store. This
0052:         * implementation executes queries against the datastore as specified in
0053:         * the configuration file as well as the statement factory. Copyright
0054:         * 2002 Sapient
0055:         *
0056:         * @author Jordan Reed, September 2002
0057:         * @version $Revision: 1.14 $($Author: dvoet $ / $Date: 2003/10/28 19:02:01 $)
0058:         *
0059:         * @since carbon 1.2
0060:         */
0061:        public class RdbmsUserManagerImpl implements  UserManager, Configurable {
0062:
0063:            /**
0064:             * Provides a handle to Apache-commons logger
0065:             */
0066:            private Log log = LogFactory.getLog(this .getClass());
0067:
0068:            /** Holds a reference to the configuration. */
0069:            protected RdbmsUserManagerConfiguration config;
0070:
0071:            /**
0072:             * Creates a new user object in the database and returns it.
0073:             *
0074:             * @param username the name of the user to create
0075:             * @param credential the credential for the user to authenticate
0076:             *
0077:             * @return the new instance of a principal generated
0078:             *
0079:             * @throws DuplicatePrincipalException indicates the a principal with
0080:             *         the same name already exists in the database
0081:             * @throws RuntimeSecurityManagementException indicates an error
0082:             *         communicating with the database
0083:             */
0084:            public Principal createUser(String username, Map userInfo)
0085:                    throws DuplicatePrincipalException {
0086:
0087:                Principal resultUser = null;
0088:                Connection connection = null;
0089:
0090:                try {
0091:                    connection = config.getConnectionFactory().getConnection();
0092:                } catch (SQLException sqle) {
0093:                    log.trace("Caught exception: " + sqle
0094:                            + ExceptionUtility.captureStackTrace(sqle));
0095:
0096:                    throw new RuntimeSecurityManagementException(this 
0097:                            .getClass(),
0098:                            "Caught SQLException while opening connection",
0099:                            sqle);
0100:                }
0101:
0102:                try {
0103:                    resultUser = createUser(connection, username, userInfo);
0104:                } finally {
0105:                    try {
0106:                        if (connection != null) {
0107:                            connection.close();
0108:                        }
0109:                    } catch (SQLException sqle) {
0110:                        log.info("Caught exception closing Connection: " + sqle
0111:                                + ExceptionUtility.captureStackTrace(sqle));
0112:                    }
0113:                }
0114:
0115:                return resultUser;
0116:            }
0117:
0118:            /**
0119:             * Creates a new user object in the database and returns it using the
0120:             * given connection.
0121:             *
0122:             * <p>
0123:             * This method makes calls to two helper methods to delegate the two
0124:             * bits of functionality.  <code>createUserEntry</code> to create the
0125:             * database entry for the user and <code>createCredentialEntry</code>
0126:             * to create the credential entry for the user.
0127:             * </p>
0128:             *
0129:             * @param connection connection to execute database calls against
0130:             * @param username the name of the user to create
0131:             * @param credential the credential for the user to authenticate
0132:             *
0133:             * @return the new instance of a principal generated
0134:             *
0135:             * @throws DuplicatePrincipalException indicates the a principal with
0136:             *         the same name already exists in the database
0137:             * @throws RuntimeSecurityManagementException indicates an error
0138:             *         communicating with the database
0139:             */
0140:            protected Principal createUser(Connection connection,
0141:                    String username, Map userInfo)
0142:                    throws DuplicatePrincipalException {
0143:
0144:                if (log.isTraceEnabled()) {
0145:                    log.trace("Adding user with name [" + username
0146:                            + "] and additional info [" + userInfo + "]");
0147:                }
0148:
0149:                Principal currentUser = retreiveUser(connection, username);
0150:
0151:                if (currentUser != null) {
0152:                    throw new DuplicatePrincipalException(this .getClass(),
0153:                            currentUser);
0154:                }
0155:
0156:                try {
0157:                    connection.setAutoCommit(false);
0158:                    createUserEntry(connection, username);
0159:                    currentUser = retreiveUser(connection, username);
0160:                    createCredentialEntry(connection, currentUser, userInfo);
0161:                    connection.commit();
0162:                    connection.setAutoCommit(true);
0163:                } catch (RuntimeSecurityManagementException rsme) {
0164:                    try {
0165:                        if (connection != null) {
0166:                            connection.rollback();
0167:                            connection.setAutoCommit(true);
0168:                        }
0169:                    } catch (SQLException se) {
0170:                        // Ignore exception.
0171:                    }
0172:
0173:                    throw rsme;
0174:                } catch (SQLException se) {
0175:                    try {
0176:                        if (connection != null) {
0177:                            connection.rollback();
0178:                            connection.setAutoCommit(true);
0179:                        }
0180:                    } catch (SQLException se2) {
0181:                        // Ignore exception.
0182:                    }
0183:
0184:                    throw new RuntimeSecurityManagementException(this 
0185:                            .getClass(), "Caught SQLException while adding "
0186:                            + "new user named [" + username + "]", se);
0187:                }
0188:
0189:                return currentUser;
0190:            }
0191:
0192:            /**
0193:             * Creates the user row in the database.  If the credential is created
0194:             * at the same time, the <code>createCredentialEntry</code> method
0195:             * should be overriden and set to empty.
0196:             *
0197:             * @param connection connection to execute database calls against
0198:             * @param username the name of the user to create
0199:             * @param credential the credential for the user to authenticate
0200:             *
0201:             * @throws RuntimeSecurityManagementException indicates an error
0202:             *         communicating with the database or inconsistent state.
0203:             */
0204:            protected void createUserEntry(Connection connection,
0205:                    String username) {
0206:                PreparedStatement createUserStatement = null;
0207:
0208:                try {
0209:                    createUserStatement = config
0210:                            .getStatementFactory()
0211:                            .createPreparedStatement(
0212:                                    config.getCreateUserQueryName(), connection);
0213:                    createUserStatement.setString(1, username);
0214:
0215:                    int resultCount = createUserStatement.executeUpdate();
0216:
0217:                    if (log.isInfoEnabled()) {
0218:                        log.info("Added user with name [" + username + "]");
0219:                    }
0220:                } catch (StatementFactoryException sfe) {
0221:                    log.trace("Caught exception: " + sfe
0222:                            + ExceptionUtility.captureStackTrace(sfe));
0223:
0224:                    throw new RuntimeSecurityManagementException(this 
0225:                            .getClass(),
0226:                            "Caught StatementFactoryException while adding "
0227:                                    + "new user.", sfe);
0228:                } catch (SQLException sqle) {
0229:                    log.trace("Caught exception: " + sqle
0230:                            + ExceptionUtility.captureStackTrace(sqle));
0231:
0232:                    throw new RuntimeSecurityManagementException(this 
0233:                            .getClass(), "Caught SQLException while adding "
0234:                            + "new user.", sqle);
0235:                } finally {
0236:                    try {
0237:                        if (createUserStatement != null) {
0238:                            createUserStatement.close();
0239:                        }
0240:                    } catch (SQLException sqle) {
0241:                        // Ignore exception.
0242:                    }
0243:                }
0244:            }
0245:
0246:            /**
0247:             * Creates the credential row in the database.  If the credential is
0248:             * created with the user this method should be overriden and set to
0249:             * empty.
0250:             *
0251:             * @param connection connection to execute database calls against
0252:             * @param currentUser the user to create a credential for
0253:             * @param credential the credential for the user to authenticate
0254:             *
0255:             * @throws RuntimeSecurityManagementException indicates an error
0256:             *         communicating with the database or inconsistent state.
0257:             */
0258:            protected void createCredentialEntry(Connection connection,
0259:                    Principal currentUser, Map userInfo) {
0260:                PreparedStatement createCredentialStatement = null;
0261:                Object userPrimaryKey = null;
0262:
0263:                try {
0264:                    userPrimaryKey = retreivePrincipalPrimaryKey(connection,
0265:                            currentUser);
0266:                } catch (UnknownPrincipalException upe) {
0267:                    throw new RuntimeSecurityManagementException(this 
0268:                            .getClass(),
0269:                            "Caught UnknownPrincipalException while getting "
0270:                                    + "primary key for ["
0271:                                    + currentUser.getName() + "]", upe);
0272:                }
0273:
0274:                try {
0275:                    Object credential = userInfo.get(this .config
0276:                            .getCreateUserBindParameters()[0]);
0277:
0278:                    createCredentialStatement = config.getStatementFactory()
0279:                            .createPreparedStatement(
0280:                                    config.getCreateCredentialQueryName(),
0281:                                    connection);
0282:
0283:                    createCredentialStatement.setObject(1, userPrimaryKey);
0284:                    createCredentialStatement.setObject(2, credential);
0285:
0286:                    int resultCount = createCredentialStatement.executeUpdate();
0287:
0288:                    if (log.isInfoEnabled()) {
0289:                        log.info("Added credential to user with name ["
0290:                                + currentUser.getName()
0291:                                + "] and credential of type ["
0292:                                + credential.getClass().getName() + "]");
0293:                    }
0294:                } catch (StatementFactoryException sfe) {
0295:                    log.trace("Caught exception: " + sfe
0296:                            + ExceptionUtility.captureStackTrace(sfe));
0297:
0298:                    throw new RuntimeSecurityManagementException(this 
0299:                            .getClass(),
0300:                            "Caught StatementFactoryException while adding "
0301:                                    + "new user.", sfe);
0302:                } catch (SQLException sqle) {
0303:                    log.trace("Caught exception: " + sqle
0304:                            + ExceptionUtility.captureStackTrace(sqle));
0305:
0306:                    throw new RuntimeSecurityManagementException(this 
0307:                            .getClass(), "Caught SQLException while adding "
0308:                            + "new user.", sqle);
0309:                } finally {
0310:                    try {
0311:                        if (createCredentialStatement != null) {
0312:                            createCredentialStatement.close();
0313:                        }
0314:                    } catch (SQLException sqle) {
0315:                        // Ignore exception.
0316:                    }
0317:                }
0318:            }
0319:
0320:            /**
0321:             * Removes the credential row from the database.
0322:             *
0323:             * @param connection connection to execute database calls against
0324:             * @param userPrimaryKey the primary key of the user.
0325:             *
0326:             * @throws RuntimeSecurityManagementException indicates an error
0327:             *         communicating with the database or inconsistent state.
0328:             */
0329:            protected void removeCredential(Connection connection,
0330:                    Object userPrimaryKey) {
0331:                PreparedStatement removeCredentialStatement = null;
0332:
0333:                try {
0334:                    removeCredentialStatement = config.getStatementFactory()
0335:                            .createPreparedStatement(
0336:                                    config.getRemoveCredentialQueryName(),
0337:                                    connection);
0338:
0339:                    removeCredentialStatement.setObject(1, userPrimaryKey);
0340:
0341:                    int resultCount = removeCredentialStatement.executeUpdate();
0342:
0343:                    if (log.isInfoEnabled()) {
0344:                        log.info("Deleted credential to user with name ["
0345:                                + userPrimaryKey + "]");
0346:                    }
0347:                } catch (StatementFactoryException sfe) {
0348:                    log.trace("Caught exception: " + sfe
0349:                            + ExceptionUtility.captureStackTrace(sfe));
0350:
0351:                    throw new RuntimeSecurityManagementException(this 
0352:                            .getClass(),
0353:                            "Caught StatementFactoryException while deleting "
0354:                                    + "credential.", sfe);
0355:                } catch (SQLException sqle) {
0356:                    log.trace("Caught exception: " + sqle
0357:                            + ExceptionUtility.captureStackTrace(sqle));
0358:
0359:                    throw new RuntimeSecurityManagementException(this 
0360:                            .getClass(), "Caught SQLException while deleting "
0361:                            + "credential.", sqle);
0362:                } finally {
0363:                    try {
0364:                        if (removeCredentialStatement != null) {
0365:                            removeCredentialStatement.close();
0366:                        }
0367:                    } catch (SQLException sqle) {
0368:                        // Ignore exception.
0369:                    }
0370:                }
0371:            }
0372:
0373:            /**
0374:             * Authenticates a user against a given credential.
0375:             *
0376:             * <p>
0377:             * This method will check the validity of a credential for a given
0378:             * user and return if the user is valid to log in of if some other
0379:             * status prevents them.
0380:             * </p>
0381:             *
0382:             * <p>
0383:             * This method does not provide business specific reasons why a user
0384:             * may be unable to log in (user does not exist, incorrect password,
0385:             * locked out, etc.). Projects must write project specific checks for
0386:             * business conditions preventing a user from logging in.
0387:             * </p>
0388:             *
0389:             * @param username The username identifying the user inside the user
0390:             *        store.
0391:             * @param credential The credential object a user needs to prove they
0392:             *        can be referenced by the principal.
0393:             *
0394:             * @return if this is the valid credential for the given user
0395:             *
0396:             * @throws RuntimeSecurityManagementException indicates an error
0397:             *         communicating with the database or inconsistent state.
0398:             */
0399:            public boolean authenticate(String username, Object credential) {
0400:                Connection connection = null;
0401:                boolean authenticated = false;
0402:
0403:                try {
0404:                    connection = config.getConnectionFactory().getConnection();
0405:                } catch (SQLException sqle) {
0406:                    log.trace("Caught exception: " + sqle
0407:                            + ExceptionUtility.captureStackTrace(sqle));
0408:
0409:                    throw new RuntimeSecurityManagementException(this 
0410:                            .getClass(), "Caught SQLException while opening "
0411:                            + "connection", sqle);
0412:                }
0413:
0414:                try {
0415:                    authenticated = authenticate(connection, username,
0416:                            credential);
0417:                } finally {
0418:                    try {
0419:                        if (connection != null) {
0420:                            connection.close();
0421:                        }
0422:                    } catch (SQLException sqle) {
0423:                        log.info("Caught exception closing Connection: " + sqle
0424:                                + ExceptionUtility.captureStackTrace(sqle));
0425:                    }
0426:                }
0427:
0428:                return authenticated;
0429:            }
0430:
0431:            /**
0432:             * Authenticates a user against a given credential.
0433:             *
0434:             * <p>
0435:             * This method will check the validity of a credential for a given
0436:             * user and return if the user is valid to log in of if some other
0437:             * status prevents them.
0438:             * </p>
0439:             *
0440:             * <p>
0441:             * This method does not provide business specific reasons why a user
0442:             * may be unable to log in (user does not exist, incorrect password,
0443:             * locked out, etc.). Projects must write project specific checks for
0444:             * business conditions preventing a user from logging in.
0445:             * </p>
0446:             *
0447:             * @param connection connection to execute database calls against
0448:             * @param username The username identifying the user inside the user
0449:             *        store.
0450:             * @param credential The credential object a user needs to prove they
0451:             *        can be referenced by the principal.
0452:             *
0453:             * @return if this is the valid credential for the given user
0454:             *
0455:             * @throws RuntimeSecurityManagementException indicates an error
0456:             *         communicating with the database or inconsistent state.
0457:             */
0458:            public boolean authenticate(Connection connection, String username,
0459:                    Object credential) {
0460:                PreparedStatement authenticateUserStatement = null;
0461:                ResultSet authenticateUserResultSet = null;
0462:                boolean authenticated = false;
0463:
0464:                if (log.isTraceEnabled()) {
0465:                    log.trace("Searching for user with principal name ["
0466:                            + username + "]");
0467:                }
0468:
0469:                try {
0470:                    authenticateUserStatement = config.getStatementFactory()
0471:                            .createPreparedStatement(
0472:                                    config.getAuthenticateUserQueryName(),
0473:                                    connection);
0474:                    authenticateUserStatement.setString(1, username);
0475:                    authenticateUserStatement.setObject(2, credential);
0476:                    authenticateUserResultSet = authenticateUserStatement
0477:                            .executeQuery();
0478:
0479:                    if (authenticateUserResultSet.next()) {
0480:                        authenticated = true;
0481:
0482:                        if (log.isTraceEnabled()) {
0483:                            log.trace("User with principal name [" + username
0484:                                    + "] was successfully authenticated");
0485:                        }
0486:                    } else {
0487:                        authenticated = false;
0488:
0489:                        if (log.isTraceEnabled()) {
0490:                            log.trace("User with principal name [" + username
0491:                                    + "] failed authentication");
0492:                        }
0493:                    }
0494:                } catch (StatementFactoryException sfe) {
0495:                    log.trace("Caught exception: " + sfe
0496:                            + ExceptionUtility.captureStackTrace(sfe));
0497:
0498:                    throw new RuntimeSecurityManagementException(this 
0499:                            .getClass(),
0500:                            "Caught StatementFactoryException while adding "
0501:                                    + "new user.", sfe);
0502:                } catch (SQLException sqle) {
0503:                    log.trace("Caught exception: " + sqle
0504:                            + ExceptionUtility.captureStackTrace(sqle));
0505:
0506:                    throw new RuntimeSecurityManagementException(this 
0507:                            .getClass(),
0508:                            "Caught SQLException while authenticating "
0509:                                    + "user.", sqle);
0510:                } finally {
0511:                    try {
0512:                        if (authenticateUserResultSet != null) {
0513:                            authenticateUserResultSet.close();
0514:                        }
0515:                    } catch (SQLException sqle) {
0516:                        log.info("Caught exception closing ResultSet: " + sqle
0517:                                + ExceptionUtility.captureStackTrace(sqle));
0518:                    }
0519:
0520:                    try {
0521:                        if (authenticateUserStatement != null) {
0522:                            authenticateUserStatement.close();
0523:                        }
0524:                    } catch (SQLException sqle) {
0525:                        log.info("Caught exception closing Statement: " + sqle
0526:                                + ExceptionUtility.captureStackTrace(sqle));
0527:                    }
0528:                }
0529:
0530:                return authenticated;
0531:            }
0532:
0533:            /**
0534:             * Removes a principal from all groups it is in.
0535:             *
0536:             * <p>
0537:             * This is used when removing a user or group from the system to
0538:             * validate that no extraneous rows are leftover.
0539:             * </p>
0540:             *
0541:             * @param connection connection to execute database calls against
0542:             * @param principalPrimaryKey the principal (either user or group) to
0543:             *        remove from all groups it is in
0544:             *
0545:             * @throws UnknownPrincipalException indicates the principal does not
0546:             *         currently exists in the system
0547:             * @throws RuntimeSecurityManagementException indicates an error
0548:             *         communicating with the database
0549:             */
0550:            protected void removeAllRelationships(Connection connection,
0551:                    Object principalPrimaryKey)
0552:                    throws UnknownPrincipalException {
0553:                PreparedStatement removeAllRelationshipsStatement = null;
0554:
0555:                if (log.isTraceEnabled()) {
0556:                    log.trace("Removing principal [" + principalPrimaryKey
0557:                            + "] from all relationships");
0558:                }
0559:
0560:                try {
0561:                    removeAllRelationshipsStatement = config
0562:                            .getStatementFactory()
0563:                            .createPreparedStatement(
0564:                                    config.getRemoveAllRelationshipsQueryName(),
0565:                                    connection);
0566:                    removeAllRelationshipsStatement.setObject(1,
0567:                            principalPrimaryKey);
0568:                    removeAllRelationshipsStatement.setObject(2,
0569:                            principalPrimaryKey);
0570:
0571:                    int resultCount = removeAllRelationshipsStatement
0572:                            .executeUpdate();
0573:
0574:                    if (log.isInfoEnabled()) {
0575:                        log.info("Removed principal with name ["
0576:                                + principalPrimaryKey + "] from ["
0577:                                + resultCount + "] relationships");
0578:                    }
0579:                } catch (StatementFactoryException sfe) {
0580:                    log.trace("Caught exception: " + sfe
0581:                            + ExceptionUtility.captureStackTrace(sfe));
0582:
0583:                    throw new RuntimeSecurityManagementException(this 
0584:                            .getClass(),
0585:                            "Caught StatementFactoryException while removing "
0586:                                    + "user.", sfe);
0587:                } catch (SQLException sqle) {
0588:                    log.trace("Caught exception: " + sqle
0589:                            + ExceptionUtility.captureStackTrace(sqle));
0590:
0591:                    throw new RuntimeSecurityManagementException(this 
0592:                            .getClass(), "Caught SQLException while removing "
0593:                            + "user.", sqle);
0594:                } finally {
0595:                    try {
0596:                        if (removeAllRelationshipsStatement != null) {
0597:                            removeAllRelationshipsStatement.close();
0598:                        }
0599:                    } catch (SQLException sqle) {
0600:                        log.info("Caught exception closing Statement: " + sqle
0601:                                + ExceptionUtility.captureStackTrace(sqle));
0602:                    }
0603:                }
0604:            }
0605:
0606:            /**
0607:             * Removes a user from the database.
0608:             *
0609:             * <p>
0610:             * This will first remove the user from any groups it may be in, and
0611:             * then proceed to delete the user. These two steps are done in a
0612:             * transaction against the database that will rollback if there is an
0613:             * error on either step.
0614:             * </p>
0615:             *
0616:             * @param user The user to remove from the database
0617:             *
0618:             * @throws UnknownPrincipalException indicates the principal does not
0619:             *         currently exists in the system
0620:             * @throws RuntimeSecurityManagementException indicates an error
0621:             *         communicating with the database
0622:             */
0623:            public void removeUser(Principal user)
0624:                    throws UnknownPrincipalException {
0625:
0626:                Connection connection = null;
0627:
0628:                try {
0629:                    connection = config.getConnectionFactory().getConnection();
0630:                } catch (SQLException sqle) {
0631:                    log.trace("Caught exception: " + sqle
0632:                            + ExceptionUtility.captureStackTrace(sqle));
0633:
0634:                    throw new RuntimeSecurityManagementException(this 
0635:                            .getClass(), "Caught SQLException while opening "
0636:                            + "connection", sqle);
0637:                }
0638:
0639:                try {
0640:                    removeUser(connection, user);
0641:                } finally {
0642:                    try {
0643:                        if (connection != null) {
0644:                            connection.close();
0645:                        }
0646:                    } catch (SQLException sqle) {
0647:                        log.info("Caught exception closing Connection: " + sqle
0648:                                + ExceptionUtility.captureStackTrace(sqle));
0649:                    }
0650:                }
0651:            }
0652:
0653:            /**
0654:             * Removes a user from the database.
0655:             *
0656:             * <p>
0657:             * This will first remove the user from any groups it may be in, and
0658:             * then proceed to delete the user. These two steps are done in a
0659:             * transaction against the database that will rollback if there is an
0660:             * error on either step.
0661:             * </p>
0662:             *
0663:             * @param connection connection to execute database calls against
0664:             * @param user The user to remove from the database
0665:             *
0666:             * @throws UnknownPrincipalException indicates the principal does not
0667:             *         currently exists in the system
0668:             * @throws RuntimeSecurityManagementException indicates an error
0669:             *         communicating with the database
0670:             */
0671:            protected void removeUser(Connection connection, Principal user)
0672:                    throws UnknownPrincipalException {
0673:
0674:                Principal currentUser = retreiveUser(connection, user.getName());
0675:
0676:                if (currentUser == null) {
0677:                    throw new UnknownPrincipalException(this .getClass(), user
0678:                            .getName());
0679:                }
0680:
0681:                Object userPrimaryKey = retreivePrincipalPrimaryKey(connection,
0682:                        user);
0683:
0684:                if (log.isTraceEnabled()) {
0685:                    log.trace("Removing user with principal [" + user.getName()
0686:                            + "]");
0687:                }
0688:
0689:                try {
0690:                    connection.setAutoCommit(false);
0691:
0692:                    removeAllRelationships(connection, userPrimaryKey);
0693:                    removeCredential(connection, userPrimaryKey);
0694:                    removeUserEntry(connection, userPrimaryKey);
0695:
0696:                    connection.commit();
0697:                    connection.setAutoCommit(true);
0698:
0699:                    if (log.isInfoEnabled()) {
0700:                        log.info("Removed user with name [" + user.getName()
0701:                                + "]");
0702:                    }
0703:                } catch (RuntimeSecurityManagementException rsme) {
0704:                    try {
0705:                        if (connection != null) {
0706:                            connection.rollback();
0707:                            connection.setAutoCommit(true);
0708:                        }
0709:                    } catch (SQLException se) {
0710:                        // Ignore exception.
0711:                    }
0712:
0713:                    throw rsme;
0714:                } catch (SQLException se) {
0715:                    try {
0716:                        if (connection != null) {
0717:                            connection.rollback();
0718:                            connection.setAutoCommit(true);
0719:                        }
0720:                    } catch (SQLException se2) {
0721:                        // Ignore exception.
0722:                    }
0723:
0724:                    throw new RuntimeSecurityManagementException(this 
0725:                            .getClass(), "Caught SQLException while deleting "
0726:                            + "user named [" + user.getName() + "]", se);
0727:                }
0728:            }
0729:
0730:            /**
0731:             * Removes the user row from the database.
0732:             *
0733:             * <p>
0734:             * This method should not normally be called until all other values
0735:             * relating to the user have been removed from the database unless
0736:             * this is an Oracle database with cascading contraints.
0737:             * </p>
0738:             *
0739:             * @param connection connection to execute database calls against
0740:             * @param userPrimaryKey the primary key of the user.
0741:             *
0742:             * @throws RuntimeSecurityManagementException indicates an error
0743:             *         communicating with the database or inconsistent state.
0744:             */
0745:            protected void removeUserEntry(Connection connection,
0746:                    Object userPrimaryKey) {
0747:                PreparedStatement removeUserStatement = null;
0748:
0749:                try {
0750:                    removeUserStatement = config
0751:                            .getStatementFactory()
0752:                            .createPreparedStatement(
0753:                                    config.getRemoveUserQueryName(), connection);
0754:                    removeUserStatement.setObject(1, userPrimaryKey);
0755:
0756:                    int resultCount = removeUserStatement.executeUpdate();
0757:                } catch (StatementFactoryException sfe) {
0758:                    log.trace("Caught exception and rolled back transaction: "
0759:                            + sfe + ExceptionUtility.captureStackTrace(sfe));
0760:
0761:                    throw new RuntimeSecurityManagementException(this 
0762:                            .getClass(),
0763:                            "Caught StatementFactoryException while removing "
0764:                                    + "user.", sfe);
0765:                } catch (SQLException sqle) {
0766:                    log.trace("Caught exception and rolled back transaction: "
0767:                            + sqle + ExceptionUtility.captureStackTrace(sqle));
0768:
0769:                    throw new RuntimeSecurityManagementException(this 
0770:                            .getClass(), "Caught SQLException while removing "
0771:                            + "user.", sqle);
0772:                } finally {
0773:                    try {
0774:                        if (removeUserStatement != null) {
0775:                            removeUserStatement.close();
0776:                        }
0777:                    } catch (SQLException sqle) {
0778:                        log.info("Caught exception closing Statement: " + sqle
0779:                                + ExceptionUtility.captureStackTrace(sqle));
0780:                    }
0781:                }
0782:            }
0783:
0784:            /**
0785:             * Updates the credential for the user in the database.
0786:             *
0787:             * @param user the user to update in the database
0788:             * @param credential the new credential to assign to the user
0789:             *
0790:             * @throws UnknownPrincipalException indicates the principal does not
0791:             *         currently exists in the system
0792:             * @throws RuntimeSecurityManagementException indicates an error
0793:             *         communicating with the database
0794:             */
0795:            public void updateCredential(Principal user, Object credential)
0796:                    throws UnknownPrincipalException {
0797:                Connection connection = null;
0798:
0799:                try {
0800:                    connection = config.getConnectionFactory().getConnection();
0801:                } catch (SQLException sqle) {
0802:                    log.trace("Caught exception: " + sqle
0803:                            + ExceptionUtility.captureStackTrace(sqle));
0804:
0805:                    throw new RuntimeSecurityManagementException(this 
0806:                            .getClass(), "Caught SQLException while opening "
0807:                            + "connection", sqle);
0808:                }
0809:
0810:                try {
0811:                    updateCredential(connection, user, credential);
0812:                } finally {
0813:                    try {
0814:                        if (connection != null) {
0815:                            connection.close();
0816:                        }
0817:                    } catch (SQLException sqle) {
0818:                        log.info("Caught exception closing Connection: " + sqle
0819:                                + ExceptionUtility.captureStackTrace(sqle));
0820:                    }
0821:                }
0822:            }
0823:
0824:            /**
0825:             * Updates the credential for the user in the database.
0826:             *
0827:             * @param connection the user to update in the database
0828:             * @param user the user to update in the database
0829:             * @param credential the new credential to assign to the user
0830:             *
0831:             * @throws UnknownPrincipalException indicates the principal does not
0832:             *         currently exists in the system
0833:             * @throws RuntimeSecurityManagementException indicates an error
0834:             *         communicating with the database
0835:             */
0836:            protected void updateCredential(Connection connection,
0837:                    Principal user, Object credential)
0838:                    throws UnknownPrincipalException {
0839:                PreparedStatement updateCredentialStatement = null;
0840:
0841:                if (log.isTraceEnabled()) {
0842:                    log.trace("Updating user with principal [" + user
0843:                            + "] and credential of type ["
0844:                            + credential.getClass().getName() + "]");
0845:                }
0846:
0847:                Object userPrimaryKey = retreivePrincipalPrimaryKey(connection,
0848:                        user);
0849:
0850:                try {
0851:                    updateCredentialStatement = config.getStatementFactory()
0852:                            .createPreparedStatement(
0853:                                    config.getUpdateCredentialQueryName(),
0854:                                    connection);
0855:                    updateCredentialStatement.setObject(1, credential);
0856:                    updateCredentialStatement.setObject(2, userPrimaryKey);
0857:
0858:                    int resultCount = updateCredentialStatement.executeUpdate();
0859:
0860:                    if (log.isDebugEnabled()) {
0861:                        log.debug("Updated credential for user with name ["
0862:                                + user.getName() + "]");
0863:                    }
0864:                } catch (StatementFactoryException sfe) {
0865:                    log.trace("Caught exception: " + sfe
0866:                            + ExceptionUtility.captureStackTrace(sfe));
0867:
0868:                    throw new RuntimeSecurityManagementException(this 
0869:                            .getClass(),
0870:                            "Caught StatementFactoryException while updating "
0871:                                    + "user.", sfe);
0872:                } catch (SQLException sqle) {
0873:                    log.trace("Caught exception: " + sqle
0874:                            + ExceptionUtility.captureStackTrace(sqle));
0875:
0876:                    throw new RuntimeSecurityManagementException(this 
0877:                            .getClass(), "Caught SQLException while updating "
0878:                            + "user.", sqle);
0879:                } finally {
0880:                    try {
0881:                        updateCredentialStatement.close();
0882:                    } catch (SQLException sqle) {
0883:                        log.info("Caught exception closing Statement: " + sqle
0884:                                + ExceptionUtility.captureStackTrace(sqle));
0885:                    }
0886:                }
0887:            }
0888:
0889:            /**
0890:             * Creates a new entry for Group in the database.
0891:             *
0892:             * @param groupName name of the group add to the database
0893:             *
0894:             * @return a new group object in the database
0895:             *
0896:             * @throws DuplicateGroupException indicates that a group with the
0897:             *         same name already exists in the database
0898:             * @throws RuntimeSecurityManagementException indicates an error
0899:             *         communicating with the database
0900:             */
0901:            public Group createGroup(String groupName)
0902:                    throws DuplicateGroupException {
0903:                Group result = null;
0904:                Connection connection = null;
0905:
0906:                try {
0907:                    connection = config.getConnectionFactory().getConnection();
0908:                } catch (SQLException sqle) {
0909:                    log.trace("Caught exception: " + sqle
0910:                            + ExceptionUtility.captureStackTrace(sqle));
0911:
0912:                    throw new RuntimeSecurityManagementException(this 
0913:                            .getClass(), "Caught SQLException while opening "
0914:                            + "connection", sqle);
0915:                }
0916:
0917:                try {
0918:                    result = createGroup(connection, groupName);
0919:                } finally {
0920:                    try {
0921:                        if (connection != null) {
0922:                            connection.close();
0923:                        }
0924:                    } catch (SQLException sqle) {
0925:                        log.info("Caught exception closing Connection: " + sqle
0926:                                + ExceptionUtility.captureStackTrace(sqle));
0927:                    }
0928:                }
0929:
0930:                return result;
0931:            }
0932:
0933:            /**
0934:             * Creates a new entry for Group in the database.
0935:             *
0936:             * @param connection connection to execute database calls against
0937:             * @param groupName name of the group add to the database
0938:             *
0939:             * @return a new group object in the database
0940:             *
0941:             * @throws DuplicateGroupException indicates that a group with the
0942:             *         same name already exists in the database
0943:             * @throws RuntimeSecurityManagementException indicates an error
0944:             *         communicating with the database
0945:             */
0946:            protected Group createGroup(Connection connection, String groupName)
0947:                    throws DuplicateGroupException {
0948:                PreparedStatement createGroupStatement = null;
0949:
0950:                if (log.isTraceEnabled()) {
0951:                    log.trace("Adding group [" + groupName + "]");
0952:                }
0953:
0954:                Group currentGroup = retreiveGroup(connection, groupName);
0955:
0956:                if (currentGroup != null) {
0957:                    throw new DuplicateGroupException(this .getClass(),
0958:                            currentGroup);
0959:                }
0960:
0961:                try {
0962:                    createGroupStatement = config.getStatementFactory()
0963:                            .createPreparedStatement(
0964:                                    config.getCreateGroupQueryName(),
0965:                                    connection);
0966:                    createGroupStatement.setString(1, groupName);
0967:
0968:                    int resultCount = createGroupStatement.executeUpdate();
0969:
0970:                    if (log.isInfoEnabled()) {
0971:                        log.info("Added group with name [" + groupName + "]");
0972:                    }
0973:                } catch (StatementFactoryException sfe) {
0974:                    log.trace("Caught exception: " + sfe
0975:                            + ExceptionUtility.captureStackTrace(sfe));
0976:
0977:                    throw new RuntimeSecurityManagementException(this 
0978:                            .getClass(),
0979:                            "Caught StatementFactoryException while adding "
0980:                                    + "new group.", sfe);
0981:                } catch (SQLException sqle) {
0982:                    log.trace("Caught exception: " + sqle
0983:                            + ExceptionUtility.captureStackTrace(sqle));
0984:
0985:                    throw new RuntimeSecurityManagementException(this 
0986:                            .getClass(), "Caught SQLException while adding "
0987:                            + "new group.", sqle);
0988:                } finally {
0989:                    try {
0990:                        createGroupStatement.close();
0991:                    } catch (SQLException sqle) {
0992:                        log.info("Caught exception closing Statement: " + sqle
0993:                                + ExceptionUtility.captureStackTrace(sqle));
0994:                    }
0995:                }
0996:
0997:                Group newGroup = retreiveGroup(connection, groupName);
0998:
0999:                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 group) throws UnknownGroupException {
1013:                Connection connection = null;
1014:
1015:                try {
1016:                    connection = config.getConnectionFactory().getConnection();
1017:                } catch (SQLException sqle) {
1018:                    log.trace("Caught exception: " + sqle
1019:                            + ExceptionUtility.captureStackTrace(sqle));
1020:
1021:                    throw new RuntimeSecurityManagementException(this 
1022:                            .getClass(), "Caught SQLException while opening "
1023:                            + "connection", sqle);
1024:                }
1025:
1026:                try {
1027:                    removeGroup(connection, group);
1028:                } finally {
1029:                    try {
1030:                        if (connection != null) {
1031:                            connection.close();
1032:                        }
1033:                    } catch (SQLException sqle) {
1034:                        log.info("Caught exception closing Connection: " + sqle
1035:                                + ExceptionUtility.captureStackTrace(sqle));
1036:                    }
1037:                }
1038:            }
1039:
1040:            /**
1041:             * Removes a group from the database.
1042:             *
1043:             * @param connection connection to execute database calls against
1044:             * @param group group to remove from the database
1045:             *
1046:             * @throws UnknownGroupException indicates the group does not
1047:             *         currently exists in the system
1048:             * @throws RuntimeSecurityManagementException indicates an error
1049:             *         communicating with the database
1050:             */
1051:            protected void removeGroup(Connection connection, Group group)
1052:                    throws UnknownGroupException {
1053:                PreparedStatement removeGroupStatement = null;
1054:                Object groupPrimaryKey;
1055:
1056:                Group currentGroup = retreiveGroup(connection, group.getName());
1057:
1058:                if (currentGroup == null) {
1059:                    throw new UnknownGroupException(this .getClass(), group
1060:                            .getName());
1061:                }
1062:
1063:                try {
1064:                    groupPrimaryKey = retreivePrincipalPrimaryKey(connection,
1065:                            group);
1066:                } catch (UnknownPrincipalException upe) {
1067:                    throw new UnknownGroupException(this .getClass(), group
1068:                            .getName(), upe);
1069:                }
1070:
1071:                if (log.isTraceEnabled()) {
1072:                    log.trace("Removing group [" + group.getName() + "]");
1073:                }
1074:
1075:                try {
1076:                    connection.setAutoCommit(false);
1077:
1078:                    removeAllRelationships(connection, groupPrimaryKey);
1079:
1080:                    removeGroupStatement = config.getStatementFactory()
1081:                            .createPreparedStatement(
1082:                                    config.getRemoveGroupQueryName(),
1083:                                    connection);
1084:                    removeGroupStatement.setObject(1, groupPrimaryKey);
1085:
1086:                    int resultCount = removeGroupStatement.executeUpdate();
1087:
1088:                    connection.commit();
1089:                    connection.setAutoCommit(true);
1090:
1091:                    if (log.isInfoEnabled()) {
1092:                        log.info("Removed group with name [" + group.getName()
1093:                                + "]");
1094:                    }
1095:                } catch (UnknownPrincipalException upe) {
1096:                    try {
1097:                        if (connection != null) {
1098:                            connection.rollback();
1099:                            connection.setAutoCommit(true);
1100:                        }
1101:                    } catch (SQLException 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(this .getClass(), group
1110:                            .getName(), upe);
1111:                } catch (StatementFactoryException sfe) {
1112:                    log.trace("Caught exception: " + sfe
1113:                            + ExceptionUtility.captureStackTrace(sfe));
1114:
1115:                    try {
1116:                        if (connection != null) {
1117:                            connection.rollback();
1118:                            connection.setAutoCommit(true);
1119:                        }
1120:                    } catch (SQLException sqle) {
1121:                        log.info("Caught exception rolling back transaction: "
1122:                                + sqle
1123:                                + ExceptionUtility.captureStackTrace(sqle));
1124:                    }
1125:
1126:                    throw new RuntimeSecurityManagementException(this 
1127:                            .getClass(),
1128:                            "Caught StatementFactoryException while removing "
1129:                                    + "group.", sfe);
1130:                } catch (SQLException sqle) {
1131:                    log.trace("Caught exception: " + sqle
1132:                            + ExceptionUtility.captureStackTrace(sqle));
1133:
1134:                    try {
1135:                        if (connection != null) {
1136:                            connection.rollback();
1137:                            connection.setAutoCommit(true);
1138:                        }
1139:                    } catch (SQLException sqle2) {
1140:                        log.info("Caught exception rolling back transaction: "
1141:                                + sqle2
1142:                                + ExceptionUtility.captureStackTrace(sqle));
1143:                    }
1144:
1145:                    throw new RuntimeSecurityManagementException(this 
1146:                            .getClass(), "Caught SQLException while removing "
1147:                            + "group.", sqle);
1148:                } finally {
1149:                    try {
1150:                        if (removeGroupStatement != null) {
1151:                            removeGroupStatement.close();
1152:                        }
1153:                    } catch (SQLException sqle) {
1154:                        log.info("Caught exception closing Statement: " + sqle
1155:                                + ExceptionUtility.captureStackTrace(sqle));
1156:                    }
1157:                }
1158:            }
1159:
1160:            /**
1161:             * Finds a user with the given name in the database.
1162:             *
1163:             * @param username the user in the database
1164:             *
1165:             * @return the principal associated with the username or null if there
1166:             *         is no user
1167:             *
1168:             * @throws RuntimeSecurityManagementException indicates an error
1169:             *         communicating with the database
1170:             */
1171:            public Principal retreiveUser(String username) {
1172:
1173:                Principal result = null;
1174:                Connection connection = null;
1175:
1176:                try {
1177:                    connection = config.getConnectionFactory().getConnection();
1178:                } catch (SQLException sqle) {
1179:                    log.trace("Caught exception: " + sqle
1180:                            + ExceptionUtility.captureStackTrace(sqle));
1181:
1182:                    throw new RuntimeSecurityManagementException(this 
1183:                            .getClass(), "Caught SQLException while opening "
1184:                            + "connection", sqle);
1185:                }
1186:
1187:                try {
1188:                    result = retreiveUser(connection, username);
1189:                } finally {
1190:                    try {
1191:                        if (connection != null) {
1192:                            connection.close();
1193:                        }
1194:                    } catch (SQLException sqle) {
1195:                        log.debug("Caught exception closing Connection: "
1196:                                + sqle
1197:                                + ExceptionUtility.captureStackTrace(sqle));
1198:                    }
1199:                }
1200:
1201:                return result;
1202:            }
1203:
1204:            /**
1205:             * Finds a user with the given name in the database.
1206:             *
1207:             * @param connection connection to execute database calls against
1208:             * @param username the user in the database
1209:             *
1210:             * @return the principal associated with the username or null if there
1211:             *         is no user
1212:             *
1213:             * @throws RuntimeSecurityManagementException indicates an error
1214:             *         communicating with the database
1215:             */
1216:            protected Principal retreiveUser(Connection connection,
1217:                    String username) {
1218:                PreparedStatement retreiveUserStatement = null;
1219:                ResultSet retreiveUserResultSet = null;
1220:                Principal resultPrincipal;
1221:
1222:                if (log.isTraceEnabled()) {
1223:                    log.trace("Searching for user with principal name ["
1224:                            + username + "]");
1225:                }
1226:
1227:                try {
1228:                    retreiveUserStatement = config.getStatementFactory()
1229:                            .createPreparedStatement(
1230:                                    config.getRetreiveUserQueryName(),
1231:                                    connection);
1232:                    retreiveUserStatement.setString(1, username);
1233:                    retreiveUserResultSet = retreiveUserStatement
1234:                            .executeQuery();
1235:
1236:                    if (retreiveUserResultSet.next()) {
1237:                        resultPrincipal = createUserObject(retreiveUserResultSet
1238:                                .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(this 
1247:                            .getClass(),
1248:                            "Caught StatementFactoryException while adding "
1249:                                    + "new user.", sfe);
1250:                } catch (SQLException sqle) {
1251:                    log.trace("Caught exception: " + sqle
1252:                            + ExceptionUtility.captureStackTrace(sqle));
1253:
1254:                    throw new RuntimeSecurityManagementException(this 
1255:                            .getClass(), "Caught SQLException while adding "
1256:                            + "new user.", sqle);
1257:                } finally {
1258:                    try {
1259:                        if (retreiveUserResultSet != null) {
1260:                            retreiveUserResultSet.close();
1261:                        }
1262:                    } catch (SQLException sqle) {
1263:                        log.info("Caught exception closing ResultSet: " + sqle
1264:                                + ExceptionUtility.captureStackTrace(sqle));
1265:                    }
1266:
1267:                    try {
1268:                        if (retreiveUserStatement != null) {
1269:                            retreiveUserStatement.close();
1270:                        }
1271:                    } catch (SQLException sqle) {
1272:                        log.info("Caught exception closing Statement: " + sqle
1273:                                + ExceptionUtility.captureStackTrace(sqle));
1274:                    }
1275:                }
1276:
1277:                return resultPrincipal;
1278:            }
1279:
1280:            /**
1281:             * Finds the group with the given name in the database.
1282:             *
1283:             * @param groupName the name of the group to get from the database
1284:             *
1285:             * @return the group with the given name or null if the group was not
1286:             *         in the database
1287:             *
1288:             * @throws RuntimeSecurityManagementException indicates an error
1289:             *         communicating with the database
1290:             */
1291:            public Group retreiveGroup(String groupName) {
1292:
1293:                Group result = null;
1294:                Connection connection = null;
1295:
1296:                try {
1297:                    connection = config.getConnectionFactory().getConnection();
1298:                } catch (SQLException sqle) {
1299:                    log.trace("Caught exception: " + sqle
1300:                            + ExceptionUtility.captureStackTrace(sqle));
1301:
1302:                    throw new RuntimeSecurityManagementException(this 
1303:                            .getClass(), "Caught SQLException while opening "
1304:                            + "connection", sqle);
1305:                }
1306:
1307:                try {
1308:                    result = retreiveGroup(connection, groupName);
1309:                } finally {
1310:                    try {
1311:                        if (connection != null) {
1312:                            connection.close();
1313:                        }
1314:                    } catch (SQLException sqle) {
1315:                        log.info("Caught exception closing Connection: " + sqle
1316:                                + ExceptionUtility.captureStackTrace(sqle));
1317:                    }
1318:                }
1319:
1320:                return result;
1321:            }
1322:
1323:            /**
1324:             * Finds the group with the given name in the database.
1325:             *
1326:             * @param connection connection to execute database calls against
1327:             * @param groupName the name of the group to get from the database
1328:             *
1329:             * @return the group with the given name or null if the group was not
1330:             *         in the database
1331:             *
1332:             * @throws RuntimeSecurityManagementException indicates an error
1333:             *         communicating with the database
1334:             */
1335:            protected Group retreiveGroup(Connection connection,
1336:                    String groupName) {
1337:
1338:                PreparedStatement retreiveGroupStatement = null;
1339:                ResultSet retreiveGroupResultSet = null;
1340:                Group resultGroup;
1341:
1342:                if (log.isTraceEnabled()) {
1343:                    log.trace("Searching for group with name [" + groupName
1344:                            + "]");
1345:                }
1346:
1347:                try {
1348:                    retreiveGroupStatement = config.getStatementFactory()
1349:                            .createPreparedStatement(
1350:                                    config.getRetreiveGroupQueryName(),
1351:                                    connection);
1352:                    retreiveGroupStatement.setString(1, groupName);
1353:                    retreiveGroupResultSet = retreiveGroupStatement
1354:                            .executeQuery();
1355:
1356:                    if (retreiveGroupResultSet.next()) {
1357:                        String resultGroupName = retreiveGroupResultSet
1358:                                .getString(1);
1359:                        resultGroup = createGroupObject(resultGroupName, null);
1360:
1361:                        if (resultGroup instanceof  LazyLoadGroup) {
1362:                            retreiveMembers(connection,
1363:                                    (LazyLoadGroup) resultGroup, null);
1364:                        } else {
1365:                            // TODO: Create a more basic loading of 1-level deep
1366:                            if (log.isDebugEnabled()) {
1367:                                log
1368:                                        .debug("Group returned is not expected class ["
1369:                                                + LazyLoadGroup.class.getName()
1370:                                                + "] but is actually "
1371:                                                + "instance of ["
1372:                                                + resultGroup.getClass()
1373:                                                        .getName()
1374:                                                + "] and therefore members will not be loaded.");
1375:                            }
1376:                        }
1377:
1378:                        if (log.isTraceEnabled()) {
1379:                            log.trace("Found group with name [" + groupName
1380:                                    + "]");
1381:                        }
1382:                    } else {
1383:                        resultGroup = null;
1384:
1385:                        if (log.isTraceEnabled()) {
1386:                            log.trace("Did not find group with name ["
1387:                                    + groupName + "]");
1388:                        }
1389:                    }
1390:                } catch (StatementFactoryException sfe) {
1391:                    log.trace("Caught exception: " + sfe
1392:                            + ExceptionUtility.captureStackTrace(sfe));
1393:
1394:                    throw new RuntimeSecurityManagementException(this 
1395:                            .getClass(),
1396:                            "Caught StatementFactoryException while finding "
1397:                                    + "group.", sfe);
1398:                } catch (SQLException sqle) {
1399:                    log.trace("Caught exception: " + sqle
1400:                            + ExceptionUtility.captureStackTrace(sqle));
1401:
1402:                    throw new RuntimeSecurityManagementException(this 
1403:                            .getClass(), "Caught SQLException while finding "
1404:                            + "group.", sqle);
1405:                } finally {
1406:                    try {
1407:                        if (retreiveGroupResultSet != null) {
1408:                            retreiveGroupResultSet.close();
1409:                        }
1410:                    } catch (SQLException sqle) {
1411:                        log.info("Caught exception closing ResultSet: " + sqle
1412:                                + ExceptionUtility.captureStackTrace(sqle));
1413:                    }
1414:
1415:                    try {
1416:                        if (retreiveGroupStatement != null) {
1417:                            retreiveGroupStatement.close();
1418:                        }
1419:                    } catch (SQLException sqle) {
1420:                        log.info("Caught exception closing Statement: " + sqle
1421:                                + ExceptionUtility.captureStackTrace(sqle));
1422:                    }
1423:                }
1424:
1425:                return resultGroup;
1426:            }
1427:
1428:            /**
1429:             * Retreives the groups contain this particular principal.
1430:             *
1431:             * <p>
1432:             * Only the first level into the group heirachy is queried.
1433:             * </p>
1434:             *
1435:             * @param principal principal to retrieve the groups for
1436:             *
1437:             * @return groups which the principals is a direct member of
1438:             *
1439:             * @throws UnknownPrincipalException indicates the user does not exist
1440:             *         in the datastore
1441:             * @throws RuntimeSecurityManagementException indicates an error
1442:             *         communicating with the database or inconsistent state.
1443:             */
1444:            public Set retreiveGroups(Principal principal)
1445:                    throws UnknownPrincipalException {
1446:
1447:                Set result = null;
1448:                Connection connection = null;
1449:
1450:                try {
1451:                    connection = config.getConnectionFactory().getConnection();
1452:                } catch (SQLException sqle) {
1453:                    log.trace("Caught exception: " + sqle
1454:                            + ExceptionUtility.captureStackTrace(sqle));
1455:
1456:                    throw new RuntimeSecurityManagementException(this 
1457:                            .getClass(), "Caught SQLException while opening "
1458:                            + "connection", sqle);
1459:                }
1460:
1461:                try {
1462:                    result = retreiveGroups(connection, principal);
1463:                } finally {
1464:                    try {
1465:                        if (connection != null) {
1466:                            connection.close();
1467:                        }
1468:                    } catch (SQLException sqle) {
1469:                        log.info("Caught exception closing Connection: " + sqle
1470:                                + ExceptionUtility.captureStackTrace(sqle));
1471:                    }
1472:                }
1473:
1474:                return result;
1475:            }
1476:
1477:            /**
1478:             * Retreives the groups contain this particular principal.
1479:             *
1480:             * <p>
1481:             * Only the first level into the group heirachy is queried.
1482:             * </p>
1483:             *
1484:             * @param connection connection to execute database calls against
1485:             * @param principal principal to retrieve the groups for
1486:             *
1487:             * @return groups which the principals is a direct member of
1488:             *
1489:             * @throws UnknownPrincipalException indicates the user does not exist
1490:             *         in the datastore
1491:             * @throws RuntimeSecurityManagementException indicates an error
1492:             *         communicating with the database or inconsistent state.
1493:             */
1494:            protected Set retreiveGroups(Connection connection,
1495:                    Principal principal) throws UnknownPrincipalException {
1496:
1497:                String queryname;
1498:                Set membershipSet = new HashSet();
1499:                PreparedStatement retreiveMembershipStatement = null;
1500:                ResultSet retreiveMembershipResultSet = null;
1501:
1502:                if (principal instanceof  Group) {
1503:                    Principal currentGroup = retreiveGroup(connection,
1504:                            principal.getName());
1505:
1506:                    if (currentGroup == null) {
1507:                        throw new UnknownPrincipalException(this .getClass(),
1508:                                principal);
1509:                    }
1510:
1511:                    if (log.isTraceEnabled()) {
1512:                        log.trace("Get membership of group with name ["
1513:                                + principal.getName() + "]");
1514:                    }
1515:
1516:                    queryname = config.getRetreiveGroupsForGroupsQueryName();
1517:                } else {
1518:                    Principal currentUser = retreiveUser(connection, principal
1519:                            .getName());
1520:
1521:                    if (currentUser == null) {
1522:                        throw new UnknownPrincipalException(this .getClass(),
1523:                                principal);
1524:                    }
1525:
1526:                    if (log.isTraceEnabled()) {
1527:                        log.trace("Get membership of user with name ["
1528:                                + principal.getName() + "]");
1529:                    }
1530:
1531:                    queryname = config.getRetreiveGroupsForUserQueryName();
1532:                }
1533:
1534:                try {
1535:                    retreiveMembershipStatement = config.getStatementFactory()
1536:                            .createPreparedStatement(queryname, connection);
1537:                    retreiveMembershipStatement.setString(1, principal
1538:                            .getName());
1539:                    retreiveMembershipResultSet = retreiveMembershipStatement
1540:                            .executeQuery();
1541:
1542:                    while (retreiveMembershipResultSet.next()) {
1543:                        Group containingGroup = retreiveGroup(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(this 
1560:                            .getClass(),
1561:                            "Caught StatementFactoryException while getting groups "
1562:                                    + "for principal [" + principal.getName()
1563:                                    + "]", sfe);
1564:                } catch (SQLException sqle) {
1565:                    log.trace("Caught exception: " + sqle
1566:                            + ExceptionUtility.captureStackTrace(sqle));
1567:
1568:                    throw new RuntimeSecurityManagementException(this 
1569:                            .getClass(),
1570:                            "Caught SQLException while getting roups "
1571:                                    + "for principal [" + principal.getName()
1572:                                    + "]", sqle);
1573:                } finally {
1574:                    try {
1575:                        if (retreiveMembershipResultSet != null) {
1576:                            retreiveMembershipResultSet.close();
1577:                        }
1578:                    } catch (SQLException sqle) {
1579:                        log.info("Caught exception closing ResultSet: " + sqle
1580:                                + ExceptionUtility.captureStackTrace(sqle));
1581:                    }
1582:
1583:                    try {
1584:                        if (retreiveMembershipStatement != null) {
1585:                            retreiveMembershipStatement.close();
1586:                        }
1587:                    } catch (SQLException sqle) {
1588:                        log.info("Caught exception closing Statement: " + sqle
1589:                                + ExceptionUtility.captureStackTrace(sqle));
1590:                    }
1591:                }
1592:
1593:                return membershipSet;
1594:            }
1595:
1596:            /**
1597:             * Retrieves all the members of the given group.
1598:             *
1599:             * <p>
1600:             * This will recursively load all members of the given group loading
1601:             * all groups under it.
1602:             * </p>
1603:             *
1604:             * @param connection connection to execute database calls against
1605:             * @param group group to get all members of
1606:             * @param loadedGroups map of groups that are already loaded
1607:             *
1608:             * @throws RuntimeSecurityManagementException indicates an error
1609:             *         communicating with the database
1610:             */
1611:            protected void retreiveMembers(Connection connection,
1612:                    LazyLoadGroup group, Map loadedGroups) {
1613:
1614:                if (loadedGroups == null) {
1615:                    loadedGroups = new HashMap();
1616:
1617:                    if (log.isTraceEnabled()) {
1618:                        log
1619:                                .trace("Retreiving members for top-level group named ["
1620:                                        + group.getName() + "]");
1621:                    }
1622:                }
1623:
1624:                Set members = new HashSet();
1625:
1626:                PreparedStatement retreiveMembersStatement = null;
1627:                ResultSet retreiveMembersResultSet = null;
1628:
1629:                try {
1630:                    retreiveMembersStatement = config.getStatementFactory()
1631:                            .createPreparedStatement(
1632:                                    config.getRetreiveMemebersQueryName(),
1633:                                    connection);
1634:
1635:                    retreiveMembersStatement.setString(1, group.getName());
1636:                    retreiveMembersResultSet = retreiveMembersStatement
1637:                            .executeQuery();
1638:
1639:                    while (retreiveMembersResultSet.next()) {
1640:                        members.add(retreiveMember(retreiveMembersResultSet,
1641:                                loadedGroups));
1642:                    }
1643:
1644:                    group.setMembers(members);
1645:
1646:                    if (log.isTraceEnabled()) {
1647:                        log.trace("Added members to group named ["
1648:                                + group.getName() + "] with total of ["
1649:                                + members.size() + "] principals");
1650:                    }
1651:                } catch (StatementFactoryException sfe) {
1652:                    log.trace("Caught exception: " + sfe
1653:                            + ExceptionUtility.captureStackTrace(sfe));
1654:
1655:                    throw new RuntimeSecurityManagementException(this 
1656:                            .getClass(),
1657:                            "Caught StatementFactoryException while adding "
1658:                                    + "new user.", sfe);
1659:                } catch (SQLException sqle) {
1660:                    log.trace("Caught exception: " + sqle
1661:                            + ExceptionUtility.captureStackTrace(sqle));
1662:
1663:                    throw new RuntimeSecurityManagementException(this 
1664:                            .getClass(), "Caught SQLException while adding "
1665:                            + "new user.", sqle);
1666:                } finally {
1667:                    try {
1668:                        retreiveMembersResultSet.close();
1669:                    } catch (SQLException sqle) {
1670:                        log.info("Caught exception closing ResultSet: " + sqle
1671:                                + ExceptionUtility.captureStackTrace(sqle));
1672:                    }
1673:
1674:                    try {
1675:                        retreiveMembersStatement.close();
1676:                    } catch (SQLException sqle) {
1677:                        log.info("Caught exception closing Statement: " + sqle
1678:                                + ExceptionUtility.captureStackTrace(sqle));
1679:                    }
1680:                }
1681:
1682:                // If the group object was constructed using the
1683:                // LazyLoadGroup it is possible to load all
1684:                // of the subgroups without errors.
1685:                Iterator membersIterator = members.iterator();
1686:
1687:                while (membersIterator.hasNext()) {
1688:                    Object currentMember = membersIterator.next();
1689:
1690:                    if (currentMember instanceof  LazyLoadGroup) {
1691:                        LazyLoadGroup currentGroup = (LazyLoadGroup) currentMember;
1692:
1693:                        if (currentGroup.isLoaded()) {
1694:                            if (log.isTraceEnabled()) {
1695:                                log.trace("In group named [" + group.getName()
1696:                                        + "] found loaded sub-group named ["
1697:                                        + currentGroup.getName() + "]");
1698:                            }
1699:                        } else {
1700:                            if (log.isTraceEnabled()) {
1701:                                log.trace("In group named [" + group.getName()
1702:                                        + "] found UNLOADED sub-group named ["
1703:                                        + currentGroup.getName() + "]");
1704:                            }
1705:
1706:                            retreiveMembers(connection, currentGroup,
1707:                                    loadedGroups);
1708:                        }
1709:                    }
1710:                }
1711:            }
1712:
1713:            /**
1714:             * Method to create a new User object implementing the principal
1715:             * interface.  This method is meant to be overridden by a subclass
1716:             * that needs to implement its own version.
1717:             *
1718:             * @param username name of the user to create an object for
1719:             *
1720:             * @return a new user object
1721:             */
1722:            protected Principal createUserObject(String username) {
1723:                return new DefaultUserImpl(username);
1724:            }
1725:
1726:            /**
1727:             * Method to create a new Group object implementing the Group
1728:             * interface.  This method is meant to be overridden by a subclass
1729:             * that needs to implement its own version.
1730:             *
1731:             * @param groupName name of the group to create an object for
1732:             * @param members a set of members for this group
1733:             *
1734:             * @return a new group object
1735:             */
1736:            protected Group createGroupObject(String groupName, Set members) {
1737:                return new DefaultGroupImpl(groupName, members, config
1738:                        .getConfigurationName());
1739:            }
1740:
1741:            /**
1742:             * Retreives a member from a given result.
1743:             *
1744:             * <p>
1745:             * A map of groupname to already loaded groups is passed in as well.
1746:             * This allows the method to either return a currently loaded group
1747:             * if it exists.  Otherwise it will create a new group with a call to
1748:             * <code>createGroupObject</code>.  It is possible to change the
1749:             * group object returned by subclassing this implementation and
1750:             * overriding that method.
1751:             * </p>
1752:             *
1753:             * @param memberResultSet ResultSet to get the next user from. This
1754:             *        method expects the first column to be the name of the user.
1755:             *        The second column is the type of user identified by the
1756:             *        <code>PrincipalTypeEnum</code> object.
1757:             * @param loadedGroups Map of already loaded groups.  The key is the
1758:             *        name of the group.  If the current row of the ResultSet
1759:             *        returns a group in this map, the already loaded group will
1760:             *        be returned instead of constructing a new one.
1761:             *
1762:             * @return a principal contained in the current row of the ResultSet
1763:             *
1764:             * @throws RuntimeSecurityManagementException indicates an error
1765:             *         communicating with the database
1766:             */
1767:            protected Principal retreiveMember(ResultSet memberResultSet,
1768:                    Map loadedGroups) {
1769:
1770:                Principal resultPrincipal = null;
1771:
1772:                try {
1773:                    String principalName = memberResultSet.getString(1);
1774:                    PrincipalTypeEnum principalTypeEnum = PrincipalTypeEnum
1775:                            .getByOrdinal(memberResultSet.getInt(2));
1776:
1777:                    if (log.isTraceEnabled()) {
1778:                        log.trace("Instantiating new principal named ["
1779:                                + principalName + "] of enumeration type ["
1780:                                + principalTypeEnum + "]");
1781:                    }
1782:
1783:                    if (principalTypeEnum.equals(PrincipalTypeEnum.USER)) {
1784:                        resultPrincipal = createUserObject(principalName);
1785:                    } else if (principalTypeEnum
1786:                            .equals(PrincipalTypeEnum.GROUP)) {
1787:                        if (loadedGroups.containsKey(principalName)) {
1788:                            resultPrincipal = (Principal) loadedGroups
1789:                                    .get(principalName);
1790:                        } else {
1791:                            resultPrincipal = createGroupObject(principalName,
1792:                                    null);
1793:
1794:                            loadedGroups.put(principalName, resultPrincipal);
1795:                        }
1796:                    }
1797:                } catch (PrincipalTypeEnum.PrincipalTypeEnumNotFoundException ptenfe) {
1798:                    log.trace("Caught exception: " + ptenfe
1799:                            + ExceptionUtility.captureStackTrace(ptenfe));
1800:
1801:                    throw new RuntimeSecurityManagementException(this 
1802:                            .getClass(), "Invalid principal type encountered.",
1803:                            ptenfe);
1804:                } catch (SQLException sqle) {
1805:                    log.trace("Caught exception: " + sqle
1806:                            + ExceptionUtility.captureStackTrace(sqle));
1807:
1808:                    throw new RuntimeSecurityManagementException(this 
1809:                            .getClass(), "Caught SQLException while adding "
1810:                            + "new user.", sqle);
1811:                }
1812:
1813:                return resultPrincipal;
1814:            }
1815:
1816:            /**
1817:             * Adds a principal (user or group) into the given group.
1818:             *
1819:             * @param principal the principal to add into the group
1820:             * @param group the group to add a principal to
1821:             *
1822:             * @return if the database was altered by this call
1823:             *
1824:             * @throws UnknownPrincipalException indicates the principal does not
1825:             *         currently exists in the system
1826:             * @throws UnknownGroupException indicates the group does not
1827:             *         currently exists in the system
1828:             * @throws RuntimeSecurityManagementException indicates an error
1829:             *         communicating with the database
1830:             */
1831:            public boolean addPrincipalToGroup(Principal principal, Group group)
1832:                    throws UnknownPrincipalException, UnknownGroupException {
1833:
1834:                boolean isPrincipalAdded = false;
1835:                Connection connection = null;
1836:
1837:                try {
1838:                    connection = config.getConnectionFactory().getConnection();
1839:                } catch (SQLException sqle) {
1840:                    log.trace("Caught exception: " + sqle
1841:                            + ExceptionUtility.captureStackTrace(sqle));
1842:
1843:                    throw new RuntimeSecurityManagementException(this 
1844:                            .getClass(),
1845:                            "Caught SQLException while opening connection",
1846:                            sqle);
1847:                }
1848:
1849:                try {
1850:                    isPrincipalAdded = addPrincipalToGroup(connection,
1851:                            principal, group);
1852:                } finally {
1853:                    try {
1854:                        if (connection != null) {
1855:                            connection.close();
1856:                        }
1857:                    } catch (SQLException sqle) {
1858:                        log.info("Caught exception closing Connection: " + sqle
1859:                                + ExceptionUtility.captureStackTrace(sqle));
1860:                    }
1861:                }
1862:
1863:                return isPrincipalAdded;
1864:            }
1865:
1866:            /**
1867:             * Adds a principal (user or group) into the given group.
1868:             *
1869:             * @param connection connection to execute database calls against
1870:             * @param principal the principal to add into the group
1871:             * @param group the group to add a principal to
1872:             *
1873:             * @return if the database was altered by this call
1874:             *
1875:             * @throws UnknownPrincipalException indicates the principal does not
1876:             *         currently exists in the system
1877:             * @throws UnknownGroupException indicates the group does not
1878:             *         currently exists in the system
1879:             * @throws RuntimeSecurityManagementException indicates an error
1880:             *         communicating with the database
1881:             */
1882:            protected boolean addPrincipalToGroup(Connection connection,
1883:                    Principal principal, Group group)
1884:                    throws UnknownPrincipalException, UnknownGroupException {
1885:                PreparedStatement addPrincipalToGroupStatement = null;
1886:                boolean result = false;
1887:
1888:                if (log.isTraceEnabled()) {
1889:                    log.trace("Adding principal [" + principal.getName()
1890:                            + "] to group [" + group.getName() + "]");
1891:                }
1892:
1893:                Object principalPrimaryKey = retreivePrincipalPrimaryKey(
1894:                        connection, principal);
1895:                Object groupPrimaryKey = retreivePrincipalPrimaryKey(
1896:                        connection, group);
1897:
1898:                if (group.isMember(principal)) {
1899:                    if (log.isTraceEnabled()) {
1900:                        log.trace("User [" + principal
1901:                                + "] is already a member of group [" + group
1902:                                + "]");
1903:                    }
1904:
1905:                    result = false;
1906:                } else {
1907:                    try {
1908:                        addPrincipalToGroupStatement = config
1909:                                .getStatementFactory()
1910:                                .createPreparedStatement(
1911:                                        config
1912:                                                .getAddPrincipalToGroupQueryName(),
1913:                                        connection);
1914:
1915:                        addPrincipalToGroupStatement.setObject(1,
1916:                                principalPrimaryKey);
1917:                        addPrincipalToGroupStatement.setObject(2,
1918:                                groupPrimaryKey);
1919:
1920:                        int resultCount = addPrincipalToGroupStatement
1921:                                .executeUpdate();
1922:
1923:                        if (resultCount > 0) {
1924:                            result = true;
1925:
1926:                            if (log.isDebugEnabled()) {
1927:                                log.debug("Added principal ["
1928:                                        + principal.getName() + "] to group ["
1929:                                        + group.getName() + "]");
1930:                            }
1931:                        }
1932:                    } catch (StatementFactoryException sfe) {
1933:                        log.trace("Caught exception: " + sfe
1934:                                + ExceptionUtility.captureStackTrace(sfe));
1935:
1936:                        throw new RuntimeSecurityManagementException(this 
1937:                                .getClass(),
1938:                                "Caught StatementFactoryException while adding "
1939:                                        + "new user.", sfe);
1940:                    } catch (SQLException sqle) {
1941:                        log.trace("Caught exception: " + sqle
1942:                                + ExceptionUtility.captureStackTrace(sqle));
1943:
1944:                        throw new RuntimeSecurityManagementException(this 
1945:                                .getClass(),
1946:                                "Caught SQLException while adding "
1947:                                        + "new user.", sqle);
1948:                    } finally {
1949:                        try {
1950:                            if (addPrincipalToGroupStatement != null) {
1951:                                addPrincipalToGroupStatement.close();
1952:                            }
1953:                        } catch (SQLException sqle) {
1954:                            log.info("Caught exception closing Statement: "
1955:                                    + sqle
1956:                                    + ExceptionUtility.captureStackTrace(sqle));
1957:                        }
1958:                    }
1959:                }
1960:
1961:                return result;
1962:            }
1963:
1964:            /**
1965:             * Removes the principal (user or group) from the given group.
1966:             *
1967:             * @param principal the principal (user or group) to remove from the
1968:             *        given group
1969:             * @param group the group to remove the principal from
1970:             *
1971:             * @return if the database changed as a result of the call
1972:             *
1973:             * @throws UnknownPrincipalException indicates the principal does not
1974:             *         currently exists in the system
1975:             * @throws UnknownGroupException indicates the group does not
1976:             *         currently exists in the system
1977:             * @throws RuntimeSecurityManagementException indicates an error
1978:             *         communicating with the database
1979:             */
1980:            public boolean removePrincipalFromGroup(Principal principal,
1981:                    Group group) throws UnknownPrincipalException,
1982:                    UnknownGroupException {
1983:                Connection connection = null;
1984:                boolean isRemoved = false;
1985:
1986:                try {
1987:                    connection = config.getConnectionFactory().getConnection();
1988:                } catch (SQLException sqle) {
1989:                    log.trace("Caught exception: " + sqle
1990:                            + ExceptionUtility.captureStackTrace(sqle));
1991:
1992:                    throw new RuntimeSecurityManagementException(this 
1993:                            .getClass(),
1994:                            "Caught SQLException while opening connection",
1995:                            sqle);
1996:                }
1997:
1998:                try {
1999:                    isRemoved = removePrincipalFromGroup(connection, principal,
2000:                            group);
2001:                } finally {
2002:                    try {
2003:                        if (connection != null) {
2004:                            connection.close();
2005:                        }
2006:                    } catch (SQLException sqle) {
2007:                        log.info("Caught exception closing Connection: " + sqle
2008:                                + ExceptionUtility.captureStackTrace(sqle));
2009:                    }
2010:                }
2011:
2012:                return isRemoved;
2013:            }
2014:
2015:            /**
2016:             * Removes the principal (user or group) from the given group.
2017:             *
2018:             * @param connection connection to execute database calls against
2019:             * @param principal the principal (user or group) to remove from the
2020:             *        given group
2021:             * @param group the group to remove the principal from
2022:             *
2023:             * @return if the database changed as a result of the call
2024:             *
2025:             * @throws UnknownPrincipalException indicates the principal does not
2026:             *         currently exists in the system
2027:             * @throws UnknownGroupException indicates the group does not
2028:             *         currently exists in the system
2029:             * @throws RuntimeSecurityManagementException indicates an error
2030:             *         communicating with the database
2031:             */
2032:            protected boolean removePrincipalFromGroup(Connection connection,
2033:                    Principal principal, Group group)
2034:                    throws UnknownPrincipalException, UnknownGroupException {
2035:                PreparedStatement removePrincipalFromGroupStatement = null;
2036:                boolean result = false;
2037:
2038:                if (log.isTraceEnabled()) {
2039:                    log.trace("Removing principal [" + principal.getName()
2040:                            + "] from group [" + group.getName() + "]");
2041:                }
2042:
2043:                Object principalPrimaryKey = retreivePrincipalPrimaryKey(
2044:                        connection, principal);
2045:                Object groupPrimaryKey = retreivePrincipalPrimaryKey(
2046:                        connection, group);
2047:
2048:                if (!group.isMember(principal)) {
2049:                    result = false;
2050:
2051:                    if (log.isTraceEnabled()) {
2052:                        log.trace("User [" + principal
2053:                                + "] is already not a member of group ["
2054:                                + group + "]");
2055:                    }
2056:                } else {
2057:                    try {
2058:                        removePrincipalFromGroupStatement = config
2059:                                .getStatementFactory()
2060:                                .createPreparedStatement(
2061:                                        config
2062:                                                .getRemovePrincipalFromGroupQueryName(),
2063:                                        connection);
2064:
2065:                        removePrincipalFromGroupStatement.setObject(1,
2066:                                principalPrimaryKey);
2067:                        removePrincipalFromGroupStatement.setObject(2,
2068:                                groupPrimaryKey);
2069:
2070:                        int resultCount = removePrincipalFromGroupStatement
2071:                                .executeUpdate();
2072:
2073:                        if (resultCount > 0) {
2074:                            result = true;
2075:
2076:                            if (log.isDebugEnabled()) {
2077:                                log.debug("Removed principal ["
2078:                                        + principal.getName()
2079:                                        + "] from group [" + group.getName()
2080:                                        + "]");
2081:                            }
2082:                        }
2083:                    } catch (StatementFactoryException sfe) {
2084:                        log.trace("Caught exception: " + sfe
2085:                                + ExceptionUtility.captureStackTrace(sfe));
2086:
2087:                        throw new RuntimeSecurityManagementException(this 
2088:                                .getClass(),
2089:                                "Caught StatementFactoryException while removing "
2090:                                        + "user.", sfe);
2091:                    } catch (SQLException sqle) {
2092:                        log.trace("Caught exception: " + sqle
2093:                                + ExceptionUtility.captureStackTrace(sqle));
2094:
2095:                        throw new RuntimeSecurityManagementException(
2096:                                this .getClass(),
2097:                                "Caught SQLException while removing " + "user.",
2098:                                sqle);
2099:                    } finally {
2100:                        try {
2101:                            removePrincipalFromGroupStatement.close();
2102:                        } catch (SQLException sqle) {
2103:                            log.info("Caught exception closing Statement: "
2104:                                    + sqle
2105:                                    + ExceptionUtility.captureStackTrace(sqle));
2106:                        }
2107:                    }
2108:                }
2109:
2110:                return result;
2111:            }
2112:
2113:            /**
2114:             * Retreives all unique names of users from the store as a Set of
2115:             * Strings.
2116:             *
2117:             * @return All unique user names as a Set of Strings.  If there are no
2118:             *         users in the system and empty Set will be returned.
2119:             *
2120:             * @throws RuntimeSecurityManagementException indicates an error
2121:             *         communicating with the database or inconsistent state.
2122:             */
2123:            public Set retreiveAllUserNames() {
2124:
2125:                Connection connection = null;
2126:                Set allUsers = null;
2127:
2128:                try {
2129:                    connection = config.getConnectionFactory().getConnection();
2130:                } catch (SQLException sqle) {
2131:                    log.trace("Caught exception: " + sqle
2132:                            + ExceptionUtility.captureStackTrace(sqle));
2133:
2134:                    throw new RuntimeSecurityManagementException(this 
2135:                            .getClass(),
2136:                            "Caught SQLException while opening connection",
2137:                            sqle);
2138:                }
2139:
2140:                try {
2141:                    allUsers = retreiveAllusernames(connection);
2142:                } finally {
2143:                    try {
2144:                        if (connection != null) {
2145:                            connection.close();
2146:                        }
2147:                    } catch (SQLException sqle) {
2148:                        log.info("Caught exception closing Connection: " + sqle
2149:                                + ExceptionUtility.captureStackTrace(sqle));
2150:                    }
2151:                }
2152:
2153:                return allUsers;
2154:            }
2155:
2156:            /**
2157:             * Retreives all unique names of users from the store as a Set of
2158:             * Strings.
2159:             *
2160:             * @param connection connection to execute database calls against
2161:             *
2162:             * @return All unique user names as a Set of Strings.  If there are no
2163:             *         users in the system and empty Set will be returned.
2164:             *
2165:             * @throws RuntimeSecurityManagementException indicates an error
2166:             *         communicating with the database or inconsistent state.
2167:             */
2168:            protected Set retreiveAllusernames(Connection connection) {
2169:                Set allUsers = new HashSet();
2170:                PreparedStatement retreiveAllUsersStatement = null;
2171:                ResultSet retreiveAllUsersResultSet = null;
2172:
2173:                if (log.isTraceEnabled()) {
2174:                    log.trace("Searching for all users.");
2175:                }
2176:
2177:                try {
2178:                    retreiveAllUsersStatement = config.getStatementFactory()
2179:                            .createPreparedStatement(
2180:                                    config.getRetreiveAllUsersQuery(),
2181:                                    connection);
2182:
2183:                    retreiveAllUsersResultSet = retreiveAllUsersStatement
2184:                            .executeQuery();
2185:
2186:                    while (retreiveAllUsersResultSet.next()) {
2187:                        allUsers.add(retreiveAllUsersResultSet.getString(1));
2188:                    }
2189:                } catch (StatementFactoryException sfe) {
2190:                    log.trace("Caught exception: " + sfe
2191:                            + ExceptionUtility.captureStackTrace(sfe));
2192:
2193:                    throw new RuntimeSecurityManagementException(this 
2194:                            .getClass(),
2195:                            "Caught StatementFactoryException while retreiving "
2196:                                    + "users.", sfe);
2197:                } catch (SQLException sqle) {
2198:                    log.trace("Caught exception: " + sqle
2199:                            + ExceptionUtility.captureStackTrace(sqle));
2200:
2201:                    throw new RuntimeSecurityManagementException(this 
2202:                            .getClass(),
2203:                            "Caught SQLException while retreiving users.", sqle);
2204:                } finally {
2205:                    try {
2206:                        if (retreiveAllUsersResultSet != null) {
2207:                            retreiveAllUsersResultSet.close();
2208:                        }
2209:                    } catch (SQLException sqle) {
2210:                        log.info("Caught exception closing ResultSet: " + sqle
2211:                                + ExceptionUtility.captureStackTrace(sqle));
2212:                    }
2213:
2214:                    try {
2215:                        if (retreiveAllUsersStatement != null) {
2216:                            retreiveAllUsersStatement.close();
2217:                        }
2218:                    } catch (SQLException sqle) {
2219:                        log.info("Caught exception closing Statement: " + sqle
2220:                                + ExceptionUtility.captureStackTrace(sqle));
2221:                    }
2222:                }
2223:
2224:                return allUsers;
2225:            }
2226:
2227:            /**
2228:             * Retreives all unique names of groups from the store as a Set of
2229:             * Strings.
2230:             *
2231:             * @return All unique group names as a Set of Strings.  If there are
2232:             *         no group in the system and empty Set will be returned.
2233:             *
2234:             * @throws RuntimeSecurityManagementException indicates an error
2235:             *         communicating with the database or inconsistent state.
2236:             */
2237:            public Set retreiveAllGroupNames() {
2238:
2239:                Connection connection = null;
2240:                Set allGroups = null;
2241:
2242:                try {
2243:                    connection = config.getConnectionFactory().getConnection();
2244:                } catch (SQLException sqle) {
2245:                    log.trace("Caught exception: " + sqle
2246:                            + ExceptionUtility.captureStackTrace(sqle));
2247:
2248:                    throw new RuntimeSecurityManagementException(this 
2249:                            .getClass(),
2250:                            "Caught SQLException while opening connection",
2251:                            sqle);
2252:                }
2253:
2254:                try {
2255:                    allGroups = retreiveAllGroupNames(connection);
2256:                } finally {
2257:                    try {
2258:                        if (connection != null) {
2259:                            connection.close();
2260:                        }
2261:                    } catch (SQLException sqle) {
2262:                        log.info("Caught exception closing Connection: " + sqle
2263:                                + ExceptionUtility.captureStackTrace(sqle));
2264:                    }
2265:                }
2266:
2267:                return allGroups;
2268:            }
2269:
2270:            /**
2271:             * Retreives all unique names of groups from the store as a Set of
2272:             * Strings.
2273:             *
2274:             * @param connection connection to execute database calls against
2275:             *
2276:             * @return All unique group names as a Set of Strings.  If there are
2277:             *         no group in the system and empty Set will be returned.
2278:             *
2279:             * @throws RuntimeSecurityManagementException indicates an error
2280:             *         communicating with the database or inconsistent state.
2281:             */
2282:            protected Set retreiveAllGroupNames(Connection connection) {
2283:                Set allGroups = new HashSet();
2284:                PreparedStatement retreiveAllGroupsStatement = null;
2285:                ResultSet retreiveAllGroupsResultSet = null;
2286:
2287:                if (log.isTraceEnabled()) {
2288:                    log.trace("Searching for all users.");
2289:                }
2290:
2291:                try {
2292:                    retreiveAllGroupsStatement = config.getStatementFactory()
2293:                            .createPreparedStatement(
2294:                                    config.getRetreiveAllGroupsQuery(),
2295:                                    connection);
2296:
2297:                    retreiveAllGroupsResultSet = retreiveAllGroupsStatement
2298:                            .executeQuery();
2299:
2300:                    while (retreiveAllGroupsResultSet.next()) {
2301:                        allGroups.add(retreiveAllGroupsResultSet.getString(1));
2302:                    }
2303:                } catch (StatementFactoryException sfe) {
2304:                    log.trace("Caught exception: " + sfe
2305:                            + ExceptionUtility.captureStackTrace(sfe));
2306:
2307:                    throw new RuntimeSecurityManagementException(this 
2308:                            .getClass(),
2309:                            "Caught StatementFactoryException while retreiving "
2310:                                    + "groups.", sfe);
2311:                } catch (SQLException sqle) {
2312:                    log.trace("Caught exception: " + sqle
2313:                            + ExceptionUtility.captureStackTrace(sqle));
2314:
2315:                    throw new RuntimeSecurityManagementException(this 
2316:                            .getClass(),
2317:                            "Caught SQLException while retreiving groups.",
2318:                            sqle);
2319:                } finally {
2320:                    try {
2321:                        if (retreiveAllGroupsResultSet != null) {
2322:                            retreiveAllGroupsResultSet.close();
2323:                        }
2324:                    } catch (SQLException sqle) {
2325:                        log.info("Caught exception closing ResultSet: " + sqle
2326:                                + ExceptionUtility.captureStackTrace(sqle));
2327:                    }
2328:
2329:                    try {
2330:                        if (retreiveAllGroupsStatement != null) {
2331:                            retreiveAllGroupsStatement.close();
2332:                        }
2333:                    } catch (SQLException sqle) {
2334:                        log.info("Caught exception closing Statement: " + sqle
2335:                                + ExceptionUtility.captureStackTrace(sqle));
2336:                    }
2337:                }
2338:
2339:                return allGroups;
2340:            }
2341:
2342:            /**
2343:             * Gets back the primary key in the database for a given principal.
2344:             *
2345:             * <p>
2346:             * This may execute a query to retreive it, or if the information is
2347:             * contained within the Principal object it may return it from there.
2348:             * </p>
2349:             *
2350:             * @param connection connection to execute database calls against
2351:             * @param principal the principal to get the primary key for.
2352:             *
2353:             * @return primary key for the user.  This may be a String, Integer,
2354:             *         etc.
2355:             *
2356:             * @throws UnknownPrincipalException indicates the principal does not
2357:             *         currently exists in the system
2358:             * @throws UnknownGroupException indicates the group does not
2359:             *         currently exists in the system
2360:             *
2361:             * @see #retreiveUserPrimaryKey
2362:             * @see #retreiveGroupPrimaryKey
2363:             */
2364:            protected Object retreivePrincipalPrimaryKey(Connection connection,
2365:                    Principal principal) throws UnknownPrincipalException,
2366:                    UnknownGroupException {
2367:                Object primaryKey;
2368:
2369:                if (principal instanceof  Group) {
2370:                    primaryKey = retreiveGroupPrimaryKey(connection,
2371:                            (Group) principal);
2372:                } else {
2373:                    primaryKey = retreiveUserPrimaryKey(connection, principal);
2374:                }
2375:
2376:                return primaryKey;
2377:            }
2378:
2379:            /**
2380:             * Gets back the primary key in the database for a given user.
2381:             *
2382:             * <p>
2383:             * This may execute a query to retreive it, or if the information is
2384:             * contained within the Principal object it may return it from there.
2385:             * </p>
2386:             *
2387:             * @param connection connection to execute database calls against
2388:             * @param principal the principal to get the primary key for.
2389:             *
2390:             * @return primary key for the user.  This may be a String, Integer,
2391:             *         etc.
2392:             *
2393:             * @throws UnknownPrincipalException indicates the principal does not
2394:             *         currently exists in the system
2395:             * @throws RuntimeSecurityManagementException indicates an error
2396:             *         communicating with the database or inconsistent state.
2397:             */
2398:            protected Object retreiveUserPrimaryKey(Connection connection,
2399:                    Principal principal) throws UnknownPrincipalException {
2400:                PreparedStatement retreiveUserPrimaryKeyStatement = null;
2401:                ResultSet retreiveUserPrimaryKeyResultSet = null;
2402:                Object userPrimaryKey = null;
2403:
2404:                try {
2405:                    retreiveUserPrimaryKeyStatement = config
2406:                            .getStatementFactory()
2407:                            .createPreparedStatement(
2408:                                    config.getRetreiveUserPrimaryKeyQueryName(),
2409:                                    connection);
2410:
2411:                    retreiveUserPrimaryKeyStatement.setObject(1, principal
2412:                            .getName());
2413:
2414:                    retreiveUserPrimaryKeyResultSet = retreiveUserPrimaryKeyStatement
2415:                            .executeQuery();
2416:
2417:                    if (retreiveUserPrimaryKeyResultSet.next()) {
2418:                        userPrimaryKey = retreiveUserPrimaryKeyResultSet
2419:                                .getObject(1);
2420:                    } else {
2421:                        throw new UnknownPrincipalException(this .getClass(),
2422:                                principal.getName());
2423:                    }
2424:
2425:                    if (log.isTraceEnabled()) {
2426:                        log.trace("Retreived primary key for user with name ["
2427:                                + principal.getName() + "] of value ["
2428:                                + userPrimaryKey + "]");
2429:                    }
2430:                } catch (StatementFactoryException sfe) {
2431:                    log.trace("Caught exception: " + sfe
2432:                            + ExceptionUtility.captureStackTrace(sfe));
2433:
2434:                    throw new RuntimeSecurityManagementException(this 
2435:                            .getClass(),
2436:                            "Caught StatementFactoryException while getting primary key "
2437:                                    + "for user [" + principal.getName() + "]",
2438:                            sfe);
2439:                } catch (SQLException sqle) {
2440:                    log.trace("Caught exception: " + sqle
2441:                            + ExceptionUtility.captureStackTrace(sqle));
2442:
2443:                    throw new RuntimeSecurityManagementException(this 
2444:                            .getClass(),
2445:                            "Caught SQLException while getting primary key "
2446:                                    + "for user [" + principal.getName() + "]",
2447:                            sqle);
2448:                } finally {
2449:                    try {
2450:                        if (retreiveUserPrimaryKeyResultSet != null) {
2451:                            retreiveUserPrimaryKeyResultSet.close();
2452:                        }
2453:                    } catch (SQLException sqle) {
2454:                        // Ignore exception.
2455:                    }
2456:
2457:                    try {
2458:                        if (retreiveUserPrimaryKeyStatement != null) {
2459:                            retreiveUserPrimaryKeyStatement.close();
2460:                        }
2461:                    } catch (SQLException sqle) {
2462:                        // Ignore exception.
2463:                    }
2464:                }
2465:
2466:                return userPrimaryKey;
2467:            }
2468:
2469:            /**
2470:             * Gets back the primary key in the database for a given group.
2471:             *
2472:             * <p>
2473:             * This may execute a query to retreive it, or if the information is
2474:             * contained within the Principal object it may return it from there.
2475:             * </p>
2476:             *
2477:             * @param connection connection to execute database calls against
2478:             * @param group the principal to get the primary key for.
2479:             *
2480:             * @return primary key for the user.  This may be a String, Integer,
2481:             *         etc.
2482:             *
2483:             * @throws UnknownGroupException indicates the principal does not
2484:             *         currently exists in the system
2485:             * @throws RuntimeSecurityManagementException indicates an error
2486:             *         communicating with the database or inconsistent state.
2487:             */
2488:            protected Object retreiveGroupPrimaryKey(Connection connection,
2489:                    Group group) throws UnknownGroupException {
2490:                PreparedStatement retreiveGroupPrimaryKeyStatement = null;
2491:                ResultSet retreiveGroupPrimaryKeyResultSet = null;
2492:                Object groupPrimaryKey = null;
2493:
2494:                try {
2495:                    retreiveGroupPrimaryKeyStatement = config
2496:                            .getStatementFactory()
2497:                            .createPreparedStatement(
2498:                                    config
2499:                                            .getRetreiveGroupPrimaryKeyQueryName(),
2500:                                    connection);
2501:
2502:                    retreiveGroupPrimaryKeyStatement.setObject(1, group
2503:                            .getName());
2504:
2505:                    retreiveGroupPrimaryKeyResultSet = retreiveGroupPrimaryKeyStatement
2506:                            .executeQuery();
2507:
2508:                    if (retreiveGroupPrimaryKeyResultSet.next()) {
2509:                        groupPrimaryKey = retreiveGroupPrimaryKeyResultSet
2510:                                .getObject(1);
2511:                    } else {
2512:                        throw new UnknownGroupException(this .getClass(), group
2513:                                .getName());
2514:                    }
2515:
2516:                    if (log.isTraceEnabled()) {
2517:                        log.trace("Retreived primary key for group with name ["
2518:                                + group.getName() + "] of value ["
2519:                                + groupPrimaryKey + "]");
2520:                    }
2521:                } catch (StatementFactoryException sfe) {
2522:                    log.trace("Caught exception: " + sfe
2523:                            + ExceptionUtility.captureStackTrace(sfe));
2524:
2525:                    throw new RuntimeSecurityManagementException(this 
2526:                            .getClass(),
2527:                            "Caught StatementFactoryException while getting primary key "
2528:                                    + "for group [" + group.getName() + "]",
2529:                            sfe);
2530:                } catch (SQLException sqle) {
2531:                    log.trace("Caught exception: " + sqle
2532:                            + ExceptionUtility.captureStackTrace(sqle));
2533:
2534:                    throw new RuntimeSecurityManagementException(this 
2535:                            .getClass(),
2536:                            "Caught SQLException while getting primary key "
2537:                                    + "for group [" + group.getName() + "]",
2538:                            sqle);
2539:                } finally {
2540:                    try {
2541:                        if (retreiveGroupPrimaryKeyResultSet != null) {
2542:                            retreiveGroupPrimaryKeyResultSet.close();
2543:                        }
2544:                    } catch (SQLException sqle) {
2545:                        // Ignore exception.
2546:                    }
2547:
2548:                    try {
2549:                        if (retreiveGroupPrimaryKeyStatement != null) {
2550:                            retreiveGroupPrimaryKeyStatement.close();
2551:                        }
2552:                    } catch (SQLException sqle) {
2553:                        // Ignore exception.
2554:                    }
2555:                }
2556:
2557:                return groupPrimaryKey;
2558:            }
2559:
2560:            /**
2561:             * Configures the service.
2562:             *
2563:             * @param configuration <code>RdbmsUserManagerConfiguration</code>
2564:             *        configuration object for the service
2565:             *
2566:             * @throws InvalidConfigurationException indicates an error loading
2567:             *         the configuration
2568:             */
2569:            public void configure(ComponentConfiguration configuration) {
2570:
2571:                try {
2572:                    this .config = (RdbmsUserManagerConfiguration) configuration;
2573:                } catch (ClassCastException cce) {
2574:                    throw new InvalidConfigurationException(this .getClass(),
2575:                            configuration.getConfigurationName(),
2576:                            "ComponentConfiguration",
2577:                            "Specifed RdbmsUserManagerConfiguration does not implement "
2578:                                    + "correct interface.", cce);
2579:                }
2580:            }
2581:        }
w___w___w._j___a_v__a_2__s.c_om__ | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.