/*
* Copyright (c) 2009-2011 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.mappers;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Set;
import org.eurekastreams.commons.hibernate.ModelViewResultTransformer;
import org.eurekastreams.server.domain.DomainGroup;
import org.eurekastreams.server.domain.PagedSet;
import org.eurekastreams.server.persistence.mappers.cache.OrganizationHierarchyCache;
import org.eurekastreams.server.persistence.mappers.requests.GetPendingDomainGroupsForOrgRequest;
import org.eurekastreams.server.search.factories.DomainGroupModelViewFactory;
import org.eurekastreams.server.search.modelview.DomainGroupModelView;
import org.eurekastreams.server.search.modelview.PersonModelView;
import org.hibernate.Criteria;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.ProjectionList;
import org.hibernate.criterion.Projections;
import org.hibernate.criterion.Restrictions;
/**
* The get pending groups action mapper - gets pending groups from the DB. Keep in mind that pending groups aren't
* cached.
*/
public class GetPendingDomainGroupsForOrg extends
BaseArgDomainMapper<GetPendingDomainGroupsForOrgRequest, PagedSet<DomainGroupModelView>>
{
/**
*The org cache to find the nested orgs from.
*/
private final OrganizationHierarchyCache orgCache;
/**
* Mapper to get people by IDs, using cache.
*/
private DomainMapper<List<Long>, List<PersonModelView>>getPeopleByIdsMapper;
/**
* Constructor.
*
* @param inOrgCache
* the org cache from spring.
*/
public GetPendingDomainGroupsForOrg(final OrganizationHierarchyCache inOrgCache)
{
orgCache = inOrgCache;
}
/**
* Execute getting the groups pending for an org.
*
* @param inRequest
* the request for the data.
* @return A pageset of Groups pending for the Org in the request.
*/
@SuppressWarnings("unchecked")
@Override
public PagedSet<DomainGroupModelView> execute(final GetPendingDomainGroupsForOrgRequest inRequest)
{
Set<Long> organizationIds = getOrganizationIds(inRequest.getOrgShortName());
// create our query
Criteria criteria = getHibernateSession().createCriteria(DomainGroup.class);
// tell hibernate which fields we want back
ProjectionList fields = Projections.projectionList();
fields.add(getColumn("id"));
fields.add(getColumn("shortName"));
fields.add(getColumn("name"));
fields.add(getColumn("description"));
fields.add(Projections.property("publicGroup").as("isPublic"));
fields.add(Projections.property("createdBy.id").as("personCreatedById"));
fields.add(getColumn("dateAdded"));
criteria.setProjection(fields);
// add restrictions (where clauses)
// pending groups
criteria.add(Restrictions.eq("isPending", true));
// under our input organization id
criteria.add(Restrictions.in("parentOrganization.id", organizationIds));
// set the sort order
criteria.addOrder(Order.asc("dateAdded"));
// set the result transformer - transforms tuples into
// DomainGroupModelViews
ModelViewResultTransformer<DomainGroupModelView> resultTransformer;
resultTransformer = new ModelViewResultTransformer<DomainGroupModelView>(new DomainGroupModelViewFactory());
criteria.setResultTransformer(resultTransformer);
criteria.setFirstResult(inRequest.getPageStart());
criteria.setMaxResults(inRequest.getMaxResults());
// get the results
List<DomainGroupModelView> results = criteria.list();
// populate info from the cache
populateCachedFields(results);
// Get Total Row Count
Criteria rowCountCriteria = getHibernateSession().createCriteria(DomainGroup.class);
rowCountCriteria.setProjection(Projections.rowCount());
rowCountCriteria.add(Restrictions.eq("isPending", true));
// under our input organization id
rowCountCriteria.add(Restrictions.in("parentOrganization.id", organizationIds));
// Create Page Set
PagedSet<DomainGroupModelView> pagedSet = new PagedSet<DomainGroupModelView>();
pagedSet.setPagedSet(results);
pagedSet.setFromIndex(inRequest.getPageStart());
pagedSet.setToIndex(inRequest.getPageStart() + results.size() - 1);
pagedSet.setTotal((Integer) rowCountCriteria.list().get(0));
return pagedSet;
}
/**
* Populate the rest of the model view object with data from the cache.
*
* @param inResults
* The groups to populate with extra data.
*/
private void populateCachedFields(final List<DomainGroupModelView> inResults)
{
// loop over the results to collect all of the people we need to ask cache for
List<Long> peopleIdsToFetch = new ArrayList<Long>();
for (DomainGroupModelView result : inResults)
{
if (!peopleIdsToFetch.contains(result.getPersonCreatedById()))
{
peopleIdsToFetch.add(result.getPersonCreatedById());
}
}
// fetch the people
List<PersonModelView> people = getPeopleByIdsMapper.execute(peopleIdsToFetch);
// put them in a map for lookup
HashMap<Long, PersonModelView> peopleByIdMap = new HashMap<Long, PersonModelView>();
for (PersonModelView person : people)
{
peopleByIdMap.put(person.getEntityId(), person);
}
for (DomainGroupModelView result : inResults)
{
if (result.getPersonCreatedById() != null)
{
PersonModelView person = peopleByIdMap.get(result.getPersonCreatedById());
result.setPersonCreatedByAccountId(person.getAccountId());
result.setPersonCreatedByDisplayName(person.getDisplayName());
}
}
}
/**
* Get the IDs of the organizations for which to retrieve pending groups.
*
* @param inOrgShortName
* The parent org's short name.
* @return A String of IDs for the orgs.
*/
private Set<Long> getOrganizationIds(final String inOrgShortName)
{
return Collections.singleton(orgCache.getOrganizationIdFromShortName(inOrgShortName));
}
/**
* @param inGetPeopleByIdsMapper
* the getPeopleByIdsMapper to set
*/
public void setGetPeopleByIdsMapper(final DomainMapper<List<Long>, List<PersonModelView>>inGetPeopleByIdsMapper)
{
getPeopleByIdsMapper = inGetPeopleByIdsMapper;
}
}