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