All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.liferay.portal.service.impl.OrganizationLocalServiceImpl Maven / Gradle / Ivy

There is a newer version: 7.4.3.112-ga112
Show newest version
/**
 * Copyright (c) 2000-present Liferay, Inc. All rights reserved.
 *
 * This library is free software; you can redistribute it and/or modify it under
 * the terms of the GNU Lesser General Public License as published by the Free
 * Software Foundation; either version 2.1 of the License, or (at your option)
 * any later version.
 *
 * This library 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 Lesser General Public License for more
 * details.
 */

package com.liferay.portal.service.impl;

import com.liferay.petra.string.StringPool;
import com.liferay.portal.kernel.dao.orm.IndexableActionableDynamicQuery;
import com.liferay.portal.kernel.dao.orm.Property;
import com.liferay.portal.kernel.dao.orm.PropertyFactoryUtil;
import com.liferay.portal.kernel.dao.orm.QueryDefinition;
import com.liferay.portal.kernel.dao.orm.QueryUtil;
import com.liferay.portal.kernel.exception.DuplicateOrganizationException;
import com.liferay.portal.kernel.exception.OrganizationNameException;
import com.liferay.portal.kernel.exception.OrganizationParentException;
import com.liferay.portal.kernel.exception.OrganizationTypeException;
import com.liferay.portal.kernel.exception.PortalException;
import com.liferay.portal.kernel.exception.RequiredOrganizationException;
import com.liferay.portal.kernel.exception.SystemException;
import com.liferay.portal.kernel.log.Log;
import com.liferay.portal.kernel.log.LogFactoryUtil;
import com.liferay.portal.kernel.model.Company;
import com.liferay.portal.kernel.model.Country;
import com.liferay.portal.kernel.model.Group;
import com.liferay.portal.kernel.model.GroupConstants;
import com.liferay.portal.kernel.model.ListTypeConstants;
import com.liferay.portal.kernel.model.Organization;
import com.liferay.portal.kernel.model.OrganizationConstants;
import com.liferay.portal.kernel.model.Region;
import com.liferay.portal.kernel.model.ResourceConstants;
import com.liferay.portal.kernel.model.Role;
import com.liferay.portal.kernel.model.RoleConstants;
import com.liferay.portal.kernel.model.SystemEventConstants;
import com.liferay.portal.kernel.model.User;
import com.liferay.portal.kernel.model.UserGroupRole;
import com.liferay.portal.kernel.search.BaseModelSearchResult;
import com.liferay.portal.kernel.search.Document;
import com.liferay.portal.kernel.search.Hits;
import com.liferay.portal.kernel.search.Indexer;
import com.liferay.portal.kernel.search.IndexerRegistryUtil;
import com.liferay.portal.kernel.search.QueryConfig;
import com.liferay.portal.kernel.search.SearchContext;
import com.liferay.portal.kernel.search.SearchException;
import com.liferay.portal.kernel.search.Sort;
import com.liferay.portal.kernel.security.auth.CompanyThreadLocal;
import com.liferay.portal.kernel.service.ServiceContext;
import com.liferay.portal.kernel.systemevent.SystemEvent;
import com.liferay.portal.kernel.transaction.TransactionCommitCallbackUtil;
import com.liferay.portal.kernel.tree.TreeModelTasksAdapter;
import com.liferay.portal.kernel.tree.TreePathUtil;
import com.liferay.portal.kernel.util.ArrayUtil;
import com.liferay.portal.kernel.util.ListUtil;
import com.liferay.portal.kernel.util.MapUtil;
import com.liferay.portal.kernel.util.OrderByComparator;
import com.liferay.portal.kernel.util.PortalUtil;
import com.liferay.portal.kernel.util.ServiceProxyFactory;
import com.liferay.portal.kernel.util.SetUtil;
import com.liferay.portal.kernel.util.StringBundler;
import com.liferay.portal.kernel.util.StringUtil;
import com.liferay.portal.kernel.util.Validator;
import com.liferay.portal.kernel.util.comparator.OrganizationIdComparator;
import com.liferay.portal.kernel.util.comparator.OrganizationNameComparator;
import com.liferay.portal.kernel.workflow.WorkflowConstants;
import com.liferay.portal.service.base.OrganizationLocalServiceBaseImpl;
import com.liferay.portal.util.PropsValues;
import com.liferay.portlet.usersadmin.search.OrganizationUsersSearcher;
import com.liferay.users.admin.kernel.file.uploads.UserFileUploadsSettings;
import com.liferay.users.admin.kernel.organization.types.OrganizationTypesSettings;
import com.liferay.users.admin.kernel.util.UsersAdminUtil;
import com.liferay.util.dao.orm.CustomSQLUtil;

import java.io.Serializable;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * Provides the local service for accessing, adding, deleting, and updating
 * organizations.
 *
 * @author Brian Wing Shun Chan
 * @author Jorge Ferrer
 * @author Julio Camarero
 * @author Hugo Huijser
 * @author Juan Fernández
 * @author Marco Leo
 */
public class OrganizationLocalServiceImpl
	extends OrganizationLocalServiceBaseImpl {

	/**
	 * Adds the organization to the group.
	 *
	 * @param groupId the primary key of the group
	 * @param organizationId the primary key of the organization
	 */
	@Override
	public void addGroupOrganization(long groupId, long organizationId) {
		super.addGroupOrganization(groupId, organizationId);

		try {
			reindexUsers(organizationId);
		}
		catch (PortalException pe) {
			throw new SystemException(pe);
		}
	}

	/**
	 * Adds the organization to the group.
	 *
	 * @param groupId the primary key of the group
	 * @param organization the organization
	 */
	@Override
	public void addGroupOrganization(long groupId, Organization organization) {
		super.addGroupOrganization(groupId, organization);

		try {
			reindexUsers(organization);
		}
		catch (PortalException pe) {
			throw new SystemException(pe);
		}
	}

	/**
	 * Adds the organizations to the group.
	 *
	 * @param groupId the primary key of the group
	 * @param organizations the organizations
	 */
	@Override
	public void addGroupOrganizations(
		long groupId, List organizations) {

		super.addGroupOrganizations(groupId, organizations);

		try {
			reindexUsers(organizations);
		}
		catch (PortalException pe) {
			throw new SystemException(pe);
		}
	}

	/**
	 * Adds the organizations to the group.
	 *
	 * @param groupId the primary key of the group
	 * @param organizationIds the primary keys of the organizations
	 */
	@Override
	public void addGroupOrganizations(long groupId, long[] organizationIds) {
		super.addGroupOrganizations(groupId, organizationIds);

		try {
			reindexUsers(organizationIds);
		}
		catch (PortalException pe) {
			throw new SystemException(pe);
		}
	}

	/**
	 * Adds an organization.
	 *
	 * 

* This method handles the creation and bookkeeping of the organization * including its resources, metadata, and internal data structures. It is * not necessary to make a subsequent call to {@link * #addOrganizationResources(long, Organization)}. *

* * @param userId the primary key of the creator/owner of the organization * @param parentOrganizationId the primary key of the organization's parent * organization * @param name the organization's name * @param site whether the organization is to be associated with a main * site * @return the organization */ @Override public Organization addOrganization( long userId, long parentOrganizationId, String name, boolean site) throws PortalException { String[] types = getTypes(); return addOrganization( userId, parentOrganizationId, name, types[0], 0, 0, ListTypeConstants.ORGANIZATION_STATUS_DEFAULT, StringPool.BLANK, site, null); } /** * Adds an organization. * *

* This method handles the creation and bookkeeping of the organization * including its resources, metadata, and internal data structures. It is * not necessary to make a subsequent call to {@link * #addOrganizationResources(long, Organization)}. *

* * @param userId the primary key of the creator/owner of the organization * @param parentOrganizationId the primary key of the organization's parent * organization * @param name the organization's name * @param type the organization's type * @param regionId the primary key of the organization's region * @param countryId the primary key of the organization's country * @param statusId the organization's workflow status * @param comments the comments about the organization * @param site whether the organization is to be associated with a main * site * @param serviceContext the service context to be applied (optionally * null). Can set asset category IDs, asset tag names, * and expando bridge attributes for the organization. * @return the organization */ @Override public Organization addOrganization( long userId, long parentOrganizationId, String name, String type, long regionId, long countryId, long statusId, String comments, boolean site, ServiceContext serviceContext) throws PortalException { // Organization User user = userPersistence.findByPrimaryKey(userId); parentOrganizationId = getParentOrganizationId( user.getCompanyId(), parentOrganizationId); validate( user.getCompanyId(), parentOrganizationId, name, type, countryId, statusId); long organizationId = counterLocalService.increment(); Organization organization = organizationPersistence.create( organizationId); if (serviceContext != null) { organization.setUuid(serviceContext.getUuid()); } organization.setCompanyId(user.getCompanyId()); organization.setUserId(user.getUserId()); organization.setUserName(user.getFullName()); organization.setParentOrganizationId(parentOrganizationId); organization.setTreePath(organization.buildTreePath()); organization.setName(name); organization.setType(type); organization.setRecursable(true); organization.setRegionId(regionId); organization.setCountryId(countryId); organization.setStatusId(statusId); organization.setComments(comments); organization.setExpandoBridgeAttributes(serviceContext); organizationPersistence.update(organization); // Group long parentGroupId = GroupConstants.DEFAULT_PARENT_GROUP_ID; if (parentOrganizationId != OrganizationConstants.DEFAULT_PARENT_ORGANIZATION_ID) { Organization parentOrganization = organizationPersistence.fetchByPrimaryKey(parentOrganizationId); if (parentOrganization != null) { Group parentGroup = parentOrganization.getGroup(); if (site && parentGroup.isSite()) { parentGroupId = parentOrganization.getGroupId(); } } } Group group = groupLocalService.addGroup( userId, parentGroupId, Organization.class.getName(), organizationId, GroupConstants.DEFAULT_LIVE_GROUP_ID, getLocalizationMap(name), null, GroupConstants.TYPE_SITE_PRIVATE, false, GroupConstants.DEFAULT_MEMBERSHIP_RESTRICTION, null, site, true, null); // Role Role role = roleLocalService.getRole( organization.getCompanyId(), RoleConstants.ORGANIZATION_OWNER); userGroupRoleLocalService.addUserGroupRoles( userId, group.getGroupId(), new long[] {role.getRoleId()}); // Resources addOrganizationResources(userId, organization); // Asset if (serviceContext != null) { updateAsset( userId, organization, serviceContext.getAssetCategoryIds(), serviceContext.getAssetTagNames()); } // Indexer if ((serviceContext == null) || serviceContext.isIndexingEnabled()) { Indexer indexer = IndexerRegistryUtil.nullSafeGetIndexer(Organization.class); indexer.reindex(organization); } return organization; } /** * Adds a resource for each type of permission available on the * organization. * * @param userId the primary key of the creator/owner of the organization * @param organization the organization */ @Override public void addOrganizationResources(long userId, Organization organization) throws PortalException { String name = Organization.class.getName(); resourceLocalService.addResources( organization.getCompanyId(), 0, userId, name, organization.getOrganizationId(), false, false, false); } /** * Assigns the password policy to the organizations, removing any other * currently assigned password policies. * * @param passwordPolicyId the primary key of the password policy * @param organizationIds the primary keys of the organizations */ @Override public void addPasswordPolicyOrganizations( long passwordPolicyId, long[] organizationIds) { passwordPolicyRelLocalService.addPasswordPolicyRels( passwordPolicyId, Organization.class.getName(), organizationIds); } /** * Deletes the organization's logo. * * @param organizationId the primary key of the organization */ @Override public void deleteLogo(long organizationId) throws PortalException { Organization organization = getOrganization(organizationId); PortalUtil.updateImageId(organization, false, null, "logoId", 0, 0, 0); } /** * Deletes the organization. The organization's associated resources and * assets are also deleted. * * @param organizationId the primary key of the organization * @return the deleted organization */ @Override public Organization deleteOrganization(long organizationId) throws PortalException { Organization organization = organizationPersistence.findByPrimaryKey( organizationId); return organizationLocalService.deleteOrganization(organization); } /** * Deletes the organization. The organization's associated resources and * assets are also deleted. * * @param organization the organization * @return the deleted organization */ @Override @SystemEvent(type = SystemEventConstants.TYPE_DELETE) public Organization deleteOrganization(Organization organization) throws PortalException { if (!CompanyThreadLocal.isDeleteInProcess()) { LinkedHashMap params = new LinkedHashMap<>(); params.put( "usersOrgs", Long.valueOf(organization.getOrganizationId())); int count1 = organizationPersistence.countByC_P( organization.getCompanyId(), organization.getOrganizationId()); int count2 = userFinder.countByKeywords( organization.getCompanyId(), null, WorkflowConstants.STATUS_APPROVED, params); if ((count1 > 0) || (count2 > 0)) { throw new RequiredOrganizationException(); } } // Asset assetEntryLocalService.deleteEntry( Organization.class.getName(), organization.getOrganizationId()); // Addresses addressLocalService.deleteAddresses( organization.getCompanyId(), Organization.class.getName(), organization.getOrganizationId()); // Email addresses emailAddressLocalService.deleteEmailAddresses( organization.getCompanyId(), Organization.class.getName(), organization.getOrganizationId()); // Expando expandoRowLocalService.deleteRows(organization.getOrganizationId()); // Password policy relation passwordPolicyRelLocalService.deletePasswordPolicyRel( Organization.class.getName(), organization.getOrganizationId()); // Phone phoneLocalService.deletePhones( organization.getCompanyId(), Organization.class.getName(), organization.getOrganizationId()); // Website websiteLocalService.deleteWebsites( organization.getCompanyId(), Organization.class.getName(), organization.getOrganizationId()); // Group Group group = organization.getGroup(); if (group.isSite()) { group.setSite(false); groupPersistence.update(group); } groupLocalService.deleteGroup(group); // Resources String name = Organization.class.getName(); resourceLocalService.deleteResource( organization.getCompanyId(), name, ResourceConstants.SCOPE_INDIVIDUAL, organization.getOrganizationId()); // Organization organizationPersistence.remove(organization); return organization; } /** * Returns the organization with the name. * * @param companyId the primary key of the organization's company * @param name the organization's name * @return the organization with the name, or null if no * organization could be found */ @Override public Organization fetchOrganization(long companyId, String name) { return organizationPersistence.fetchByC_N(companyId, name); } @Override public String[] getChildrenTypes(String type) { return _organizationTypesSettings.getChildrenTypes(type); } @Override public List getGroupUserOrganizations( long groupId, long userId) throws PortalException { long[] groupOrganizationIds = groupPersistence.getOrganizationPrimaryKeys(groupId); if (groupOrganizationIds.length == 0) { return Collections.emptyList(); } long[] userOrganizationIds = userPersistence.getOrganizationPrimaryKeys( userId); if (userOrganizationIds.length == 0) { return Collections.emptyList(); } Set organizationIds = SetUtil.intersect( groupOrganizationIds, userOrganizationIds); if (organizationIds.isEmpty()) { return Collections.emptyList(); } List organizations = new ArrayList<>( organizationIds.size()); for (Long organizationId : organizationIds) { organizations.add( organizationPersistence.findByPrimaryKey(organizationId)); } return organizations; } @Override public List getNoAssetOrganizations() { return organizationFinder.findO_ByNoAssets(); } /** * Returns the organization with the name. * * @param companyId the primary key of the organization's company * @param name the organization's name * @return the organization with the name */ @Override public Organization getOrganization(long companyId, String name) throws PortalException { return organizationPersistence.findByC_N(companyId, name); } /** * Returns the primary key of the organization with the name. * * @param companyId the primary key of the organization's company * @param name the organization's name * @return the primary key of the organization with the name, or * 0 if the organization could not be found */ @Override public long getOrganizationId(long companyId, String name) { Organization organization = organizationPersistence.fetchByC_N( companyId, name); if (organization != null) { return organization.getOrganizationId(); } return 0; } @Override public List getOrganizations( long userId, int start, int end, OrderByComparator obc) throws PortalException { User user = userPersistence.findByPrimaryKey(userId); List organizations = ListUtil.copy( userPersistence.getOrganizations(userId)); Iterator iterator = organizations.iterator(); while (iterator.hasNext()) { Organization organization = iterator.next(); if (organization.getCompanyId() != user.getCompanyId()) { iterator.remove(); } } if (organizations.isEmpty()) { return organizations; } if (obc == null) { obc = new OrganizationNameComparator(true); } Collections.sort(organizations, obc); return ListUtil.subList(organizations, start, end); } /** * Returns all the organizations belonging to the parent organization. * * @param companyId the primary key of the organization's company * @param parentOrganizationId the primary key of the organization's parent * organization * @return the organizations belonging to the parent organization */ @Override public List getOrganizations( long companyId, long parentOrganizationId) { return getOrganizations( companyId, parentOrganizationId, QueryUtil.ALL_POS, QueryUtil.ALL_POS); } /** * Returns a range of all the organizations belonging to the parent * organization. * *

* Useful when paginating results. Returns a maximum of end - * start instances. start and end are not * primary keys, they are indexes in the result set. Thus, 0 * refers to the first result in the set. Setting both start * and end to {@link QueryUtil#ALL_POS} will return the full * result set. *

* * @param companyId the primary key of the organization's company * @param parentOrganizationId the primary key of the organization's parent * organization * @param start the lower bound of the range of organizations to return * @param end the upper bound of the range of organizations to return (not * inclusive) * @return the range of organizations belonging to the parent organization * @see com.liferay.portal.kernel.service.persistence.OrganizationPersistence#findByC_P( * long, long, int, int) */ @Override public List getOrganizations( long companyId, long parentOrganizationId, int start, int end) { if (parentOrganizationId == OrganizationConstants.ANY_PARENT_ORGANIZATION_ID) { return organizationPersistence.findByCompanyId( companyId, start, end); } return organizationPersistence.findByC_P( companyId, parentOrganizationId, start, end); } @Override public List getOrganizations( long companyId, long parentOrganizationId, String name, int start, int end) { if (Validator.isNull(name)) { return organizationPersistence.findByC_P( companyId, parentOrganizationId, start, end); } return organizationPersistence.findByC_P_LikeN( companyId, parentOrganizationId, name, start, end); } @Override public List getOrganizations( long companyId, String treePath) { return organizationPersistence.findByC_T(companyId, treePath); } /** * Returns the organizations with the primary keys. * * @param organizationIds the primary keys of the organizations * @return the organizations with the primary keys */ @Override public List getOrganizations(long[] organizationIds) throws PortalException { List organizations = new ArrayList<>( organizationIds.length); for (long organizationId : organizationIds) { Organization organization = getOrganization(organizationId); organizations.add(organization); } return organizations; } /** * Returns all the organizations and users belonging to the parent * organization. * * @param companyId the primary key of the organization and user's company * @param parentOrganizationId the primary key of the organization and * user's parent organization * @param status the user's workflow status * @param start the lower bound of the range of organizations and users to * return * @param end the upper bound of the range of organizations and users to * return (not inclusive) * @param obc the comparator to order the organizations and users * (optionally null) * @return the organizations and users belonging to the parent organization */ @Override public List getOrganizationsAndUsers( long companyId, long parentOrganizationId, int status, int start, int end, OrderByComparator obc) { QueryDefinition queryDefinition = new QueryDefinition<>( status, false, 0, false, start, end, (OrderByComparator)obc); return organizationFinder.findO_U_ByC_P( companyId, parentOrganizationId, queryDefinition); } /** * Returns the number of organizations and users belonging to the parent * organization. * * @param companyId the primary key of the organization and user's company * @param parentOrganizationId the primary key of the organization and * user's parent organization * @param status the user's workflow status * @return the number of organizations and users belonging to the parent * organization */ @Override public int getOrganizationsAndUsersCount( long companyId, long parentOrganizationId, int status) { QueryDefinition queryDefinition = new QueryDefinition<>( status, false, 0, false, QueryUtil.ALL_POS, QueryUtil.ALL_POS, null); return organizationFinder.countO_U_ByC_P( companyId, parentOrganizationId, queryDefinition); } /** * Returns the number of organizations belonging to the parent organization. * * @param companyId the primary key of the organization's company * @param parentOrganizationId the primary key of the organization's parent * organization * @return the number of organizations belonging to the parent organization */ @Override public int getOrganizationsCount( long companyId, long parentOrganizationId) { if (parentOrganizationId == OrganizationConstants.ANY_PARENT_ORGANIZATION_ID) { return organizationPersistence.countByCompanyId(companyId); } return organizationPersistence.countByC_P( companyId, parentOrganizationId); } @Override public int getOrganizationsCount( long companyId, long parentOrganizationId, String name) { if (Validator.isNull(name)) { return organizationPersistence.countByC_P( companyId, parentOrganizationId); } return organizationPersistence.countByC_P_LikeN( companyId, parentOrganizationId, name); } /** * Returns the parent organizations in order by closest ancestor. The list * starts with the organization itself. * * @param organizationId the primary key of the organization * @return the parent organizations in order by closest ancestor */ @Override public List getParentOrganizations(long organizationId) throws PortalException { if (organizationId == OrganizationConstants.DEFAULT_PARENT_ORGANIZATION_ID) { return new ArrayList<>(); } Organization organization = organizationPersistence.findByPrimaryKey( organizationId); return organization.getAncestors(); } /** * Returns the suborganizations of the organizations. * * @param organizations the organizations from which to get * suborganizations * @return the suborganizations of the organizations */ @Override public List getSuborganizations( List organizations) { List allSuborganizations = new ArrayList<>(); for (Organization organization : organizations) { List suborganizations = organizationPersistence.findByC_P( organization.getCompanyId(), organization.getOrganizationId()); addSuborganizations(allSuborganizations, suborganizations); } return allSuborganizations; } /** * Returns the suborganizations of the organization. * * @param companyId the primary key of the organization's company * @param organizationId the primary key of the organization * @return the suborganizations of the organization */ @Override public List getSuborganizations( long companyId, long organizationId) { return organizationPersistence.findByC_P(companyId, organizationId); } /** * Returns the count of suborganizations of the organization. * * @param companyId the primary key of the organization's company * @param organizationId the primary key of the organization * @return the count of suborganizations of the organization */ @Override public int getSuborganizationsCount(long companyId, long organizationId) { return organizationPersistence.countByC_P(companyId, organizationId); } /** * Returns the intersection of allOrganizations and * availableOrganizations. * * @param allOrganizations the organizations to check for availability * @param availableOrganizations the available organizations * @return the intersection of allOrganizations and * availableOrganizations */ @Override public List getSubsetOrganizations( List allOrganizations, List availableOrganizations) { List subsetOrganizations = new ArrayList<>(); for (Organization organization : allOrganizations) { if (availableOrganizations.contains(organization)) { subsetOrganizations.add(organization); } } return subsetOrganizations; } @Override public String[] getTypes() { return _organizationTypesSettings.getTypes(); } /** * Returns all the IDs of organizations with which the user is explicitly * associated, optionally including the IDs of organizations that the user * administers or owns. * *

* A user is considered to be explicitly associated with an * organization if his account is individually created within the * organization or if the user is later added to it. *

* * @param userId the primary key of the user * @param includeAdministrative whether to include the IDs of organizations * that the user administers or owns, even if he's not a member of * the organizations * @return the IDs of organizations with which the user is explicitly * associated, optionally including the IDs of organizations that * the user administers or owns */ @Override public long[] getUserOrganizationIds( long userId, boolean includeAdministrative) throws PortalException { if (!includeAdministrative) { return userPersistence.getOrganizationPrimaryKeys(userId); } Set organizationIds = SetUtil.fromArray( userPersistence.getOrganizationPrimaryKeys(userId)); List userGroupRoles = userGroupRoleLocalService.getUserGroupRoles(userId); for (UserGroupRole userGroupRole : userGroupRoles) { Role role = userGroupRole.getRole(); String roleName = role.getName(); if (roleName.equals(RoleConstants.ORGANIZATION_ADMINISTRATOR) || roleName.equals(RoleConstants.ORGANIZATION_OWNER)) { Group group = userGroupRole.getGroup(); organizationIds.add(group.getOrganizationId()); } } return ArrayUtil.toLongArray(organizationIds); } /** * Returns all the organizations with which the user is explicitly * associated, optionally including the organizations that the user * administers or owns. * *

* A user is considered to be explicitly associated with an * organization if his account is individually created within the * organization or if the user is later added as a member. *

* * @param userId the primary key of the user * @param includeAdministrative whether to include the IDs of organizations * that the user administers or owns, even if he's not a member of * the organizations * @return the organizations with which the user is explicitly associated, * optionally including the organizations that the user administers * or owns */ @Override public List getUserOrganizations( long userId, boolean includeAdministrative) throws PortalException { if (!includeAdministrative) { return getUserOrganizations(userId); } Set organizations = new HashSet<>( getUserOrganizations(userId)); List userGroupRoles = userGroupRoleLocalService.getUserGroupRoles(userId); for (UserGroupRole userGroupRole : userGroupRoles) { Role role = userGroupRole.getRole(); String roleName = role.getName(); if (roleName.equals(RoleConstants.ORGANIZATION_ADMINISTRATOR) || roleName.equals(RoleConstants.ORGANIZATION_OWNER)) { Group group = userGroupRole.getGroup(); Organization organization = organizationPersistence.findByPrimaryKey( group.getOrganizationId()); organizations.add(organization); } } return new ArrayList<>(organizations); } /** * Returns true if the password policy has been assigned to the * organization. * * @param passwordPolicyId the primary key of the password policy * @param organizationId the primary key of the organization * @return true if the password policy has been assigned to the * organization; false otherwise */ @Override public boolean hasPasswordPolicyOrganization( long passwordPolicyId, long organizationId) { return passwordPolicyRelLocalService.hasPasswordPolicyRel( passwordPolicyId, Organization.class.getName(), organizationId); } /** * Returns true if the user is a member of the organization, * optionally focusing on suborganizations or the specified organization. * This method is usually called to determine if the user has view access to * a resource belonging to the organization. * *
    *
  1. * If inheritSuborganizations=false: * the method checks whether the user belongs to the organization specified * by organizationId. The parameter * includeSpecifiedOrganization is ignored. *
  2. *
  3. * The parameter includeSpecifiedOrganization is * ignored unless inheritSuborganizations is also * true. *
  4. *
  5. * If inheritSuborganizations=true and * includeSpecifiedOrganization=false: the method * checks * whether the user belongs to one of the child organizations of the one * specified by organizationId. *
  6. *
  7. * If inheritSuborganizations=true and * includeSpecifiedOrganization=true: the method * checks whether * the user belongs to the organization specified by * organizationId or any of * its child organizations. *
  8. *
* * @param userId the primary key of the organization's user * @param organizationId the primary key of the organization * @param inheritSuborganizations if true suborganizations are * considered in the determination * @param includeSpecifiedOrganization if true the * organization specified by organizationId is * considered in the determination * @return true if the user has access to the organization; * false otherwise * @see com.liferay.portal.kernel.service.persistence.OrganizationFinder */ @Override public boolean hasUserOrganization( long userId, long organizationId, boolean inheritSuborganizations, boolean includeSpecifiedOrganization) throws PortalException { if (!inheritSuborganizations) { return userPersistence.containsOrganization(userId, organizationId); } List organizationsTree = new ArrayList<>(); Organization organization = organizationPersistence.findByPrimaryKey( organizationId); if (includeSpecifiedOrganization) { organizationsTree.add(organization); } else { organizationsTree.addAll(organization.getSuborganizations()); } if (!ListUtil.isEmpty(organizationsTree)) { LinkedHashMap params = new LinkedHashMap<>(); params.put("usersOrgsTree", organizationsTree); if (userFinder.countByUser(userId, params) > 0) { return true; } } return false; } @Override public boolean isCountryEnabled(String type) { return _organizationTypesSettings.isCountryEnabled(type); } @Override public boolean isCountryRequired(String type) { return _organizationTypesSettings.isCountryRequired(type); } @Override public boolean isRootable(String type) { return _organizationTypesSettings.isRootable(type); } /** * Rebuilds the organization's tree. * *

* Only call this method if the tree has become stale through operations * other than normal CRUD. Under normal circumstances the tree is * automatically rebuilt whenever necessary. *

* * @param companyId the primary key of the organization's company */ @Override public void rebuildTree(long companyId) throws PortalException { TreePathUtil.rebuildTree( companyId, OrganizationConstants.DEFAULT_PARENT_ORGANIZATION_ID, StringPool.SLASH, new TreeModelTasksAdapter() { @Override public List findTreeModels( long previousId, long companyId, long parentPrimaryKey, int size) { return organizationPersistence.findByO_C_P( previousId, companyId, parentPrimaryKey, QueryUtil.ALL_POS, size, new OrganizationIdComparator(true)); } }); } /** * Returns an ordered range of all the organizations that match the * keywords, using the indexer. It is preferable to use this method instead * of the non-indexed version whenever possible for performance reasons. * *

* Useful when paginating results. Returns a maximum of end - * start instances. start and end are not * primary keys, they are indexes in the result set. Thus, 0 * refers to the first result in the set. Setting both start * and end to {@link QueryUtil#ALL_POS} will return the full * result set. *

* * @param companyId the primary key of the organization's company * @param parentOrganizationId the primary key of the organization's parent * organization * @param keywords the keywords (space separated), which may occur in the * organization's name, street, city, zipcode, type, region or * country (optionally null) * @param params the finder parameters (optionally null). For * more information see {@link * com.liferay.portlet.usersadmin.util.OrganizationIndexer} * @param start the lower bound of the range of organizations to return * @param end the upper bound of the range of organizations to return (not * inclusive) * @param sort the field and direction by which to sort (optionally * null) * @return the matching organizations ordered by name * @see com.liferay.portlet.usersadmin.util.OrganizationIndexer */ @Override public Hits search( long companyId, long parentOrganizationId, String keywords, LinkedHashMap params, int start, int end, Sort sort) { String name = null; String type = null; String street = null; String city = null; String zip = null; String region = null; String country = null; boolean andOperator = false; if (Validator.isNotNull(keywords)) { name = keywords; type = keywords; street = keywords; city = keywords; zip = keywords; region = keywords; country = keywords; } else { andOperator = true; } if (params != null) { params.put("keywords", keywords); } return search( companyId, parentOrganizationId, name, type, street, city, zip, region, country, params, andOperator, start, end, sort); } /** * Returns a name ordered range of all the organizations that match the * keywords, type, region, and country, without using the indexer. It is * preferable to use the indexed version {@link #search(long, long, String, * LinkedHashMap, int, int, Sort)} instead of this method wherever possible * for performance reasons. * *

* Useful when paginating results. Returns a maximum of end - * start instances. start and end are not * primary keys, they are indexes in the result set. Thus, 0 * refers to the first result in the set. Setting both start * and end to {@link QueryUtil#ALL_POS} will return the full * result set. *

* * @param companyId the primary key of the organization's company * @param parentOrganizationId the primary key of the organization's parent * organization * @param keywords the keywords (space separated), which may occur in the * organization's name, street, city, or zipcode (optionally * null) * @param type the organization's type (optionally null) * @param regionId the primary key of the organization's region (optionally * null) * @param countryId the primary key of the organization's country * (optionally null) * @param params the finder params. For more information see {@link * com.liferay.portal.kernel.service.persistence.OrganizationFinder} * @param start the lower bound of the range of organizations to return * @param end the upper bound of the range of organizations to return (not * inclusive) * @return the matching organizations ordered by name * @see com.liferay.portal.kernel.service.persistence.OrganizationFinder */ @Override public List search( long companyId, long parentOrganizationId, String keywords, String type, Long regionId, Long countryId, LinkedHashMap params, int start, int end) { return search( companyId, parentOrganizationId, keywords, type, regionId, countryId, params, start, end, new OrganizationNameComparator(true)); } /** * Returns an ordered range of all the organizations that match the * keywords, type, region, and country, without using the indexer. It is * preferable to use the indexed version {@link #search(long, long, String, * String, String, String, String, String, String, LinkedHashMap, boolean, * int, int, Sort)} instead of this method wherever possible for performance * reasons. * *

* Useful when paginating results. Returns a maximum of end - * start instances. start and end are not * primary keys, they are indexes in the result set. Thus, 0 * refers to the first result in the set. Setting both start * and end to {@link QueryUtil#ALL_POS} will return the full * result set. *

* * @param companyId the primary key of the organization's company * @param parentOrganizationId the primary key of the organization's parent * organization * @param keywords the keywords (space separated), which may occur in the * organization's name, street, city, or zipcode (optionally * null) * @param type the organization's type (optionally null) * @param regionId the primary key of the organization's region (optionally * null) * @param countryId the primary key of the organization's country * (optionally null) * @param params the finder params. For more information see {@link * com.liferay.portal.kernel.service.persistence.OrganizationFinder} * @param start the lower bound of the range of organizations to return * @param end the upper bound of the range of organizations to return (not * inclusive) * @param obc the comparator to order the organizations (optionally * null) * @return the matching organizations ordered by comparator obc * @see com.liferay.portal.kernel.service.persistence.OrganizationFinder */ @Override public List search( long companyId, long parentOrganizationId, String keywords, String type, Long regionId, Long countryId, LinkedHashMap params, int start, int end, OrderByComparator obc) { String parentOrganizationIdComparator = StringPool.EQUAL; if (parentOrganizationId == OrganizationConstants.ANY_PARENT_ORGANIZATION_ID) { parentOrganizationIdComparator = StringPool.NOT_EQUAL; } return organizationFinder.findO_ByKeywords( companyId, parentOrganizationId, parentOrganizationIdComparator, keywords, type, regionId, countryId, params, start, end, obc); } /** * Returns a name ordered range of all the organizations with the type, * region, and country, and whose name, street, city, and zipcode match the * keywords specified for them, without using the indexer. It is preferable * to use the indexed version {@link #search(long, long, String, String, * String, String, String, String, String, LinkedHashMap, boolean, int, int, * Sort)} instead of this method wherever possible for performance reasons. * *

* Useful when paginating results. Returns a maximum of end - * start instances. start and end are not * primary keys, they are indexes in the result set. Thus, 0 * refers to the first result in the set. Setting both start * and end to {@link QueryUtil#ALL_POS} will return the full * result set. *

* * @param companyId the primary key of the organization's company * @param parentOrganizationId the primary key of the organization's parent * @param name the name keywords (space separated, optionally * null) * @param type the organization's type (optionally null) * @param street the street keywords (optionally null) * @param city the city keywords (optionally null) * @param zip the zipcode keywords (optionally null) * @param regionId the primary key of the organization's region (optionally * null) * @param countryId the primary key of the organization's country * (optionally null) * @param params the finder parameters (optionally null). For * more information see {@link * com.liferay.portal.kernel.service.persistence.OrganizationFinder} * @param andOperator whether every field must match its keywords, or just * one field. For example, "organizations with the name * 'Employees' and city 'Chicago'" vs "organizations with * the name 'Employees' or the city 'Chicago'". * @param start the lower bound of the range of organizations to return * @param end the upper bound of the range of organizations to return (not * inclusive) * @return the matching organizations ordered by name * @see com.liferay.portal.kernel.service.persistence.OrganizationFinder */ @Override public List search( long companyId, long parentOrganizationId, String name, String type, String street, String city, String zip, Long regionId, Long countryId, LinkedHashMap params, boolean andOperator, int start, int end) { return search( companyId, parentOrganizationId, name, type, street, city, zip, regionId, countryId, params, andOperator, start, end, new OrganizationNameComparator(true)); } /** * Returns an ordered range of all the organizations with the type, region, * and country, and whose name, street, city, and zipcode match the keywords * specified for them, without using the indexer. It is preferable to use * the indexed version {@link #search(long, long, String, String, String, * String, String, String, String, LinkedHashMap, boolean, int, int, Sort)} * instead of this method wherever possible for performance reasons. * *

* Useful when paginating results. Returns a maximum of end - * start instances. start and end are not * primary keys, they are indexes in the result set. Thus, 0 * refers to the first result in the set. Setting both start * and end to {@link QueryUtil#ALL_POS} will return the full * result set. *

* * @param companyId the primary key of the organization's company * @param parentOrganizationId the primary key of the organization's parent * organization * @param name the name keywords (space separated, optionally * null) * @param type the organization's type (optionally null) * @param street the street keywords (optionally null) * @param city the city keywords (optionally null) * @param zip the zipcode keywords (optionally null) * @param regionId the primary key of the organization's region (optionally * null) * @param countryId the primary key of the organization's country * (optionally null) * @param params the finder parameters (optionally null). For * more information see {@link * com.liferay.portal.kernel.service.persistence.OrganizationFinder} * @param andOperator whether every field must match its keywords, or just * one field. For example, "organizations with the name * 'Employees' and city 'Chicago'" vs "organizations with * the name 'Employees' or the city 'Chicago'". * @param start the lower bound of the range of organizations to return * @param end the upper bound of the range of organizations to return (not * inclusive) * @param obc the comparator to order the organizations (optionally * null) * @return the matching organizations ordered by comparator obc * @see com.liferay.portal.kernel.service.persistence.OrganizationFinder */ @Override public List search( long companyId, long parentOrganizationId, String name, String type, String street, String city, String zip, Long regionId, Long countryId, LinkedHashMap params, boolean andOperator, int start, int end, OrderByComparator obc) { String parentOrganizationIdComparator = StringPool.EQUAL; if (parentOrganizationId == OrganizationConstants.ANY_PARENT_ORGANIZATION_ID) { parentOrganizationIdComparator = StringPool.NOT_EQUAL; } return organizationFinder.findO_ByC_PO_N_T_S_C_Z_R_C( companyId, parentOrganizationId, parentOrganizationIdComparator, name, type, street, city, zip, regionId, countryId, params, andOperator, start, end, obc); } /** * Returns an ordered range of all the organizations whose name, type, or * location fields match the keywords specified for them, using the indexer. * It is preferable to use this method instead of the non-indexed version * whenever possible for performance reasons. * *

* Useful when paginating results. Returns a maximum of end - * start instances. start and end are not * primary keys, they are indexes in the result set. Thus, 0 * refers to the first result in the set. Setting both start * and end to {@link QueryUtil#ALL_POS} will return the full * result set. *

* * @param companyId the primary key of the organization's company * @param parentOrganizationId the primary key of the organization's parent * organization * @param name the name keywords (space separated, optionally * null) * @param type the type keywords (optionally null) * @param street the street keywords (optionally null) * @param city the city keywords (optionally null) * @param zip the zipcode keywords (optionally null) * @param region the region keywords (optionally null) * @param country the country keywords (optionally null) * @param params the finder parameters (optionally null). For * more information see {@link * com.liferay.portlet.usersadmin.util.OrganizationIndexer}. * @param andSearch whether every field must match its keywords or just one * field * @param start the lower bound of the range of organizations to return * @param end the upper bound of the range of organizations to return (not * inclusive) * @param sort the field and direction by which to sort (optionally * null) * @return the matching organizations ordered by sort * @see com.liferay.portlet.usersadmin.util.OrganizationIndexer */ @Override public Hits search( long companyId, long parentOrganizationId, String name, String type, String street, String city, String zip, String region, String country, LinkedHashMap params, boolean andSearch, int start, int end, Sort sort) { try { Indexer indexer = IndexerRegistryUtil.nullSafeGetIndexer(Organization.class); SearchContext searchContext = buildSearchContext( companyId, parentOrganizationId, name, type, street, city, zip, region, country, params, andSearch, start, end, sort); return indexer.search(searchContext); } catch (Exception e) { throw new SystemException(e); } } /** * Returns the number of organizations that match the keywords, type, * region, and country. * * @param companyId the primary key of the organization's company * @param parentOrganizationId the primary key of the organization's parent * organization * @param keywords the keywords (space separated), which may occur in the * organization's name, street, city, or zipcode (optionally * null) * @param type the organization's type (optionally null) * @param regionId the primary key of the organization's region (optionally * null) * @param countryId the primary key of the organization's country * (optionally null) * @param params the finder parameters (optionally null). For * more information see {@link * com.liferay.portal.kernel.service.persistence.OrganizationFinder} * @return the number of matching organizations * @see com.liferay.portal.kernel.service.persistence.OrganizationFinder */ @Override public int searchCount( long companyId, long parentOrganizationId, String keywords, String type, Long regionId, Long countryId, LinkedHashMap params) { Indexer indexer = IndexerRegistryUtil.nullSafeGetIndexer( Organization.class); if (!indexer.isIndexerEnabled() || !PropsValues.ORGANIZATIONS_SEARCH_WITH_INDEX || isUseCustomSQL(params)) { String parentOrganizationIdComparator = StringPool.EQUAL; if (parentOrganizationId == OrganizationConstants.ANY_PARENT_ORGANIZATION_ID) { parentOrganizationIdComparator = StringPool.NOT_EQUAL; } return organizationFinder.countO_ByKeywords( companyId, parentOrganizationId, parentOrganizationIdComparator, keywords, type, regionId, countryId, params); } try { String name = null; String street = null; String city = null; String zip = null; boolean andOperator = false; if (Validator.isNotNull(keywords)) { name = keywords; street = keywords; city = keywords; zip = keywords; } else { andOperator = true; } if (params != null) { params.put("keywords", keywords); } SearchContext searchContext = buildSearchContext( companyId, parentOrganizationId, name, type, street, city, zip, regionId, countryId, params, andOperator, QueryUtil.ALL_POS, QueryUtil.ALL_POS, null); return (int)indexer.searchCount(searchContext); } catch (Exception e) { throw new SystemException(e); } } /** * Returns the number of organizations with the type, region, and country, * and whose name, street, city, and zipcode match the keywords specified * for them. * * @param companyId the primary key of the organization's company * @param parentOrganizationId the primary key of the organization's parent * organization * @param name the name keywords (space separated, optionally * null) * @param type the organization's type (optionally null) * @param street the street keywords (optionally null) * @param city the city keywords (optionally null) * @param zip the zipcode keywords (optionally null) * @param regionId the primary key of the organization's region (optionally * null) * @param countryId the primary key of the organization's country * (optionally null) * @param params the finder parameters (optionally null). For * more information see {@link * com.liferay.portal.kernel.service.persistence.OrganizationFinder} * @param andOperator whether every field must match its keywords, or just * one field. For example, "organizations with the name * 'Employees' and city 'Chicago'" vs "organizations with * the name 'Employees' or the city 'Chicago'". * @return the number of matching organizations * @see com.liferay.portal.kernel.service.persistence.OrganizationFinder */ @Override public int searchCount( long companyId, long parentOrganizationId, String name, String type, String street, String city, String zip, Long regionId, Long countryId, LinkedHashMap params, boolean andOperator) { Indexer indexer = IndexerRegistryUtil.nullSafeGetIndexer( Organization.class); if (!indexer.isIndexerEnabled() || !PropsValues.ORGANIZATIONS_SEARCH_WITH_INDEX || isUseCustomSQL(params)) { String parentOrganizationIdComparator = StringPool.EQUAL; if (parentOrganizationId == OrganizationConstants.ANY_PARENT_ORGANIZATION_ID) { parentOrganizationIdComparator = StringPool.NOT_EQUAL; } return organizationFinder.countO_ByC_PO_N_T_S_C_Z_R_C( companyId, parentOrganizationId, parentOrganizationIdComparator, name, type, street, city, zip, regionId, countryId, params, andOperator); } try { SearchContext searchContext = buildSearchContext( companyId, parentOrganizationId, name, type, street, city, zip, regionId, countryId, params, andOperator, QueryUtil.ALL_POS, QueryUtil.ALL_POS, null); return (int)indexer.searchCount(searchContext); } catch (Exception e) { throw new SystemException(e); } } @Override public BaseModelSearchResult searchOrganizations( long companyId, long parentOrganizationId, String keywords, LinkedHashMap params, int start, int end, Sort sort) throws PortalException { String name = null; String type = null; String street = null; String city = null; String zip = null; String region = null; String country = null; boolean andOperator = false; if (Validator.isNotNull(keywords)) { name = keywords; type = keywords; street = keywords; city = keywords; zip = keywords; region = keywords; country = keywords; } else { andOperator = true; } if (params != null) { params.put("keywords", keywords); } return searchOrganizations( companyId, parentOrganizationId, name, type, street, city, zip, region, country, params, andOperator, start, end, sort); } @Override public BaseModelSearchResult searchOrganizations( long companyId, long parentOrganizationId, String name, String type, String street, String city, String zip, String region, String country, LinkedHashMap params, boolean andSearch, int start, int end, Sort sort) throws PortalException { Indexer indexer = IndexerRegistryUtil.nullSafeGetIndexer( Organization.class); SearchContext searchContext = buildSearchContext( companyId, parentOrganizationId, name, type, street, city, zip, region, country, params, andSearch, start, end, sort); for (int i = 0; i < 10; i++) { Hits hits = indexer.search(searchContext); List organizations = UsersAdminUtil.getOrganizations( hits); if (organizations != null) { return new BaseModelSearchResult<>( organizations, hits.getLength()); } } throw new SearchException( "Unable to fix the search index after 10 attempts"); } /** * Returns the organizations and users that match the keywords specified for * them and belong to the parent organization. * * @param companyId the primary key of the organization and user's company * @param parentOrganizationId the primary key of the organization and * user's parent organization * @param keywords the keywords (space separated), which may occur in the * organization's name, type, or location fields or user's first * name, middle name, last name, screen name, email address, or * address fields * @param status user's workflow status * @param params the finder parameters (optionally null). * @param start the lower bound of the range of organizations and users to * return * @param end the upper bound of the range of organizations and users to * return (not inclusive) * @return the matching organizations and users */ @Override public Hits searchOrganizationsAndUsers( long companyId, long parentOrganizationId, String keywords, int status, LinkedHashMap params, int start, int end, Sort[] sorts) throws PortalException { Indexer indexer = OrganizationUsersSearcher.getInstance(); SearchContext searchContext = buildSearchContext( companyId, parentOrganizationId, keywords, status, params, start, end, sorts); return indexer.search(searchContext); } /** * Returns the number of organizations and users that match the keywords * specified for them and belong to the parent organization. * * @param companyId the primary key of the organization and user's company * @param parentOrganizationId the primary key of the organization and * user's parent organization * @param keywords the keywords (space separated), which may occur in the * organization's name, type, or location fields or user's first * name, middle name, last name, screen name, email address, or * address fields * @param status user's workflow status * @param params the finder parameters (optionally null). * @return the number of matching organizations and users */ @Override public int searchOrganizationsAndUsersCount( long companyId, long parentOrganizationId, String keywords, int status, LinkedHashMap params) throws PortalException { Indexer indexer = OrganizationUsersSearcher.getInstance(); SearchContext searchContext = buildSearchContext( companyId, parentOrganizationId, keywords, status, params, QueryUtil.ALL_POS, QueryUtil.ALL_POS, null); Hits hits = indexer.search(searchContext); return hits.getLength(); } /** * Removes the organizations from the group. * * @param groupId the primary key of the group * @param organizationIds the primary keys of the organizations */ @Override public void unsetGroupOrganizations(long groupId, long[] organizationIds) { groupPersistence.removeOrganizations(groupId, organizationIds); try { reindexUsers(organizationIds); } catch (PortalException pe) { throw new SystemException(pe); } } /** * Removes the organizations from the password policy. * * @param passwordPolicyId the primary key of the password policy * @param organizationIds the primary keys of the organizations */ @Override public void unsetPasswordPolicyOrganizations( long passwordPolicyId, long[] organizationIds) { passwordPolicyRelLocalService.deletePasswordPolicyRels( passwordPolicyId, Organization.class.getName(), organizationIds); } /** * Updates the organization's asset with the new asset categories and tag * names, removing and adding asset categories and tag names as necessary. * * @param userId the primary key of the user * @param organization the organization * @param assetCategoryIds the primary keys of the asset categories * @param assetTagNames the asset tag names */ @Override public void updateAsset( long userId, Organization organization, long[] assetCategoryIds, String[] assetTagNames) throws PortalException { User user = userPersistence.findByPrimaryKey(userId); Company company = companyPersistence.findByPrimaryKey( user.getCompanyId()); Group companyGroup = company.getGroup(); assetEntryLocalService.updateEntry( userId, companyGroup.getGroupId(), null, null, Organization.class.getName(), organization.getOrganizationId(), organization.getUuid(), 0, assetCategoryIds, assetTagNames, true, false, null, null, null, null, null, organization.getName(), StringPool.BLANK, null, null, null, 0, 0, null); } /** * Updates the organization. * * @param companyId the primary key of the organization's company * @param organizationId the primary key of the organization * @param parentOrganizationId the primary key of organization's parent * organization * @param name the organization's name * @param type the organization's type * @param regionId the primary key of the organization's region * @param countryId the primary key of the organization's country * @param statusId the organization's workflow status * @param comments the comments about the organization * @param logo whether to update the ogranization's logo * @param logoBytes the new logo image data * @param site whether the organization is to be associated with a main * site * @param serviceContext the service context to be applied (optionally * null). Can set asset category IDs and asset tag * names for the organization, and merge expando bridge attributes * for the organization. * @return the organization */ @Override public Organization updateOrganization( long companyId, long organizationId, long parentOrganizationId, String name, String type, long regionId, long countryId, long statusId, String comments, boolean logo, byte[] logoBytes, boolean site, ServiceContext serviceContext) throws PortalException { // Organization parentOrganizationId = getParentOrganizationId( companyId, parentOrganizationId); validate( companyId, organizationId, parentOrganizationId, name, type, countryId, statusId); Organization organization = organizationPersistence.findByPrimaryKey( organizationId); long oldParentOrganizationId = organization.getParentOrganizationId(); String oldName = organization.getName(); organization.setParentOrganizationId(parentOrganizationId); organization.setTreePath(organization.buildTreePath()); organization.setName(name); organization.setType(type); organization.setRecursable(true); organization.setRegionId(regionId); organization.setCountryId(countryId); organization.setStatusId(statusId); organization.setComments(comments); PortalUtil.updateImageId( organization, logo, logoBytes, "logoId", _userFileUploadsSettings.getImageMaxSize(), _userFileUploadsSettings.getImageMaxHeight(), _userFileUploadsSettings.getImageMaxWidth()); organization.setExpandoBridgeAttributes(serviceContext); organizationPersistence.update(organization); // Group Group group = organization.getGroup(); long parentGroupId = group.getParentGroupId(); boolean createSite = false; if (!group.isSite() && site) { createSite = true; } boolean organizationGroup = isOrganizationGroup( oldParentOrganizationId, group.getParentGroupId()); if (createSite || organizationGroup) { if (parentOrganizationId != OrganizationConstants.DEFAULT_PARENT_ORGANIZATION_ID) { Organization parentOrganization = organizationPersistence.fetchByPrimaryKey( parentOrganizationId); Group parentGroup = parentOrganization.getGroup(); if (site && parentGroup.isSite()) { parentGroupId = parentOrganization.getGroupId(); } else { parentGroupId = GroupConstants.DEFAULT_PARENT_GROUP_ID; } } else { parentGroupId = GroupConstants.DEFAULT_PARENT_GROUP_ID; } } if (createSite || !oldName.equals(name) || organizationGroup) { groupLocalService.updateGroup( group.getGroupId(), parentGroupId, getLocalizationMap(name), group.getDescriptionMap(), group.getType(), group.isManualMembership(), group.getMembershipRestriction(), group.getFriendlyURL(), group.isInheritContent(), group.isActive(), null); } if (group.isSite() != site) { groupLocalService.updateSite(group.getGroupId(), site); reindexUsers(organizationId); } // Organizations if (createSite) { List childOrganizations = organizationLocalService.getOrganizations( companyId, organizationId); for (Organization childOrganization : childOrganizations) { Group childGroup = childOrganization.getGroup(); if (childGroup.isSite() && (childGroup.getParentGroupId() == GroupConstants.DEFAULT_PARENT_GROUP_ID)) { childGroup.setParentGroupId(group.getGroupId()); groupLocalService.updateGroup(childGroup); } } } // Asset if (serviceContext != null) { updateAsset( serviceContext.getUserId(), organization, serviceContext.getAssetCategoryIds(), serviceContext.getAssetTagNames()); } // Indexer Indexer indexer = IndexerRegistryUtil.nullSafeGetIndexer( Organization.class); if (!oldName.equals(name) || (oldParentOrganizationId != parentOrganizationId)) { long[] reindexOrganizationIds = getReindexOrganizationIds( organization); List reindexOrganizations = new ArrayList<>( reindexOrganizationIds.length); for (long reindexOrganizationId : reindexOrganizationIds) { Organization reindexOrganization = fetchOrganization( reindexOrganizationId); reindexOrganizations.add(reindexOrganization); } indexer.reindex(reindexOrganizations); } else { indexer.reindex(organization); } return organization; } /** * Updates the organization. * * @param companyId the primary key of the organization's company * @param organizationId the primary key of the organization * @param parentOrganizationId the primary key of organization's parent * organization * @param name the organization's name * @param type the organization's type * @param regionId the primary key of the organization's region * @param countryId the primary key of the organization's country * @param statusId the organization's workflow status * @param comments the comments about the organization * @param site whether the organization is to be associated with a main * site * @param serviceContext the service context to be applied (optionally * null). Can set asset category IDs and asset tag * names for the organization, and merge expando bridge * attributes for the organization. * @return the organization * @deprecated As of Wilberforce (7.0.x), replaced by {@link * #updateOrganization(long, long, long, String, String, long, * long, long, String, boolean, byte[], boolean, * ServiceContext)} */ @Deprecated @Override public Organization updateOrganization( long companyId, long organizationId, long parentOrganizationId, String name, String type, long regionId, long countryId, long statusId, String comments, boolean site, ServiceContext serviceContext) throws PortalException { return updateOrganization( companyId, organizationId, parentOrganizationId, name, type, regionId, countryId, statusId, comments, site, serviceContext); } protected void addSuborganizations( List allSuborganizations, List organizations) { for (Organization organization : organizations) { if (!allSuborganizations.contains(organization)) { allSuborganizations.add(organization); List suborganizations = organizationPersistence.findByC_P( organization.getCompanyId(), organization.getOrganizationId()); addSuborganizations(allSuborganizations, suborganizations); } } } protected SearchContext buildSearchContext( long companyId, long parentOrganizationId, String keywords, int status, LinkedHashMap params, int start, int end, Sort[] sorts) { String city = null; String country = null; String emailAddress = null; String firstName = null; String fullName = null; String lastName = null; String middleName = null; String name = null; String region = null; String screenName = null; String street = null; String type = null; String zip = null; boolean andOperator = false; if (Validator.isNotNull(keywords)) { city = keywords; country = keywords; emailAddress = keywords; firstName = keywords; fullName = keywords; lastName = keywords; middleName = keywords; name = keywords; region = keywords; screenName = keywords; street = keywords; type = keywords; zip = keywords; } else { andOperator = true; } if (params == null) { params = new LinkedHashMap<>(); } params.put("keywords", keywords); params.put("usersOrgs", parentOrganizationId); SearchContext searchContext = buildSearchContext( companyId, parentOrganizationId, name, type, street, city, zip, region, country, params, andOperator, start, end, null); Map attributes = searchContext.getAttributes(); attributes.put("emailAddress", emailAddress); attributes.put("firstName", firstName); attributes.put("fullName", fullName); attributes.put("lastName", lastName); attributes.put("middleName", middleName); attributes.put("screenName", screenName); attributes.put("status", status); searchContext.setAttributes(attributes); if (sorts != null) { searchContext.setSorts(sorts); } return searchContext; } protected SearchContext buildSearchContext( long companyId, long parentOrganizationId, String name, String type, String street, String city, String zip, Long regionId, Long countryId, LinkedHashMap params, boolean andSearch, int start, int end, Sort sort) { String regionCode = null; if (regionId != null) { Region region = regionPersistence.fetchByPrimaryKey(regionId); regionCode = region.getRegionCode(); } String countryName = null; if (countryId != null) { Country country = countryPersistence.fetchByPrimaryKey(countryId); countryName = country.getName(); } return buildSearchContext( companyId, parentOrganizationId, name, type, street, city, zip, regionCode, countryName, params, andSearch, start, end, sort); } protected SearchContext buildSearchContext( long companyId, long parentOrganizationId, String name, String type, String street, String city, String zip, String region, String country, LinkedHashMap params, boolean andSearch, int start, int end, Sort sort) { SearchContext searchContext = new SearchContext(); searchContext.setAndSearch(andSearch); Map attributes = new HashMap<>(); attributes.put("city", city); attributes.put("country", country); attributes.put("name", name); attributes.put("params", params); attributes.put( "parentOrganizationId", String.valueOf(parentOrganizationId)); attributes.put("region", region); attributes.put("street", street); attributes.put("type", type); attributes.put("zip", zip); searchContext.setAttributes(attributes); searchContext.setCompanyId(companyId); searchContext.setEnd(end); if (params != null) { String keywords = (String)params.remove("keywords"); if (Validator.isNotNull(keywords)) { searchContext.setKeywords(keywords); } } if (sort != null) { searchContext.setSorts(sort); } searchContext.setStart(start); QueryConfig queryConfig = searchContext.getQueryConfig(); queryConfig.setHighlightEnabled(false); queryConfig.setScoreEnabled(false); return searchContext; } protected long getParentOrganizationId( long companyId, long parentOrganizationId) { if (parentOrganizationId != OrganizationConstants.DEFAULT_PARENT_ORGANIZATION_ID) { // Ensure parent organization exists and belongs to the proper // company Organization parentOrganization = organizationPersistence.fetchByPrimaryKey(parentOrganizationId); if ((parentOrganization == null) || (companyId != parentOrganization.getCompanyId())) { parentOrganizationId = OrganizationConstants.DEFAULT_PARENT_ORGANIZATION_ID; } } return parentOrganizationId; } protected long[] getReindexOrganizationIds(Organization organization) throws PortalException { StringBundler sb = new StringBundler(3); sb.append(StringPool.FORWARD_SLASH); sb.append(organization.getOrganizationId()); sb.append(StringPool.FORWARD_SLASH); List organizations = organizationPersistence.findByC_T( organization.getCompanyId(), CustomSQLUtil.keywords(sb.toString())[0], QueryUtil.ALL_POS, QueryUtil.ALL_POS, new OrganizationNameComparator(true)); long[] organizationIds = new long[organizations.size()]; for (int i = 0; i < organizations.size(); i++) { Organization curOrganization = organizations.get(i); curOrganization.setTreePath(curOrganization.buildTreePath()); organizationPersistence.update(curOrganization); organizationIds[i] = curOrganization.getOrganizationId(); } if (!ArrayUtil.contains( organizationIds, organization.getOrganizationId())) { organizationIds = ArrayUtil.append( organizationIds, organization.getOrganizationId()); } return organizationIds; } protected boolean isOrganizationGroup(long organizationId, long groupId) { if ((organizationId == OrganizationConstants.DEFAULT_PARENT_ORGANIZATION_ID) && (groupId == GroupConstants.DEFAULT_PARENT_GROUP_ID)) { return true; } if (organizationId != OrganizationConstants.DEFAULT_PARENT_ORGANIZATION_ID) { Organization organization = organizationPersistence.fetchByPrimaryKey(organizationId); if (organization.getGroupId() == groupId) { return true; } } return false; } protected boolean isParentOrganization( long parentOrganizationId, long organizationId) throws PortalException { // Return true if parentOrganizationId is among the parent organizatons // of organizationId if (organizationId == OrganizationConstants.DEFAULT_PARENT_ORGANIZATION_ID) { return false; } Organization organization = organizationPersistence.findByPrimaryKey( organizationId); String treePath = organization.getTreePath(); if (treePath.contains( StringPool.SLASH + parentOrganizationId + StringPool.SLASH)) { return true; } return false; } protected boolean isUseCustomSQL(LinkedHashMap params) { if (MapUtil.isEmpty(params)) { return false; } return true; } protected void reindex(long companyId, long[] userIds) throws PortalException { final Indexer indexer = IndexerRegistryUtil.nullSafeGetIndexer( User.class); final IndexableActionableDynamicQuery indexableActionableDynamicQuery = userLocalService.getIndexableActionableDynamicQuery(); indexableActionableDynamicQuery.setAddCriteriaMethod( dynamicQuery -> { Property userId = PropertyFactoryUtil.forName("userId"); dynamicQuery.add(userId.in(userIds)); }); indexableActionableDynamicQuery.setCompanyId(companyId); indexableActionableDynamicQuery.setPerformActionMethod( (User user) -> { if (!user.isDefaultUser()) { try { Document document = indexer.getDocument(user); indexableActionableDynamicQuery.addDocuments(document); } catch (PortalException pe) { if (_log.isWarnEnabled()) { _log.warn( "Unable to index user " + user.getUserId(), pe); } } } }); indexableActionableDynamicQuery.setSearchEngineId( indexer.getSearchEngineId()); indexableActionableDynamicQuery.performActions(); } protected void reindexUsers(List organizations) throws PortalException { for (Organization organization : organizations) { reindexUsers(organization); } } protected void reindexUsers(long organizationId) throws PortalException { Organization organization = getOrganization(organizationId); reindexUsers(organization); } protected void reindexUsers(long[] organizationIds) throws PortalException { for (long organizationId : organizationIds) { reindexUsers(organizationId); } } protected void reindexUsers(Organization organization) throws PortalException { long companyId = organization.getCompanyId(); long[] userIds = getUserPrimaryKeys(organization.getOrganizationId()); if (ArrayUtil.isNotEmpty(userIds)) { TransactionCommitCallbackUtil.registerCallback( () -> { reindex(companyId, userIds); return null; }); } } protected void validate( long companyId, long organizationId, long parentOrganizationId, String name, String type, long countryId, long statusId) throws PortalException { if (!ArrayUtil.contains(getTypes(), type)) { throw new OrganizationTypeException( "Invalid organization type " + type); } if (parentOrganizationId == OrganizationConstants.DEFAULT_PARENT_ORGANIZATION_ID) { if (!isRootable(type)) { throw new OrganizationParentException.MustBeRootable(type); } } else { Organization parentOrganization = organizationPersistence.fetchByPrimaryKey(parentOrganizationId); if (parentOrganization == null) { throw new OrganizationParentException( "Organization " + parentOrganizationId + " does not exist"); } String[] childrenTypes = getChildrenTypes( parentOrganization.getType()); if (childrenTypes.length == 0) { throw new OrganizationParentException.MustNotHaveChildren(type); } if ((companyId != parentOrganization.getCompanyId()) || (parentOrganizationId == organizationId)) { throw new OrganizationParentException(); } if (!ArrayUtil.contains(childrenTypes, type)) { throw new OrganizationParentException.MustHaveValidChildType( type, parentOrganization.getType()); } } if ((organizationId > 0) && (parentOrganizationId != OrganizationConstants.DEFAULT_PARENT_ORGANIZATION_ID)) { // Prevent circular organizational references if (isParentOrganization(organizationId, parentOrganizationId)) { throw new OrganizationParentException(); } } if (Validator.isNull(name)) { throw new OrganizationNameException(); } Organization organization = organizationPersistence.fetchByC_N( companyId, name); if ((organization != null) && StringUtil.equalsIgnoreCase(organization.getName(), name)) { if ((organizationId <= 0) || (organization.getOrganizationId() != organizationId)) { throw new DuplicateOrganizationException( "There is another organization named " + name); } } boolean countryRequired = _organizationTypesSettings.isCountryRequired( type); if (countryRequired || (countryId > 0)) { countryPersistence.findByPrimaryKey(countryId); } listTypeLocalService.validate( statusId, ListTypeConstants.ORGANIZATION_STATUS); } protected void validate( long companyId, long parentOrganizationId, String name, String type, long countryId, long statusId) throws PortalException { validate( companyId, 0, parentOrganizationId, name, type, countryId, statusId); } private static final Log _log = LogFactoryUtil.getLog( OrganizationLocalServiceImpl.class); private static volatile OrganizationTypesSettings _organizationTypesSettings = ServiceProxyFactory.newServiceTrackedInstance( OrganizationTypesSettings.class, OrganizationLocalServiceImpl.class, "_organizationTypesSettings", false); private static volatile UserFileUploadsSettings _userFileUploadsSettings = ServiceProxyFactory.newServiceTrackedInstance( UserFileUploadsSettings.class, OrganizationLocalServiceImpl.class, "_userFileUploadsSettings", false); }