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