/* =============================================================================== * * Part of the InfoGlue Content Management Platform (www.infoglue.org) * * =============================================================================== * * Copyright (C) * * This program is free software; you can redistribute it and/or modify it under * the terms of the GNU General Public License version 2, as published by the * Free Software Foundation. See the file LICENSE.html for more information. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY, including the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along with * this program; if not, write to the Free Software Foundation, Inc. / 59 Temple * Place, Suite 330 / Boston, MA 02111-1307 / USA. * * =============================================================================== */ package org.infoglue.cms.controllers.kernel.impl.simple; import java.sql.Connection; import java.sql.PreparedStatement; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Set; import org.apache.log4j.Logger; import org.exolab.castor.jdo.Database; import org.exolab.castor.jdo.OQLQuery; import org.exolab.castor.jdo.QueryResults; import org.infoglue.cms.entities.kernel.BaseEntityVO; import org.infoglue.cms.entities.management.Group; import org.infoglue.cms.entities.management.GroupVO; import org.infoglue.cms.entities.management.SystemUserVO; import org.infoglue.cms.entities.management.impl.simple.GroupImpl; import org.infoglue.cms.entities.management.impl.simple.SystemUserGroupImpl; import org.infoglue.cms.exception.Bug; import org.infoglue.cms.exception.ConstraintException; import org.infoglue.cms.exception.SystemException; import org.infoglue.cms.util.ConstraintExceptionBuffer; import org.infoglue.deliver.util.CacheController; /** * GroupHelper.java * Created on 2002-aug-28 * @author Stefan Sik, ss@frovi.com * @author Mattias Bogeblad * This class is a helper class for the use case handle groups */ public class GroupController extends BaseController { private final static Logger logger = Logger.getLogger(GroupController.class.getName()); /** * Factory method */ public static GroupController getController() { return new GroupController(); } public Group getGroupWithId(String groupName, Database db) throws SystemException, Bug { return (Group)getObjectWithId(GroupImpl.class, groupName, db); } public GroupVO getGroupVOWithId(Integer groupId) throws SystemException, Bug { return (GroupVO) getVOWithId(GroupImpl.class, groupId); } public GroupVO getGroupVOWithId(String groupName) throws SystemException, Bug { return (GroupVO) getVOWithId(GroupImpl.class, groupName); } public GroupVO getGroupVOWithId(String groupName, Database db) throws SystemException, Bug { return (GroupVO) getVOWithId(GroupImpl.class, groupName, db); } public List getGroupVOList() throws SystemException, Bug { return getAllVOObjects(GroupImpl.class, "groupName"); } public List getGroupVOList(Database db) throws SystemException, Bug { String cacheKey = "allGroupVO"; logger.info("cacheKey in getGroupVOList:" + cacheKey); List groupVOList = (List)CacheController.getCachedObject("groupVOListCache", cacheKey); if(groupVOList != null) { logger.info("There was an cached list of GroupVO:" + groupVOList.size()); } else { groupVOList = getAllVOObjects(GroupImpl.class, "groupName", db); if(groupVOList != null) CacheController.cacheObject("groupVOListCache", cacheKey, groupVOList); } return groupVOList; } public GroupVO create(GroupVO groupVO) throws ConstraintException, SystemException { Group group = new GroupImpl(); group.setValueObject(groupVO); group = (Group) createEntity(group); return group.getValueObject(); } public Group create(GroupVO groupVO, Database db) throws ConstraintException, SystemException, Exception { Group group = new GroupImpl(); group.setValueObject(groupVO); group = (Group) createEntity(group, db); return group; } public void delete(GroupVO groupVO) throws ConstraintException, SystemException, Exception { removeUsers(groupVO.getGroupName()); deleteEntity(GroupImpl.class, groupVO.getGroupName()); } public void delete(String groupName) throws ConstraintException, SystemException, Exception { removeUsers(groupName); deleteEntity(GroupImpl.class, groupName); } public void delete(String groupName, Database db) throws ConstraintException, SystemException, Exception { removeUsers(groupName); deleteEntity(GroupImpl.class, groupName, db); } // Get list of users accosiated with this group public List<SystemUserVO> getGroupSystemUserVOList(Integer offset, Integer limit, String sortProperty, String direction, String searchString, String groupName, Database db) throws SystemException, Bug { List<SystemUserVO> systemUsersVOList = new ArrayList(); try { systemUsersVOList = SystemUserController.getController().getFilteredSystemUserList(offset, limit, sortProperty, direction, searchString, null, groupName, db); } catch( Exception e) { throw new SystemException("An error occurred when we tried to fetch a list of users in this group. Reason:" + e.getMessage(), e); } return systemUsersVOList; } public List getGroupSystemUserVOList(Integer offset, Integer limit, String sortProperty, String direction, String searchString, String groupName) throws SystemException, Bug { List<SystemUserVO> systemUsersVOList = new ArrayList(); Database db = CastorDatabaseService.getDatabase(); try { beginTransaction(db); systemUsersVOList = getGroupSystemUserVOList(offset, limit, sortProperty, direction, searchString, groupName, db); commitTransaction(db); } catch ( Exception e ) { rollbackTransaction(db); throw new SystemException("An error occurred when we tried to fetch a list of users in this group. Reason:" + e.getMessage(), e); } return systemUsersVOList; } public Integer getGroupSystemUserCount(String groupName, String searchString, Database db) throws SystemException, Bug { Integer count = 0; try { count = SystemUserController.getController().getFilteredSystemUserCount(null, groupName, searchString, db); } catch( Exception e) { throw new SystemException("An error occurred when we tried to fetch a list of users in this group. Reason:" + e.getMessage(), e); } return count; } public Integer getGroupSystemUserCount(String groupName, String searchString) throws SystemException, Bug { Integer count = 0; Database db = CastorDatabaseService.getDatabase(); try { beginTransaction(db); count = getGroupSystemUserCount(groupName, searchString, db); commitTransaction(db); } catch ( Exception e ) { rollbackTransaction(db); throw new SystemException("An error occurred when we tried to fetch a list of users in this group. Reason:" + e.getMessage(), e); } return count; } // Get list of users accosiated with this group public List<SystemUserVO> getGroupSystemUserVOListInverted(Integer offset, Integer limit, String sortProperty, String direction, String searchString, String groupName, Database db) throws SystemException, Bug { List<SystemUserVO> systemUsersVOList = new ArrayList(); try { systemUsersVOList = SystemUserController.getController().getFilteredSystemUserListInvertedOnRoleOrGroup(offset, limit, sortProperty, direction, searchString, null, groupName, db); } catch( Exception e) { throw new SystemException("An error occurred when we tried to fetch a list of users in this group. Reason:" + e.getMessage(), e); } return systemUsersVOList; } public List<SystemUserVO> getGroupSystemUserVOListInverted(Integer offset, Integer limit, String sortProperty, String direction, String searchString, String groupName) throws SystemException, Bug { List<SystemUserVO> systemUsersVOList = new ArrayList(); Database db = CastorDatabaseService.getDatabase(); try { beginTransaction(db); systemUsersVOList = getGroupSystemUserVOListInverted(offset, limit, sortProperty, direction, searchString, groupName, db); commitTransaction(db); } catch ( Exception e ) { rollbackTransaction(db); throw new SystemException("An error occurred when we tried to fetch a list of users in this group. Reason:" + e.getMessage(), e); } return systemUsersVOList; } public Integer getGroupSystemUserCountInverted(String groupName, String searchString, Database db) throws SystemException, Bug { Integer count = 0; try { count = SystemUserController.getController().getFilteredSystemUserCountInverted(null, groupName, searchString, db); } catch( Exception e) { throw new SystemException("An error occurred when we tried to fetch a list of users in this group. Reason:" + e.getMessage(), e); } return count; } public Integer getGroupSystemUserCountInverted(String groupName, String searchString) throws SystemException, Bug { Integer count = 0; Database db = CastorDatabaseService.getDatabase(); try { beginTransaction(db); count = getGroupSystemUserCountInverted(groupName, searchString, db); commitTransaction(db); } catch ( Exception e ) { rollbackTransaction(db); throw new SystemException("An error occurred when we tried to fetch a list of users in this group. Reason:" + e.getMessage(), e); } return count; } public GroupVO update(GroupVO groupVO, Set<String> userNamesSet) throws ConstraintException, SystemException, Exception { if(userNamesSet != null) removeUsers(groupVO.getGroupName()); Database db = CastorDatabaseService.getDatabase(); ConstraintExceptionBuffer ceb = new ConstraintExceptionBuffer(); Group group = null; beginTransaction(db); try { //add validation here if needed group = update(groupVO, userNamesSet, db); //If any of the validations or setMethods reported an error, we throw them up now before create. ceb.throwIfNotEmpty(); commitTransaction(db); } catch(ConstraintException ce) { logger.warn("An error occurred so we should not complete the transaction:" + ce, ce); rollbackTransaction(db); throw ce; } catch(Exception e) { logger.error("An error occurred so we should not complete the transaction:" + e, e); rollbackTransaction(db); throw new SystemException(e.getMessage()); } return group.getValueObject(); } public Group update(GroupVO groupVO, Set<String> userNamesSet, Database db) throws ConstraintException, SystemException, Exception { Group group = getGroupWithId(groupVO.getGroupName(), db); if(userNamesSet != null) { for (String userName : userNamesSet) { addUser(groupVO.getGroupName(), userName, db); } } group.setValueObject(groupVO); return group; } /** * This method gets a list of Groups for a particular systemUser. * @param systemUserId * @return * @throws SystemException * @throws Bug */ public List<GroupVO> getGroupVOList(String userName) throws SystemException, Bug { List<GroupVO> groupVOList = null; Database db = CastorDatabaseService.getDatabase(); try { beginTransaction(db); groupVOList = getGroupVOList(userName, db); commitTransaction(db); } catch(Exception e) { rollbackTransaction(db); throw new SystemException("An error occurred when we tried to fetch a list of users in this group. Reason:" + e.getMessage(), e); } return groupVOList; } /** * Get the the groups for a user (very light) */ public List<GroupVO> getGroupVOList(String userName, Database db) throws SystemException, Bug { List<GroupVO> groupVOList = new ArrayList<GroupVO>(); OQLQuery oql; try { oql = db.getOQLQuery( "CALL SQL SELECT r.groupName, r.description, r.source, r.groupType, r.isActive, r.modifiedDateTime FROM cmGroup r, cmSystemUserGroup sur WHERE r.groupName = sur.groupName AND sur.userName = $1 AS org.infoglue.cms.entities.management.impl.simple.GroupImpl"); oql.bind(userName); QueryResults results = oql.execute(Database.READONLY); while(results.hasMore()) { Group group = (Group)results.next(); groupVOList.add(group.getValueObject()); } results.close(); oql.close(); } catch(Exception e) { throw new SystemException("An error occurred when we tried to fetch groupVOList for " + userName + " Reason:" + e.getMessage(), e); } return groupVOList; } public void addUser(String groupName, String userName) throws ConstraintException, SystemException { Database db = CastorDatabaseService.getDatabase(); ConstraintExceptionBuffer ceb = new ConstraintExceptionBuffer(); beginTransaction(db); try { addUser(groupName, userName, db); //If any of the validations or setMethods reported an error, we throw them up now before create. ceb.throwIfNotEmpty(); commitTransaction(db); } catch(ConstraintException ce) { logger.warn("An error occurred so we should not complete the transaction:" + ce, ce); rollbackTransaction(db); throw ce; } catch(Exception e) { logger.error("An error occurred so we should not complete the transaction:" + e, e); rollbackTransaction(db); throw new SystemException(e.getMessage()); } } public void addUser(String groupName, String userName, Database db) throws ConstraintException, SystemException, Exception { if(groupName != null && userName != null) { SystemUserGroupImpl sug = new SystemUserGroupImpl(); sug.setUserName(userName); sug.setGroupName(groupName); db.create(sug); } } public void addUsers(String groupName, Set<String> userNames, Database db) throws ConstraintException, SystemException, Exception { try { String sql = "insert into cmSystemUserGroup (userName, groupName) values (?, ?)"; Connection connection = db.getJdbcConnection(); PreparedStatement ps = connection.prepareStatement(sql); final int batchSize = 1000; int count = 0; for (String userName: userNames) { if(logger.isInfoEnabled()) logger.info("Adding " + groupName + " = " + userName); ps.setString(1, userName); ps.setString(2, groupName); ps.addBatch(); if(++count % batchSize == 0) { ps.executeBatch(); } } ps.executeBatch(); // insert remaining records ps.close(); } catch (Exception e) { logger.error("Error inserting users: " + e.getMessage(), e); } } public Map<String,List<String>> getSystemUserGroupMappingLowerCase(Database db) throws ConstraintException, SystemException, Exception { Map<String,List<String>> userGroupMapping = new HashMap<String,List<String>>(); OQLQuery oql = db.getOQLQuery( "SELECT sur FROM org.infoglue.cms.entities.management.impl.simple.SystemUserGroupImpl sur ORDER BY sur.userName"); QueryResults results = oql.execute(Database.READONLY); while (results.hasMore()) { SystemUserGroupImpl sur = (SystemUserGroupImpl)results.nextElement(); List<String> groupNames = userGroupMapping.get(sur.getUserName()); if(groupNames == null) { groupNames = new ArrayList<String>(); userGroupMapping.put(sur.getUserName().toLowerCase(), groupNames); } groupNames.add(sur.getGroupName().toLowerCase()); } results.close(); oql.close(); return userGroupMapping; } public void removeUser(String groupName, String userName) throws ConstraintException, SystemException { Database db = CastorDatabaseService.getDatabase(); ConstraintExceptionBuffer ceb = new ConstraintExceptionBuffer(); beginTransaction(db); try { removeUser(groupName, userName, db); //If any of the validations or setMethods reported an error, we throw them up now before create. ceb.throwIfNotEmpty(); commitTransaction(db); } catch(ConstraintException ce) { logger.warn("An error occurred so we should not complete the transaction:" + ce, ce); rollbackTransaction(db); throw ce; } catch(Exception e) { logger.error("An error occurred so we should not complete the transaction:" + e, e); rollbackTransaction(db); throw new SystemException(e.getMessage()); } } public void removeUser(String groupName, String userName, Database db) throws ConstraintException, SystemException, Exception { OQLQuery oql = db.getOQLQuery( "SELECT sur FROM org.infoglue.cms.entities.management.impl.simple.SystemUserGroupImpl sur WHERE sur.groupName = $1 AND sur.userName = $2"); oql.bind(groupName); oql.bind(userName); QueryResults results = oql.execute(); while (results.hasMore()) { SystemUserGroupImpl sur = (SystemUserGroupImpl)results.nextElement(); db.remove(sur); } results.close(); oql.close(); } public void removeUsers(String groupName) throws ConstraintException, SystemException, Exception { Database db = CastorDatabaseService.getDatabase(); beginTransaction(db); try { OQLQuery oql = db.getOQLQuery( "SELECT sur FROM org.infoglue.cms.entities.management.impl.simple.SystemUserGroupImpl sur WHERE sur.groupName = $1"); oql.bind(groupName); QueryResults results = oql.execute(); while (results.hasMore()) { SystemUserGroupImpl sur = (SystemUserGroupImpl)results.nextElement(); logger.info("Deleting " + sur.getUserName() + "/" + sur.getGroupName()); db.remove(sur); } results.close(); oql.close(); commitTransaction(db); } catch(Exception e) { logger.error("An error occurred so we should not complete the transaction:" + e, e); rollbackTransaction(db); throw new SystemException(e.getMessage()); } } /** * Get if the Group with the groupName exists */ public boolean groupExists(String groupName) throws SystemException, Bug { Database db = CastorDatabaseService.getDatabase(); beginTransaction(db); boolean groupExists = false; try { groupExists = groupExists(groupName, db); commitTransaction(db); } catch(Exception e) { logger.error("An error occurred so we should not complete the transaction:" + e, e); rollbackTransaction(db); throw new SystemException(e.getMessage()); } return groupExists; } /** * Get if the Group with the groupName exists */ public boolean groupExists(String groupName, Database db) throws SystemException, Bug { boolean groupExists = false; try { OQLQuery oql = db.getOQLQuery( "SELECT g FROM org.infoglue.cms.entities.management.impl.simple.GroupImpl g WHERE g.groupName = $1"); oql.bind(groupName); QueryResults results = oql.execute(Database.READONLY); if (results.hasMore()) { groupExists = true; } results.close(); oql.close(); } catch(Exception e) { throw new SystemException("An error occurred when we tried to fetch " + groupExists + " Reason:" + e.getMessage(), e); } return groupExists; } public Map<String,List<String>> getSystemUserGroupMapping(Database db) throws ConstraintException, SystemException, Exception { Map<String,List<String>> userGroupMapping = new HashMap<String,List<String>>(); OQLQuery oql = db.getOQLQuery( "SELECT sur FROM org.infoglue.cms.entities.management.impl.simple.SystemUserGroupImpl sur ORDER BY sur.userName"); QueryResults results = oql.execute(Database.READONLY); while (results.hasMore()) { SystemUserGroupImpl sur = (SystemUserGroupImpl)results.nextElement(); List<String> groupNames = userGroupMapping.get(sur.getUserName()); if(groupNames == null) { groupNames = new ArrayList<String>(); userGroupMapping.put(sur.getUserName(), groupNames); } groupNames.add(sur.getGroupName()); } results.close(); oql.close(); return userGroupMapping; } /** * This is a method that gives the user back an newly initialized ValueObject for this entity that the controller * is handling. */ public BaseEntityVO getNewVO() { return new GroupVO(); } }