/** * 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.portal.kernel.configuration.Filter; 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.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.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.tree.TreeModelTasksAdapter; import com.liferay.portal.kernel.tree.TreePathUtil; import com.liferay.portal.kernel.util.ArrayUtil; import com.liferay.portal.kernel.util.GetterUtil; 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.PropsKeys; 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.StringPool; 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.model.impl.OrganizationImpl; import com.liferay.portal.service.base.OrganizationLocalServiceBaseImpl; import com.liferay.portal.util.PropsUtil; 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.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 */ public class OrganizationLocalServiceImpl extends OrganizationLocalServiceBaseImpl { /** * Adds an organization. * * <p> * 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)}. * </p> * * @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 { return addOrganization( userId, parentOrganizationId, name, PropsValues.ORGANIZATIONS_TYPES[0], 0, 0, ListTypeConstants.ORGANIZATION_STATUS_DEFAULT, StringPool.BLANK, site, null); } /** * Adds an organization. * * <p> * 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)}. * </p> * * @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 * <code>null</code>). 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<Organization> 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<String, Object> params = new LinkedHashMap<>(); params.put( "usersOrgs", Long.valueOf(organization.getOrganizationId())); if ((organizationPersistence.countByC_P( organization.getCompanyId(), organization.getOrganizationId()) > 0) || (userFinder.countByKeywords( organization.getCompanyId(), null, WorkflowConstants.STATUS_APPROVED, params) > 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 <code>null</code> if no * organization could be found */ @Override public Organization fetchOrganization(long companyId, String name) { return organizationPersistence.fetchByC_N(companyId, name); } @Override public List<Organization> 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<Long> organizationIds = SetUtil.intersect( groupOrganizationIds, userOrganizationIds); if (organizationIds.isEmpty()) { return Collections.emptyList(); } List<Organization> organizations = new ArrayList<>( organizationIds.size()); for (Long organizationId : organizationIds) { organizations.add( organizationPersistence.findByPrimaryKey(organizationId)); } return organizations; } @Override public List<Organization> 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 * <code>0</code> 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(); } else { return 0; } } @Override public List<Organization> getOrganizations( long userId, int start, int end, OrderByComparator<Organization> obc) throws PortalException { User user = userPersistence.findByPrimaryKey(userId); List<Organization> organizations = ListUtil.copy( userPersistence.getOrganizations(userId)); Iterator<Organization> 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<Organization> 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. * * <p> * Useful when paginating results. Returns a maximum of <code>end - * start</code> instances. <code>start</code> and <code>end</code> are not * primary keys, they are indexes in the result set. Thus, <code>0</code> * refers to the first result in the set. Setting both <code>start</code> * and <code>end</code> to {@link QueryUtil#ALL_POS} will return the full * result set. * </p> * * @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<Organization> getOrganizations( long companyId, long parentOrganizationId, int start, int end) { if (parentOrganizationId == OrganizationConstants.ANY_PARENT_ORGANIZATION_ID) { return organizationPersistence.findByCompanyId( companyId, start, end); } else { return organizationPersistence.findByC_P( companyId, parentOrganizationId, start, end); } } /** * 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<Organization> getOrganizations(long[] organizationIds) throws PortalException { List<Organization> 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 <code>null</code>) * @return the organizations and users belonging to the parent organization */ @Override public List<Object> getOrganizationsAndUsers( long companyId, long parentOrganizationId, int status, int start, int end, OrderByComparator<?> obc) { QueryDefinition<?> queryDefinition = new QueryDefinition<>( status, false, 0, false, start, end, (OrderByComparator<Object>)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); } else { return organizationPersistence.countByC_P( companyId, parentOrganizationId); } } /** * 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<Organization> 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<Organization> getSuborganizations( List<Organization> organizations) { List<Organization> allSuborganizations = new ArrayList<>(); for (int i = 0; i < organizations.size(); i++) { Organization organization = organizations.get(i); List<Organization> 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<Organization> 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 <code>allOrganizations</code> and * <code>availableOrganizations</code>. * * @param allOrganizations the organizations to check for availability * @param availableOrganizations the available organizations * @return the intersection of <code>allOrganizations</code> and * <code>availableOrganizations</code> */ @Override public List<Organization> getSubsetOrganizations( List<Organization> allOrganizations, List<Organization> availableOrganizations) { List<Organization> subsetOrganizations = new ArrayList<>(); for (Organization organization : allOrganizations) { if (availableOrganizations.contains(organization)) { subsetOrganizations.add(organization); } } return subsetOrganizations; } /** * 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. * * <p> * A user is considered to be <i>explicitly</i> associated with an * organization if his account is individually created within the * organization or if the user is later added to it. * </p> * * @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<Long> organizationIds = SetUtil.fromArray( userPersistence.getOrganizationPrimaryKeys(userId)); List<UserGroupRole> 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. * * <p> * A user is considered to be <i>explicitly</i> associated with an * organization if his account is individually created within the * organization or if the user is later added as a member. * </p> * * @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<Organization> getUserOrganizations( long userId, boolean includeAdministrative) throws PortalException { if (!includeAdministrative) { return getUserOrganizations(userId); } Set<Organization> organizations = new HashSet<>( getUserOrganizations(userId)); List<UserGroupRole> 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 <code>true</code> 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 <code>true</code> if the password policy has been assigned to the * organization; <code>false</code> otherwise */ @Override public boolean hasPasswordPolicyOrganization( long passwordPolicyId, long organizationId) { return passwordPolicyRelLocalService.hasPasswordPolicyRel( passwordPolicyId, Organization.class.getName(), organizationId); } /** * Returns <code>true</code> 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. * * <ol> * <li> * If <code>inheritSuborganizations=<code>false</code></code>: * the method checks whether the user belongs to the organization specified * by <code>organizationId</code>. The parameter * <code>includeSpecifiedOrganization</code> is ignored. * </li> * <li> * The parameter <code>includeSpecifiedOrganization</code> is * ignored unless <code>inheritSuborganizations</code> is also * <code>true</code>. * </li> * <li> * If <code>inheritSuborganizations=<code>true</code></code> and * <code>includeSpecifiedOrganization=<code>false</code></code>: the method * checks * whether the user belongs to one of the child organizations of the one * specified by <code>organizationId</code>. * </li> * <li> * If <code>inheritSuborganizations=<code>true</code></code> and * <code>includeSpecifiedOrganization=<code>true</code></code>: the method * checks whether * the user belongs to the organization specified by * <code>organizationId</code> or any of * its child organizations. * </li> * </ol> * * @param userId the primary key of the organization's user * @param organizationId the primary key of the organization * @param inheritSuborganizations if <code>true</code> suborganizations are * considered in the determination * @param includeSpecifiedOrganization if <code>true</code> the * organization specified by <code>organizationId</code> is * considered in the determination * @return <code>true</code> if the user has access to the organization; * <code>false</code> 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<Organization> organizationsTree = new ArrayList<>(); Organization organization = organizationPersistence.findByPrimaryKey( organizationId); if (includeSpecifiedOrganization) { organizationsTree.add(organization); } else { organizationsTree.addAll(organization.getSuborganizations()); } if (!ListUtil.isEmpty(organizationsTree)) { LinkedHashMap<String, Object> params = new LinkedHashMap<>(); params.put("usersOrgsTree", organizationsTree); if (userFinder.countByUser(userId, params) > 0) { return true; } } return false; } /** * Rebuilds the organization's tree. * * <p> * 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. * </p> * * @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<Organization>() { @Override public List<Organization> 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. * * <p> * Useful when paginating results. Returns a maximum of <code>end - * start</code> instances. <code>start</code> and <code>end</code> are not * primary keys, they are indexes in the result set. Thus, <code>0</code> * refers to the first result in the set. Setting both <code>start</code> * and <code>end</code> to {@link QueryUtil#ALL_POS} will return the full * result set. * </p> * * @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 <code>null</code>) * @param params the finder parameters (optionally <code>null</code>). 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 * <code>null</code>) * @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<String, Object> 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. * * <p> * Useful when paginating results. Returns a maximum of <code>end - * start</code> instances. <code>start</code> and <code>end</code> are not * primary keys, they are indexes in the result set. Thus, <code>0</code> * refers to the first result in the set. Setting both <code>start</code> * and <code>end</code> to {@link QueryUtil#ALL_POS} will return the full * result set. * </p> * * @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 * <code>null</code>) * @param type the organization's type (optionally <code>null</code>) * @param regionId the primary key of the organization's region (optionally * <code>null</code>) * @param countryId the primary key of the organization's country * (optionally <code>null</code>) * @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<Organization> search( long companyId, long parentOrganizationId, String keywords, String type, Long regionId, Long countryId, LinkedHashMap<String, Object> 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. * * <p> * Useful when paginating results. Returns a maximum of <code>end - * start</code> instances. <code>start</code> and <code>end</code> are not * primary keys, they are indexes in the result set. Thus, <code>0</code> * refers to the first result in the set. Setting both <code>start</code> * and <code>end</code> to {@link QueryUtil#ALL_POS} will return the full * result set. * </p> * * @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 * <code>null</code>) * @param type the organization's type (optionally <code>null</code>) * @param regionId the primary key of the organization's region (optionally * <code>null</code>) * @param countryId the primary key of the organization's country * (optionally <code>null</code>) * @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 * <code>null</code>) * @return the matching organizations ordered by comparator <code>obc</code> * @see com.liferay.portal.kernel.service.persistence.OrganizationFinder */ @Override public List<Organization> search( long companyId, long parentOrganizationId, String keywords, String type, Long regionId, Long countryId, LinkedHashMap<String, Object> params, int start, int end, OrderByComparator<Organization> 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. * * <p> * Useful when paginating results. Returns a maximum of <code>end - * start</code> instances. <code>start</code> and <code>end</code> are not * primary keys, they are indexes in the result set. Thus, <code>0</code> * refers to the first result in the set. Setting both <code>start</code> * and <code>end</code> to {@link QueryUtil#ALL_POS} will return the full * result set. * </p> * * @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 * <code>null</code>) * @param type the organization's type (optionally <code>null</code>) * @param street the street keywords (optionally <code>null</code>) * @param city the city keywords (optionally <code>null</code>) * @param zip the zipcode keywords (optionally <code>null</code>) * @param regionId the primary key of the organization's region (optionally * <code>null</code>) * @param countryId the primary key of the organization's country * (optionally <code>null</code>) * @param params the finder parameters (optionally <code>null</code>). 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<Organization> search( long companyId, long parentOrganizationId, String name, String type, String street, String city, String zip, Long regionId, Long countryId, LinkedHashMap<String, Object> 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. * * <p> * Useful when paginating results. Returns a maximum of <code>end - * start</code> instances. <code>start</code> and <code>end</code> are not * primary keys, they are indexes in the result set. Thus, <code>0</code> * refers to the first result in the set. Setting both <code>start</code> * and <code>end</code> to {@link QueryUtil#ALL_POS} will return the full * result set. * </p> * * @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 * <code>null</code>) * @param type the organization's type (optionally <code>null</code>) * @param street the street keywords (optionally <code>null</code>) * @param city the city keywords (optionally <code>null</code>) * @param zip the zipcode keywords (optionally <code>null</code>) * @param regionId the primary key of the organization's region (optionally * <code>null</code>) * @param countryId the primary key of the organization's country * (optionally <code>null</code>) * @param params the finder parameters (optionally <code>null</code>). 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 * <code>null</code>) * @return the matching organizations ordered by comparator <code>obc</code> * @see com.liferay.portal.kernel.service.persistence.OrganizationFinder */ @Override public List<Organization> search( long companyId, long parentOrganizationId, String name, String type, String street, String city, String zip, Long regionId, Long countryId, LinkedHashMap<String, Object> params, boolean andOperator, int start, int end, OrderByComparator<Organization> 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. * * <p> * Useful when paginating results. Returns a maximum of <code>end - * start</code> instances. <code>start</code> and <code>end</code> are not * primary keys, they are indexes in the result set. Thus, <code>0</code> * refers to the first result in the set. Setting both <code>start</code> * and <code>end</code> to {@link QueryUtil#ALL_POS} will return the full * result set. * </p> * * @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 * <code>null</code>) * @param type the type keywords (optionally <code>null</code>) * @param street the street keywords (optionally <code>null</code>) * @param city the city keywords (optionally <code>null</code>) * @param zip the zipcode keywords (optionally <code>null</code>) * @param region the region keywords (optionally <code>null</code>) * @param country the country keywords (optionally <code>null</code>) * @param params the finder parameters (optionally <code>null</code>). 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 * <code>null</code>) * @return the matching organizations ordered by <code>sort</code> * @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<String, Object> params, boolean andSearch, int start, int end, Sort sort) { try { Indexer<Organization> 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 * <code>null</code>) * @param type the organization's type (optionally <code>null</code>) * @param regionId the primary key of the organization's region (optionally * <code>null</code>) * @param countryId the primary key of the organization's country * (optionally <code>null</code>) * @param params the finder parameters (optionally <code>null</code>). 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<String, Object> 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 * <code>null</code>) * @param type the organization's type (optionally <code>null</code>) * @param street the street keywords (optionally <code>null</code>) * @param city the city keywords (optionally <code>null</code>) * @param zip the zipcode keywords (optionally <code>null</code>) * @param regionId the primary key of the organization's region (optionally * <code>null</code>) * @param countryId the primary key of the organization's country * (optionally <code>null</code>) * @param params the finder parameters (optionally <code>null</code>). 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<String, Object> 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<Organization> searchOrganizations( long companyId, long parentOrganizationId, String keywords, LinkedHashMap<String, Object> 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<Organization> searchOrganizations( long companyId, long parentOrganizationId, String name, String type, String street, String city, String zip, String region, String country, LinkedHashMap<String, Object> params, boolean andSearch, int start, int end, Sort sort) throws PortalException { Indexer<Organization> 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<Organization> 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 <code>null</code>). * @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<String, Object> 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 <code>null</code>). * @return the number of matching organizations and users */ @Override public int searchOrganizationsAndUsersCount( long companyId, long parentOrganizationId, String keywords, int status, LinkedHashMap<String, Object> 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); } /** * 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 * <code>null</code>). 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); } // Organizations if (createSite) { List<Organization> 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<Organization> indexer = IndexerRegistryUtil.nullSafeGetIndexer( Organization.class); if (oldParentOrganizationId != parentOrganizationId) { long[] reindexOrganizationIds = getReindexOrganizationIds( organization); List<Organization> 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 * <code>null</code>). 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 7.0.0, 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<Organization> allSuborganizations, List<Organization> organizations) { for (Organization organization : organizations) { if (!allSuborganizations.contains(organization)) { allSuborganizations.add(organization); List<Organization> suborganizations = organizationPersistence.findByC_P( organization.getCompanyId(), organization.getOrganizationId()); addSuborganizations(allSuborganizations, suborganizations); } } } protected SearchContext buildSearchContext( long companyId, long parentOrganizationId, String keywords, int status, LinkedHashMap<String, Object> 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<String, Serializable> 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<String, Object> 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<String, Object> params, boolean andSearch, int start, int end, Sort sort) { SearchContext searchContext = new SearchContext(); searchContext.setAndSearch(andSearch); Map<String, Serializable> 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<Organization> 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; } else { return false; } } protected boolean isUseCustomSQL(LinkedHashMap<String, Object> params) { if (MapUtil.isEmpty(params)) { return false; } return true; } protected void validate( long companyId, long organizationId, long parentOrganizationId, String name, String type, long countryId, long statusId) throws PortalException { if (!ArrayUtil.contains(PropsValues.ORGANIZATIONS_TYPES, type)) { throw new OrganizationTypeException( "Invalid organization type " + type); } if (parentOrganizationId == OrganizationConstants.DEFAULT_PARENT_ORGANIZATION_ID) { if (!OrganizationImpl.isRootable(type)) { throw new OrganizationParentException( "Organization of type " + type + " cannot be a root"); } } else { Organization parentOrganization = organizationPersistence.fetchByPrimaryKey(parentOrganizationId); if (parentOrganization == null) { throw new OrganizationParentException( "Organization " + parentOrganizationId + " doesn't exist"); } String[] childrenTypes = OrganizationImpl.getChildrenTypes( parentOrganization.getType()); if (childrenTypes.length == 0) { throw new OrganizationParentException( "Organization of type " + type + " cannot have children"); } if ((companyId != parentOrganization.getCompanyId()) || (parentOrganizationId == organizationId)) { throw new OrganizationParentException(); } if (!ArrayUtil.contains(childrenTypes, type)) { throw new OrganizationParentException( "Type " + type + " not allowed as child of " + 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(); } else { 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 = GetterUtil.getBoolean( PropsUtil.get( PropsKeys.ORGANIZATIONS_COUNTRY_REQUIRED, new Filter(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 volatile UserFileUploadsSettings _userFileUploadsSettings = ServiceProxyFactory.newServiceTrackedInstance( UserFileUploadsSettings.class, OrganizationLocalServiceImpl.class, "_userFileUploadsSettings", false); }