001    /**
002     * Copyright (c) 2000-2012 Liferay, Inc. All rights reserved.
003     *
004     * This library is free software; you can redistribute it and/or modify it under
005     * the terms of the GNU Lesser General Public License as published by the Free
006     * Software Foundation; either version 2.1 of the License, or (at your option)
007     * any later version.
008     *
009     * This library is distributed in the hope that it will be useful, but WITHOUT
010     * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
011     * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
012     * details.
013     */
014    
015    package com.liferay.portal.service.impl;
016    
017    import com.liferay.portal.DuplicateOrganizationException;
018    import com.liferay.portal.OrganizationNameException;
019    import com.liferay.portal.OrganizationParentException;
020    import com.liferay.portal.OrganizationTypeException;
021    import com.liferay.portal.RequiredOrganizationException;
022    import com.liferay.portal.kernel.cache.ThreadLocalCachable;
023    import com.liferay.portal.kernel.configuration.Filter;
024    import com.liferay.portal.kernel.dao.orm.QueryUtil;
025    import com.liferay.portal.kernel.exception.PortalException;
026    import com.liferay.portal.kernel.exception.SystemException;
027    import com.liferay.portal.kernel.search.Hits;
028    import com.liferay.portal.kernel.search.Indexer;
029    import com.liferay.portal.kernel.search.IndexerRegistryUtil;
030    import com.liferay.portal.kernel.search.QueryConfig;
031    import com.liferay.portal.kernel.search.SearchContext;
032    import com.liferay.portal.kernel.search.Sort;
033    import com.liferay.portal.kernel.util.ArrayUtil;
034    import com.liferay.portal.kernel.util.GetterUtil;
035    import com.liferay.portal.kernel.util.ListUtil;
036    import com.liferay.portal.kernel.util.OrderByComparator;
037    import com.liferay.portal.kernel.util.PropsKeys;
038    import com.liferay.portal.kernel.util.StringPool;
039    import com.liferay.portal.kernel.util.Validator;
040    import com.liferay.portal.kernel.workflow.WorkflowConstants;
041    import com.liferay.portal.model.Company;
042    import com.liferay.portal.model.Group;
043    import com.liferay.portal.model.GroupConstants;
044    import com.liferay.portal.model.LayoutSet;
045    import com.liferay.portal.model.ListTypeConstants;
046    import com.liferay.portal.model.Organization;
047    import com.liferay.portal.model.OrganizationConstants;
048    import com.liferay.portal.model.ResourceConstants;
049    import com.liferay.portal.model.Role;
050    import com.liferay.portal.model.RoleConstants;
051    import com.liferay.portal.model.User;
052    import com.liferay.portal.model.UserGroupRole;
053    import com.liferay.portal.model.impl.OrganizationImpl;
054    import com.liferay.portal.security.auth.MembershipPolicyUtil;
055    import com.liferay.portal.security.permission.PermissionCacheUtil;
056    import com.liferay.portal.service.ServiceContext;
057    import com.liferay.portal.service.base.OrganizationLocalServiceBaseImpl;
058    import com.liferay.portal.util.PropsUtil;
059    import com.liferay.portal.util.PropsValues;
060    import com.liferay.portal.util.comparator.OrganizationNameComparator;
061    
062    import java.io.Serializable;
063    
064    import java.util.ArrayList;
065    import java.util.Collections;
066    import java.util.HashMap;
067    import java.util.HashSet;
068    import java.util.Iterator;
069    import java.util.LinkedHashMap;
070    import java.util.List;
071    import java.util.Map;
072    import java.util.Set;
073    
074    /**
075     * The implementation of the organization local service.
076     *
077     * @author Brian Wing Shun Chan
078     * @author Jorge Ferrer
079     * @author Julio Camarero
080     * @author Hugo Huijser
081     * @author Juan Fernández
082     */
083    public class OrganizationLocalServiceImpl
084            extends OrganizationLocalServiceBaseImpl {
085    
086            /**
087             * Adds the organizations to the group.
088             *
089             * @param  groupId the primary key of the group
090             * @param  organizationIds the primary keys of the organizations
091             * @throws PortalException if a group or organization with the primary key
092             *         could not be found
093             * @throws SystemException if a system exception occurred
094             */
095            public void addGroupOrganizations(long groupId, long[] organizationIds)
096                    throws PortalException, SystemException {
097    
098                    groupPersistence.addOrganizations(groupId, organizationIds);
099    
100                    PermissionCacheUtil.clearCache();
101            }
102    
103            /**
104             * Adds an organization.
105             *
106             * <p>
107             * This method handles the creation and bookkeeping of the organization
108             * including its resources, metadata, and internal data structures. It is
109             * not necessary to make a subsequent call to {@link
110             * #addOrganizationResources(long, Organization)}.
111             * </p>
112             *
113             * @param  userId the primary key of the creator/owner of the organization
114             * @param  parentOrganizationId the primary key of the organization's parent
115             *         organization
116             * @param  name the organization's name
117             * @param  type the organization's type
118             * @param  recursable whether the permissions of the organization are to be
119             *         inherited by its suborganizations
120             * @param  regionId the primary key of the organization's region
121             * @param  countryId the primary key of the organization's country
122             * @param  statusId the organization's workflow status
123             * @param  comments the comments about the organization
124             * @param  site whether the organization is to be associated with a main
125             *         site
126             * @param  serviceContext the organization's service context (optionally
127             *         <code>null</code>). Can set asset category IDs, asset tag names,
128             *         and expando bridge attributes for the organization.
129             * @return the organization
130             * @throws PortalException if a creator or parent organization with the
131             *         primary key could not be found or if the organization's
132             *         information was invalid
133             * @throws SystemException if a system exception occurred
134             */
135            public Organization addOrganization(
136                            long userId, long parentOrganizationId, String name, String type,
137                            boolean recursable, long regionId, long countryId, int statusId,
138                            String comments, boolean site, ServiceContext serviceContext)
139                    throws PortalException, SystemException {
140    
141                    // Organization
142    
143                    User user = userPersistence.findByPrimaryKey(userId);
144                    parentOrganizationId = getParentOrganizationId(
145                            user.getCompanyId(), parentOrganizationId);
146                    recursable = true;
147    
148                    validate(
149                            user.getCompanyId(), parentOrganizationId, name, type, countryId,
150                            statusId);
151    
152                    long organizationId = counterLocalService.increment();
153    
154                    Organization organization = organizationPersistence.create(
155                            organizationId);
156    
157                    organization.setCompanyId(user.getCompanyId());
158                    organization.setParentOrganizationId(parentOrganizationId);
159    
160                    String treePath = organization.buildTreePath();
161    
162                    organization.setTreePath(treePath);
163    
164                    organization.setName(name);
165                    organization.setType(type);
166                    organization.setRecursable(recursable);
167                    organization.setRegionId(regionId);
168                    organization.setCountryId(countryId);
169                    organization.setStatusId(statusId);
170                    organization.setComments(comments);
171                    organization.setExpandoBridgeAttributes(serviceContext);
172    
173                    organizationPersistence.update(organization);
174    
175                    // Group
176    
177                    long parentGroupId = GroupConstants.DEFAULT_PARENT_GROUP_ID;
178    
179                    if (parentOrganizationId !=
180                                    OrganizationConstants.DEFAULT_PARENT_ORGANIZATION_ID) {
181    
182                            Organization parentOrganization =
183                                    organizationPersistence.fetchByPrimaryKey(parentOrganizationId);
184    
185                            if (parentOrganization != null) {
186                                    parentGroupId = parentOrganization.getGroupId();
187                            }
188                    }
189    
190                    Group group = groupLocalService.addGroup(
191                            userId, parentGroupId, Organization.class.getName(), organizationId,
192                            GroupConstants.DEFAULT_LIVE_GROUP_ID, name, null,
193                            GroupConstants.TYPE_SITE_PRIVATE, null, site, true, null);
194    
195                    // Role
196    
197                    Role role = roleLocalService.getRole(
198                            organization.getCompanyId(), RoleConstants.ORGANIZATION_OWNER);
199    
200                    userGroupRoleLocalService.addUserGroupRoles(
201                            userId, group.getGroupId(), new long[] {role.getRoleId()});
202    
203                    // Resources
204    
205                    addOrganizationResources(userId, organization);
206    
207                    // Asset
208    
209                    if (serviceContext != null) {
210                            updateAsset(
211                                    userId, organization, serviceContext.getAssetCategoryIds(),
212                                    serviceContext.getAssetTagNames());
213                    }
214    
215                    // Indexer
216    
217                    if ((serviceContext == null) || serviceContext.isIndexingEnabled()) {
218                            Indexer indexer = IndexerRegistryUtil.nullSafeGetIndexer(
219                                    Organization.class);
220    
221                            indexer.reindex(organization);
222                    }
223    
224                    return organization;
225            }
226    
227            /**
228             * Adds a resource for each type of permission available on the
229             * organization.
230             *
231             * @param  userId the primary key of the creator/owner of the organization
232             * @param  organization the organization
233             * @throws PortalException if a portal exception occurred
234             * @throws SystemException if a system exception occurred
235             */
236            public void addOrganizationResources(long userId, Organization organization)
237                    throws PortalException, SystemException {
238    
239                    String name = Organization.class.getName();
240    
241                    resourceLocalService.addResources(
242                            organization.getCompanyId(), 0, userId, name,
243                            organization.getOrganizationId(), false, false, false);
244            }
245    
246            /**
247             * Assigns the password policy to the organizations, removing any other
248             * currently assigned password policies.
249             *
250             * @param  passwordPolicyId the primary key of the password policy
251             * @param  organizationIds the primary keys of the organizations
252             * @throws SystemException if a system exception occurred
253             */
254            public void addPasswordPolicyOrganizations(
255                            long passwordPolicyId, long[] organizationIds)
256                    throws SystemException {
257    
258                    passwordPolicyRelLocalService.addPasswordPolicyRels(
259                            passwordPolicyId, Organization.class.getName(), organizationIds);
260            }
261    
262            public void checkMembershipPolicy(User user)
263                    throws PortalException, SystemException {
264    
265                    List<Organization> organizations =
266                            organizationLocalService.getUserOrganizations(user.getUserId());
267    
268                    for (Organization organization : organizations) {
269                            if (!MembershipPolicyUtil.isMembershipAllowed(organization, user)) {
270                                    userLocalService.unsetOrganizationUsers(
271                                            organization.getOrganizationId(),
272                                            new long[] {user.getUserId()});
273                            }
274                    }
275    
276                    Set<Organization> mandatoryOrganizations =
277                            MembershipPolicyUtil.getMandatoryOrganizations(user);
278    
279                    for (Organization organization : mandatoryOrganizations) {
280                            if (!hasUserOrganization(
281                                            user.getUserId(), organization.getOrganizationId())) {
282    
283                                    userLocalService.addOrganizationUsers(
284                                            organization.getOrganizationId(),
285                                            new long[] {user.getUserId()});
286                            }
287                    }
288            }
289    
290            /**
291             * Deletes the logo of the organization.
292             *
293             * @param  organizationId the primary key of the organization
294             * @throws PortalException if an organization or parent organization with
295             *         the primary key could not be found or if the organization's logo
296             *         could not be found
297             * @throws SystemException if a system exception occurred
298             */
299            public void deleteLogo(long organizationId)
300                    throws PortalException, SystemException {
301    
302                    Organization organization = getOrganization(organizationId);
303    
304                    Group group = organization.getGroup();
305    
306                    LayoutSet publicLayoutSet = layoutSetLocalService.getLayoutSet(
307                            group.getGroupId(), false);
308    
309                    if (publicLayoutSet.isLogo()) {
310                            long logoId = publicLayoutSet.getLogoId();
311    
312                            publicLayoutSet.setLogo(false);
313                            publicLayoutSet.setLogoId(0);
314    
315                            layoutSetPersistence.update(publicLayoutSet);
316    
317                            imageLocalService.deleteImage(logoId);
318                    }
319    
320                    LayoutSet privateLayoutSet = layoutSetLocalService.getLayoutSet(
321                            group.getGroupId(), true);
322    
323                    if (privateLayoutSet.isLogo()) {
324                            long logoId = privateLayoutSet.getLogoId();
325    
326                            privateLayoutSet.setLogo(false);
327                            privateLayoutSet.setLogoId(0);
328    
329                            layoutSetPersistence.update(privateLayoutSet);
330    
331                            if (imageLocalService.getImage(logoId) != null) {
332                                    imageLocalService.deleteImage(logoId);
333                            }
334                    }
335            }
336    
337            /**
338             * Deletes the organization. The organization's associated resources and
339             * assets are also deleted.
340             *
341             * @param  organizationId the primary key of the organization
342             * @return the deleted organization
343             * @throws PortalException if an organization with the primary key could not
344             *         be found, if the organization had a workflow in approved status,
345             *         or if the organization was a parent organization
346             * @throws SystemException if a system exception occurred
347             */
348            @Override
349            public Organization deleteOrganization(long organizationId)
350                    throws PortalException, SystemException {
351    
352                    Organization organization = organizationPersistence.findByPrimaryKey(
353                            organizationId);
354    
355                    return deleteOrganization(organization);
356            }
357    
358            /**
359             * Deletes the organization. The organization's associated resources and
360             * assets are also deleted.
361             *
362             * @param  organization the organization
363             * @return the deleted organization
364             * @throws PortalException if the organization had a workflow in approved
365             *         status or if the organization was a parent organization
366             * @throws SystemException if a system exception occurred
367             */
368            @Override
369            public Organization deleteOrganization(Organization organization)
370                    throws PortalException, SystemException {
371    
372                    if ((userLocalService.getOrganizationUsersCount(
373                                    organization.getOrganizationId(),
374                                    WorkflowConstants.STATUS_APPROVED) > 0) ||
375                            (organizationPersistence.countByC_P(
376                                    organization.getCompanyId(),
377                                    organization.getOrganizationId()) > 0)) {
378    
379                            throw new RequiredOrganizationException();
380                    }
381    
382                    // Asset
383    
384                    assetEntryLocalService.deleteEntry(
385                            Organization.class.getName(), organization.getOrganizationId());
386    
387                    // Addresses
388    
389                    addressLocalService.deleteAddresses(
390                            organization.getCompanyId(), Organization.class.getName(),
391                            organization.getOrganizationId());
392    
393                    // Email addresses
394    
395                    emailAddressLocalService.deleteEmailAddresses(
396                            organization.getCompanyId(), Organization.class.getName(),
397                            organization.getOrganizationId());
398    
399                    // Expando
400    
401                    expandoValueLocalService.deleteValues(
402                            Organization.class.getName(), organization.getOrganizationId());
403    
404                    // Password policy relation
405    
406                    passwordPolicyRelLocalService.deletePasswordPolicyRel(
407                            Organization.class.getName(), organization.getOrganizationId());
408    
409                    // Phone
410    
411                    phoneLocalService.deletePhones(
412                            organization.getCompanyId(), Organization.class.getName(),
413                            organization.getOrganizationId());
414    
415                    // Website
416    
417                    websiteLocalService.deleteWebsites(
418                            organization.getCompanyId(), Organization.class.getName(),
419                            organization.getOrganizationId());
420    
421                    // Group
422    
423                    Group group = organization.getGroup();
424    
425                    if (group.isSite()) {
426                            group.setSite(false);
427    
428                            groupPersistence.update(group);
429                    }
430    
431                    groupLocalService.deleteGroup(group);
432    
433                    // Resources
434    
435                    String name = Organization.class.getName();
436    
437                    resourceLocalService.deleteResource(
438                            organization.getCompanyId(), name,
439                            ResourceConstants.SCOPE_INDIVIDUAL,
440                            organization.getOrganizationId());
441    
442                    // Organization
443    
444                    organizationPersistence.remove(organization);
445    
446                    // Permission cache
447    
448                    PermissionCacheUtil.clearCache();
449    
450                    return organization;
451            }
452    
453            /**
454             * Returns all the organizations belonging to the group.
455             *
456             * @param  groupId the primary key of the group
457             * @return the organizations belonging to the group
458             * @throws SystemException if a system exception occurred
459             */
460            public List<Organization> getGroupOrganizations(long groupId)
461                    throws SystemException {
462    
463                    return groupPersistence.getOrganizations(groupId);
464            }
465    
466            /**
467             * Returns the organization with the name.
468             *
469             * @param  companyId the primary key of the organization's company
470             * @param  name the organization's name
471             * @return the organization with the name
472             * @throws PortalException if the organization with the name could not be
473             *         found
474             * @throws SystemException if a system exception occurred
475             */
476            public Organization getOrganization(long companyId, String name)
477                    throws PortalException, SystemException {
478    
479                    return organizationPersistence.findByC_N(companyId, name);
480            }
481    
482            /**
483             * Returns the primary key of the organization with the name.
484             *
485             * @param  companyId the primary key of the organization's company
486             * @param  name the organization's name
487             * @return the primary key of the organization with the name, or
488             *         <code>0</code> if the organization could not be found
489             * @throws SystemException if a system exception occurred
490             */
491            public long getOrganizationId(long companyId, String name)
492                    throws SystemException {
493    
494                    Organization organization = organizationPersistence.fetchByC_N(
495                            companyId, name);
496    
497                    if (organization != null) {
498                            return organization.getOrganizationId();
499                    }
500                    else {
501                            return 0;
502                    }
503            }
504    
505            public List<Organization> getOrganizations(
506                            long userId, int start, int end, OrderByComparator obc)
507                    throws PortalException, SystemException {
508    
509                    User user = userPersistence.findByPrimaryKey(userId);
510    
511                    List<Organization> organizations = ListUtil.copy(
512                            userPersistence.getOrganizations(userId));
513    
514                    Iterator<Organization> iterator = organizations.iterator();
515    
516                    while (iterator.hasNext()) {
517                            Organization organization = iterator.next();
518    
519                            if ((organization.getCompanyId() != user.getCompanyId()) ||
520                                    (organization.getParentOrganization() == null)) {
521    
522                                    iterator.remove();
523                            }
524                    }
525    
526                    if (organizations.isEmpty()) {
527                            return organizations;
528                    }
529    
530                    if (obc == null) {
531                            obc = new OrganizationNameComparator(true);
532                    }
533    
534                    Collections.sort(organizations, obc);
535    
536                    if ((start != QueryUtil.ALL_POS) || (end != QueryUtil.ALL_POS)) {
537                            organizations = ListUtil.subList(organizations, start, end);
538                    }
539    
540                    return organizations;
541            }
542    
543            /**
544             * Returns all the organizations belonging to the parent organization.
545             *
546             * @param  companyId the primary key of the organization's company
547             * @param  parentOrganizationId the primary key of the organization's parent
548             *         organization
549             * @return the organizations belonging to the parent organization
550             * @throws SystemException if a system exception occurred
551             */
552            public List<Organization> getOrganizations(
553                            long companyId, long parentOrganizationId)
554                    throws SystemException {
555    
556                    return getOrganizations(
557                            companyId, parentOrganizationId, QueryUtil.ALL_POS,
558                            QueryUtil.ALL_POS);
559            }
560    
561            /**
562             * Returns a range of all the organizations belonging to the parent
563             * organization.
564             *
565             * <p>
566             * Useful when paginating results. Returns a maximum of <code>end -
567             * start</code> instances. <code>start</code> and <code>end</code> are not
568             * primary keys, they are indexes in the result set. Thus, <code>0</code>
569             * refers to the first result in the set. Setting both <code>start</code>
570             * and <code>end</code> to {@link
571             * com.liferay.portal.kernel.dao.orm.QueryUtil#ALL_POS} will return the full
572             * result set.
573             * </p>
574             *
575             * @param  companyId the primary key of the organization's company
576             * @param  parentOrganizationId the primary key of the organization's parent
577             *         organization
578             * @param  start the lower bound of the range of organizations to return
579             * @param  end the upper bound of the range of organizations to return (not
580             *         inclusive)
581             * @return the range of organizations belonging to the parent organization
582             * @throws SystemException if a system exception occurred
583             * @see    com.liferay.portal.service.persistence.OrganizationPersistence#findByC_P(
584             *         long, long, int, int)
585             */
586            public List<Organization> getOrganizations(
587                            long companyId, long parentOrganizationId, int start, int end)
588                    throws SystemException {
589    
590                    if (parentOrganizationId ==
591                                    OrganizationConstants.ANY_PARENT_ORGANIZATION_ID) {
592    
593                            return organizationPersistence.findByCompanyId(
594                                    companyId, start, end);
595                    }
596                    else {
597                            return organizationPersistence.findByC_P(
598                                    companyId, parentOrganizationId, start, end);
599                    }
600            }
601    
602            /**
603             * Returns the organizations with the primary keys.
604             *
605             * @param  organizationIds the primary keys of the organizations
606             * @return the organizations with the primary keys
607             * @throws PortalException if any one of the organizations could not be
608             *         found
609             * @throws SystemException if a system exception occurred
610             */
611            public List<Organization> getOrganizations(long[] organizationIds)
612                    throws PortalException, SystemException {
613    
614                    List<Organization> organizations = new ArrayList<Organization>(
615                            organizationIds.length);
616    
617                    for (long organizationId : organizationIds) {
618                            Organization organization = getOrganization(organizationId);
619    
620                            organizations.add(organization);
621                    }
622    
623                    return organizations;
624            }
625    
626            /**
627             * Returns the number of organizations belonging to the parent organization.
628             *
629             * @param  companyId the primary key of the organization's company
630             * @param  parentOrganizationId the primary key of the organization's parent
631             *         organization
632             * @return the number of organizations belonging to the parent organization
633             * @throws SystemException if a system exception occurred
634             */
635            public int getOrganizationsCount(long companyId, long parentOrganizationId)
636                    throws SystemException {
637    
638                    if (parentOrganizationId ==
639                                    OrganizationConstants.ANY_PARENT_ORGANIZATION_ID) {
640    
641                            return organizationPersistence.countByCompanyId(companyId);
642                    }
643                    else {
644                            return organizationPersistence.countByC_P(
645                                    companyId, parentOrganizationId);
646                    }
647            }
648    
649            /**
650             * Returns the parent organizations in order by closest ancestor. The list
651             * starts with the organization itself.
652             *
653             * @param  organizationId the primary key of the organization
654             * @return the parent organizations in order by closest ancestor
655             * @throws PortalException if an organization with the primary key could not
656             *         be found
657             * @throws SystemException if a system exception occurred
658             */
659            public List<Organization> getParentOrganizations(long organizationId)
660                    throws PortalException, SystemException {
661    
662                    if (organizationId ==
663                                    OrganizationConstants.DEFAULT_PARENT_ORGANIZATION_ID) {
664    
665                            return new ArrayList<Organization>();
666                    }
667    
668                    Organization organization = organizationPersistence.findByPrimaryKey(
669                            organizationId);
670    
671                    return getParentOrganizations(organization, true);
672            }
673    
674            /**
675             * Returns the suborganizations of the organizations.
676             *
677             * @param  organizations the organizations from which to get
678             *         suborganizations
679             * @return the suborganizations of the organizations
680             * @throws SystemException if a system exception occurred
681             */
682            public List<Organization> getSuborganizations(
683                            List<Organization> organizations)
684                    throws SystemException {
685    
686                    List<Organization> allSuborganizations = new ArrayList<Organization>();
687    
688                    for (int i = 0; i < organizations.size(); i++) {
689                            Organization organization = organizations.get(i);
690    
691                            List<Organization> suborganizations =
692                                    organizationPersistence.findByC_P(
693                                            organization.getCompanyId(),
694                                            organization.getOrganizationId());
695    
696                            addSuborganizations(allSuborganizations, suborganizations);
697                    }
698    
699                    return allSuborganizations;
700            }
701    
702            /**
703             * Returns the suborganizations of the organization.
704             *
705             * @param  companyId the primary key of the organization's company
706             * @param  organizationId the primary key of the organization
707             * @return the suborganizations of the organization
708             * @throws SystemException if a system exception occurred
709             */
710            public List<Organization> getSuborganizations(
711                            long companyId, long organizationId)
712                    throws SystemException {
713    
714                    return organizationPersistence.findByC_P(companyId, organizationId);
715            }
716    
717            /**
718             * Returns the count of suborganizations of the organization.
719             *
720             * @param  companyId the primary key of the organization's company
721             * @param  organizationId the primary key of the organization
722             * @return the count of suborganizations of the organization
723             * @throws SystemException if a system exception occurred
724             */
725            public int getSuborganizationsCount(long companyId, long organizationId)
726                    throws SystemException {
727    
728                    return organizationPersistence.countByC_P(companyId, organizationId);
729            }
730    
731            /**
732             * Returns the intersection of <code>allOrganizations</code> and
733             * <code>availableOrganizations</code>.
734             *
735             * @param  allOrganizations the organizations to check for availability
736             * @param  availableOrganizations the available organizations
737             * @return the intersection of <code>allOrganizations</code> and
738             *         <code>availableOrganizations</code>
739             */
740            public List<Organization> getSubsetOrganizations(
741                    List<Organization> allOrganizations,
742                    List<Organization> availableOrganizations) {
743    
744                    List<Organization> subsetOrganizations = new ArrayList<Organization>();
745    
746                    for (Organization organization : allOrganizations) {
747                            if (availableOrganizations.contains(organization)) {
748                                    subsetOrganizations.add(organization);
749                            }
750                    }
751    
752                    return subsetOrganizations;
753            }
754    
755            /**
756             * Returns all the organizations associated with the user.
757             *
758             * @param  userId the primary key of the user
759             * @return the organizations associated with the user
760             * @throws PortalException if a user with the primary key could not be found
761             * @throws SystemException if a system exception occurred
762             */
763            public List<Organization> getUserOrganizations(long userId)
764                    throws PortalException, SystemException {
765    
766                    return getUserOrganizations(
767                            userId, QueryUtil.ALL_POS, QueryUtil.ALL_POS);
768            }
769    
770            /**
771             * Returns all the organizations associated with the user. If
772             * includeAdministrative is <code>true</code>, the result includes those
773             * organizations that are not directly associated to the user but he is an
774             * administrator or an owner of the organization.
775             *
776             * @param  userId the primary key of the user
777             * @param  includeAdministrative whether to includes organizations that are
778             *         indirectly associated to the user because he is an administrator
779             *         or an owner of the organization
780             * @return the organizations associated with the user
781             * @throws PortalException if a user with the primary key could not be found
782             * @throws SystemException if a system exception occurred
783             */
784            public List<Organization> getUserOrganizations(
785                            long userId, boolean includeAdministrative)
786                    throws PortalException, SystemException {
787    
788                    if (!includeAdministrative) {
789                            return getUserOrganizations(userId);
790                    }
791    
792                    Set<Organization> organizations = new HashSet<Organization>();
793    
794                    List<UserGroupRole> userGroupRoles =
795                            userGroupRoleLocalService.getUserGroupRoles(userId);
796    
797                    for (UserGroupRole userGroupRole : userGroupRoles) {
798                            Role role = userGroupRole.getRole();
799    
800                            String roleName = role.getName();
801    
802                            if (roleName.equals(RoleConstants.ORGANIZATION_ADMINISTRATOR) ||
803                                    roleName.equals(RoleConstants.ORGANIZATION_OWNER)) {
804    
805                                    Group group = userGroupRole.getGroup();
806    
807                                    Organization organization =
808                                            organizationPersistence.findByPrimaryKey(
809                                                    group.getOrganizationId());
810    
811                                    organizations.add(organization);
812                            }
813                    }
814    
815                    organizations.addAll(getUserOrganizations(userId));
816    
817                    return new ArrayList<Organization>(organizations);
818            }
819    
820            /**
821             * Returns a range of all the organizations associated with the user.
822             *
823             * <p>
824             * Useful when paginating results. Returns a maximum of <code>end -
825             * start</code> instances. <code>start</code> and <code>end</code> are not
826             * primary keys, they are indexes in the result set. Thus, <code>0</code>
827             * refers to the first result in the set. Setting both <code>start</code>
828             * and <code>end</code> to {@link
829             * com.liferay.portal.kernel.dao.orm.QueryUtil#ALL_POS} will return the full
830             * result set.
831             * </p>
832             *
833             * @param  userId the primary key of the user
834             * @param  start the lower bound of the range of organizations to return
835             * @param  end the upper bound of the range of organizations to return (not
836             *         inclusive)
837             * @return the range organizations associated with the user
838             * @throws PortalException if a user with the primary key could not be found
839             * @throws SystemException if a system exception occurred
840             */
841            public List<Organization> getUserOrganizations(
842                            long userId, int start, int end)
843                    throws PortalException, SystemException {
844    
845                    return userPersistence.getOrganizations(userId, start, end);
846            }
847    
848            /**
849             * Returns the number of organizations associated with the user.
850             *
851             * @param  userId the primary key of the user
852             * @return the number of organizations associated with the user
853             * @throws SystemException if a system exception occurred
854             */
855            @ThreadLocalCachable
856            public int getUserOrganizationsCount(long userId) throws SystemException {
857                    return userPersistence.getOrganizationsSize(userId);
858            }
859    
860            /**
861             * Returns <code>true</code> if the organization belongs to the group.
862             *
863             * @param  groupId the primary key of the group
864             * @param  organizationId the primary key of the organization
865             * @return <code>true</code> if the organization belongs to the group;
866             *         <code>false</code> otherwise
867             * @throws SystemException if a system exception occurred
868             */
869            public boolean hasGroupOrganization(long groupId, long organizationId)
870                    throws SystemException {
871    
872                    return groupPersistence.containsOrganization(groupId, organizationId);
873            }
874    
875            /**
876             * Returns <code>true</code> if the password policy has been assigned to the
877             * organization.
878             *
879             * @param  passwordPolicyId the primary key of the password policy
880             * @param  organizationId the primary key of the organization
881             * @return <code>true</code> if the password policy has been assigned to the
882             *         organization; <code>false</code> otherwise
883             * @throws SystemException if a system exception occurred
884             */
885            public boolean hasPasswordPolicyOrganization(
886                            long passwordPolicyId, long organizationId)
887                    throws SystemException {
888    
889                    return passwordPolicyRelLocalService.hasPasswordPolicyRel(
890                            passwordPolicyId, Organization.class.getName(), organizationId);
891            }
892    
893            /**
894             * Returns <code>true</code> if the user is a member of the organization.
895             * This method is usually called to determine if the user has view access to
896             * a resource belonging to the organization.
897             *
898             * @param  userId the primary key of the user
899             * @param  organizationId the primary key of the organization
900             * @return <code>true</code> if the user has access to the organization;
901             *         <code>false</code> otherwise
902             * @throws SystemException if a system exception occurred
903             */
904            public boolean hasUserOrganization(long userId, long organizationId)
905                    throws SystemException {
906    
907                    return userPersistence.containsOrganization(userId, organizationId);
908            }
909    
910            /**
911             * Returns <code>true</code> if the user is a member of the organization,
912             * optionally focusing on suborganizations or the specified organization.
913             * This method is usually called to determine if the user has view access to
914             * a resource belonging to the organization.
915             *
916             * <ol>
917             * <li>
918             * If <code>inheritSuborganizations=<code>false</code></code>:
919             * the method checks whether the user belongs to the organization specified
920             * by <code>organizationId</code>. The parameter
921             * <code>includeSpecifiedOrganization</code> is ignored.
922             * </li>
923             * <li>
924             * The parameter <code>includeSpecifiedOrganization</code> is
925             * ignored unless <code>inheritSuborganizations</code> is also
926             * <code>true</code>.
927             * </li>
928             * <li>
929             * If <code>inheritSuborganizations=<code>true</code></code> and
930             * <code>includeSpecifiedOrganization=<code>false</code></code>: the method
931             * checks
932             * whether the user belongs to one of the child organizations of the one
933             * specified by <code>organizationId</code>.
934             * </li>
935             * <li>
936             * If <code>inheritSuborganizations=<code>true</code></code> and
937             * <code>includeSpecifiedOrganization=<code>true</code></code>: the method
938             * checks whether
939             * the user belongs to the organization specified by
940             * <code>organizationId</code> or any of
941             * its child organizations.
942             * </li>
943             * </ol>
944             *
945             * @param  userId the primary key of the organization's user
946             * @param  organizationId the primary key of the organization
947             * @param  inheritSuborganizations if <code>true</code> suborganizations are
948             *         considered in the determination
949             * @param  includeSpecifiedOrganization if <code>true</code> the
950             *         organization specified by <code>organizationId</code> is
951             *         considered in the determination
952             * @return <code>true</code> if the user has access to the organization;
953             *         <code>false</code> otherwise
954             * @throws PortalException if an organization with the primary key could not
955             *         be found
956             * @throws SystemException if a system exception occurred
957             * @see    com.liferay.portal.service.persistence.OrganizationFinder
958             */
959            public boolean hasUserOrganization(
960                            long userId, long organizationId, boolean inheritSuborganizations,
961                            boolean includeSpecifiedOrganization)
962                    throws PortalException, SystemException {
963    
964                    if (!inheritSuborganizations) {
965                            return userPersistence.containsOrganization(userId, organizationId);
966                    }
967    
968                    LinkedHashMap<String, Object> params =
969                            new LinkedHashMap<String, Object>();
970    
971                    List<Organization> organizationsTree = new ArrayList<Organization>();
972    
973                    Organization organization = organizationPersistence.findByPrimaryKey(
974                            organizationId);
975    
976                    if (!includeSpecifiedOrganization) {
977                            organizationsTree.add(organization);
978                    }
979                    else {
980                            organizationsTree.add(organization.getParentOrganization());
981                    }
982    
983                    params.put("usersOrgsTree", organizationsTree);
984    
985                    if (userFinder.countByUser(userId, params) > 0) {
986                            return true;
987                    }
988    
989                    return false;
990            }
991    
992            /**
993             * Rebuilds the organizations tree.
994             *
995             * <p>
996             * Only call this method if the tree has become stale through operations
997             * other than normal CRUD. Under normal circumstances the tree is
998             * automatically rebuilt whenever necessary.
999             * </p>
1000             *
1001             * @param  companyId the primary key of the organization's company
1002             * @throws PortalException if an organization with the primary key could not
1003             *         be found
1004             * @throws SystemException if a system exception occurred
1005             */
1006            public void rebuildTree(long companyId)
1007                    throws PortalException, SystemException {
1008    
1009                    List<Organization> organizations =
1010                            organizationPersistence.findByCompanyId(companyId);
1011    
1012                    for (Organization organization : organizations) {
1013                            String treePath = organization.buildTreePath();
1014    
1015                            organization.setTreePath(treePath);
1016    
1017                            organizationPersistence.update(organization);
1018                    }
1019            }
1020    
1021            /**
1022             * Returns a range of all the organizations of the company.
1023             *
1024             * <p>
1025             * Useful when paginating results. Returns a maximum of <code>end -
1026             * start</code> instances. <code>start</code> and <code>end</code> are not
1027             * primary keys, they are indexes in the result set. Thus, <code>0</code>
1028             * refers to the first result in the set. Setting both <code>start</code>
1029             * and <code>end</code> to {@link
1030             * com.liferay.portal.kernel.dao.orm.QueryUtil#ALL_POS} will return the full
1031             * result set.
1032             * </p>
1033             *
1034             * @param  companyId the primary key of the company
1035             * @param  params the finder parameters (optionally <code>null</code>). For
1036             *         more information see {@link
1037             *         com.liferay.portlet.usersadmin.util.OrganizationIndexer}
1038             * @param  start the lower bound of the range of organizations to return
1039             * @param  end the upper bound of the range of organizations to return (not
1040             *         inclusive)
1041             * @return the range of all the organizations of the company
1042             * @throws SystemException if a system exception occurred
1043             */
1044            public List<Organization> search(
1045                            long companyId, LinkedHashMap<String, Object> params, int start,
1046                            int end)
1047                    throws SystemException {
1048    
1049                    return organizationFinder.findByCompanyId(
1050                            companyId, params, start, end,
1051                            new OrganizationNameComparator(true));
1052            }
1053    
1054            /**
1055             * Returns an ordered range of all the organizations that match the
1056             * keywords, using the indexer. It is preferable to use this method instead
1057             * of the non-indexed version whenever possible for performance reasons.
1058             *
1059             * <p>
1060             * Useful when paginating results. Returns a maximum of <code>end -
1061             * start</code> instances. <code>start</code> and <code>end</code> are not
1062             * primary keys, they are indexes in the result set. Thus, <code>0</code>
1063             * refers to the first result in the set. Setting both <code>start</code>
1064             * and <code>end</code> to {@link
1065             * com.liferay.portal.kernel.dao.orm.QueryUtil#ALL_POS} will return the full
1066             * result set.
1067             * </p>
1068             *
1069             * @param  companyId the primary key of the organization's company
1070             * @param  parentOrganizationId the primary key of the organization's parent
1071             *         organization
1072             * @param  keywords the keywords (space separated), which may occur in the
1073             *         organization's name, street, city, zipcode, type, region or
1074             *         country (optionally <code>null</code>)
1075             * @param  params the finder parameters (optionally <code>null</code>). For
1076             *         more information see {@link
1077             *         com.liferay.portlet.usersadmin.util.OrganizationIndexer}
1078             * @param  start the lower bound of the range of organizations to return
1079             * @param  end the upper bound of the range of organizations to return (not
1080             *         inclusive)
1081             * @param  sort the field and direction by which to sort (optionally
1082             *         <code>null</code>)
1083             * @return the matching organizations ordered by name
1084             * @throws SystemException if a system exception occurred
1085             * @see    com.liferay.portlet.usersadmin.util.OrganizationIndexer
1086             */
1087            public Hits search(
1088                            long companyId, long parentOrganizationId, String keywords,
1089                            LinkedHashMap<String, Object> params, int start, int end, Sort sort)
1090                    throws SystemException {
1091    
1092                    String name = null;
1093                    String type = null;
1094                    String street = null;
1095                    String city = null;
1096                    String zip = null;
1097                    String region = null;
1098                    String country = null;
1099                    boolean andOperator = false;
1100    
1101                    if (Validator.isNotNull(keywords)) {
1102                            name = keywords;
1103                            type = keywords;
1104                            street = keywords;
1105                            city = keywords;
1106                            zip = keywords;
1107                            region = keywords;
1108                            country = keywords;
1109                    }
1110                    else {
1111                            andOperator = true;
1112                    }
1113    
1114                    if (params != null) {
1115                            params.put("keywords", keywords);
1116                    }
1117    
1118                    return search(
1119                            companyId, parentOrganizationId, name, type, street, city, zip,
1120                            region, country, params, andOperator, start, end, sort);
1121            }
1122    
1123            /**
1124             * Returns a name ordered range of all the organizations that match the
1125             * keywords, type, region, and country, without using the indexer. It is
1126             * preferable to use the indexed version {@link #search(long, long, String,
1127             * LinkedHashMap, int, int, Sort)} instead of this method wherever possible
1128             * for performance reasons.
1129             *
1130             * <p>
1131             * Useful when paginating results. Returns a maximum of <code>end -
1132             * start</code> instances. <code>start</code> and <code>end</code> are not
1133             * primary keys, they are indexes in the result set. Thus, <code>0</code>
1134             * refers to the first result in the set. Setting both <code>start</code>
1135             * and <code>end</code> to {@link
1136             * com.liferay.portal.kernel.dao.orm.QueryUtil#ALL_POS} will return the full
1137             * result set.
1138             * </p>
1139             *
1140             * @param  companyId the primary key of the organization's company
1141             * @param  parentOrganizationId the primary key of the organization's parent
1142             *         organization
1143             * @param  keywords the keywords (space separated), which may occur in the
1144             *         organization's name, street, city, or zipcode (optionally
1145             *         <code>null</code>)
1146             * @param  type the organization's type (optionally <code>null</code>)
1147             * @param  regionId the primary key of the organization's region (optionally
1148             *         <code>null</code>)
1149             * @param  countryId the primary key of the organization's country
1150             *         (optionally <code>null</code>)
1151             * @param  params the finder params. For more information see {@link
1152             *         com.liferay.portal.service.persistence.OrganizationFinder}
1153             * @param  start the lower bound of the range of organizations to return
1154             * @param  end the upper bound of the range of organizations to return (not
1155             *         inclusive)
1156             * @return the matching organizations ordered by name
1157             * @throws SystemException if a system exception occurred
1158             * @see    com.liferay.portal.service.persistence.OrganizationFinder
1159             */
1160            public List<Organization> search(
1161                            long companyId, long parentOrganizationId, String keywords,
1162                            String type, Long regionId, Long countryId,
1163                            LinkedHashMap<String, Object> params, int start, int end)
1164                    throws SystemException {
1165    
1166                    return search(
1167                            companyId, parentOrganizationId, keywords, type, regionId,
1168                            countryId, params, start, end,
1169                            new OrganizationNameComparator(true));
1170            }
1171    
1172            /**
1173             * Returns an ordered range of all the organizations that match the
1174             * keywords, type, region, and country, without using the indexer. It is
1175             * preferable to use the indexed version {@link #search(long, long, String,
1176             * String, String, String, String, String, String, LinkedHashMap, boolean,
1177             * int, int, Sort)} instead of this method wherever possible for performance
1178             * reasons.
1179             *
1180             * <p>
1181             * Useful when paginating results. Returns a maximum of <code>end -
1182             * start</code> instances. <code>start</code> and <code>end</code> are not
1183             * primary keys, they are indexes in the result set. Thus, <code>0</code>
1184             * refers to the first result in the set. Setting both <code>start</code>
1185             * and <code>end</code> to {@link
1186             * com.liferay.portal.kernel.dao.orm.QueryUtil#ALL_POS} will return the full
1187             * result set.
1188             * </p>
1189             *
1190             * @param  companyId the primary key of the organization's company
1191             * @param  parentOrganizationId the primary key of the organization's parent
1192             *         organization
1193             * @param  keywords the keywords (space separated), which may occur in the
1194             *         organization's name, street, city, or zipcode (optionally
1195             *         <code>null</code>)
1196             * @param  type the organization's type (optionally <code>null</code>)
1197             * @param  regionId the primary key of the organization's region (optionally
1198             *         <code>null</code>)
1199             * @param  countryId the primary key of the organization's country
1200             *         (optionally <code>null</code>)
1201             * @param  params the finder params. For more information see {@link
1202             *         com.liferay.portal.service.persistence.OrganizationFinder}
1203             * @param  start the lower bound of the range of organizations to return
1204             * @param  end the upper bound of the range of organizations to return (not
1205             *         inclusive)
1206             * @param  obc the comparator to order the organizations (optionally
1207             *         <code>null</code>)
1208             * @return the matching organizations ordered by comparator <code>obc</code>
1209             * @throws SystemException if a system exception occurred
1210             * @see    com.liferay.portal.service.persistence.OrganizationFinder
1211             */
1212            public List<Organization> search(
1213                            long companyId, long parentOrganizationId, String keywords,
1214                            String type, Long regionId, Long countryId,
1215                            LinkedHashMap<String, Object> params, int start, int end,
1216                            OrderByComparator obc)
1217                    throws SystemException {
1218    
1219                    String parentOrganizationIdComparator = StringPool.EQUAL;
1220    
1221                    if (parentOrganizationId ==
1222                                    OrganizationConstants.ANY_PARENT_ORGANIZATION_ID) {
1223    
1224                            parentOrganizationIdComparator = StringPool.NOT_EQUAL;
1225                    }
1226    
1227                    return organizationFinder.findByKeywords(
1228                            companyId, parentOrganizationId, parentOrganizationIdComparator,
1229                            keywords, type, regionId, countryId, params, start, end, obc);
1230            }
1231    
1232            /**
1233             * Returns a name ordered range of all the organizations with the type,
1234             * region, and country, and whose name, street, city, and zipcode match the
1235             * keywords specified for them, without using the indexer. It is preferable
1236             * to use the indexed version {@link #search(long, long, String, String,
1237             * String, String, String, String, String, LinkedHashMap, boolean, int, int,
1238             * Sort)} instead of this method wherever possible for performance reasons.
1239             *
1240             * <p>
1241             * Useful when paginating results. Returns a maximum of <code>end -
1242             * start</code> instances. <code>start</code> and <code>end</code> are not
1243             * primary keys, they are indexes in the result set. Thus, <code>0</code>
1244             * refers to the first result in the set. Setting both <code>start</code>
1245             * and <code>end</code> to {@link
1246             * com.liferay.portal.kernel.dao.orm.QueryUtil#ALL_POS} will return the full
1247             * result set.
1248             * </p>
1249             *
1250             * @param  companyId the primary key of the organization's company
1251             * @param  parentOrganizationId the primary key of the organization's parent
1252             * @param  name the name keywords (space separated, optionally
1253             *         <code>null</code>)
1254             * @param  type the organization's type (optionally <code>null</code>)
1255             * @param  street the street keywords (optionally <code>null</code>)
1256             * @param  city the city keywords (optionally <code>null</code>)
1257             * @param  zip the zipcode keywords (optionally <code>null</code>)
1258             * @param  regionId the primary key of the organization's region (optionally
1259             *         <code>null</code>)
1260             * @param  countryId the primary key of the organization's country
1261             *         (optionally <code>null</code>)
1262             * @param  params the finder parameters (optionally <code>null</code>). For
1263             *         more information see {@link
1264             *         com.liferay.portal.service.persistence.OrganizationFinder}
1265             * @param  andOperator whether every field must match its keywords, or just
1266             *         one field. For example, &quot;organizations with the name
1267             *         'Employees' and city 'Chicago'&quot; vs &quot;organizations with
1268             *         the name 'Employees' or the city 'Chicago'&quot;.
1269             * @param  start the lower bound of the range of organizations to return
1270             * @param  end the upper bound of the range of organizations to return (not
1271             *         inclusive)
1272             * @return the matching organizations ordered by name
1273             * @throws SystemException if a system exception occurred
1274             * @see    com.liferay.portal.service.persistence.OrganizationFinder
1275             */
1276            public List<Organization> search(
1277                            long companyId, long parentOrganizationId, String name, String type,
1278                            String street, String city, String zip, Long regionId,
1279                            Long countryId, LinkedHashMap<String, Object> params,
1280                            boolean andOperator, int start, int end)
1281                    throws SystemException {
1282    
1283                    return search(
1284                            companyId, parentOrganizationId, name, type, street, city, zip,
1285                            regionId, countryId, params, andOperator, start, end,
1286                            new OrganizationNameComparator(true));
1287            }
1288    
1289            /**
1290             * Returns an ordered range of all the organizations with the type, region,
1291             * and country, and whose name, street, city, and zipcode match the keywords
1292             * specified for them, without using the indexer. It is preferable to use
1293             * the indexed version {@link #search(long, long, String, String, String,
1294             * String, String, String, String, LinkedHashMap, boolean, int, int, Sort)}
1295             * instead of this method wherever possible for performance reasons.
1296             *
1297             * <p>
1298             * Useful when paginating results. Returns a maximum of <code>end -
1299             * start</code> instances. <code>start</code> and <code>end</code> are not
1300             * primary keys, they are indexes in the result set. Thus, <code>0</code>
1301             * refers to the first result in the set. Setting both <code>start</code>
1302             * and <code>end</code> to {@link
1303             * com.liferay.portal.kernel.dao.orm.QueryUtil#ALL_POS} will return the full
1304             * result set.
1305             * </p>
1306             *
1307             * @param  companyId the primary key of the organization's company
1308             * @param  parentOrganizationId the primary key of the organization's parent
1309             *         organization
1310             * @param  name the name keywords (space separated, optionally
1311             *         <code>null</code>)
1312             * @param  type the organization's type (optionally <code>null</code>)
1313             * @param  street the street keywords (optionally <code>null</code>)
1314             * @param  city the city keywords (optionally <code>null</code>)
1315             * @param  zip the zipcode keywords (optionally <code>null</code>)
1316             * @param  regionId the primary key of the organization's region (optionally
1317             *         <code>null</code>)
1318             * @param  countryId the primary key of the organization's country
1319             *         (optionally <code>null</code>)
1320             * @param  params the finder parameters (optionally <code>null</code>). For
1321             *         more information see {@link
1322             *         com.liferay.portal.service.persistence.OrganizationFinder}
1323             * @param  andOperator whether every field must match its keywords, or just
1324             *         one field. For example, &quot;organizations with the name
1325             *         'Employees' and city 'Chicago'&quot; vs &quot;organizations with
1326             *         the name 'Employees' or the city 'Chicago'&quot;.
1327             * @param  start the lower bound of the range of organizations to return
1328             * @param  end the upper bound of the range of organizations to return (not
1329             *         inclusive)
1330             * @param  obc the comparator to order the organizations (optionally
1331             *         <code>null</code>)
1332             * @return the matching organizations ordered by comparator <code>obc</code>
1333             * @throws SystemException if a system exception occurred
1334             * @see    com.liferay.portal.service.persistence.OrganizationFinder
1335             */
1336            public List<Organization> search(
1337                            long companyId, long parentOrganizationId, String name, String type,
1338                            String street, String city, String zip, Long regionId,
1339                            Long countryId, LinkedHashMap<String, Object> params,
1340                            boolean andOperator, int start, int end, OrderByComparator obc)
1341                    throws SystemException {
1342    
1343                    String parentOrganizationIdComparator = StringPool.EQUAL;
1344    
1345                    if (parentOrganizationId ==
1346                                    OrganizationConstants.ANY_PARENT_ORGANIZATION_ID) {
1347    
1348                            parentOrganizationIdComparator = StringPool.NOT_EQUAL;
1349                    }
1350    
1351                    return organizationFinder.findByC_PO_N_T_S_C_Z_R_C(
1352                            companyId, parentOrganizationId, parentOrganizationIdComparator,
1353                            name, type, street, city, zip, regionId, countryId, params,
1354                            andOperator, start, end, obc);
1355            }
1356    
1357            /**
1358             * Returns an ordered range of all the organizations whose name, type, or
1359             * location fields match the keywords specified for them, using the indexer.
1360             * It is preferable to use this method instead of the non-indexed version
1361             * whenever possible for performance reasons.
1362             *
1363             * <p>
1364             * Useful when paginating results. Returns a maximum of <code>end -
1365             * start</code> instances. <code>start</code> and <code>end</code> are not
1366             * primary keys, they are indexes in the result set. Thus, <code>0</code>
1367             * refers to the first result in the set. Setting both <code>start</code>
1368             * and <code>end</code> to {@link
1369             * com.liferay.portal.kernel.dao.orm.QueryUtil#ALL_POS} will return the full
1370             * result set.
1371             * </p>
1372             *
1373             * @param  companyId the primary key of the organization's company
1374             * @param  parentOrganizationId the primary key of the organization's parent
1375             *         organization
1376             * @param  name the name keywords (space separated, optionally
1377             *         <code>null</code>)
1378             * @param  type the type keywords (optionally <code>null</code>)
1379             * @param  street the street keywords (optionally <code>null</code>)
1380             * @param  city the city keywords (optionally <code>null</code>)
1381             * @param  zip the zipcode keywords (optionally <code>null</code>)
1382             * @param  region the region keywords (optionally <code>null</code>)
1383             * @param  country the country keywords (optionally <code>null</code>)
1384             * @param  params the finder parameters (optionally <code>null</code>). For
1385             *         more information see {@link
1386             *         com.liferay.portlet.usersadmin.util.OrganizationIndexer}.
1387             * @param  andSearch whether every field must match its keywords or just one
1388             *         field
1389             * @param  start the lower bound of the range of organizations to return
1390             * @param  end the upper bound of the range of organizations to return (not
1391             *         inclusive)
1392             * @param  sort the field and direction by which to sort (optionally
1393             *         <code>null</code>)
1394             * @return the matching organizations ordered by <code>sort</code>
1395             * @throws SystemException if a system exception occurred
1396             * @see    com.liferay.portlet.usersadmin.util.OrganizationIndexer
1397             */
1398            public Hits search(
1399                            long companyId, long parentOrganizationId, String name, String type,
1400                            String street, String city, String zip, String region,
1401                            String country, LinkedHashMap<String, Object> params,
1402                            boolean andSearch, int start, int end, Sort sort)
1403                    throws SystemException {
1404    
1405                    try {
1406                            SearchContext searchContext = new SearchContext();
1407    
1408                            searchContext.setAndSearch(andSearch);
1409    
1410                            Map<String, Serializable> attributes =
1411                                    new HashMap<String, Serializable>();
1412    
1413                            attributes.put("city", city);
1414                            attributes.put("country", country);
1415                            attributes.put("name", name);
1416                            attributes.put("params", params);
1417    
1418                            if (parentOrganizationId !=
1419                                            OrganizationConstants.ANY_PARENT_ORGANIZATION_ID) {
1420    
1421                                    attributes.put(
1422                                            "parentOrganizationId",
1423                                            String.valueOf(parentOrganizationId));
1424                            }
1425    
1426                            attributes.put("region", region);
1427                            attributes.put("street", street);
1428                            attributes.put("type", type);
1429                            attributes.put("zip", zip);
1430    
1431                            searchContext.setAttributes(attributes);
1432    
1433                            searchContext.setCompanyId(companyId);
1434                            searchContext.setEnd(end);
1435    
1436                            if (params != null) {
1437                                    String keywords = (String)params.remove("keywords");
1438    
1439                                    if (Validator.isNotNull(keywords)) {
1440                                            searchContext.setKeywords(keywords);
1441                                    }
1442                            }
1443    
1444                            QueryConfig queryConfig = new QueryConfig();
1445    
1446                            queryConfig.setHighlightEnabled(false);
1447                            queryConfig.setScoreEnabled(false);
1448    
1449                            searchContext.setQueryConfig(queryConfig);
1450    
1451                            if (sort != null) {
1452                                    searchContext.setSorts(new Sort[] {sort});
1453                            }
1454    
1455                            searchContext.setStart(start);
1456    
1457                            Indexer indexer = IndexerRegistryUtil.nullSafeGetIndexer(
1458                                    Organization.class);
1459    
1460                            return indexer.search(searchContext);
1461                    }
1462                    catch (Exception e) {
1463                            throw new SystemException(e);
1464                    }
1465            }
1466    
1467            /**
1468             * Returns the number of organizations that match the keywords, type,
1469             * region, and country.
1470             *
1471             * @param  companyId the primary key of the organization's company
1472             * @param  parentOrganizationId the primary key of the organization's parent
1473             *         organization
1474             * @param  keywords the keywords (space separated), which may occur in the
1475             *         organization's name, street, city, or zipcode (optionally
1476             *         <code>null</code>)
1477             * @param  type the organization's type (optionally <code>null</code>)
1478             * @param  regionId the primary key of the organization's region (optionally
1479             *         <code>null</code>)
1480             * @param  countryId the primary key of the organization's country
1481             *         (optionally <code>null</code>)
1482             * @param  params the finder parameters (optionally <code>null</code>). For
1483             *         more information see {@link
1484             *         com.liferay.portal.service.persistence.OrganizationFinder}
1485             * @return the number of matching organizations
1486             * @throws SystemException if a system exception occurred
1487             * @see    com.liferay.portal.service.persistence.OrganizationFinder
1488             */
1489            public int searchCount(
1490                            long companyId, long parentOrganizationId, String keywords,
1491                            String type, Long regionId, Long countryId,
1492                            LinkedHashMap<String, Object> params)
1493                    throws SystemException {
1494    
1495                    String parentOrganizationIdComparator = StringPool.EQUAL;
1496    
1497                    if (parentOrganizationId ==
1498                                    OrganizationConstants.ANY_PARENT_ORGANIZATION_ID) {
1499    
1500                            parentOrganizationIdComparator = StringPool.NOT_EQUAL;
1501                    }
1502    
1503                    return organizationFinder.countByKeywords(
1504                            companyId, parentOrganizationId, parentOrganizationIdComparator,
1505                            keywords, type, regionId, countryId, params);
1506            }
1507    
1508            /**
1509             * Returns the number of organizations with the type, region, and country,
1510             * and whose name, street, city, and zipcode match the keywords specified
1511             * for them.
1512             *
1513             * @param  companyId the primary key of the organization's company
1514             * @param  parentOrganizationId the primary key of the organization's parent
1515             *         organization
1516             * @param  name the name keywords (space separated, optionally
1517             *         <code>null</code>)
1518             * @param  type the organization's type (optionally <code>null</code>)
1519             * @param  street the street keywords (optionally <code>null</code>)
1520             * @param  city the city keywords (optionally <code>null</code>)
1521             * @param  zip the zipcode keywords (optionally <code>null</code>)
1522             * @param  regionId the primary key of the organization's region (optionally
1523             *         <code>null</code>)
1524             * @param  countryId the primary key of the organization's country
1525             *         (optionally <code>null</code>)
1526             * @param  params the finder parameters (optionally <code>null</code>). For
1527             *         more information see {@link
1528             *         com.liferay.portal.service.persistence.OrganizationFinder}
1529             * @param  andOperator whether every field must match its keywords, or just
1530             *         one field. For example, &quot;organizations with the name
1531             *         'Employees' and city 'Chicago'&quot; vs &quot;organizations with
1532             *         the name 'Employees' or the city 'Chicago'&quot;.
1533             * @return the number of matching organizations
1534             * @throws SystemException if a system exception occurred
1535             * @see    com.liferay.portal.service.persistence.OrganizationFinder
1536             */
1537            public int searchCount(
1538                            long companyId, long parentOrganizationId, String name, String type,
1539                            String street, String city, String zip, Long regionId,
1540                            Long countryId, LinkedHashMap<String, Object> params,
1541                            boolean andOperator)
1542                    throws SystemException {
1543    
1544                    String parentOrganizationIdComparator = StringPool.EQUAL;
1545    
1546                    if (parentOrganizationId ==
1547                                    OrganizationConstants.ANY_PARENT_ORGANIZATION_ID) {
1548    
1549                            parentOrganizationIdComparator = StringPool.NOT_EQUAL;
1550                    }
1551    
1552                    return organizationFinder.countByC_PO_N_T_S_C_Z_R_C(
1553                            companyId, parentOrganizationId, parentOrganizationIdComparator,
1554                            name, type, street, city, zip, regionId, countryId, params,
1555                            andOperator);
1556            }
1557    
1558            /**
1559             * Sets the organizations in the group, removing and adding organizations to
1560             * the group as necessary.
1561             *
1562             * @param  groupId the primary key of the group
1563             * @param  organizationIds the primary keys of the organizations
1564             * @throws PortalException if a portal exception occurred
1565             * @throws SystemException if a system exception occurred
1566             */
1567            public void setGroupOrganizations(long groupId, long[] organizationIds)
1568                    throws PortalException, SystemException {
1569    
1570                    groupPersistence.setOrganizations(groupId, organizationIds);
1571    
1572                    PermissionCacheUtil.clearCache();
1573            }
1574    
1575            /**
1576             * Removes the organizations from the group.
1577             *
1578             * @param  groupId the primary key of the group
1579             * @param  organizationIds the primary keys of the organizations
1580             * @throws PortalException if a portal exception occurred
1581             * @throws SystemException if a system exception occurred
1582             */
1583            public void unsetGroupOrganizations(long groupId, long[] organizationIds)
1584                    throws PortalException, SystemException {
1585    
1586                    groupPersistence.removeOrganizations(groupId, organizationIds);
1587    
1588                    PermissionCacheUtil.clearCache();
1589            }
1590    
1591            /**
1592             * Removes the organizations from the password policy.
1593             *
1594             * @param  passwordPolicyId the primary key of the password policy
1595             * @param  organizationIds the primary keys of the organizations
1596             * @throws SystemException if a system exception occurred
1597             */
1598            public void unsetPasswordPolicyOrganizations(
1599                            long passwordPolicyId, long[] organizationIds)
1600                    throws SystemException {
1601    
1602                    passwordPolicyRelLocalService.deletePasswordPolicyRels(
1603                            passwordPolicyId, Organization.class.getName(), organizationIds);
1604            }
1605    
1606            /**
1607             * Updates the organization's asset with the new asset categories and tag
1608             * names, removing and adding asset categories and tag names as necessary.
1609             *
1610             * @param  userId the primary key of the user
1611             * @param  organization the organization
1612             * @param  assetCategoryIds the primary keys of the asset categories
1613             * @param  assetTagNames the asset tag names
1614             * @throws PortalException if a user with the primary key could not be found
1615             * @throws SystemException if a system exception occurred
1616             */
1617            public void updateAsset(
1618                            long userId, Organization organization, long[] assetCategoryIds,
1619                            String[] assetTagNames)
1620                    throws PortalException, SystemException {
1621    
1622                    User user = userPersistence.findByPrimaryKey(userId);
1623    
1624                    Company company = companyPersistence.findByPrimaryKey(
1625                            user.getCompanyId());
1626    
1627                    Group companyGroup = company.getGroup();
1628    
1629                    assetEntryLocalService.updateEntry(
1630                            userId, companyGroup.getGroupId(), null, null,
1631                            Organization.class.getName(), organization.getOrganizationId(),
1632                            null, 0, assetCategoryIds, assetTagNames, false, null, null, null,
1633                            null, organization.getName(), StringPool.BLANK, null, null, null, 0,
1634                            0, null, false);
1635            }
1636    
1637            /**
1638             * Updates the organization.
1639             *
1640             * @param  companyId the primary key of the organization's company
1641             * @param  organizationId the primary key of the organization
1642             * @param  parentOrganizationId the primary key of organization's parent
1643             *         organization
1644             * @param  name the organization's name
1645             * @param  type the organization's type
1646             * @param  recursable whether permissions of the organization are to be
1647             *         inherited by its suborganizations
1648             * @param  regionId the primary key of the organization's region
1649             * @param  countryId the primary key of the organization's country
1650             * @param  statusId the organization's workflow status
1651             * @param  comments the comments about the organization
1652             * @param  site whether the organization is to be associated with a main
1653             *         site
1654             * @param  serviceContext the organization's service context (optionally
1655             *         <code>null</code>). Can set asset category IDs and asset tag
1656             *         names for the organization, and merge expando bridge attributes
1657             *         for the organization.
1658             * @return the organization
1659             * @throws PortalException if an organization or parent organization with
1660             *         the primary key could not be found or if the new information was
1661             *         invalid
1662             * @throws SystemException if a system exception occurred
1663             */
1664            public Organization updateOrganization(
1665                            long companyId, long organizationId, long parentOrganizationId,
1666                            String name, String type, boolean recursable, long regionId,
1667                            long countryId, int statusId, String comments, boolean site,
1668                            ServiceContext serviceContext)
1669                    throws PortalException, SystemException {
1670    
1671                    // Organization
1672    
1673                    parentOrganizationId = getParentOrganizationId(
1674                            companyId, parentOrganizationId);
1675                    recursable = true;
1676    
1677                    validate(
1678                            companyId, organizationId, parentOrganizationId, name, type,
1679                            countryId, statusId);
1680    
1681                    Organization organization = organizationPersistence.findByPrimaryKey(
1682                            organizationId);
1683    
1684                    long oldParentOrganizationId = organization.getParentOrganizationId();
1685                    String oldName = organization.getName();
1686    
1687                    organization.setParentOrganizationId(parentOrganizationId);
1688    
1689                    String treePath = organization.buildTreePath();
1690    
1691                    organization.setTreePath(treePath);
1692    
1693                    organization.setName(name);
1694                    organization.setType(type);
1695                    organization.setRecursable(recursable);
1696                    organization.setRegionId(regionId);
1697                    organization.setCountryId(countryId);
1698                    organization.setStatusId(statusId);
1699                    organization.setComments(comments);
1700                    organization.setExpandoBridgeAttributes(serviceContext);
1701    
1702                    organizationPersistence.update(organization);
1703    
1704                    // Group
1705    
1706                    Group group = organization.getGroup();
1707    
1708                    long parentGroupId = group.getParentGroupId();
1709    
1710                    boolean organizationGroup = isOrganizationGroup(
1711                            oldParentOrganizationId, group.getParentGroupId());
1712    
1713                    if (organizationGroup) {
1714                            if (parentOrganizationId !=
1715                                            OrganizationConstants.DEFAULT_PARENT_ORGANIZATION_ID) {
1716    
1717                                    Organization parentOrganization =
1718                                            organizationPersistence.fetchByPrimaryKey(
1719                                                    parentOrganizationId);
1720    
1721                                    parentGroupId = parentOrganization.getGroupId();
1722                            }
1723                            else {
1724                                    parentGroupId = GroupConstants.DEFAULT_PARENT_GROUP_ID;
1725                            }
1726                    }
1727    
1728                    if (!oldName.equals(name) || organizationGroup) {
1729                            groupLocalService.updateGroup(
1730                                    group.getGroupId(), parentGroupId, name, group.getDescription(),
1731                                    group.getType(), group.getFriendlyURL(), group.isActive(),
1732                                    null);
1733                    }
1734    
1735                    if (group.isSite() != site) {
1736                            groupLocalService.updateSite(group.getGroupId(), site);
1737                    }
1738    
1739                    // Asset
1740    
1741                    if (serviceContext != null) {
1742                            updateAsset(
1743                                    serviceContext.getUserId(), organization,
1744                                    serviceContext.getAssetCategoryIds(),
1745                                    serviceContext.getAssetTagNames());
1746                    }
1747    
1748                    // Indexer
1749    
1750                    Indexer indexer = IndexerRegistryUtil.nullSafeGetIndexer(
1751                            Organization.class);
1752    
1753                    if (oldParentOrganizationId != parentOrganizationId) {
1754                            long[] organizationIds = getReindexOrganizationIds(organization);
1755    
1756                            indexer.reindex(organizationIds);
1757                    }
1758                    else {
1759                            indexer.reindex(organization);
1760                    }
1761    
1762                    return organization;
1763            }
1764    
1765            protected void addSuborganizations(
1766                            List<Organization> allSuborganizations,
1767                            List<Organization> organizations)
1768                    throws SystemException {
1769    
1770                    for (Organization organization : organizations) {
1771                            if (!allSuborganizations.contains(organization)) {
1772                                    allSuborganizations.add(organization);
1773    
1774                                    List<Organization> suborganizations =
1775                                            organizationPersistence.findByC_P(
1776                                                    organization.getCompanyId(),
1777                                                    organization.getOrganizationId());
1778    
1779                                    addSuborganizations(allSuborganizations, suborganizations);
1780                            }
1781                    }
1782            }
1783    
1784            protected long getParentOrganizationId(
1785                            long companyId, long parentOrganizationId)
1786                    throws SystemException {
1787    
1788                    if (parentOrganizationId !=
1789                                    OrganizationConstants.DEFAULT_PARENT_ORGANIZATION_ID) {
1790    
1791                            // Ensure parent organization exists and belongs to the proper
1792                            // company
1793    
1794                            Organization parentOrganization =
1795                                    organizationPersistence.fetchByPrimaryKey(parentOrganizationId);
1796    
1797                            if ((parentOrganization == null) ||
1798                                    (companyId != parentOrganization.getCompanyId())) {
1799    
1800                                    parentOrganizationId =
1801                                            OrganizationConstants.DEFAULT_PARENT_ORGANIZATION_ID;
1802                            }
1803                    }
1804    
1805                    return parentOrganizationId;
1806            }
1807    
1808            protected List<Organization> getParentOrganizations(
1809                            Organization organization, boolean lastOrganization)
1810                    throws PortalException, SystemException {
1811    
1812                    List<Organization> organizations = new ArrayList<Organization>();
1813    
1814                    if (!lastOrganization) {
1815                            organizations.add(organization);
1816                    }
1817    
1818                    long parentOrganizationId = organization.getParentOrganizationId();
1819    
1820                    if (parentOrganizationId ==
1821                                    OrganizationConstants.DEFAULT_PARENT_ORGANIZATION_ID) {
1822    
1823                            return organizations;
1824                    }
1825    
1826                    Organization parentOrganization =
1827                            organizationPersistence.findByPrimaryKey(parentOrganizationId);
1828    
1829                    List<Organization> parentOrganizatons = getParentOrganizations(
1830                            parentOrganization, false);
1831    
1832                    organizations.addAll(parentOrganizatons);
1833    
1834                    return organizations;
1835            }
1836    
1837            protected long[] getReindexOrganizationIds(Organization organization)
1838                    throws PortalException, SystemException {
1839    
1840                    List<Organization> organizationsTree = new ArrayList<Organization>();
1841    
1842                    organizationsTree.add(organization);
1843    
1844                    LinkedHashMap<String, Object> params =
1845                            new LinkedHashMap<String, Object>();
1846    
1847                    params.put("organizationsTree", organizationsTree);
1848    
1849                    List<Organization> organizations = search(
1850                            organization.getCompanyId(), params, QueryUtil.ALL_POS,
1851                            QueryUtil.ALL_POS);
1852    
1853                    long[] organizationIds = new long[organizations.size()];
1854    
1855                    for (int i = 0; i < organizations.size(); i++) {
1856                            Organization curOrganization = organizations.get(i);
1857    
1858                            String treePath = curOrganization.buildTreePath();
1859    
1860                            curOrganization.setTreePath(treePath.toString());
1861    
1862                            organizationPersistence.update(curOrganization);
1863    
1864                            organizationIds[i] = curOrganization.getOrganizationId();
1865                    }
1866    
1867                    if (!ArrayUtil.contains(
1868                                    organizationIds, organization.getOrganizationId())) {
1869    
1870                            organizationIds = ArrayUtil.append(
1871                                    organizationIds, organization.getOrganizationId());
1872                    }
1873    
1874                    return organizationIds;
1875            }
1876    
1877            protected boolean isOrganizationGroup(long organizationId, long groupId)
1878                    throws SystemException {
1879    
1880                    if ((organizationId ==
1881                                    OrganizationConstants.DEFAULT_PARENT_ORGANIZATION_ID) &&
1882                            (groupId == GroupConstants.DEFAULT_PARENT_GROUP_ID)) {
1883    
1884                            return true;
1885                    }
1886    
1887                    if (organizationId !=
1888                                    OrganizationConstants.DEFAULT_PARENT_ORGANIZATION_ID) {
1889    
1890                            Organization organization =
1891                                    organizationPersistence.fetchByPrimaryKey(organizationId);
1892    
1893                            if (organization.getGroupId() == groupId) {
1894                                    return true;
1895                            }
1896                    }
1897    
1898                    return false;
1899            }
1900    
1901            protected boolean isParentOrganization(
1902                            long parentOrganizationId, long organizationId)
1903                    throws PortalException, SystemException {
1904    
1905                    // Return true if parentOrganizationId is among the parent organizatons
1906                    // of organizationId
1907    
1908                    Organization parentOrganization =
1909                            organizationPersistence.findByPrimaryKey(parentOrganizationId);
1910    
1911                    List<Organization> parentOrganizations = getParentOrganizations(
1912                            organizationId);
1913    
1914                    if (parentOrganizations.contains(parentOrganization)) {
1915                            return true;
1916                    }
1917                    else {
1918                            return false;
1919                    }
1920            }
1921    
1922            protected void validate(
1923                            long companyId, long organizationId, long parentOrganizationId,
1924                            String name, String type, long countryId, int statusId)
1925                    throws PortalException, SystemException {
1926    
1927                    if (!ArrayUtil.contains(PropsValues.ORGANIZATIONS_TYPES, type)) {
1928                            throw new OrganizationTypeException(
1929                                    "Invalid organization type " + type);
1930                    }
1931    
1932                    if (parentOrganizationId ==
1933                                    OrganizationConstants.DEFAULT_PARENT_ORGANIZATION_ID) {
1934    
1935                            if (!OrganizationImpl.isRootable(type)) {
1936                                    throw new OrganizationParentException(
1937                                            "Organization of type " + type + " cannot be a root");
1938                            }
1939                    }
1940                    else {
1941                            Organization parentOrganization =
1942                                    organizationPersistence.fetchByPrimaryKey(parentOrganizationId);
1943    
1944                            if (parentOrganization == null) {
1945                                    throw new OrganizationParentException(
1946                                            "Organization " + parentOrganizationId + " doesn't exist");
1947                            }
1948    
1949                            String[] childrenTypes = OrganizationImpl.getChildrenTypes(
1950                                    parentOrganization.getType());
1951    
1952                            if (childrenTypes.length == 0) {
1953                                    throw new OrganizationParentException(
1954                                            "Organization of type " + type + " cannot have children");
1955                            }
1956    
1957                            if ((companyId != parentOrganization.getCompanyId()) ||
1958                                    (parentOrganizationId == organizationId)) {
1959    
1960                                    throw new OrganizationParentException();
1961                            }
1962    
1963                            if (!ArrayUtil.contains(childrenTypes, type)) {
1964                                    throw new OrganizationParentException(
1965                                            "Type " + type + " not allowed as child of " +
1966                                                    parentOrganization.getType());
1967                            }
1968                    }
1969    
1970                    if ((organizationId > 0) &&
1971                            (parentOrganizationId !=
1972                                    OrganizationConstants.DEFAULT_PARENT_ORGANIZATION_ID)) {
1973    
1974                            // Prevent circular organizational references
1975    
1976                            if (isParentOrganization(organizationId, parentOrganizationId)) {
1977                                    throw new OrganizationParentException();
1978                            }
1979                    }
1980    
1981                    if (Validator.isNull(name)) {
1982                            throw new OrganizationNameException();
1983                    }
1984                    else {
1985                            Organization organization = organizationPersistence.fetchByC_N(
1986                                    companyId, name);
1987    
1988                            if ((organization != null) &&
1989                                    organization.getName().equalsIgnoreCase(name)) {
1990    
1991                                    if ((organizationId <= 0) ||
1992                                            (organization.getOrganizationId() != organizationId)) {
1993    
1994                                            throw new DuplicateOrganizationException(
1995                                                    "There is another organization named " + name);
1996                                    }
1997                            }
1998                    }
1999    
2000                    boolean countryRequired = GetterUtil.getBoolean(
2001                            PropsUtil.get(
2002                                    PropsKeys.ORGANIZATIONS_COUNTRY_REQUIRED, new Filter(type)));
2003    
2004                    if (countryRequired || (countryId > 0)) {
2005                            countryPersistence.findByPrimaryKey(countryId);
2006                    }
2007    
2008                    listTypeService.validate(
2009                            statusId, ListTypeConstants.ORGANIZATION_STATUS);
2010            }
2011    
2012            protected void validate(
2013                            long companyId, long parentOrganizationId, String name, String type,
2014                            long countryId, int statusId)
2015                    throws PortalException, SystemException {
2016    
2017                    validate(
2018                            companyId, 0, parentOrganizationId, name, type, countryId,
2019                            statusId);
2020            }
2021    
2022    }