/** * Licensed to Apereo under one or more contributor license agreements. See the NOTICE file * distributed with this work for additional information regarding copyright ownership. Apereo * licenses this file to you under the Apache License, Version 2.0 (the "License"); you may not use * this file except in compliance with the License. You may obtain a copy of the License at the * following location: * * <p>http://www.apache.org/licenses/LICENSE-2.0 * * <p>Unless required by applicable law or agreed to in writing, software distributed under the * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either * express or implied. See the License for the specific language governing permissions and * limitations under the License. */ package org.apereo.portal; import com.googlecode.ehcache.annotations.Cacheable; import java.io.Serializable; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.util.List; import java.util.Set; import java.util.regex.Pattern; import javax.sql.DataSource; import net.sf.ehcache.Ehcache; import net.sf.ehcache.constructs.blocking.CacheEntryFactory; import net.sf.ehcache.constructs.blocking.SelfPopulatingCache; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apereo.portal.groups.IEntityGroup; import org.apereo.portal.groups.IGroupMember; import org.apereo.portal.groups.ILockableEntityGroup; import org.apereo.portal.jdbc.RDBMServices; import org.apereo.portal.jpa.BasePortalJpaDao; import org.apereo.portal.layout.dao.IStylesheetUserPreferencesDao; import org.apereo.portal.layout.om.IStylesheetUserPreferences; import org.apereo.portal.persondir.ILocalAccountDao; import org.apereo.portal.persondir.ILocalAccountPerson; import org.apereo.portal.portlet.dao.IPortletEntityDao; import org.apereo.portal.portlet.om.IPortletEntity; import org.apereo.portal.security.IPerson; import org.apereo.portal.security.PersonFactory; import org.apereo.portal.services.GroupService; import org.apereo.portal.spring.locator.CounterStoreLocator; import org.apereo.portal.utils.SerializableObject; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.beans.factory.annotation.Value; import org.springframework.dao.DataAccessException; import org.springframework.dao.support.DataAccessUtils; import org.springframework.jdbc.core.ConnectionCallback; import org.springframework.jdbc.core.JdbcOperations; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.stereotype.Service; import org.springframework.transaction.PlatformTransactionManager; import org.springframework.transaction.TransactionStatus; import org.springframework.transaction.support.TransactionCallback; import org.springframework.transaction.support.TransactionCallbackWithoutResult; import org.springframework.transaction.support.TransactionOperations; import org.springframework.transaction.support.TransactionTemplate; /** * SQL implementation for managing creation and removal of User Portal Data * * Dalquist - edalquist@unicon.net) */ @Service("userIdentityStore") public class RDBMUserIdentityStore implements IUserIdentityStore { private static final Log log = LogFactory.getLog(RDBMUserIdentityStore.class); private static final String PROFILE_TABLE = "UP_USER_PROFILE"; public static final String USERNAME_VALIDATOR_REGEX = "^[^\\s]{1,100}$"; private static final Pattern USERNAME_VALIDATOR_PATTERN = Pattern.compile(USERNAME_VALIDATOR_REGEX); //********************************************************************* // Constants private static final String templateAttrName = "uPortalTemplateUserName"; private String defaultTemplateUserName; private JdbcOperations jdbcOperations; private TransactionOperations transactionOperations; private IPortletEntityDao portletEntityDao; private IStylesheetUserPreferencesDao stylesheetUserPreferencesDao; private ILocalAccountDao localAccountDao; private Ehcache userLockCache; @Value("${org.apereo.portal.services.Authentication.defaultTemplateUserName}") public void setDefaultTemplateUserName(String defaultTemplateUserName) { this.defaultTemplateUserName = defaultTemplateUserName; } @Autowired public void setPortletEntityDao(@Qualifier("persistence") IPortletEntityDao portletEntityDao) { this.portletEntityDao = portletEntityDao; } @Autowired public void setStylesheetUserPreferencesDao( IStylesheetUserPreferencesDao stylesheetUserPreferencesDao) { this.stylesheetUserPreferencesDao = stylesheetUserPreferencesDao; } @Autowired public void setLocalAccountDao(ILocalAccountDao localAccountDao) { this.localAccountDao = localAccountDao; } @Autowired @Qualifier("org.apereo.portal.RDBMUserIdentityStore.userLockCache") public void setUserLockCache(Ehcache userLockCache) { this.userLockCache = new SelfPopulatingCache( userLockCache, new CacheEntryFactory() { @Override public Object createEntry(Object key) throws Exception { return new SerializableObject(); } }); } @Autowired public void setPlatformTransactionManager( @Qualifier(BasePortalJpaDao.PERSISTENCE_UNIT_NAME) PlatformTransactionManager platformTransactionManager) { this.transactionOperations = new TransactionTemplate(platformTransactionManager); } @javax.annotation.Resource(name = BasePortalJpaDao.PERSISTENCE_UNIT_NAME) public void setDataSource(DataSource dataSource) { this.jdbcOperations = new JdbcTemplate(dataSource); } private Serializable getLock(IPerson person) { final String username = (String) person.getAttribute(IPerson.USERNAME); return this.userLockCache.get(username); } /** * getuPortalUID - return a unique uPortal key for a user. calls alternate signature with * createPortalData set to false. * * @param person the person object * @return uPortalUID number * @throws Exception if no user is found. */ public int getPortalUID(IPerson person) throws AuthorizationException { int uPortalUID = -1; uPortalUID = this.getPortalUID(person, false); return uPortalUID; } @Override public void removePortalUID(final String userName) { this.transactionOperations.execute( new TransactionCallbackWithoutResult() { @Override protected void doInTransactionWithoutResult(TransactionStatus arg0) { if (PersonFactory.GUEST_USERNAMES.contains(userName)) { throw new IllegalArgumentException( "CANNOT RESET LAYOUT FOR A GUEST USER"); } final int userId = jdbcOperations.queryForObject( "SELECT USER_ID FROM UP_USER WHERE USER_NAME=?", Integer.class, userName); final int type = jdbcOperations.queryForObject( "SELECT ENTITY_TYPE_ID FROM UP_ENTITY_TYPE WHERE ENTITY_TYPE_NAME = ?", Integer.class, IPerson.class.getName()); jdbcOperations.update( "DELETE FROM UP_PERMISSION WHERE PRINCIPAL_KEY=? AND PRINCIPAL_TYPE=?", userName, type); final List<Integer> groupIds = jdbcOperations.queryForList( "SELECT M.GROUP_ID " + "FROM UP_GROUP_MEMBERSHIP M, UP_GROUP G, UP_ENTITY_TYPE E " + "WHERE M.GROUP_ID = G.GROUP_ID " + " AND G.ENTITY_TYPE_ID = E.ENTITY_TYPE_ID " + " AND E.ENTITY_TYPE_NAME = 'org.apereo.portal.security.IPerson'" + " AND M.MEMBER_KEY =? AND M.MEMBER_IS_GROUP = 'F'", Integer.class, userName); // Remove from local group // Delete from DeleteUser.java and place here // must be made before delete user in UP_USER for (final Integer groupId : groupIds) { // GROUP_ID is a VARCHAR String gid = groupId.toString(); jdbcOperations.update( "DELETE FROM UP_GROUP_MEMBERSHIP WHERE MEMBER_KEY=? AND GROUP_ID=?", userName, gid); } jdbcOperations.update( "DELETE FROM UP_USER WHERE USER_ID = ?", userId); jdbcOperations.update( "DELETE FROM UP_USER_LAYOUT WHERE USER_ID = ?", userId); jdbcOperations.update( "DELETE FROM UP_USER_PROFILE WHERE USER_ID = ?", userId); jdbcOperations.update( "DELETE FROM UP_LAYOUT_PARAM WHERE USER_ID = ?", userId); jdbcOperations.update( "DELETE FROM UP_LAYOUT_STRUCT WHERE USER_ID = ?", userId); jdbcOperations.update( "DELETE FROM UP_USER_LOCALE WHERE USER_ID = ?", userId); //Purge all portlet entity data final Set<IPortletEntity> portletEntities = portletEntityDao.getPortletEntitiesForUser(userId); for (final IPortletEntity portletEntity : portletEntities) { portletEntityDao.deletePortletEntity(portletEntity); } //Purge all stylesheet preference data final List<? extends IStylesheetUserPreferences> stylesheetUserPreferences = stylesheetUserPreferencesDao.getStylesheetUserPreferencesForUser( userId); for (final IStylesheetUserPreferences stylesheetUserPreference : stylesheetUserPreferences) { stylesheetUserPreferencesDao.deleteStylesheetUserPreferences( stylesheetUserPreference); } final ILocalAccountPerson person = localAccountDao.getPerson(userName); if (person != null) { localAccountDao.deleteAccount(person); } } }); } /** * removeuPortalUID * * @param uPortalUID integer key to uPortal data for a user * @throws SQLException exception if a sql error is encountered */ @Override public void removePortalUID(final int uPortalUID) { this.transactionOperations.execute( new TransactionCallbackWithoutResult() { @Override protected void doInTransactionWithoutResult(TransactionStatus arg0) { final String name = jdbcOperations.queryForObject( "SELECT USER_NAME FROM UP_USER WHERE USER_ID=?", String.class, uPortalUID); if (name == null) { log.warn( "No user exists for id " + uPortalUID + " Nothing will be deleted"); return; } removePortalUID(name); } }); } /** * Get the portal user ID for this person object. * * @param person * @param createPortalData indicating whether to try to create all uPortal data for this user * from template prototype * @return uPortalUID number or -1 if unable to create user. * @throws AuthorizationException if createPortalData is false and no user is found or if a sql * error is encountered */ public int getPortalUID(IPerson person, boolean createPortalData) throws AuthorizationException { int uid; String username = (String) person.getAttribute(IPerson.USERNAME); // only synchronize a non-guest request. if (PersonFactory.GUEST_USERNAMES.contains(username)) { uid = __getPortalUID(person, createPortalData); } else { Object lock = getLock(person); synchronized (lock) { uid = __getPortalUID(person, createPortalData); } } return uid; } /* (non-javadoc) * @see org.apereo.portal.IUserIdentityStore#getPortalUserName(int) */ public String getPortalUserName(final int uPortalUID) { final List<String> results = this.jdbcOperations.queryForList( "SELECT USER_NAME FROM UP_USER WHERE USER_ID=?", String.class, uPortalUID); return DataAccessUtils.singleResult(results); } /* (non-Javadoc) * @see org.apereo.portal.IUserIdentityStore#getPortalUserId(java.lang.String) */ @Override public Integer getPortalUserId(String userName) { final List<Integer> results = this.jdbcOperations.queryForList( "SELECT USER_ID FROM UP_USER WHERE USER_NAME=?", Integer.class, userName); return DataAccessUtils.singleResult(results); } @Override public boolean validateUsername(final String username) { /* * The rules, so far... * - Must not be blank * - Must not contain spaces * - Must not exceed 100 characters (current DB column size) */ return USERNAME_VALIDATOR_PATTERN.matcher(username).matches(); } private static final String IS_DEFAULT_USER_QUERY = "SELECT count(*)\n" + "FROM up_user upuA\n" + " right join up_user upuB on upuA.USER_ID = upuB.USER_DFLT_USR_ID\n" + "WHERE upuA.user_name=?"; /* (non-Javadoc) * @see org.apereo.portal.IUserIdentityStore#isDefaultUser(java.lang.String) */ @Override @Cacheable(cacheName = "org.apereo.portal.RDBMUserIdentityStore.isDefaultUser") public boolean isDefaultUser(String username) { final int defaultUserCount = this.jdbcOperations.queryForObject(IS_DEFAULT_USER_QUERY, Integer.class, username); return defaultUserCount > 0; } private int __getPortalUID(IPerson person, boolean createPortalData) throws AuthorizationException { PortalUser portalUser = null; try { String userName = person.getUserName(); String templateName = getTemplateName(person); portalUser = getPortalUser(userName); if (createPortalData) { //If we are allowed to modify the database if (portalUser != null) { //If the user has logged in we may have to update their template user information boolean hasSavedLayout = userHasSavedLayout(portalUser.getUserId()); if (!hasSavedLayout) { TemplateUser templateUser = getTemplateUser(templateName); if (portalUser.getDefaultUserId() != templateUser.getUserId()) { //Update user data with new template user's data updateUser(portalUser.getUserId(), person, templateUser); } } } else { //User hasn't logged in before, some data needs to be created for them based on their template user // Retrieve the information for the template user TemplateUser templateUser = getTemplateUser(templateName); if (templateUser == null) { throw new AuthorizationException( "No information found for template user = " + templateName + ". Cannot create new account for " + userName); } // Get a new user ID for this user int newUID = getNewPortalUID(person); // Add new user to all appropriate tables int newPortalUID = addNewUser(newUID, person, templateUser); portalUser = new PortalUser(); portalUser.setUserId(newPortalUID); } } else if (portalUser == null) { //If this is a new user and we can't create them throw new AuthorizationException( "No portal information exists for user " + userName); } } catch (AuthorizationException e) { throw e; } catch (Exception e) { final String msg = "Failed to obtain a portal user Id for the specified person: " + person; throw new RuntimeException(msg, e); } return portalUser.getUserId(); } protected int getNewPortalUID(IPerson person) throws Exception { return CounterStoreLocator.getCounterStore().getNextId("UP_USER"); } protected static final void commit(Connection connection) { try { if (RDBMServices.getDbMetaData().supportsTransactions()) connection.commit(); } catch (Exception e) { log.error("RDBMUserIdentityStore::commit(): " + e); } } protected static final void rollback(Connection connection) { try { if (RDBMServices.getDbMetaData().supportsTransactions()) connection.rollback(); } catch (Exception e) { log.error("RDBMUserIdentityStore::rollback(): " + e); } } /** * Gets the PortalUser data store object for the specified user name. * * @param userName The user's name * @return A PortalUser object or null if the user doesn't exist. * @throws Exception */ protected PortalUser getPortalUser(final String userName) throws Exception { return jdbcOperations.execute( new ConnectionCallback<PortalUser>() { @Override public PortalUser doInConnection(Connection con) throws SQLException, DataAccessException { PortalUser portalUser = null; PreparedStatement pstmt = null; try { String query = "SELECT USER_ID, USER_DFLT_USR_ID FROM UP_USER WHERE USER_NAME=?"; pstmt = con.prepareStatement(query); pstmt.setString(1, userName); ResultSet rs = null; try { if (log.isDebugEnabled()) log.debug( "RDBMUserIdentityStore::getPortalUID(userName=" + userName + "): " + query); rs = pstmt.executeQuery(); if (rs.next()) { portalUser = new PortalUser(); portalUser.setUserId(rs.getInt("USER_ID")); portalUser.setUserName(userName); portalUser.setDefaultUserId(rs.getInt("USER_DFLT_USR_ID")); } } finally { try { rs.close(); } catch (Exception e) { } } } finally { try { pstmt.close(); } catch (Exception e) { } } return portalUser; } }); } protected String getTemplateName(IPerson person) { String templateName = (String) person.getAttribute(templateAttrName); // Just use the default template if requested template not populated if (templateName == null || templateName.equals("")) { templateName = defaultTemplateUserName; } return templateName; } /** * Gets the TemplateUser data store object for the specified template user name. * * @param templateUserName The template user's name * @return A TemplateUser object or null if the user doesn't exist. * @throws Exception */ protected TemplateUser getTemplateUser(final String templateUserName) throws Exception { return jdbcOperations.execute( new ConnectionCallback<TemplateUser>() { @Override public TemplateUser doInConnection(Connection con) throws SQLException, DataAccessException { TemplateUser templateUser = null; PreparedStatement pstmt = null; try { String query = "SELECT USER_ID, USER_DFLT_LAY_ID FROM UP_USER WHERE USER_NAME=?"; pstmt = con.prepareStatement(query); pstmt.setString(1, templateUserName); ResultSet rs = null; try { if (log.isDebugEnabled()) log.debug( "RDBMUserIdentityStore::getTemplateUser(templateUserName=" + templateUserName + "): " + query); rs = pstmt.executeQuery(); if (rs.next()) { templateUser = new TemplateUser(); templateUser.setUserName(templateUserName); templateUser.setUserId(rs.getInt("USER_ID")); templateUser.setDefaultLayoutId(rs.getInt("USER_DFLT_LAY_ID")); } else { if (!templateUserName.equals(defaultTemplateUserName)) { try { templateUser = getTemplateUser(defaultTemplateUserName); } catch (Exception e) { throw new SQLException(e); } } } } finally { try { rs.close(); } catch (Exception e) { } } } finally { try { pstmt.close(); } catch (Exception e) { } } return templateUser; } }); } protected boolean userHasSavedLayout(final int userId) throws Exception { return jdbcOperations.execute( new ConnectionCallback<Boolean>() { @Override public Boolean doInConnection(Connection con) throws SQLException, DataAccessException { boolean userHasSavedLayout = false; PreparedStatement pstmt = null; try { String query = "SELECT * FROM UP_USER_PROFILE WHERE USER_ID=? AND LAYOUT_ID IS NOT NULL AND LAYOUT_ID!=0"; pstmt = con.prepareStatement(query); pstmt.setInt(1, userId); ResultSet rs = null; try { if (log.isDebugEnabled()) log.debug( "RDBMUserIdentityStore::getTemplateUser(userId=" + userId + "): " + query); rs = pstmt.executeQuery(); if (rs.next()) { userHasSavedLayout = true; } } finally { try { rs.close(); } catch (Exception e) { } } } finally { try { pstmt.close(); } catch (Exception e) { } } return userHasSavedLayout; } }); } private ILockableEntityGroup getSafeLockableGroup(IEntityGroup eg, IGroupMember gm) { if (log.isTraceEnabled()) { log.trace("Creating lockable group for group/member: " + eg + "/" + gm); } ILockableEntityGroup leg = null; try { if (eg.isEditable()) { leg = GroupService.findLockableGroup(eg.getKey(), gm.getKey()); } } catch (Exception e) { // Bummer. but the only thing to do is to press on log.error("Unable to create lockable group for group/member: " + eg + "/" + gm, e); } return leg; } /** * Remove a person from a group. This method catches and logs exceptions exceptions encountered * performing the removal. * * @param person person to be removed (used for logging) * @param me member representing the person * @param eg group from which the user should be removed */ private void removePersonFromGroup(IPerson person, IGroupMember me, IEntityGroup eg) { if (log.isTraceEnabled()) { log.trace("Removing " + person + " from group " + eg); } try { if (eg.isEditable()) { eg.removeChild(me); eg.updateMembers(); } } catch (Exception e) { // Bummer. but the only thing to do is to press on log.error("Unable to remove " + person + " from group " + eg, e); } } /** * Add a person to a group. This method catches and logs exceptions encountered performing the * removal. * * @param person person to be added (used for logging) * @param me member representing the person * @param eg group to which the user should be added */ private void addPersonToGroup(IPerson person, IGroupMember me, IEntityGroup eg) { if (log.isTraceEnabled()) { log.trace("Adding " + person + " to group " + eg); } try { if (eg.isEditable()) { eg.addChild(me); eg.updateMembers(); } } catch (Exception e) { log.error("Unable to add " + person + " to group " + eg, e); } } protected void updateUser( final int userId, final IPerson person, final TemplateUser templateUser) throws Exception { // Remove my existing group memberships IGroupMember me = GroupService.getGroupMember(person.getEntityIdentifier()); for (IEntityGroup eg : me.getParentGroups()) { ILockableEntityGroup leg = getSafeLockableGroup(eg, me); if (leg != null) { removePersonFromGroup(person, me, leg); } } // Copy template user's groups memberships IGroupMember template = GroupService.getEntity(templateUser.getUserName(), IPerson.class); for (IEntityGroup eg : template.getParentGroups()) { ILockableEntityGroup leg = getSafeLockableGroup(eg, me); if (leg != null) { addPersonToGroup(person, me, leg); } } this.transactionOperations.execute( new TransactionCallback<Object>() { @Override public Object doInTransaction(TransactionStatus status) { return jdbcOperations.execute( new ConnectionCallback<Object>() { @Override public Object doInConnection(Connection con) throws SQLException, DataAccessException { PreparedStatement deleteStmt = null; PreparedStatement queryStmt = null; PreparedStatement insertStmt = null; try { // Update UP_USER String update = "UPDATE UP_USER " + "SET USER_DFLT_USR_ID=?, " + "USER_DFLT_LAY_ID=?, " + "NEXT_STRUCT_ID=null " + "WHERE USER_ID=?"; insertStmt = con.prepareStatement(update); insertStmt.setInt(1, templateUser.getUserId()); insertStmt.setInt(2, templateUser.getDefaultLayoutId()); insertStmt.setInt(3, userId); if (log.isDebugEnabled()) log.debug( "RDBMUserIdentityStore::addNewUser(): " + update); insertStmt.executeUpdate(); insertStmt.close(); // Start copying... ResultSet rs = null; String delete = null; String query = null; String insert = null; try { // Update UP_USER_PROFILE delete = "DELETE FROM UP_USER_PROFILE " + "WHERE USER_ID=?"; deleteStmt = con.prepareStatement(delete); deleteStmt.setInt(1, userId); if (log.isDebugEnabled()) log.debug( "RDBMUserIdentityStore::updateUser(USER_ID=" + userId + "): " + delete); deleteStmt.executeUpdate(); deleteStmt.close(); query = "SELECT USER_ID, PROFILE_FNAME, PROFILE_NAME, DESCRIPTION, " + "STRUCTURE_SS_ID, THEME_SS_ID " + "FROM UP_USER_PROFILE " + "WHERE USER_ID=?"; queryStmt = con.prepareStatement(query); queryStmt.setInt(1, templateUser.getUserId()); if (log.isDebugEnabled()) log.debug( "RDBMUserIdentityStore::updateUser(USER_ID=" + templateUser.getUserId() + "): " + query); rs = queryStmt.executeQuery(); insert = "INSERT INTO UP_USER_PROFILE (USER_ID, PROFILE_ID, PROFILE_FNAME, PROFILE_NAME, DESCRIPTION, LAYOUT_ID, STRUCTURE_SS_ID, THEME_SS_ID) " + "VALUES(?, ?, ?, ?, ?, NULL, ?, ?)"; insertStmt = con.prepareStatement(insert); while (rs.next()) { int id = getNextKey(); String profileFname = rs.getString("PROFILE_FNAME"); String profileName = rs.getString("PROFILE_NAME"); String description = rs.getString("DESCRIPTION"); int structure = rs.getInt("STRUCTURE_SS_ID"); int theme = rs.getInt("THEME_SS_ID"); insertStmt.setInt(1, userId); insertStmt.setInt(2, id); insertStmt.setString(3, profileFname); insertStmt.setString(4, profileName); insertStmt.setString(5, description); insertStmt.setInt(6, structure); insertStmt.setInt(7, theme); if (log.isDebugEnabled()) log.debug( "RDBMUserIdentityStore::updateUser(USER_ID=" + userId + ", PROFILE_FNAME=" + profileFname + ", PROFILE_NAME=" + profileName + ", DESCRIPTION=" + description + "): " + insert); insertStmt.executeUpdate(); } rs.close(); queryStmt.close(); insertStmt.close(); // If we made it all the way though, commit the transaction if (RDBMServices.getDbMetaData() .supportsTransactions()) con.commit(); } finally { try { rs.close(); } catch (Exception e) { } } } finally { try { deleteStmt.close(); } catch (Exception e) { } try { queryStmt.close(); } catch (Exception e) { } try { insertStmt.close(); } catch (Exception e) { } } return null; } }); } }); } protected int addNewUser( final int newUID, final IPerson person, final TemplateUser templateUser) throws Exception { // Copy template user's groups memberships IGroupMember me = GroupService.getGroupMember(person.getEntityIdentifier()); IGroupMember template = GroupService.getEntity( templateUser.getUserName(), Class.forName("org.apereo.portal.security.IPerson")); for (IEntityGroup eg : template.getParentGroups()) { ILockableEntityGroup leg = getSafeLockableGroup(eg, me); if (leg != null) { addPersonToGroup(person, me, leg); } } return this.transactionOperations.execute( new TransactionCallback<Integer>() { @Override public Integer doInTransaction(TransactionStatus status) { return jdbcOperations.execute( new ConnectionCallback<Integer>() { @Override public Integer doInConnection(Connection con) throws SQLException, DataAccessException { int uPortalUID = -1; PreparedStatement queryStmt = null; PreparedStatement insertStmt = null; try { // Add to UP_USER String insert = "INSERT INTO UP_USER (USER_ID, USER_NAME, USER_DFLT_USR_ID, USER_DFLT_LAY_ID, NEXT_STRUCT_ID, LST_CHAN_UPDT_DT)" + "VALUES (?, ?, ?, ?, null, null)"; String userName = person.getUserName(); insertStmt = con.prepareStatement(insert); insertStmt.setInt(1, newUID); insertStmt.setString(2, userName); insertStmt.setInt(3, templateUser.getUserId()); insertStmt.setInt(4, templateUser.getDefaultLayoutId()); if (log.isDebugEnabled()) log.debug( "RDBMUserIdentityStore::addNewUser(USER_ID=" + newUID + ", USER_NAME=" + userName + ", USER_DFLT_USR_ID=" + templateUser.getUserId() + ", USER_DFLT_LAY_ID=" + templateUser.getDefaultLayoutId() + "): " + insert); insertStmt.executeUpdate(); insertStmt.close(); insertStmt = null; // Start copying... ResultSet rs = null; String query = null; try { // Add to UP_USER_PROFILE query = "SELECT USER_ID, PROFILE_FNAME, PROFILE_NAME, DESCRIPTION, " + "STRUCTURE_SS_ID, THEME_SS_ID " + "FROM UP_USER_PROFILE " + "WHERE USER_ID=?"; queryStmt = con.prepareStatement(query); queryStmt.setInt(1, templateUser.getUserId()); if (log.isDebugEnabled()) log.debug( "RDBMUserIdentityStore::addNewUser(USER_ID=" + templateUser.getUserId() + "): " + query); rs = queryStmt.executeQuery(); insert = "INSERT INTO UP_USER_PROFILE (USER_ID, PROFILE_ID, PROFILE_FNAME, PROFILE_NAME, DESCRIPTION, LAYOUT_ID, STRUCTURE_SS_ID, THEME_SS_ID) " + "VALUES(?, ?, ?, ?, ?, NULL, ?, ?)"; insertStmt = con.prepareStatement(insert); while (rs.next()) { int id = getNextKey(); String profileFname = rs.getString("PROFILE_FNAME"); String profileName = rs.getString("PROFILE_NAME"); String description = rs.getString("DESCRIPTION"); int structure = rs.getInt("STRUCTURE_SS_ID"); int theme = rs.getInt("THEME_SS_ID"); insertStmt.setInt(1, newUID); insertStmt.setInt(2, id); insertStmt.setString(3, profileFname); insertStmt.setString(4, profileName); insertStmt.setString(5, description); insertStmt.setInt(6, structure); insertStmt.setInt(7, theme); if (log.isDebugEnabled()) log.debug( "RDBMUserIdentityStore::addNewUser(USER_ID=" + newUID + ", PROFILE_FNAME=" + profileFname + ", PROFILE_NAME=" + profileName + ", DESCRIPTION=" + description + "): " + insert); insertStmt.executeUpdate(); } rs.close(); queryStmt.close(); if (insertStmt != null) { insertStmt.close(); insertStmt = null; } // If we made it all the way though, commit the transaction if (RDBMServices.getDbMetaData() .supportsTransactions()) con.commit(); uPortalUID = newUID; } finally { try { if (rs != null) rs.close(); } catch (Exception e) { } } } finally { try { if (queryStmt != null) queryStmt.close(); } catch (Exception e) { } try { if (insertStmt != null) insertStmt.close(); } catch (Exception e) { } } return uPortalUID; } }); } }); } private int getNextKey() { return CounterStoreLocator.getCounterStore().getNextId(PROFILE_TABLE); } protected class PortalUser { String userName; int userId; int defaultUserId; public String getUserName() { return userName; } public int getUserId() { return userId; } public int getDefaultUserId() { return defaultUserId; } public void setUserName(String userName) { this.userName = userName; } public void setUserId(int userId) { this.userId = userId; } public void setDefaultUserId(int defaultUserId) { this.defaultUserId = defaultUserId; } } protected class TemplateUser { String userName; int userId; int defaultLayoutId; public String getUserName() { return userName; } public int getUserId() { return userId; } public int getDefaultLayoutId() { return defaultLayoutId; } public void setUserName(String userName) { this.userName = userName; } public void setUserId(int userId) { this.userId = userId; } public void setDefaultLayoutId(int defaultLayoutId) { this.defaultLayoutId = defaultLayoutId; } } }