/*
* Copyright (c) 2009-2010 Lockheed Martin Corporation
*
* Licensed 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
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* 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.eurekastreams.server.persistence;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import javax.persistence.FlushModeType;
import javax.persistence.Query;
import org.eurekastreams.commons.hibernate.QueryOptimizer;
import org.eurekastreams.server.domain.DomainGroup;
import org.eurekastreams.server.domain.Followable;
import org.eurekastreams.server.domain.GroupFollower;
import org.eurekastreams.server.domain.PagedSet;
import org.eurekastreams.server.domain.Person;
import org.apache.commons.logging.Log;
import org.eurekastreams.commons.logging.LogFactory;
/**
* This class provides the mapper functionality for DomainGroup entities.
*/
@Deprecated
public class DomainGroupMapper extends DomainEntityMapper<DomainGroup> implements FollowMapper, CompositeEntityMapper
{
/**
* Logger.
*/
private final Log log = LogFactory.make();
/**
* Constructor.
*
* @param inQueryOptimizer
* the QueryOptimizer to use for specialized functions.
*/
public DomainGroupMapper(final QueryOptimizer inQueryOptimizer)
{
super(inQueryOptimizer);
}
/**
* Look up a group by its short name.
*
* @param groupShortName
* the short name of a group to look for
* @return the DomainGroup corresponding to the provided short name
*/
@SuppressWarnings("unchecked")
public DomainGroup findByShortName(final String groupShortName)
{
Query q = getEntityManager().createQuery("from DomainGroup where shortname = :inName")
.setParameter("inName", groupShortName.toLowerCase()).setFlushMode(FlushModeType.COMMIT);
List results = q.getResultList();
return (results.size() == 0) ? null : (DomainGroup) results.get(0);
}
/**
* @return the entity's type
*/
@Override
protected String getDomainEntityName()
{
return "DomainGroup";
}
/**
* Creates a follower/following relationship between two entities.
*
* @param followerId
* The id of the follower Person
* @param followingId
* The entity id being Followed.
*/
public void addFollower(final long followerId, final long followingId)
{
Query q = getEntityManager()
.createQuery("FROM GroupFollower where followerId=:followerId and followingId=:followingId")
.setParameter("followerId", followerId).setParameter("followingId", followingId);
if (q.getResultList().size() > 0)
{
// already following
return;
}
// add follower
getEntityManager().persist(new GroupFollower(followerId, followingId));
// now update the counts for persons.
getEntityManager()
.createQuery(
"update versioned Person set groupsCount = followingGroup.size,"
+ " groupStreamHiddenLineIndex = groupStreamHiddenLineIndex + 1 where id=:followerId")
.setParameter("followerId", followerId).executeUpdate();
getEntityManager()
.createQuery("update versioned DomainGroup set followersCount = followers.size where id=:followingId")
.setParameter("followingId", followingId).executeUpdate();
getEntityManager().flush();
getEntityManager().clear();
DomainGroup followingEntity = findById(followingId);
// reindex the following in the search index
getFullTextSession().index(followingEntity);
}
/**
* Returns a set of People following the specified DomainGroup.
*
* @param shortName
* The shortName of the DomainGroup for whom to get followers.
* @param start
* paging start.
* @param end
* paging end.
* @return paged set of followers.
*/
public PagedSet<Person> getFollowers(final String shortName, final int start, final int end)
{
HashMap<String, Object> parameters = new HashMap<String, Object>();
parameters.put("shortName", shortName.toLowerCase());
String query = "select g.followers from DomainGroup g where g.shortName = :shortName";
// although the line above is just concatenating a query string
// and this implies vulnerability to SQL injection attacks,
// the call to this.getPagedResults() actually parameterizes the SQL
// so there is not actually risk of SQL injection here.
PagedSet<Person> results = getTypedPagedResults(start, end, query, parameters);
return results;
}
/**
* Returns a set of DomainGroups that are being followed by the specified person.
*
* @param accountId
* The id of the DomainGroup for whom to get following.
* @param start
* paging start.
* @param end
* paging end.
* @return paged set of following.
*/
public PagedSet<Followable> getFollowing(final String accountId, final int start, final int end)
{
HashMap<String, Object> parameters = new HashMap<String, Object>();
parameters.put("accountId", accountId);
String query = "select p.followingGroup from Person p where p.accountId = :accountId";
// although the line above is just concatenating a query string
// and this implies vulnerability to SQL injection attacks,
// the call to this.getPagedResults() actually parameterizes the SQL
// so there is not actually risk of SQL injection here.
PagedSet<Followable> results = getTypedPagedResults(start, end, query, parameters);
return results;
}
/**
* Returns true if follower/following relationship exists false otherwise.
*
* @param followerAccountId
* The follower person's account Id.
* @param shortName
* The short name of the group being followed
* @return True if follower/following relationship exists false otherwise.
*/
@SuppressWarnings("unchecked")
public boolean isFollowing(final String followerAccountId, final String shortName)
{
Query q = getEntityManager()
.createQuery(
"FROM Person as follower" + " inner join follower.followingGroup as following"
+ " where follower.accountId=:followerAccountId and"
+ " following.shortName=:followingShortName")
.setParameter("followerAccountId", followerAccountId)
.setParameter("followingShortName", shortName.toLowerCase());
List<Person> results = q.getResultList();
return (results.size() != 0);
}
/**
* Removes a follower/following relationship between a Person and a DomainGroup.
*
* @param followerId
* The if of the follower Person
* @param followingId
* The group id being Followed.
*/
public void removeFollower(final long followerId, final long followingId)
{
int rowsDeleted = getEntityManager()
.createQuery("DELETE FROM GroupFollower where followerId=:followerId and followingId=:followingId")
.setParameter("followerId", followerId).setParameter("followingId", followingId).executeUpdate();
if (rowsDeleted == 0)
{
// not following, short circuit.
return;
}
// now update the counts for persons.
getEntityManager()
.createQuery("update versioned Person set groupsCount = followingGroup.size where id=:followerId")
.setParameter("followerId", followerId).executeUpdate();
getEntityManager()
.createQuery("update versioned DomainGroup set followersCount = followers.size where id=:followingId")
.setParameter("followingId", followingId).executeUpdate();
getEntityManager().flush();
getEntityManager().clear();
DomainGroup followingEntity = findById(followingId);
// reindex the following in the search index
getFullTextSession().index(followingEntity);
}
/**
* Removes a follower/following relationship between a Person and a DomainGroup.coordinators.
*
* @param followerId
* The if of the follower Person
* @param followingId
* The group id being Followed.
*/
public void removeGroupCoordinator(final long followerId, final long followingId)
{
DomainGroup followingEntity = findById(followingId);
Set<Person> groupCoordinators = followingEntity.getCoordinators();
removeGroupCoordinator(groupCoordinators, followerId, followingId);
followingEntity.setCoordinators(groupCoordinators);
getEntityManager().flush();
}
/**
* Get a String representation the Person.id of all of the Person.ids for coordinators and followers of the input
* group.
*
* @param domainGroup
* the DomainGroup to find coordinators and followers for
* @return an array of all of the Person.ids for coordinators and followers of the input group
*/
@SuppressWarnings("unchecked")
public Long[] getFollowerAndCoordinatorPersonIds(final DomainGroup domainGroup)
{
// use a set to eliminate duplicates
HashSet<Long> peopleIds = new HashSet<Long>();
Query q = getEntityManager().createQuery("SELECT pk.followerId FROM GroupFollower WHERE followingId=:groupId")
.setParameter("groupId", domainGroup.getId());
peopleIds.addAll(q.getResultList());
q = getEntityManager().createQuery(
"SELECT p.id FROM Person p, DomainGroup g WHERE p MEMBER OF g.coordinators AND g.id=:groupId")
.setParameter("groupId", domainGroup.getId());
peopleIds.addAll(q.getResultList());
return peopleIds.toArray(new Long[peopleIds.size()]);
}
/**
* Delete this group.
*
* @param id
* the id of the group to delete.
*/
public void deleteById(final long id)
{
DomainGroup group = findById(id);
getEntityManager().remove(group);
getEntityManager().flush();
}
/**
* Is the input Person a Group Coordinator of the input Group?
*
* @param followerId
* Person
*
* @param followingId
* Group
*
* @return Whether 'Person' is a Group Coordinator of 'Group'
*/
public boolean isInputUserGroupCoordinator(final long followerId, final long followingId)
{
String groupCoordinatorQuery = "SELECT p.id FROM Person p, DomainGroup g WHERE p member of g.coordinators"
+ " AND g.id = :groupId";
List<Long> groupCoordinatorResult = getEntityManager().createQuery(groupCoordinatorQuery)
.setParameter("groupId", followingId).getResultList();
if (groupCoordinatorResult.contains(new Long(followerId)))
{
return true;
}
return false;
}
/**
* Removes a User from being a Group Coordinator.
*
* @param groupCoordinators
* List of group coordinators
*
* @param followerId
* Id of User to Remove
*
* @param followingId
* Id of Group from which a User will be removed
*
*/
private void removeGroupCoordinator(final Set<Person> groupCoordinators, final long followerId,
final long followingId)
{
String groupCoordinatorQuery = "SELECT p.accountId FROM Person p, "
+ "DomainGroup g WHERE p member of g.coordinators" + " AND g.id = :groupId AND p.id = :followerId";
List<String> groupCoordinatorResult = getEntityManager().createQuery(groupCoordinatorQuery)
.setParameter("groupId", followingId).setParameter("followerId", followerId).getResultList();
if ((groupCoordinatorResult == null) || (groupCoordinatorResult.size() == 0))
{
return;
}
String accountId = groupCoordinatorResult.get(0);
for (Person p : groupCoordinators)
{
if (p.getAccountId().equals(accountId))
{
groupCoordinators.remove(p);
return;
}
}
}
/**
* isGroupPrivate - returns true/false depending if a given Group is private.
*
* @param followingId
* - id of the Group
*
* @return Whether the Group is Private
*/
public boolean isGroupPrivate(final long followingId)
{
String groupCoordinatorQuery = "SELECT g FROM DomainGroup g WHERE g.id = :groupId";
List<DomainGroup> groupCoordinatorResult = getEntityManager().createQuery(groupCoordinatorQuery)
.setParameter("groupId", followingId).getResultList();
DomainGroup group = groupCoordinatorResult.get(0);
return !group.isPublicGroup();
}
/**
* getGroupCoordinatorCount - returns the number of Group Coordinators for a given Group.
*
* @param followingId
* - id of the Group
*
* @return number of Group Coordinators for Group
*/
public int getGroupCoordinatorCount(final long followingId)
{
String groupCoordinatorQuery = "SELECT p.accountId FROM Person p, "
+ "DomainGroup g WHERE p member of g.coordinators" + " AND g.id = :groupId";
List<String> groupCoordinatorResult = getEntityManager().createQuery(groupCoordinatorQuery)
.setParameter("groupId", followingId).getResultList();
return groupCoordinatorResult.size();
}
}