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