/*
* The Kuali Financial System, a comprehensive financial management system for higher education.
*
* Copyright 2005-2014 The Kuali Foundation
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.kuali.kfs.sys.service.impl;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.commons.lang.StringUtils;
import org.kuali.kfs.coa.businessobject.Chart;
import org.kuali.kfs.coa.businessobject.Organization;
import org.kuali.kfs.coa.identity.FinancialSystemUserRoleTypeServiceImpl;
import org.kuali.kfs.coa.service.ChartService;
import org.kuali.kfs.coa.service.OrganizationService;
import org.kuali.kfs.sys.KFSConstants;
import org.kuali.kfs.sys.businessobject.ChartOrgHolder;
import org.kuali.kfs.sys.identity.KfsKimAttributes;
import org.kuali.kfs.sys.service.FinancialSystemUserService;
import org.kuali.rice.kim.api.KimConstants;
import org.kuali.rice.kim.api.identity.Person;
import org.kuali.rice.kim.api.identity.PersonService;
import org.kuali.rice.kim.api.identity.entity.Entity;
import org.kuali.rice.kim.api.role.RoleService;
import org.kuali.rice.kim.api.services.KimApiServiceLocator;
import org.kuali.rice.krad.util.ObjectUtils;
public class FinancialSystemUserServiceImpl implements FinancialSystemUserService {
protected ChartService chartService;
protected OrganizationService organizationService;
protected RoleService roleService;
protected PersonService personService;
protected String userRoleId;
private final List<String> userRoleIdList = new ArrayList<String>(1);
protected String getUserRoleId() {
if (userRoleId == null) {
userRoleId = roleService.getRoleIdByNamespaceCodeAndName(KFSConstants.CoreModuleNamespaces.KFS, KFSConstants.SysKimApiConstants.KFS_USER_ROLE_NAME);
}
return userRoleId;
}
protected List<String> getUserRoleIdAsList() {
if (userRoleIdList.isEmpty()) {
userRoleIdList.add(getUserRoleId());
}
return userRoleIdList;
}
/**
* @see org.kuali.kfs.sys.service.FinancialSystemUserService#isActiveFinancialSystemUser(java.lang.String)
*/
@Override
public boolean isActiveFinancialSystemUser(String principalId) {
if (StringUtils.isBlank(principalId)) {
return false;
}
return roleService.principalHasRole(principalId, getUserRoleIdAsList(), new HashMap<String, String>());
}
/**
* @see org.kuali.kfs.sys.service.FinancialSystemUserService#getPrimaryOrganization(org.kuali.rice.kim.api.identity.Person,
* java.lang.String)
*/
@Override
public ChartOrgHolder getPrimaryOrganization(Person person, String namespaceCode) {
if (person == null) {
return null;
}
ChartOrgHolder chartOrgHolder = getOrganizationForFinancialSystemUser(person.getPrincipalId(), namespaceCode);
if (chartOrgHolder == null) {
chartOrgHolder = getOrganizationForNonFinancialSystemUser(person);
}
return (chartOrgHolder == null) ? new ChartOrgHolderImpl() : chartOrgHolder;
}
/**
* @see org.kuali.kfs.sys.service.FinancialSystemUserService#getOrganizationByNamespaceCode(org.kuali.rice.kim.api.identity.Person,
* java.lang.String)
*/
@Override
public ChartOrgHolder getPrimaryOrganization(String principalId, String namespaceCode) {
if (StringUtils.isBlank(principalId)) {
return new ChartOrgHolderImpl();
}
ChartOrgHolder chartOrgHolder = getOrganizationForFinancialSystemUser(principalId, namespaceCode);
if (chartOrgHolder == null) {
chartOrgHolder = getOrganizationForNonFinancialSystemUser(personService.getPerson(principalId));
}
return (chartOrgHolder == null) ? new ChartOrgHolderImpl() : chartOrgHolder;
}
protected ChartOrgHolder getOrganizationForFinancialSystemUser(String principalId, String namespaceCode) {
if (StringUtils.isBlank(principalId)) {
return null;
}
Map<String, String> qualification = new HashMap<String, String>(2);
qualification.put(FinancialSystemUserRoleTypeServiceImpl.PERFORM_QUALIFIER_MATCH, "true");
qualification.put(KimConstants.AttributeConstants.NAMESPACE_CODE, namespaceCode);
List<Map<String, String>> roleQualifiers = roleService.getRoleQualifersForPrincipalByNamespaceAndRolename(principalId, KFSConstants.CoreModuleNamespaces.KFS, KFSConstants.SysKimApiConstants.KFS_USER_ROLE_NAME, qualification);
if ((roleQualifiers != null) && !roleQualifiers.isEmpty()) {
int count = 0;
while (count < roleQualifiers.size()) {
if (!StringUtils.isBlank(roleQualifiers.get(count).get(KfsKimAttributes.CHART_OF_ACCOUNTS_CODE)) && !StringUtils.isBlank(roleQualifiers.get(count).get(KfsKimAttributes.ORGANIZATION_CODE))) {
return new ChartOrgHolderImpl(roleQualifiers.get(count).get(KfsKimAttributes.CHART_OF_ACCOUNTS_CODE), roleQualifiers.get(count).get(KfsKimAttributes.ORGANIZATION_CODE));
}
count += 1;
}
}
return null;
}
@Deprecated
protected ChartOrgHolder getOrganizationForNonFinancialSystemUser(Person person) {
// HACK ALERT!!!!! - This is to support the original universal user table setup where the home department
// was encoded as CAMPUS-ORG (Where campus happened to match the chart) in the original FS_UNIVERSAL_USR_T table.
// This **REALLY** needs a new implementation
if (person != null && person.getPrimaryDepartmentCode().contains("-")) {
return new ChartOrgHolderImpl(StringUtils.substringBefore(person.getPrimaryDepartmentCode(), "-"), StringUtils.substringAfter(person.getPrimaryDepartmentCode(), "-"));
}
return null;
}
@Override
public Collection<String> getPrincipalIdsForFinancialSystemOrganizationUsers(String namespaceCode, ChartOrgHolder chartOrg) {
Map<String, String> qualification = new HashMap<String, String>(4);
qualification.put(FinancialSystemUserRoleTypeServiceImpl.PERFORM_QUALIFIER_MATCH, "true");
qualification.put(KimConstants.AttributeConstants.NAMESPACE_CODE, namespaceCode);
qualification.put(KfsKimAttributes.CHART_OF_ACCOUNTS_CODE, chartOrg.getChartOfAccountsCode());
qualification.put(KfsKimAttributes.ORGANIZATION_CODE, chartOrg.getOrganizationCode());
return roleService.getRoleMemberPrincipalIds(KFSConstants.CoreModuleNamespaces.KFS, KFSConstants.SysKimApiConstants.KFS_USER_ROLE_NAME, qualification);
}
@Override
public Collection<String> getPrincipalIdsForFinancialSystemOrganizationUsers(String namespaceCode, List<ChartOrgHolder> chartOrgs) {
List<String> principalIds = new ArrayList<String>();
for (ChartOrgHolder chartOrg : chartOrgs) {
principalIds.addAll(getPrincipalIdsForFinancialSystemOrganizationUsers(namespaceCode, chartOrg));
}
return principalIds;
}
public class ChartOrgHolderImpl implements ChartOrgHolder {
protected String chartOfAccountsCode;
protected String organizationCode;
public ChartOrgHolderImpl() {
}
public ChartOrgHolderImpl(String chartOfAccountsCode, String organizationCode) {
this.chartOfAccountsCode = chartOfAccountsCode;
this.organizationCode = organizationCode;
}
@Override
public Chart getChartOfAccounts() {
return chartService.getByPrimaryId(chartOfAccountsCode);
}
@Override
public Organization getOrganization() {
return organizationService.getByPrimaryIdWithCaching(chartOfAccountsCode, organizationCode);
}
@Override
public String getChartOfAccountsCode() {
return chartOfAccountsCode;
}
public void setChartOfAccountsCode(String chartOfAccountsCode) {
this.chartOfAccountsCode = chartOfAccountsCode;
}
@Override
public String getOrganizationCode() {
return organizationCode;
}
public void setOrganizationCode(String organizationCode) {
this.organizationCode = organizationCode;
}
@Override
public boolean equals(Object obj) {
if (!(obj instanceof ChartOrgHolder)) {
return false;
}
return chartOfAccountsCode.equals(((ChartOrgHolder) obj).getChartOfAccountsCode()) && organizationCode.equals(((ChartOrgHolder) obj).getOrganizationCode());
}
@Override
public int hashCode() {
return chartOfAccountsCode.hashCode() + organizationCode.hashCode();
}
}
/**
* KFSCNTRB-1344 This implementation serves as a default place-holder. It uses IdentityService to retrieve Person name instead
* of using PersonService, which is usually very slow with large date sets. Institutions that need to further speed up Person
* name retrieval can override the implementation by using IdentityService.getDefaultNamesForPrincipalId (however that will only
* work if PrincipalId is always the same as EmployeeId); Or, if speed is not a concern, fall back to using PersonService, which
* is a lot slower than IdentityService.
*
* @see org.kuali.kfs.sys.service.FinancialSystemUserService#getPersonNameByEmployeeId(java.lang.String)
*/
// TODO This method can be replaced if Rice adds method IdentityService.getPersonNameByEmployeeId.
@Override
public String getPersonNameByEmployeeId(String employeeId) {
Entity entity = KimApiServiceLocator.getIdentityService().getEntityByEmployeeId(employeeId);
if (ObjectUtils.isNotNull(entity) && ObjectUtils.isNotNull(entity.getDefaultName())) {
return entity.getDefaultName().getCompositeName();
}
return null;
}
public void setChartService(ChartService chartService) {
this.chartService = chartService;
}
public void setOrganizationService(OrganizationService organizationService) {
this.organizationService = organizationService;
}
public void setRoleService(RoleService roleService) {
this.roleService = roleService;
}
public void setPersonService(PersonService personService) {
this.personService = personService;
}
}