/**
* 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.groups;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apereo.portal.EntityIdentifier;
import org.apereo.portal.jdbc.RDBMServices;
import org.apereo.portal.services.GroupService;
import org.apereo.portal.spring.locator.CounterStoreLocator;
import org.apereo.portal.spring.locator.EntityTypesLocator;
import org.apereo.portal.utils.SqlTransaction;
/**
* Store for <code>EntityGroupImpl</code>.
*
*/
public class RDBMEntityGroupStore implements IEntityGroupStore, IGroupConstants {
private static final Log log = LogFactory.getLog(RDBMEntityGroupStore.class);
private static RDBMEntityGroupStore singleton;
// Constant SQL strings:
private static String EQ = " = ";
private static String QUOTE = "'";
private static String EQUALS_PARAM = EQ + "?";
// Constant strings for GROUP table:
private static String GROUP_TABLE = "UP_GROUP";
private static String GROUP_TABLE_ALIAS = "T1";
private static String GROUP_TABLE_WITH_ALIAS = GROUP_TABLE + " " + GROUP_TABLE_ALIAS;
private static String GROUP_ID_COLUMN = "GROUP_ID";
private static String GROUP_CREATOR_COLUMN = "CREATOR_ID";
private static String GROUP_TYPE_COLUMN = "ENTITY_TYPE_ID";
private static String GROUP_NAME_COLUMN = "GROUP_NAME";
private static String GROUP_DESCRIPTION_COLUMN = "DESCRIPTION";
// SQL strings for GROUP crud:
private static String allGroupColumns;
private static String allGroupColumnsWithTableAlias;
private static String countAMemberGroupSql;
private static String countMemberGroupsNamedSql;
private static String countAMemberEntitySql;
private static String findParentGroupsForEntitySql;
private static String findParentGroupsForGroupSql;
private static String findGroupSql;
private static String findMemberGroupKeysSql;
private static String findMemberGroupsSql;
private static String insertGroupSql;
private static String updateGroupSql;
// Constant strings for MEMBERS table:
private static String MEMBER_TABLE = "UP_GROUP_MEMBERSHIP";
private static String MEMBER_TABLE_ALIAS = "T2";
private static String MEMBER_TABLE_WITH_ALIAS = MEMBER_TABLE + " " + MEMBER_TABLE_ALIAS;
private static String MEMBER_GROUP_ID_COLUMN = "GROUP_ID";
private static String MEMBER_MEMBER_SERVICE_COLUMN = "MEMBER_SERVICE";
private static String MEMBER_MEMBER_KEY_COLUMN = "MEMBER_KEY";
private static String MEMBER_IS_GROUP_COLUMN = "MEMBER_IS_GROUP";
private static String MEMBER_IS_ENTITY = "F";
private static String MEMBER_IS_GROUP = "T";
private static String GROUP_NODE_SEPARATOR;
// SQL strings for group MEMBERS crud:
private static String allMemberColumns;
private static String deleteMembersInGroupSql;
private static String deleteMemberGroupSql;
private static String deleteMemberEntitySql;
private static String insertMemberSql;
// SQL group search string
private static String searchGroupsPartial =
"SELECT "
+ GROUP_ID_COLUMN
+ " FROM "
+ GROUP_TABLE
+ " WHERE "
+ GROUP_TYPE_COLUMN
+ "=? AND UPPER("
+ GROUP_NAME_COLUMN
+ ") LIKE UPPER(?)";
private static String searchGroups =
"SELECT "
+ GROUP_ID_COLUMN
+ " FROM "
+ GROUP_TABLE
+ " WHERE "
+ GROUP_TYPE_COLUMN
+ "=? AND UPPER("
+ GROUP_NAME_COLUMN
+ ") = UPPER(?)";
/** RDBMEntityGroupStore constructor. */
public RDBMEntityGroupStore() {
super();
initialize();
}
/**
* Get the node separator character from the GroupServiceConfiguration. Default it to
* IGroupConstants.NODE_SEPARATOR.
*/
private void initialize() {
String sep;
try {
sep = GroupServiceConfiguration.getConfiguration().getNodeSeparator();
} catch (Exception ex) {
sep = NODE_SEPARATOR;
}
GROUP_NODE_SEPARATOR = sep;
if (log.isDebugEnabled()) {
log.debug("RDBMEntityGroupStore.initialize(): Node separator set to " + sep);
}
}
/**
* @param conn java.sql.Connection
* @exception java.sql.SQLException
*/
protected static void commit(Connection conn) throws java.sql.SQLException {
SqlTransaction.commit(conn);
}
/**
* Answers if <code>IGroupMember</code> member is a member of <code>group</code>.
*
* @return boolean
* @param group org.apereo.portal.groups.IEntityGroup
* @param member org.apereo.portal.groups.IGroupMember
*/
public boolean contains(IEntityGroup group, IGroupMember member) throws GroupsException {
return (member.isGroup())
? containsGroup(group, (IEntityGroup) member)
: containsEntity(group, member);
}
private boolean containsEntity(IEntityGroup group, IGroupMember member) throws GroupsException {
String groupKey = group.getLocalKey();
String memberKey = member.getKey();
Connection conn = RDBMServices.getConnection();
try {
String sql = getCountAMemberEntitySql();
PreparedStatement ps = conn.prepareStatement(sql);
try {
ps.clearParameters();
ps.setString(1, groupKey);
ps.setString(2, memberKey);
if (log.isDebugEnabled())
log.debug(
"RDBMEntityGroupStore.containsEntity(): "
+ ps
+ " ("
+ groupKey
+ ", "
+ memberKey
+ ")");
ResultSet rs = ps.executeQuery();
try {
return (rs.next()) && (rs.getInt(1) > 0);
} finally {
rs.close();
}
} finally {
ps.close();
}
} catch (Exception e) {
log.error("RDBMEntityGroupStore.containsEntity(): " + e);
throw new GroupsException("Problem retrieving data from store: " + e);
} finally {
RDBMServices.releaseConnection(conn);
}
}
private boolean containsGroup(IEntityGroup group, IEntityGroup member) throws GroupsException {
String memberService = member.getServiceName().toString();
String groupKey = group.getLocalKey();
String memberKey = member.getLocalKey();
Connection conn = RDBMServices.getConnection();
try {
String sql = getCountAMemberGroupSql();
PreparedStatement ps = conn.prepareStatement(sql);
try {
ps.clearParameters();
ps.setString(1, groupKey);
ps.setString(2, memberKey);
ps.setString(3, memberService);
if (log.isDebugEnabled())
log.debug(
"RDBMEntityGroupStore.containsGroup(): "
+ ps
+ " ("
+ groupKey
+ ", "
+ memberKey
+ ", "
+ memberService
+ ")");
ResultSet rs = ps.executeQuery();
try {
return (rs.next()) && (rs.getInt(1) > 0);
} finally {
rs.close();
}
} finally {
ps.close();
}
} catch (Exception e) {
log.error("RDBMEntityGroupStore.containsGroup(): " + e);
throw new GroupsException("Problem retrieving data from store: " + e);
} finally {
RDBMServices.releaseConnection(conn);
}
}
/**
* If this entity exists, delete it.
*
* @param group org.apereo.portal.groups.IEntityGroup
*/
public void delete(IEntityGroup group) throws GroupsException {
if (existsInDatabase(group)) {
try {
primDelete(group);
} catch (SQLException sqle) {
throw new GroupsException("Problem deleting " + group, sqle);
}
}
}
/**
* Answer if the IEntityGroup entity exists in the database.
*
* @return boolean
* @param group IEntityGroup
*/
private boolean existsInDatabase(IEntityGroup group) throws GroupsException {
IEntityGroup ug = this.find(group.getLocalKey());
return ug != null;
}
/**
* Find and return an instance of the group.
*
* @param groupID the group ID
* @return org.apereo.portal.groups.IEntityGroup
*/
public IEntityGroup find(String groupID) throws GroupsException {
return primFind(groupID, false);
}
/**
* Find the groups that this entity belongs to.
*
* @param ent the entity in question
* @return java.util.Iterator
*/
public java.util.Iterator findParentGroups(IEntity ent) throws GroupsException {
String memberKey = ent.getKey();
Integer type = EntityTypesLocator.getEntityTypes().getEntityIDFromType(ent.getLeafType());
return findParentGroupsForEntity(memberKey, type.intValue());
}
/**
* Find the groups that this group belongs to.
*
* @param group org.apereo.portal.groups.IEntityGroup
* @return java.util.Iterator
*/
public java.util.Iterator findParentGroups(IEntityGroup group) throws GroupsException {
String memberKey = group.getLocalKey();
String serviceName = group.getServiceName().toString();
Integer type = EntityTypesLocator.getEntityTypes().getEntityIDFromType(group.getLeafType());
return findParentGroupsForGroup(serviceName, memberKey, type.intValue());
}
/**
* Find the groups that this group member belongs to.
*
* @param gm the group member in question
* @return java.util.Iterator
*/
public Iterator findParentGroups(IGroupMember gm) throws GroupsException {
if (gm.isGroup()) {
IEntityGroup group = (IEntityGroup) gm;
return findParentGroups(group);
} else {
IEntity ent = (IEntity) gm;
return findParentGroups(ent);
}
}
/**
* Find the groups associated with this member key.
*
* @param memberKey
* @param type
* @return java.util.Iterator
*/
private java.util.Iterator findParentGroupsForEntity(String memberKey, int type)
throws GroupsException {
java.sql.Connection conn = null;
Collection groups = new ArrayList();
IEntityGroup eg = null;
try {
conn = RDBMServices.getConnection();
String sql = getFindParentGroupsForEntitySql();
PreparedStatement ps = conn.prepareStatement(sql);
try {
ps.setString(1, memberKey);
ps.setInt(2, type);
if (log.isDebugEnabled())
log.debug(
"RDBMEntityGroupStore.findParentGroupsForEntity(): "
+ ps
+ " ("
+ memberKey
+ ", "
+ type
+ ", memberIsGroup = F)");
java.sql.ResultSet rs = ps.executeQuery();
try {
while (rs.next()) {
eg = instanceFromResultSet(rs);
groups.add(eg);
}
} finally {
rs.close();
}
} finally {
ps.close();
}
} catch (Exception e) {
log.error("RDBMEntityGroupStore.findParentGroupsForEntity(): " + e);
throw new GroupsException("Problem retrieving containing groups: " + e);
} finally {
RDBMServices.releaseConnection(conn);
}
return groups.iterator();
}
/**
* Find the groups associated with this member key.
*
* @param serviceName
* @param memberKey
* @param type
* @return java.util.Iterator
*/
private java.util.Iterator findParentGroupsForGroup(
String serviceName, String memberKey, int type) throws GroupsException {
java.sql.Connection conn = null;
Collection groups = new ArrayList();
IEntityGroup eg = null;
try {
conn = RDBMServices.getConnection();
String sql = getFindParentGroupsForGroupSql();
PreparedStatement ps = conn.prepareStatement(sql);
try {
ps.setString(1, serviceName);
ps.setString(2, memberKey);
ps.setInt(3, type);
if (log.isDebugEnabled())
log.debug(
"RDBMEntityGroupStore.findParentGroupsForGroup(): "
+ ps
+ " ("
+ serviceName
+ ", "
+ memberKey
+ ", "
+ type
+ ", memberIsGroup = T)");
java.sql.ResultSet rs = ps.executeQuery();
try {
while (rs.next()) {
eg = instanceFromResultSet(rs);
groups.add(eg);
}
} finally {
rs.close();
}
} finally {
ps.close();
}
} catch (Exception e) {
log.error("RDBMEntityGroupStore.findParentGroupsForGroup(): " + e);
throw new GroupsException("Problem retrieving containing groups: " + e);
} finally {
RDBMServices.releaseConnection(conn);
}
return groups.iterator();
}
/**
* Find the <code>IEntities</code> that are members of the <code>IEntityGroup</code>.
*
* @param group the entity group in question
* @return java.util.Iterator
*/
public Iterator findEntitiesForGroup(IEntityGroup group) throws GroupsException {
Collection entities = new ArrayList();
Connection conn = null;
String groupID = group.getLocalKey();
Class cls = group.getLeafType();
try {
conn = RDBMServices.getConnection();
Statement stmnt = conn.createStatement();
try {
String query =
"SELECT "
+ MEMBER_MEMBER_KEY_COLUMN
+ " FROM "
+ MEMBER_TABLE
+ " WHERE "
+ MEMBER_GROUP_ID_COLUMN
+ " = '"
+ groupID
+ "' AND "
+ MEMBER_IS_GROUP_COLUMN
+ " = '"
+ MEMBER_IS_ENTITY
+ "'";
ResultSet rs = stmnt.executeQuery(query);
try {
while (rs.next()) {
String key = rs.getString(1);
IEntity e = newEntity(cls, key);
entities.add(e);
}
} finally {
rs.close();
}
} finally {
stmnt.close();
}
} catch (SQLException sqle) {
log.error("Problem retrieving Entities for Group: " + group, sqle);
throw new GroupsException("Problem retrieving Entities for Group", sqle);
} finally {
RDBMServices.releaseConnection(conn);
}
return entities.iterator();
}
/**
* Find and return an instance of the group.
*
* @param groupID the group ID
* @return org.apereo.portal.groups.ILockableEntityGroup
*/
public ILockableEntityGroup findLockable(String groupID) throws GroupsException {
return (ILockableEntityGroup) primFind(groupID, true);
}
/**
* Find the keys of groups that are members of group.
*
* @param group the org.apereo.portal.groups.IEntityGroup
* @return String[]
*/
public String[] findMemberGroupKeys(IEntityGroup group) throws GroupsException {
java.sql.Connection conn = null;
Collection groupKeys = new ArrayList();
String groupKey = null;
try {
conn = RDBMServices.getConnection();
String sql = getFindMemberGroupKeysSql();
PreparedStatement ps = conn.prepareStatement(sql);
try {
ps.setString(1, group.getLocalKey());
if (log.isDebugEnabled())
log.debug(
"RDBMEntityGroupStore.findMemberGroupKeys(): "
+ ps
+ " ("
+ group.getLocalKey()
+ ")");
java.sql.ResultSet rs = ps.executeQuery();
try {
while (rs.next()) {
groupKey = rs.getString(1) + GROUP_NODE_SEPARATOR + rs.getString(2);
groupKeys.add(groupKey);
}
} finally {
rs.close();
}
} finally {
ps.close();
}
} catch (Exception sqle) {
log.error("RDBMEntityGroupStore.findMemberGroupKeys(): " + sqle);
throw new GroupsException("Problem retrieving member group keys: " + sqle);
} finally {
RDBMServices.releaseConnection(conn);
}
return (String[]) groupKeys.toArray(new String[groupKeys.size()]);
}
/**
* Find the IUserGroups that are members of the group.
*
* @param group org.apereo.portal.groups.IEntityGroup
* @return java.util.Iterator
*/
public Iterator findMemberGroups(IEntityGroup group) throws GroupsException {
java.sql.Connection conn = null;
Collection groups = new ArrayList();
IEntityGroup eg = null;
String serviceName = group.getServiceName().toString();
String localKey = group.getLocalKey();
try {
conn = RDBMServices.getConnection();
String sql = getFindMemberGroupsSql();
PreparedStatement ps = conn.prepareStatement(sql);
try {
ps.setString(1, localKey);
ps.setString(2, serviceName);
if (log.isDebugEnabled())
log.debug(
"RDBMEntityGroupStore.findMemberGroups(): "
+ ps
+ " ("
+ localKey
+ ", "
+ serviceName
+ ")");
java.sql.ResultSet rs = ps.executeQuery();
try {
while (rs.next()) {
eg = instanceFromResultSet(rs);
groups.add(eg);
}
} finally {
rs.close();
}
} finally {
ps.close();
}
} catch (Exception sqle) {
log.error("RDBMEntityGroupStore.findMemberGroups(): " + sqle);
throw new GroupsException("Problem retrieving member groups: " + sqle);
} finally {
RDBMServices.releaseConnection(conn);
}
return groups.iterator();
}
/** @return java.lang.String */
private static java.lang.String getAllGroupColumns() {
if (allGroupColumns == null) {
StringBuffer buff = new StringBuffer(100);
buff.append(GROUP_ID_COLUMN);
buff.append(", ");
buff.append(GROUP_CREATOR_COLUMN);
buff.append(", ");
buff.append(GROUP_TYPE_COLUMN);
buff.append(", ");
buff.append(GROUP_NAME_COLUMN);
buff.append(", ");
buff.append(GROUP_DESCRIPTION_COLUMN);
allGroupColumns = buff.toString();
}
return allGroupColumns;
}
/** @return java.lang.String */
private static java.lang.String getAllGroupColumnsWithTableAlias() {
if (allGroupColumnsWithTableAlias == null) {
StringBuffer buff = new StringBuffer(100);
buff.append(groupAlias(GROUP_ID_COLUMN));
buff.append(", ");
buff.append(groupAlias(GROUP_CREATOR_COLUMN));
buff.append(", ");
buff.append(groupAlias(GROUP_TYPE_COLUMN));
buff.append(", ");
buff.append(groupAlias(GROUP_NAME_COLUMN));
buff.append(", ");
buff.append(groupAlias(GROUP_DESCRIPTION_COLUMN));
allGroupColumnsWithTableAlias = buff.toString();
}
return allGroupColumnsWithTableAlias;
}
/** @return java.lang.String */
private static java.lang.String getAllMemberColumns() {
if (allMemberColumns == null) {
StringBuffer buff = new StringBuffer(100);
buff.append(MEMBER_GROUP_ID_COLUMN);
buff.append(", ");
buff.append(MEMBER_MEMBER_SERVICE_COLUMN);
buff.append(", ");
buff.append(MEMBER_MEMBER_KEY_COLUMN);
buff.append(", ");
buff.append(MEMBER_IS_GROUP_COLUMN);
allMemberColumns = buff.toString();
}
return allMemberColumns;
}
/** @return java.lang.String */
private static java.lang.String getCountAMemberEntitySql() {
if (countAMemberEntitySql == null) {
StringBuffer buff = new StringBuffer(100);
buff.append("SELECT COUNT(*) FROM " + MEMBER_TABLE);
buff.append(" WHERE " + MEMBER_GROUP_ID_COLUMN + EQUALS_PARAM);
buff.append(" AND " + MEMBER_MEMBER_KEY_COLUMN + EQUALS_PARAM);
buff.append(" AND " + MEMBER_IS_GROUP_COLUMN + EQ + sqlQuote(MEMBER_IS_ENTITY));
countAMemberEntitySql = buff.toString();
}
return countAMemberEntitySql;
}
/** @return java.lang.String */
private static java.lang.String getCountAMemberGroupSql() {
if (countAMemberGroupSql == null) {
StringBuffer buff = new StringBuffer(100);
buff.append("SELECT COUNT(*) FROM " + MEMBER_TABLE);
buff.append(" WHERE " + MEMBER_GROUP_ID_COLUMN + EQUALS_PARAM);
buff.append(" AND " + MEMBER_MEMBER_KEY_COLUMN + EQUALS_PARAM);
buff.append(" AND " + MEMBER_MEMBER_SERVICE_COLUMN + EQUALS_PARAM);
buff.append(" AND " + MEMBER_IS_GROUP_COLUMN + EQ + sqlQuote(MEMBER_IS_GROUP));
countAMemberGroupSql = buff.toString();
}
return countAMemberGroupSql;
}
/** @return java.lang.String */
private static java.lang.String getDeleteGroupSql(IEntityGroup group) {
StringBuffer buff = new StringBuffer(100);
buff.append("DELETE FROM ");
buff.append(GROUP_TABLE);
buff.append(" WHERE ");
buff.append(GROUP_ID_COLUMN + EQ + sqlQuote(group.getLocalKey()));
return buff.toString();
}
/** @return java.lang.String */
private static java.lang.String getDeleteMemberEntitySql() {
if (deleteMemberEntitySql == null) {
StringBuffer buff = new StringBuffer(100);
buff.append("DELETE FROM ");
buff.append(MEMBER_TABLE);
buff.append(" WHERE ");
buff.append(MEMBER_GROUP_ID_COLUMN + EQUALS_PARAM);
buff.append(" AND ");
buff.append(MEMBER_MEMBER_KEY_COLUMN + EQUALS_PARAM);
buff.append(" AND ");
buff.append(MEMBER_IS_GROUP_COLUMN + EQ + sqlQuote(MEMBER_IS_ENTITY));
deleteMemberEntitySql = buff.toString();
}
return deleteMemberEntitySql;
}
/** @return java.lang.String */
private static java.lang.String getDeleteMemberGroupSql() {
if (deleteMemberGroupSql == null) {
StringBuffer buff = new StringBuffer(100);
buff.append("DELETE FROM ");
buff.append(MEMBER_TABLE);
buff.append(" WHERE ");
buff.append(MEMBER_GROUP_ID_COLUMN + EQUALS_PARAM);
buff.append(" AND ");
buff.append(MEMBER_MEMBER_SERVICE_COLUMN + EQUALS_PARAM);
buff.append(" AND ");
buff.append(MEMBER_MEMBER_KEY_COLUMN + EQUALS_PARAM);
buff.append(" AND ");
buff.append(MEMBER_IS_GROUP_COLUMN + EQ + sqlQuote(MEMBER_IS_GROUP));
deleteMemberGroupSql = buff.toString();
}
return deleteMemberGroupSql;
}
/** @return java.lang.String */
private static java.lang.String getDeleteMembersInGroupSql() {
if (deleteMembersInGroupSql == null) {
StringBuffer buff = new StringBuffer(100);
buff.append("DELETE FROM ");
buff.append(MEMBER_TABLE);
buff.append(" WHERE ");
buff.append(GROUP_ID_COLUMN + EQ);
deleteMembersInGroupSql = buff.toString();
}
return deleteMembersInGroupSql;
}
/** @return java.lang.String */
private static java.lang.String getDeleteMembersInGroupSql(IEntityGroup group) {
return getDeleteMembersInGroupSql() + sqlQuote(group.getLocalKey());
}
/** @return java.lang.String */
private static java.lang.String getFindParentGroupsForEntitySql() {
if (findParentGroupsForEntitySql == null) {
StringBuffer buff = new StringBuffer(500);
buff.append("SELECT ");
buff.append(getAllGroupColumnsWithTableAlias());
buff.append(" FROM " + GROUP_TABLE_WITH_ALIAS + ", " + MEMBER_TABLE_WITH_ALIAS);
buff.append(" WHERE ");
buff.append(groupAlias(GROUP_ID_COLUMN) + EQ);
buff.append(memberAlias(MEMBER_GROUP_ID_COLUMN));
buff.append(" AND ");
buff.append(memberAlias(MEMBER_MEMBER_KEY_COLUMN) + EQUALS_PARAM);
buff.append(" AND ");
buff.append(groupAlias(GROUP_TYPE_COLUMN) + EQUALS_PARAM);
buff.append(" AND ");
buff.append(memberAlias(MEMBER_IS_GROUP_COLUMN) + EQ + sqlQuote(MEMBER_IS_ENTITY));
findParentGroupsForEntitySql = buff.toString();
}
return findParentGroupsForEntitySql;
}
/** @return java.lang.String */
private static java.lang.String getFindParentGroupsForGroupSql() {
if (findParentGroupsForGroupSql == null) {
StringBuffer buff = new StringBuffer(500);
buff.append("SELECT ");
buff.append(getAllGroupColumnsWithTableAlias());
buff.append(" FROM ");
buff.append(GROUP_TABLE_WITH_ALIAS);
buff.append(", ");
buff.append(MEMBER_TABLE_WITH_ALIAS);
buff.append(" WHERE ");
buff.append(groupAlias(GROUP_ID_COLUMN) + EQ);
buff.append(memberAlias(MEMBER_GROUP_ID_COLUMN));
buff.append(" AND ");
buff.append(memberAlias(MEMBER_MEMBER_SERVICE_COLUMN) + EQUALS_PARAM);
buff.append(" AND ");
buff.append(memberAlias(MEMBER_MEMBER_KEY_COLUMN) + EQUALS_PARAM);
buff.append(" AND ");
buff.append(groupAlias(GROUP_TYPE_COLUMN) + EQUALS_PARAM);
buff.append(" AND ");
buff.append(memberAlias(MEMBER_IS_GROUP_COLUMN) + EQ + sqlQuote(MEMBER_IS_GROUP));
findParentGroupsForGroupSql = buff.toString();
}
return findParentGroupsForGroupSql;
}
/** @return java.lang.String */
private static java.lang.String getFindGroupSql() {
if (findGroupSql == null) {
StringBuffer buff = new StringBuffer(200);
buff.append("SELECT ");
buff.append(getAllGroupColumns());
buff.append(" FROM ");
buff.append(GROUP_TABLE);
buff.append(" WHERE ");
buff.append(GROUP_ID_COLUMN + EQUALS_PARAM);
findGroupSql = buff.toString();
}
return findGroupSql;
}
/** @return java.lang.String */
private static java.lang.String getFindMemberGroupKeysSql() {
if (findMemberGroupKeysSql == null) {
StringBuffer buff = new StringBuffer(200);
buff.append("SELECT ");
buff.append(MEMBER_MEMBER_SERVICE_COLUMN + ", " + MEMBER_MEMBER_KEY_COLUMN);
buff.append(" FROM ");
buff.append(MEMBER_TABLE);
buff.append(" WHERE ");
buff.append(MEMBER_GROUP_ID_COLUMN + EQUALS_PARAM);
buff.append(" AND ");
buff.append(MEMBER_IS_GROUP_COLUMN + EQ);
buff.append(sqlQuote(MEMBER_IS_GROUP));
findMemberGroupKeysSql = buff.toString();
}
return findMemberGroupKeysSql;
}
/** @return java.lang.String */
private static java.lang.String getFindMemberGroupsSql() {
if (findMemberGroupsSql == null) {
StringBuffer buff = new StringBuffer(500);
buff.append("SELECT ");
buff.append(getAllGroupColumnsWithTableAlias());
buff.append(" FROM ");
buff.append(GROUP_TABLE + " " + GROUP_TABLE_ALIAS);
buff.append(", ");
buff.append(MEMBER_TABLE + " " + MEMBER_TABLE_ALIAS);
buff.append(" WHERE ");
buff.append(groupAlias(GROUP_ID_COLUMN) + EQ);
buff.append(memberAlias(MEMBER_MEMBER_KEY_COLUMN));
buff.append(" AND ");
buff.append(memberAlias(MEMBER_IS_GROUP_COLUMN) + EQ);
buff.append(sqlQuote(MEMBER_IS_GROUP));
buff.append(" AND ");
buff.append(memberAlias(MEMBER_GROUP_ID_COLUMN) + EQUALS_PARAM);
buff.append(" AND ");
buff.append(memberAlias(MEMBER_MEMBER_SERVICE_COLUMN) + EQUALS_PARAM);
findMemberGroupsSql = buff.toString();
}
return findMemberGroupsSql;
}
/** @return java.lang.String */
private static java.lang.String getInsertGroupSql() {
if (insertGroupSql == null) {
StringBuffer buff = new StringBuffer(200);
buff.append("INSERT INTO ");
buff.append(GROUP_TABLE);
buff.append(" (");
buff.append(getAllGroupColumns());
buff.append(") VALUES (?, ?, ?, ?, ?)");
insertGroupSql = buff.toString();
}
return insertGroupSql;
}
/** @return java.lang.String */
private static java.lang.String getInsertMemberSql() {
if (insertMemberSql == null) {
StringBuffer buff = new StringBuffer(200);
buff.append("INSERT INTO ");
buff.append(MEMBER_TABLE);
buff.append(" (");
buff.append(getAllMemberColumns());
buff.append(") VALUES (?, ?, ?, ? )");
insertMemberSql = buff.toString();
}
return insertMemberSql;
}
/**
* @return java.lang.String
* @exception java.lang.Exception
*/
private String getNextKey() throws java.lang.Exception {
return Integer.toString(CounterStoreLocator.getCounterStore().getNextId(GROUP_TABLE));
}
/** @return java.lang.String */
private static java.lang.String getUpdateGroupSql() {
if (updateGroupSql == null) {
StringBuffer buff = new StringBuffer(200);
buff.append("UPDATE ");
buff.append(GROUP_TABLE);
buff.append(" SET ");
buff.append(GROUP_CREATOR_COLUMN + EQUALS_PARAM);
buff.append(", ");
buff.append(GROUP_TYPE_COLUMN + EQUALS_PARAM);
buff.append(", ");
buff.append(GROUP_NAME_COLUMN + EQUALS_PARAM);
buff.append(", ");
buff.append(GROUP_DESCRIPTION_COLUMN + EQUALS_PARAM);
buff.append(" WHERE ");
buff.append(GROUP_ID_COLUMN + EQUALS_PARAM);
updateGroupSql = buff.toString();
}
return updateGroupSql;
}
/**
* Find and return an instance of the group.
*
* @param rs the SQL result set
* @return org.apereo.portal.groups.IEntityGroup
*/
private IEntityGroup instanceFromResultSet(java.sql.ResultSet rs)
throws SQLException, GroupsException {
IEntityGroup eg = null;
String key = rs.getString(1);
String creatorID = rs.getString(2);
Integer entityTypeID = new Integer(rs.getInt(3));
Class entityType = EntityTypesLocator.getEntityTypes().getEntityTypeFromID(entityTypeID);
String groupName = rs.getString(4);
String description = rs.getString(5);
if (key != null) {
eg = newInstance(key, entityType, creatorID, groupName, description);
}
return eg;
}
/**
* Find and return an instance of the group.
*
* @param rs the SQL result set
* @return org.apereo.portal.groups.ILockableEntityGroup
*/
private ILockableEntityGroup lockableInstanceFromResultSet(java.sql.ResultSet rs)
throws SQLException, GroupsException {
ILockableEntityGroup eg = null;
String key = rs.getString(1);
String creatorID = rs.getString(2);
Integer entityTypeID = new Integer(rs.getInt(3));
Class entityType = EntityTypesLocator.getEntityTypes().getEntityTypeFromID(entityTypeID);
String groupName = rs.getString(4);
String description = rs.getString(5);
if (key != null) {
eg = newLockableInstance(key, entityType, creatorID, groupName, description);
}
return eg;
}
/** @return org.apereo.portal.groups.IEntity */
public IEntity newEntity(Class type, String key) throws GroupsException {
if (EntityTypesLocator.getEntityTypes().getEntityIDFromType(type) == null) {
throw new GroupsException("Invalid group type: " + type);
}
return GroupService.getEntity(key, type);
}
/** @return org.apereo.portal.groups.IEntityGroup */
public IEntityGroup newInstance(Class type) throws GroupsException {
if (EntityTypesLocator.getEntityTypes().getEntityIDFromType(type) == null) {
throw new GroupsException("Invalid group type: " + type);
}
try {
return new EntityGroupImpl(getNextKey(), type);
} catch (Exception ex) {
throw new GroupsException("Could not create new group", ex);
}
}
/** @return org.apereo.portal.groups.IEntityGroup */
private IEntityGroup newInstance(
String newKey,
Class newType,
String newCreatorID,
String newName,
String newDescription)
throws GroupsException {
EntityGroupImpl egi = new EntityGroupImpl(newKey, newType);
egi.setCreatorID(newCreatorID);
egi.primSetName(newName);
egi.setDescription(newDescription);
return egi;
}
/** @return org.apereo.portal.groups.ILockableEntityGroup */
private ILockableEntityGroup newLockableInstance(
String newKey,
Class newType,
String newCreatorID,
String newName,
String newDescription)
throws GroupsException {
LockableEntityGroupImpl group = new LockableEntityGroupImpl(newKey, newType);
group.setCreatorID(newCreatorID);
group.primSetName(newName);
group.setDescription(newDescription);
return group;
}
/** @return java.lang.String */
private static java.lang.String groupAlias(String column) {
return GROUP_TABLE_ALIAS + "." + column;
}
/** @return java.lang.String */
private static java.lang.String memberAlias(String column) {
return MEMBER_TABLE_ALIAS + "." + column;
}
/**
* Insert the entity into the database.
*
* @param group org.apereo.portal.groups.IEntityGroup
* @param conn the database connection
*/
private void primAdd(IEntityGroup group, Connection conn) throws SQLException, GroupsException {
try {
PreparedStatement ps = conn.prepareStatement(getInsertGroupSql());
try {
Integer typeID =
EntityTypesLocator.getEntityTypes()
.getEntityIDFromType(group.getLeafType());
ps.setString(1, group.getLocalKey());
ps.setString(2, group.getCreatorID());
ps.setInt(3, typeID.intValue());
ps.setString(4, group.getName());
ps.setString(5, group.getDescription());
if (log.isDebugEnabled())
log.debug(
"RDBMEntityGroupStore.primAdd(): "
+ ps
+ "("
+ group.getLocalKey()
+ ", "
+ group.getCreatorID()
+ ", "
+ typeID
+ ", "
+ group.getName()
+ ", "
+ group.getDescription()
+ ")");
int rc = ps.executeUpdate();
if (rc != 1) {
String errString = "Problem adding " + group;
log.error(errString);
throw new GroupsException(errString);
}
} finally {
ps.close();
}
} catch (java.sql.SQLException sqle) {
log.error("Error inserting an entity into the database. Group:" + group, sqle);
throw sqle;
}
}
/**
* Delete this entity from the database after first deleting its memberships. Exception
* java.sql.SQLException - if we catch a SQLException, we rollback and re-throw it.
*
* @param group org.apereo.portal.groups.IEntityGroup
*/
private void primDelete(IEntityGroup group) throws SQLException {
java.sql.Connection conn = null;
String deleteGroupSql = getDeleteGroupSql(group);
String deleteMembershipSql = getDeleteMembersInGroupSql(group);
try {
conn = RDBMServices.getConnection();
Statement stmnt = conn.createStatement();
setAutoCommit(conn, false);
try {
if (log.isDebugEnabled())
log.debug("RDBMEntityGroupStore.primDelete(): " + deleteMembershipSql);
stmnt.executeUpdate(deleteMembershipSql);
if (log.isDebugEnabled())
log.debug("RDBMEntityGroupStore.primDelete(): " + deleteGroupSql);
stmnt.executeUpdate(deleteGroupSql);
} finally {
stmnt.close();
}
commit(conn);
} catch (SQLException sqle) {
rollback(conn);
throw sqle;
} finally {
try {
setAutoCommit(conn, true);
} finally {
RDBMServices.releaseConnection(conn);
}
}
}
/**
* Find and return an instance of the group.
*
* @param groupID the group ID
* @param lockable boolean
* @return org.apereo.portal.groups.IEntityGroup
*/
private IEntityGroup primFind(String groupID, boolean lockable) throws GroupsException {
IEntityGroup eg = null;
java.sql.Connection conn = null;
try {
conn = RDBMServices.getConnection();
String sql = getFindGroupSql();
PreparedStatement ps = conn.prepareStatement(sql);
try {
ps.setString(1, groupID);
if (log.isDebugEnabled())
log.debug("RDBMEntityGroupStore.find(): " + ps + " (" + groupID + ")");
java.sql.ResultSet rs = ps.executeQuery();
try {
while (rs.next()) {
eg =
(lockable)
? lockableInstanceFromResultSet(rs)
: instanceFromResultSet(rs);
}
} finally {
rs.close();
}
} finally {
ps.close();
}
} catch (Exception e) {
log.error("RDBMEntityGroupStore.find(): ", e);
throw new GroupsException("Error retrieving " + groupID + ": ", e);
} finally {
RDBMServices.releaseConnection(conn);
}
return eg;
}
/**
* Update the entity in the database.
*
* @param group org.apereo.portal.groups.IEntityGroup
* @param conn the database connection
*/
private void primUpdate(IEntityGroup group, Connection conn)
throws SQLException, GroupsException {
try {
PreparedStatement ps = conn.prepareStatement(getUpdateGroupSql());
try {
Integer typeID =
EntityTypesLocator.getEntityTypes()
.getEntityIDFromType(group.getLeafType());
ps.setString(1, group.getCreatorID());
ps.setInt(2, typeID.intValue());
ps.setString(3, group.getName());
ps.setString(4, group.getDescription());
ps.setString(5, group.getLocalKey());
if (log.isDebugEnabled())
log.debug(
"RDBMEntityGroupStore.primUpdate(): "
+ ps
+ "("
+ group.getCreatorID()
+ ", "
+ typeID
+ ", "
+ group.getName()
+ ", "
+ group.getDescription()
+ ", "
+ group.getLocalKey()
+ ")");
int rc = ps.executeUpdate();
if (rc != 1) {
String errString = "Problem updating " + group;
log.error(errString);
throw new GroupsException(errString);
}
} finally {
ps.close();
}
} catch (java.sql.SQLException sqle) {
log.error("Error updating entity in database. Group: " + group, sqle);
throw sqle;
}
}
/**
* Insert and delete group membership rows. The transaction is maintained by the caller.
*
* @param egi org.apereo.portal.groups.EntityGroupImpl
* @param conn the database connection
*/
private void primUpdateMembers(EntityGroupImpl egi, Connection conn)
throws java.sql.SQLException {
String groupKey = egi.getLocalKey();
String memberKey, isGroup, serviceName = null;
try {
if (egi.hasDeletes()) {
List deletedGroups = new ArrayList();
List deletedEntities = new ArrayList();
Iterator deletes = egi.getRemovedMembers().values().iterator();
while (deletes.hasNext()) {
IGroupMember gm = (IGroupMember) deletes.next();
if (gm.isGroup()) {
deletedGroups.add(gm);
} else {
deletedEntities.add(gm);
}
}
if (!deletedGroups.isEmpty()) {
PreparedStatement psDeleteMemberGroup =
conn.prepareStatement(getDeleteMemberGroupSql());
try {
for (Iterator groups = deletedGroups.iterator(); groups.hasNext(); ) {
IEntityGroup removedGroup = (IEntityGroup) groups.next();
memberKey = removedGroup.getLocalKey();
isGroup = MEMBER_IS_GROUP;
serviceName = removedGroup.getServiceName().toString();
psDeleteMemberGroup.setString(1, groupKey);
psDeleteMemberGroup.setString(2, serviceName);
psDeleteMemberGroup.setString(3, memberKey);
if (log.isDebugEnabled())
log.debug(
"RDBMEntityGroupStore.primUpdateMembers(): "
+ psDeleteMemberGroup
+ "("
+ groupKey
+ ", "
+ serviceName
+ ", "
+ memberKey
+ ", isGroup = T)");
psDeleteMemberGroup.executeUpdate();
} // for
} // try
finally {
psDeleteMemberGroup.close();
}
} // if ( ! deletedGroups.isEmpty() )
if (!deletedEntities.isEmpty()) {
PreparedStatement psDeleteMemberEntity =
conn.prepareStatement(getDeleteMemberEntitySql());
try {
for (Iterator entities = deletedEntities.iterator(); entities.hasNext(); ) {
IGroupMember removedEntity = (IGroupMember) entities.next();
memberKey = removedEntity.getUnderlyingEntityIdentifier().getKey();
isGroup = MEMBER_IS_ENTITY;
psDeleteMemberEntity.setString(1, groupKey);
psDeleteMemberEntity.setString(2, memberKey);
if (log.isDebugEnabled())
log.debug(
"RDBMEntityGroupStore.primUpdateMembers(): "
+ psDeleteMemberEntity
+ "("
+ groupKey
+ ", "
+ memberKey
+ ", "
+ "isGroup = F)");
psDeleteMemberEntity.executeUpdate();
} // for
} // try
finally {
psDeleteMemberEntity.close();
}
} // if ( ! deletedEntities.isEmpty() )
}
if (egi.hasAdds()) {
PreparedStatement psAdd = conn.prepareStatement(getInsertMemberSql());
try {
Iterator adds = egi.getAddedMembers().values().iterator();
while (adds.hasNext()) {
IGroupMember addedGM = (IGroupMember) adds.next();
memberKey = addedGM.getKey();
if (addedGM.isGroup()) {
IEntityGroup addedGroup = (IEntityGroup) addedGM;
isGroup = MEMBER_IS_GROUP;
serviceName = addedGroup.getServiceName().toString();
memberKey = addedGroup.getLocalKey();
} else {
isGroup = MEMBER_IS_ENTITY;
serviceName = egi.getServiceName().toString();
memberKey = addedGM.getUnderlyingEntityIdentifier().getKey();
}
psAdd.setString(1, groupKey);
psAdd.setString(2, serviceName);
psAdd.setString(3, memberKey);
psAdd.setString(4, isGroup);
if (log.isDebugEnabled())
log.debug(
"RDBMEntityGroupStore.primUpdateMembers(): "
+ psAdd
+ "("
+ groupKey
+ ", "
+ memberKey
+ ", "
+ isGroup
+ ")");
psAdd.executeUpdate();
}
} finally {
psAdd.close();
}
}
} catch (SQLException sqle) {
log.error("Error inserting/deleting membership rows.", sqle);
throw sqle;
}
}
/**
* @param conn java.sql.Connection
* @exception java.sql.SQLException
*/
protected static void rollback(Connection conn) throws java.sql.SQLException {
SqlTransaction.rollback(conn);
}
public EntityIdentifier[] searchForGroups(String query, int method, Class leaftype)
throws GroupsException {
EntityIdentifier[] r = new EntityIdentifier[0];
ArrayList ar = new ArrayList();
Connection conn = null;
PreparedStatement ps = null;
int type = EntityTypesLocator.getEntityTypes().getEntityIDFromType(leaftype).intValue();
//System.out.println("Checking out groups of leaftype "+leaftype.getName()+" or "+type);
try {
conn = RDBMServices.getConnection();
switch (method) {
case IS:
ps = conn.prepareStatement(RDBMEntityGroupStore.searchGroups);
break;
case STARTS_WITH:
query = query + "%";
ps = conn.prepareStatement(RDBMEntityGroupStore.searchGroupsPartial);
break;
case ENDS_WITH:
query = "%" + query;
ps = conn.prepareStatement(RDBMEntityGroupStore.searchGroupsPartial);
break;
case CONTAINS:
query = "%" + query + "%";
ps = conn.prepareStatement(RDBMEntityGroupStore.searchGroupsPartial);
break;
default:
throw new GroupsException("Unknown search type");
}
try {
ps.clearParameters();
ps.setInt(1, type);
ps.setString(2, query);
ResultSet rs = ps.executeQuery();
try {
//System.out.println(ps.toString());
while (rs.next()) {
//System.out.println("result");
ar.add(
new EntityIdentifier(
rs.getString(1), ICompositeGroupService.GROUP_ENTITY_TYPE));
}
} finally {
close(rs);
}
} finally {
close(ps);
}
} catch (Exception e) {
log.error("RDBMChannelDefSearcher.searchForEntities(): " + ps, e);
} finally {
RDBMServices.releaseConnection(conn);
}
return (EntityIdentifier[]) ar.toArray(r);
}
/**
* @param conn java.sql.Connection
* @param newValue boolean
* @exception java.sql.SQLException The exception description.
*/
protected static void setAutoCommit(Connection conn, boolean newValue)
throws java.sql.SQLException {
SqlTransaction.setAutoCommit(conn, newValue);
}
/** @return org.apereo.portal.groups.RDBMEntityGroupStore */
public static synchronized RDBMEntityGroupStore singleton() throws GroupsException {
if (singleton == null) {
singleton = new RDBMEntityGroupStore();
}
return singleton;
}
/** @return java.lang.String */
private static java.lang.String sqlQuote(Object o) {
return QUOTE + o + QUOTE;
}
/**
* Commit this entity AND ITS MEMBERSHIPS to the underlying store.
*
* @param group org.apereo.portal.groups.IEntityGroup
*/
public void update(IEntityGroup group) throws GroupsException {
Connection conn = null;
boolean exists = existsInDatabase(group);
try {
conn = RDBMServices.getConnection();
setAutoCommit(conn, false);
try {
if (exists) {
primUpdate(group, conn);
} else {
primAdd(group, conn);
}
primUpdateMembers((EntityGroupImpl) group, conn);
commit(conn);
} catch (Exception ex) {
rollback(conn);
throw new GroupsException("Problem updating " + this + ex);
}
} catch (SQLException sqlex) {
throw new GroupsException(sqlex);
} finally {
if (conn != null) {
try {
setAutoCommit(conn, true);
} catch (SQLException sqle) {
throw new GroupsException(sqle);
} finally {
RDBMServices.releaseConnection(conn);
}
}
}
}
/**
* Insert and delete group membership rows inside a transaction.
*
* @param eg org.apereo.portal.groups.IEntityGroup
*/
public void updateMembers(IEntityGroup eg) throws GroupsException {
Connection conn = null;
EntityGroupImpl egi = (EntityGroupImpl) eg;
if (egi.isDirty())
try {
conn = RDBMServices.getConnection();
setAutoCommit(conn, false);
try {
primUpdateMembers(egi, conn);
commit(conn);
} catch (SQLException sqle) {
rollback(conn);
throw new GroupsException("Problem updating memberships for " + egi, sqle);
}
} catch (SQLException sqlex) {
throw new GroupsException(sqlex);
} finally {
if (conn != null) {
try {
setAutoCommit(conn, true);
} catch (SQLException sqle) {
throw new GroupsException(sqle);
} finally {
RDBMServices.releaseConnection(conn);
}
}
}
}
private static final void close(final Statement statement) {
if (statement != null) {
try {
statement.close();
} catch (SQLException e) {
log.warn("problem closing statement", e);
}
}
}
private static final void close(final ResultSet resultset) {
if (resultset != null) {
try {
resultset.close();
} catch (SQLException e) {
log.warn("problem closing resultset", e);
}
}
}
}