/* * 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.mappers; import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.eurekastreams.server.domain.OrganizationTreeDTO; import org.eurekastreams.server.search.modelview.OrganizationModelView; /** * Mapper to get the Organization Tree DTO from the root downward, using the database only. */ public class GetOrganizationTreeDTO extends BaseArgDomainMapper<Long, OrganizationTreeDTO> { /** * Logger instance. */ private Log log = LogFactory.getLog(GetOrganizationTreeDTO.class); /** * Mapper to get all org ids. */ private DomainMapper<Long, List<Long>> getAllOrganizationIdsMapper; /** * Mapper to get orgs by id. */ private DomainMapper<List<Long>, List<OrganizationModelView>> getOrganizationsByIdMapper; /** * Constructor. * * @param inGetAllOrganizationIdsMapper * mapper to get all organization ids * @param inGetOrganizationsByIdMapper * mapper to get organization model views by id */ public GetOrganizationTreeDTO(final DomainMapper<Long, List<Long>> inGetAllOrganizationIdsMapper, final DomainMapper<List<Long>, List<OrganizationModelView>> inGetOrganizationsByIdMapper) { getAllOrganizationIdsMapper = inGetAllOrganizationIdsMapper; getOrganizationsByIdMapper = inGetOrganizationsByIdMapper; } /** * Fetch the OrganizationTreeDTO. * * @param ignored * not used * * @return the OrganizationTreeDTO from the root, downward */ public OrganizationTreeDTO execute(final Long ignored) { log.info("Building Organization Tree."); // build a hash of all orgs, grouped by parent org id HashMap<Long, Set<OrganizationModelView>> orgHash = new HashMap<Long, Set<OrganizationModelView>>(); OrganizationModelView rootOrg = buildOrgTreeHash(orgHash); // build the org tree OrganizationTreeDTO tree = populateTree(rootOrg, orgHash); log.info("Organization Tree built."); return tree; } /** * Build a Map of org id -> children OrganizationModelViews for all OrganizationModelViews. * * @param inOrgHash * the org hash to store org id -> OrganizationModelViews * @return the root OrganizationModelView */ private OrganizationModelView buildOrgTreeHash(final Map<Long, Set<OrganizationModelView>> inOrgHash) { OrganizationModelView rootOrg = null; // get all of the organization model views List<Long> orgIds = getAllOrganizationIdsMapper.execute(null); List<OrganizationModelView> orgs = getOrganizationsByIdMapper.execute(orgIds); // loop through the orgs, grouping them by parent org id for quicker looping while building the tree for (OrganizationModelView org : orgs) { if (org.getParentOrganizationId() == org.getEntityId()) { // don't add the root org to its parent list (self) rootOrg = org; continue; } Set<OrganizationModelView> children; if (!inOrgHash.containsKey(org.getParentOrganizationId())) { children = new HashSet<OrganizationModelView>(); inOrgHash.put(org.getParentOrganizationId(), children); } else { children = inOrgHash.get(org.getParentOrganizationId()); } children.add(org); } return rootOrg; } /** * Populate the tree of organizations recursively. * * @param inOrg * the starting point * @param inOrgMap * all OrganizationModelViews in the system * @return the tree. */ private OrganizationTreeDTO populateTree(final OrganizationModelView inOrg, final Map<Long, Set<OrganizationModelView>> inOrgMap) { OrganizationTreeDTO orgTree = new OrganizationTreeDTO(); orgTree.setDisplayName(inOrg.getName()); orgTree.setOrgId(inOrg.getEntityId()); orgTree.setShortName(inOrg.getShortName()); List<OrganizationTreeDTO> children = new ArrayList<OrganizationTreeDTO>(); if (inOrgMap.containsKey(inOrg.getEntityId())) { // has children for (OrganizationModelView childOrg : inOrgMap.get(inOrg.getEntityId())) { children.add(populateTree(childOrg, inOrgMap)); } } orgTree.setChildren(children); return orgTree; } }