001    /**
002     * Copyright (c) 2000-present Liferay, Inc. All rights reserved.
003     *
004     * This library is free software; you can redistribute it and/or modify it under
005     * the terms of the GNU Lesser General Public License as published by the Free
006     * Software Foundation; either version 2.1 of the License, or (at your option)
007     * any later version.
008     *
009     * This library is distributed in the hope that it will be useful, but WITHOUT
010     * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
011     * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
012     * details.
013     */
014    
015    package com.liferay.portal.service.impl;
016    
017    import com.liferay.portal.NoSuchGroupException;
018    import com.liferay.portal.kernel.dao.orm.QueryUtil;
019    import com.liferay.portal.kernel.exception.PortalException;
020    import com.liferay.portal.kernel.util.ArrayUtil;
021    import com.liferay.portal.kernel.util.ListUtil;
022    import com.liferay.portal.kernel.util.LocaleUtil;
023    import com.liferay.portal.kernel.util.MapUtil;
024    import com.liferay.portal.kernel.util.OrderByComparator;
025    import com.liferay.portal.kernel.util.UnicodeProperties;
026    import com.liferay.portal.model.Company;
027    import com.liferay.portal.model.Group;
028    import com.liferay.portal.model.GroupConstants;
029    import com.liferay.portal.model.Organization;
030    import com.liferay.portal.model.Portlet;
031    import com.liferay.portal.model.User;
032    import com.liferay.portal.model.UserGroup;
033    import com.liferay.portal.security.auth.PrincipalException;
034    import com.liferay.portal.security.membershippolicy.SiteMembershipPolicyUtil;
035    import com.liferay.portal.security.permission.ActionKeys;
036    import com.liferay.portal.security.permission.PermissionChecker;
037    import com.liferay.portal.security.permission.UserBag;
038    import com.liferay.portal.security.permission.UserBagFactoryUtil;
039    import com.liferay.portal.service.ServiceContext;
040    import com.liferay.portal.service.base.GroupServiceBaseImpl;
041    import com.liferay.portal.service.permission.GroupPermissionUtil;
042    import com.liferay.portal.service.permission.PortalPermissionUtil;
043    import com.liferay.portal.service.permission.PortletPermissionUtil;
044    import com.liferay.portal.service.permission.RolePermissionUtil;
045    import com.liferay.portal.service.permission.UserPermissionUtil;
046    import com.liferay.portal.util.PortalUtil;
047    import com.liferay.portal.util.PortletKeys;
048    import com.liferay.portal.util.PropsValues;
049    import com.liferay.portlet.asset.model.AssetCategory;
050    import com.liferay.portlet.asset.model.AssetTag;
051    import com.liferay.portlet.expando.model.ExpandoBridge;
052    import com.liferay.portlet.exportimport.staging.StagingUtil;
053    import com.liferay.portlet.ratings.transformer.RatingsDataTransformerUtil;
054    
055    import java.io.Serializable;
056    
057    import java.util.ArrayList;
058    import java.util.Collection;
059    import java.util.Collections;
060    import java.util.HashMap;
061    import java.util.Iterator;
062    import java.util.LinkedHashMap;
063    import java.util.LinkedHashSet;
064    import java.util.List;
065    import java.util.Locale;
066    import java.util.Map;
067    import java.util.Set;
068    
069    /**
070     * Provides the remote service for accessing, adding, deleting, and updating
071     * groups. Its methods include permission checks. Groups are mostly used in
072     * Liferay as a resource container for permissioning and content scoping
073     * purposes.
074     *
075     * @author Brian Wing Shun Chan
076     * @see    com.liferay.portal.service.impl.GroupLocalServiceImpl
077     */
078    public class GroupServiceImpl extends GroupServiceBaseImpl {
079    
080            @Override
081            public Group addGroup(
082                            long parentGroupId, long liveGroupId, Map<Locale, String> nameMap,
083                            Map<Locale, String> descriptionMap, int type,
084                            boolean manualMembership, int membershipRestriction,
085                            String friendlyURL, boolean site, boolean inheritContent,
086                            boolean active, ServiceContext serviceContext)
087                    throws PortalException {
088    
089                    if (parentGroupId == GroupConstants.DEFAULT_PARENT_GROUP_ID) {
090                            PortalPermissionUtil.check(
091                                    getPermissionChecker(), ActionKeys.ADD_COMMUNITY);
092                    }
093                    else {
094                            GroupPermissionUtil.check(
095                                    getPermissionChecker(), parentGroupId,
096                                    ActionKeys.ADD_COMMUNITY);
097                    }
098    
099                    Group group = groupLocalService.addGroup(
100                            getUserId(), parentGroupId, null, 0, liveGroupId, nameMap,
101                            descriptionMap, type, manualMembership, membershipRestriction,
102                            friendlyURL, site, inheritContent, active, serviceContext);
103    
104                    if (site) {
105                            SiteMembershipPolicyUtil.verifyPolicy(group);
106                    }
107    
108                    return group;
109            }
110    
111            @Override
112            public Group addGroup(
113                            long parentGroupId, long liveGroupId, Map<Locale, String> nameMap,
114                            Map<Locale, String> descriptionMap, int type,
115                            boolean manualMembership, int membershipRestriction,
116                            String friendlyURL, boolean site, boolean active,
117                            ServiceContext serviceContext)
118                    throws PortalException {
119    
120                    return addGroup(
121                            parentGroupId, liveGroupId, nameMap, descriptionMap, type,
122                            manualMembership, membershipRestriction, friendlyURL, site, false,
123                            active, serviceContext);
124            }
125    
126            /**
127             * Adds a group.
128             *
129             * @param      parentGroupId the primary key of the parent group
130             * @param      liveGroupId the primary key of the live group
131             * @param      name the entity's name
132             * @param      description the group's description (optionally
133             *             <code>null</code>)
134             * @param      type the group's type. For more information see {@link
135             *             GroupConstants}.
136             * @param      manualMembership whether manual membership is allowed for the
137             *             group
138             * @param      membershipRestriction the group's membership restriction. For
139             *             more information see {@link GroupConstants}.
140             * @param      friendlyURL the group's friendlyURL (optionally
141             *             <code>null</code>)
142             * @param      site whether the group is to be associated with a main site
143             * @param      active whether the group is active
144             * @param      serviceContext the service context to be applied (optionally
145             *             <code>null</code>). Can set the asset category IDs and asset
146             *             tag names for the group, and can set whether the group is for
147             *             staging
148             * @return     the group
149             * @deprecated As of 7.0.0, replaced by {@link #addGroup(long, long, Map,
150             *             Map, int, boolean, int, String, boolean, boolean,
151             *             ServiceContext)}
152             */
153            @Deprecated
154            @Override
155            public Group addGroup(
156                            long parentGroupId, long liveGroupId, String name,
157                            String description, int type, boolean manualMembership,
158                            int membershipRestriction, String friendlyURL, boolean site,
159                            boolean active, ServiceContext serviceContext)
160                    throws PortalException {
161    
162                    return addGroup(
163                            parentGroupId, liveGroupId, getLocalizationMap(name),
164                            getLocalizationMap(description), type, manualMembership,
165                            membershipRestriction, friendlyURL, site, false, active,
166                            serviceContext);
167            }
168    
169            /**
170             * Adds the group using the group default live group ID.
171             *
172             * @param      parentGroupId the primary key of the parent group
173             * @param      name the entity's name
174             * @param      description the group's description (optionally
175             *             <code>null</code>)
176             * @param      type the group's type. For more information see {@link
177             *             GroupConstants}.
178             * @param      friendlyURL the group's friendlyURL
179             * @param      site whether the group is to be associated with a main site
180             * @param      active whether the group is active
181             * @param      serviceContext the service context to be applied (optionally
182             *             <code>null</code>). Can set asset category IDs and asset tag
183             *             names for the group, and can set whether the group is for
184             *             staging
185             * @return     the group
186             * @deprecated As of 6.2.0, replaced by {@link #addGroup(long, long, Map,
187             *             Map, int, boolean, int, String, boolean, boolean,
188             *             ServiceContext)}
189             */
190            @Deprecated
191            @Override
192            public Group addGroup(
193                            long parentGroupId, String name, String description, int type,
194                            String friendlyURL, boolean site, boolean active,
195                            ServiceContext serviceContext)
196                    throws PortalException {
197    
198                    return addGroup(
199                            parentGroupId, GroupConstants.DEFAULT_LIVE_GROUP_ID,
200                            getLocalizationMap(name), getLocalizationMap(description), type,
201                            true, GroupConstants.DEFAULT_MEMBERSHIP_RESTRICTION, friendlyURL,
202                            site, active, serviceContext);
203            }
204    
205            /**
206             * @deprecated As of 6.2.0, replaced by {@link #addGroup(long, String,
207             *             String, int, String, boolean, boolean, ServiceContext)}
208             */
209            @Deprecated
210            @Override
211            public Group addGroup(
212                            String name, String description, int type, String friendlyURL,
213                            boolean site, boolean active, ServiceContext serviceContext)
214                    throws PortalException {
215    
216                    return addGroup(
217                            GroupConstants.DEFAULT_PARENT_GROUP_ID, name, description, type,
218                            friendlyURL, site, active, serviceContext);
219            }
220    
221            /**
222             * Adds the groups to the role.
223             *
224             * @param roleId the primary key of the role
225             * @param groupIds the primary keys of the groups
226             */
227            @Override
228            public void addRoleGroups(long roleId, long[] groupIds)
229                    throws PortalException {
230    
231                    RolePermissionUtil.check(
232                            getPermissionChecker(), roleId, ActionKeys.ASSIGN_MEMBERS);
233    
234                    groupLocalService.addRoleGroups(roleId, groupIds);
235            }
236    
237            /**
238             * Checks that the current user is permitted to use the group for Remote
239             * Staging.
240             *
241             * @param groupId the primary key of the group
242             */
243            @Override
244            public void checkRemoteStagingGroup(long groupId) throws PortalException {
245                    Group group = getGroup(groupId);
246    
247                    PermissionChecker permissionChecker = getPermissionChecker();
248    
249                    if (group.getCompanyId() != permissionChecker.getCompanyId()) {
250                            throw new NoSuchGroupException(
251                                    "Group " + groupId + " does not belong in company " +
252                                            permissionChecker.getCompanyId());
253                    }
254            }
255    
256            /**
257             * Deletes the group.
258             *
259             * <p>
260             * The group is unstaged and its assets and resources including layouts,
261             * membership requests, subscriptions, teams, blogs, bookmarks, calendar
262             * events, image gallery, journals, message boards, polls, shopping related
263             * entities, and wikis are also deleted.
264             * </p>
265             *
266             * @param groupId the primary key of the group
267             */
268            @Override
269            public void deleteGroup(long groupId) throws PortalException {
270                    GroupPermissionUtil.check(
271                            getPermissionChecker(), groupId, ActionKeys.DELETE);
272    
273                    groupLocalService.deleteGroup(groupId);
274            }
275    
276            @Override
277            public void disableStaging(long groupId) throws PortalException {
278                    Group group = groupLocalService.getGroup(groupId);
279    
280                    GroupPermissionUtil.check(
281                            getPermissionChecker(), group, ActionKeys.UPDATE);
282    
283                    groupLocalService.disableStaging(groupId);
284            }
285    
286            @Override
287            public void enableStaging(long groupId) throws PortalException {
288                    Group group = groupLocalService.getGroup(groupId);
289    
290                    GroupPermissionUtil.check(
291                            getPermissionChecker(), group, ActionKeys.UPDATE);
292    
293                    groupLocalService.enableStaging(groupId);
294            }
295    
296            /**
297             * Returns the company group.
298             *
299             * @param  companyId the primary key of the company
300             * @return the group associated with the company
301             */
302            @Override
303            public Group getCompanyGroup(long companyId) throws PortalException {
304                    Group group = groupLocalService.getCompanyGroup(companyId);
305    
306                    GroupPermissionUtil.check(
307                            getPermissionChecker(), group, ActionKeys.VIEW);
308    
309                    return group;
310            }
311    
312            /**
313             * Returns the group with the primary key.
314             *
315             * @param  groupId the primary key of the group
316             * @return the group with the primary key
317             */
318            @Override
319            public Group getGroup(long groupId) throws PortalException {
320                    Group group = groupLocalService.getGroup(groupId);
321    
322                    GroupPermissionUtil.check(
323                            getPermissionChecker(), group, ActionKeys.VIEW);
324    
325                    return group;
326            }
327    
328            /**
329             * Returns the group with the name.
330             *
331             * @param  companyId the primary key of the company
332             * @param  groupKey the group key
333             * @return the group with the group key
334             */
335            @Override
336            public Group getGroup(long companyId, String groupKey)
337                    throws PortalException {
338    
339                    Group group = groupLocalService.getGroup(companyId, groupKey);
340    
341                    GroupPermissionUtil.check(
342                            getPermissionChecker(), group, ActionKeys.VIEW);
343    
344                    return group;
345            }
346    
347            @Override
348            public String getGroupDisplayURL(
349                            long groupId, boolean privateLayout, boolean secureConnection)
350                    throws PortalException {
351    
352                    Group group = groupLocalService.getGroup(groupId);
353    
354                    GroupPermissionUtil.check(
355                            getPermissionChecker(), group, ActionKeys.VIEW);
356    
357                    if (!privateLayout && (group.getPublicLayoutsPageCount() > 0)) {
358                            return PortalUtil.getLayoutSetDisplayURL(
359                                    group.getPublicLayoutSet(), secureConnection);
360                    }
361                    else if (privateLayout && (group.getPrivateLayoutsPageCount() > 0)) {
362                            return PortalUtil.getLayoutSetDisplayURL(
363                                    group.getPrivateLayoutSet(), secureConnection);
364                    }
365    
366                    GroupPermissionUtil.check(
367                            getPermissionChecker(), group, ActionKeys.UPDATE);
368    
369                    return PortalUtil.getControlPanelFullURL(
370                            groupId, PortletKeys.LAYOUTS_ADMIN, null);
371            }
372    
373            /**
374             * Returns all the groups that are direct children of the parent group.
375             *
376             * @param  companyId the primary key of the company
377             * @param  parentGroupId the primary key of the parent group
378             * @param  site whether the group is to be associated with a main site
379             * @return the matching groups, or <code>null</code> if no matches were
380             *         found
381             */
382            @Override
383            public List<Group> getGroups(
384                            long companyId, long parentGroupId, boolean site)
385                    throws PortalException {
386    
387                    return filterGroups(
388                            groupLocalService.getGroups(companyId, parentGroupId, site));
389            }
390    
391            /**
392             * Returns a range of all the site groups for which the user has control
393             * panel access.
394             *
395             * @param  portlets the portlets to manage
396             * @param  max the upper bound of the range of groups to consider (not
397             *         inclusive)
398             * @return the range of site groups for which the user has Control Panel
399             *         access
400             */
401            @Override
402            public List<Group> getManageableSiteGroups(
403                            Collection<Portlet> portlets, int max)
404                    throws PortalException {
405    
406                    PermissionChecker permissionChecker = getPermissionChecker();
407    
408                    if (permissionChecker.isCompanyAdmin()) {
409                            LinkedHashMap<String, Object> params = new LinkedHashMap<>();
410    
411                            params.put("site", Boolean.TRUE);
412    
413                            return ListUtil.unique(
414                                    groupLocalService.search(
415                                            permissionChecker.getCompanyId(), null, null, null, params,
416                                            true, 0, max));
417                    }
418    
419                    Set<Group> groups = new LinkedHashSet<>();
420    
421                    List<Group> userSitesGroups = getUserSitesGroups(null, max);
422    
423                    Iterator<Group> itr = userSitesGroups.iterator();
424    
425                    while (itr.hasNext()) {
426                            Group group = itr.next();
427    
428                            if (group.isSite() &&
429                                    PortletPermissionUtil.hasControlPanelAccessPermission(
430                                            permissionChecker, group.getGroupId(), portlets)) {
431    
432                                    groups.add(group);
433                            }
434                    }
435    
436                    return new ArrayList<>(groups);
437            }
438    
439            /**
440             * Returns a range of all the site groups for which the user has control
441             * panel access.
442             *
443             * @param      portlets the portlets to manage
444             * @param      max the upper bound of the range of groups to consider (not
445             *             inclusive)
446             * @return     the range of site groups for which the user has Control Panel
447             *             access
448             * @deprecated As of 6.2.0, replaced by {@link
449             *             #getManageableSiteGroups(Collection, int)}
450             */
451            @Deprecated
452            @Override
453            public List<Group> getManageableSites(Collection<Portlet> portlets, int max)
454                    throws PortalException {
455    
456                    return getManageableSiteGroups(portlets, max);
457            }
458    
459            /**
460             * Returns the groups associated with the organizations.
461             *
462             * @param  organizations the organizations
463             * @return the groups associated with the organizations
464             */
465            @Override
466            public List<Group> getOrganizationsGroups(List<Organization> organizations)
467                    throws PortalException {
468    
469                    List<Group> groups = groupLocalService.getOrganizationsGroups(
470                            organizations);
471    
472                    return filterGroups(groups);
473            }
474    
475            /**
476             * Returns the group directly associated with the user.
477             *
478             * @param  companyId the primary key of the company
479             * @param  userId the primary key of the user
480             * @return the group directly associated with the user
481             */
482            @Override
483            public Group getUserGroup(long companyId, long userId)
484                    throws PortalException {
485    
486                    Group group = groupLocalService.getUserGroup(companyId, userId);
487    
488                    GroupPermissionUtil.check(
489                            getPermissionChecker(), group, ActionKeys.VIEW);
490    
491                    return group;
492            }
493    
494            /**
495             * Returns the groups associated with the user groups.
496             *
497             * @param  userGroups the user groups
498             * @return the groups associated with the user groups
499             */
500            @Override
501            public List<Group> getUserGroupsGroups(List<UserGroup> userGroups)
502                    throws PortalException {
503    
504                    List<Group> groups = groupLocalService.getUserGroupsGroups(userGroups);
505    
506                    return filterGroups(groups);
507            }
508    
509            /**
510             * Returns the range of all groups associated with the user's organization
511             * groups, including the ancestors of the organization groups, unless portal
512             * property <code>organizations.membership.strict</code> is set to
513             * <code>true</code>.
514             *
515             * <p>
516             * Useful when paginating results. Returns a maximum of <code>end -
517             * start</code> instances. <code>start</code> and <code>end</code> are not
518             * primary keys, they are indexes in the result set. Thus, <code>0</code>
519             * refers to the first result in the set. Setting both <code>start</code>
520             * and <code>end</code> to {@link QueryUtil#ALL_POS} will return the full
521             * result set.
522             * </p>
523             *
524             * @param  userId the primary key of the user
525             * @param  start the lower bound of the range of groups to consider
526             * @param  end the upper bound of the range of groups to consider (not
527             *         inclusive)
528             * @return the range of groups associated with the user's organizations
529             */
530            @Override
531            public List<Group> getUserOrganizationsGroups(
532                            long userId, int start, int end)
533                    throws PortalException {
534    
535                    List<Group> groups = groupLocalService.getUserOrganizationsGroups(
536                            userId, start, end);
537    
538                    return filterGroups(groups);
539            }
540    
541            /**
542             * @deprecated As of 6.2.0, replaced by {@link #getUserSitesGroups(long,
543             *             String[], int)}
544             */
545            @Deprecated
546            @Override
547            public List<Group> getUserPlaces(
548                            long userId, String[] classNames, boolean includeControlPanel,
549                            int max)
550                    throws PortalException {
551    
552                    return getUserSitesGroups(userId, classNames, max);
553            }
554    
555            /**
556             * Returns the user's groups &quot;sites&quot; associated with the group
557             * entity class names, including the Control Panel group if the user is
558             * permitted to view the Control Panel.
559             *
560             * <ul>
561             * <li>
562             * Class name &quot;User&quot; includes the user's layout set
563             * group.
564             * </li>
565             * <li>
566             * Class name &quot;Organization&quot; includes the user's
567             * immediate organization groups and inherited organization groups.
568             * </li>
569             * <li>
570             * Class name &quot;Group&quot; includes the user's immediate
571             * organization groups and site groups.
572             * </li>
573             * <li>
574             * A <code>classNames</code>
575             * value of <code>null</code> includes the user's layout set group,
576             * organization groups, inherited organization groups, and site groups.
577             * </li>
578             * </ul>
579             *
580             * @param      userId the primary key of the user
581             * @param      classNames the group entity class names (optionally
582             *             <code>null</code>). For more information see {@link
583             *             #getUserSitesGroups(long, String[], int)}.
584             * @param      max the maximum number of groups to return
585             * @return     the user's groups &quot;sites&quot;
586             * @deprecated As of 6.2.0, replaced by {@link #getUserSitesGroups(long,
587             *             String[], int)}
588             */
589            @Deprecated
590            @Override
591            public List<Group> getUserPlaces(long userId, String[] classNames, int max)
592                    throws PortalException {
593    
594                    return getUserSitesGroups(userId, classNames, max);
595            }
596    
597            /**
598             * Returns the guest or current user's groups &quot;sites&quot; associated
599             * with the group entity class names, including the Control Panel group if
600             * the user is permitted to view the Control Panel.
601             *
602             * <ul>
603             * <li>
604             * Class name &quot;User&quot; includes the user's layout set
605             * group.
606             * </li>
607             * <li>
608             * Class name &quot;Organization&quot; includes the user's
609             * immediate organization groups and inherited organization groups.
610             * </li>
611             * <li>
612             * Class name &quot;Group&quot; includes the user's immediate
613             * organization groups and site groups.
614             * </li>
615             * <li>
616             * A <code>classNames</code>
617             * value of <code>null</code> includes the user's layout set group,
618             * organization groups, inherited organization groups, and site groups.
619             * </li>
620             * </ul>
621             *
622             * @param      classNames the group entity class names (optionally
623             *             <code>null</code>). For more information see {@link
624             *             #getUserSitesGroups(String[], int)}.
625             * @param      max the maximum number of groups to return
626             * @return     the user's groups &quot;sites&quot;
627             * @deprecated As of 6.2.0, replaced by {@link #getUserSitesGroups(String[],
628             *             int)}
629             */
630            @Deprecated
631            @Override
632            public List<Group> getUserPlaces(String[] classNames, int max)
633                    throws PortalException {
634    
635                    return getUserSitesGroups(classNames, max);
636            }
637    
638            /**
639             * Returns the number of the guest or current user's groups
640             * &quot;sites&quot; associated with the group entity class names, including
641             * the Control Panel group if the user is permitted to view the Control
642             * Panel.
643             *
644             * @return     the number of user's groups &quot;sites&quot;
645             * @deprecated As of 6.2.0, replaced by {@link #getUserSitesGroupsCount()}
646             */
647            @Deprecated
648            @Override
649            public int getUserPlacesCount() throws PortalException {
650                    return getUserSitesGroupsCount();
651            }
652    
653            /**
654             * Returns the guest or current user's layout set group, organization
655             * groups, inherited organization groups, and site groups.
656             *
657             * @return     the user's layout set group, organization groups, and
658             *             inherited organization groups, and site groups
659             * @deprecated As of 6.2.0, replaced by {@link #getUserSitesGroups}
660             */
661            @Deprecated
662            @Override
663            public List<Group> getUserSites() throws PortalException {
664                    return getUserSitesGroups();
665            }
666    
667            @Override
668            public List<Group> getUserSitesGroups() throws PortalException {
669                    return getUserSitesGroups(null, QueryUtil.ALL_POS);
670            }
671    
672            /**
673             * Returns the user's groups &quot;sites&quot; associated with the group
674             * entity class names, including the Control Panel group if the user is
675             * permitted to view the Control Panel.
676             *
677             * <ul>
678             * <li>
679             * Class name &quot;User&quot; includes the user's layout set
680             * group.
681             * </li>
682             * <li>
683             * Class name &quot;Organization&quot; includes the user's
684             * immediate organization groups and inherited organization groups.
685             * </li>
686             * <li>
687             * Class name &quot;Group&quot; includes the user's immediate
688             * organization groups and site groups.
689             * </li>
690             * <li>
691             * A <code>classNames</code>
692             * value of <code>null</code> includes the user's layout set group,
693             * organization groups, inherited organization groups, and site groups.
694             * </li>
695             * </ul>
696             *
697             * @param  userId the primary key of the user
698             * @param  classNames the group entity class names (optionally
699             *         <code>null</code>). For more information see {@link
700             *         #getUserSitesGroups(long, String[], int)}.
701             * @param  max the maximum number of groups to return
702             * @return the user's groups &quot;sites&quot;
703             */
704            @Override
705            public List<Group> getUserSitesGroups(
706                            long userId, String[] classNames, int max)
707                    throws PortalException {
708    
709                    User user = userPersistence.findByPrimaryKey(userId);
710    
711                    if (user.isDefaultUser()) {
712                            return Collections.emptyList();
713                    }
714    
715                    Set<Group> userSiteGroups = new LinkedHashSet<>();
716    
717                    if (classNames == null) {
718                            classNames = new String[] {
719                                    Company.class.getName(), Group.class.getName(),
720                                    Organization.class.getName(), User.class.getName()
721                            };
722                    }
723    
724                    if (ArrayUtil.contains(classNames, User.class.getName())) {
725                            if (PropsValues.LAYOUT_USER_PRIVATE_LAYOUTS_ENABLED ||
726                                    PropsValues.LAYOUT_USER_PUBLIC_LAYOUTS_ENABLED) {
727    
728                                    userSiteGroups.add(user.getGroup());
729    
730                                    if (userSiteGroups.size() == max) {
731                                            return new ArrayList<>(userSiteGroups);
732                                    }
733                            }
734                    }
735    
736                    if (ArrayUtil.contains(classNames, Company.class.getName())) {
737                            userSiteGroups.add(
738                                    groupLocalService.getCompanyGroup(user.getCompanyId()));
739    
740                            if (userSiteGroups.size() == max) {
741                                    return new ArrayList<>(userSiteGroups);
742                            }
743                    }
744    
745                    if (ArrayUtil.contains(classNames, Group.class.getName()) ||
746                            ArrayUtil.contains(classNames, Organization.class.getName())) {
747    
748                            UserBag userBag = UserBagFactoryUtil.create(userId);
749    
750                            if (ArrayUtil.contains(classNames, Group.class.getName())) {
751                                    for (Group group : userBag.getUserGroups()) {
752                                            if (group.isActive() && group.isSite()) {
753                                                    if (userSiteGroups.add(group) &&
754                                                            (userSiteGroups.size() == max)) {
755    
756                                                            return new ArrayList<>(userSiteGroups);
757                                                    }
758                                            }
759                                    }
760                            }
761    
762                            if (ArrayUtil.contains(classNames, Organization.class.getName())) {
763                                    for (Group group : userBag.getUserOrgGroups()) {
764                                            if (group.isActive() && group.isSite()) {
765                                                    if (userSiteGroups.add(group) &&
766                                                            (userSiteGroups.size() == max)) {
767    
768                                                            return new ArrayList<>(userSiteGroups);
769                                                    }
770                                            }
771                                    }
772                            }
773                    }
774    
775                    return new ArrayList<>(userSiteGroups);
776            }
777    
778            /**
779             * Returns the guest or current user's groups &quot;sites&quot; associated
780             * with the group entity class names, including the Control Panel group if
781             * the user is permitted to view the Control Panel.
782             *
783             * <ul>
784             * <li>
785             * Class name &quot;User&quot; includes the user's layout set
786             * group.
787             * </li>
788             * <li>
789             * Class name &quot;Organization&quot; includes the user's
790             * immediate organization groups and inherited organization groups.
791             * </li>
792             * <li>
793             * Class name &quot;Group&quot; includes the user's immediate
794             * organization groups and site groups.
795             * </li>
796             * <li>
797             * A <code>classNames</code>
798             * value of <code>null</code> includes the user's layout set group,
799             * organization groups, inherited organization groups, and site groups.
800             * </li>
801             * </ul>
802             *
803             * @param  classNames the group entity class names (optionally
804             *         <code>null</code>). For more information see {@link
805             *         #getUserSitesGroups(long, String[], int)}.
806             * @param  max the maximum number of groups to return
807             * @return the user's groups &quot;sites&quot;
808             */
809            @Override
810            public List<Group> getUserSitesGroups(String[] classNames, int max)
811                    throws PortalException {
812    
813                    return getUserSitesGroups(getGuestOrUserId(), classNames, max);
814            }
815    
816            /**
817             * Returns the number of the guest or current user's groups
818             * &quot;sites&quot; associated with the group entity class names, including
819             * the Control Panel group if the user is permitted to view the Control
820             * Panel.
821             *
822             * @return the number of user's groups &quot;sites&quot;
823             */
824            @Override
825            public int getUserSitesGroupsCount() throws PortalException {
826                    List<Group> userSitesGroups = getUserSitesGroups(
827                            getGuestOrUserId(), null, QueryUtil.ALL_POS);
828    
829                    return userSitesGroups.size();
830            }
831    
832            /**
833             * Returns <code>true</code> if the user is associated with the group,
834             * including the user's inherited organizations and user groups. System and
835             * staged groups are not included.
836             *
837             * @param  userId the primary key of the user
838             * @param  groupId the primary key of the group
839             * @return <code>true</code> if the user is associated with the group;
840             *         <code>false</code> otherwise
841             */
842            @Override
843            public boolean hasUserGroup(long userId, long groupId)
844                    throws PortalException {
845    
846                    try {
847                            UserPermissionUtil.check(
848                                    getPermissionChecker(), userId, ActionKeys.VIEW);
849                    }
850                    catch (PrincipalException pe) {
851                            GroupPermissionUtil.check(
852                                    getPermissionChecker(), groupId, ActionKeys.VIEW_MEMBERS);
853                    }
854    
855                    return groupLocalService.hasUserGroup(userId, groupId);
856            }
857    
858            @Override
859            public List<Group> search(
860                            long companyId, long[] classNameIds, String keywords,
861                            LinkedHashMap<String, Object> params, int start, int end,
862                            OrderByComparator<Group> obc)
863                    throws PortalException {
864    
865                    List<Group> groups = groupLocalService.search(
866                            companyId, classNameIds, keywords, params, start, end, obc);
867    
868                    return filterGroups(groups);
869            }
870    
871            @Override
872            public List<Group> search(
873                            long companyId, long[] classNameIds, String name,
874                            String description, LinkedHashMap<String, Object> params,
875                            boolean andOperator, int start, int end,
876                            OrderByComparator<Group> obc)
877                    throws PortalException {
878    
879                    List<Group> groups = groupLocalService.search(
880                            companyId, classNameIds, name, description, params, andOperator,
881                            start, end, obc);
882    
883                    return filterGroups(groups);
884            }
885    
886            /**
887             * Returns an ordered range of all the site groups and organization groups
888             * that match the name and description, optionally including the user's
889             * inherited organization groups and user groups. System and staged groups
890             * are not included.
891             *
892             * <p>
893             * Useful when paginating results. Returns a maximum of <code>end -
894             * start</code> instances. <code>start</code> and <code>end</code> are not
895             * primary keys, they are indexes in the result set. Thus, <code>0</code>
896             * refers to the first result in the set. Setting both <code>start</code>
897             * and <code>end</code> to {@link QueryUtil#ALL_POS} will return the full
898             * result set.
899             * </p>
900             *
901             * @param  companyId the primary key of the company
902             * @param  name the group's name (optionally <code>null</code>)
903             * @param  description the group's description (optionally
904             *         <code>null</code>)
905             * @param  params the finder params (optionally <code>null</code>). To
906             *         include the user's inherited organizations and user groups in the
907             *         search, add entries having &quot;usersGroups&quot; and
908             *         &quot;inherit&quot; as keys mapped to the the user's ID. For more
909             *         information see {@link
910             *         com.liferay.portal.service.persistence.GroupFinder}.
911             * @param  start the lower bound of the range of groups to return
912             * @param  end the upper bound of the range of groups to return (not
913             *         inclusive)
914             * @return the matching groups ordered by name
915             */
916            @Override
917            public List<Group> search(
918                            long companyId, String name, String description, String[] params,
919                            int start, int end)
920                    throws PortalException {
921    
922                    if (params == null) {
923                            params = new String[0];
924                    }
925    
926                    LinkedHashMap<String, Object> paramsObj = MapUtil.toLinkedHashMap(
927                            params);
928    
929                    List<Group> groups = groupLocalService.search(
930                            companyId, name, description, paramsObj, true, start, end);
931    
932                    return filterGroups(groups);
933            }
934    
935            /**
936             * Returns the number of groups and organization groups that match the name
937             * and description, optionally including the user's inherited organizations
938             * and user groups. System and staged groups are not included.
939             *
940             * @param  companyId the primary key of the company
941             * @param  name the group's name (optionally <code>null</code>)
942             * @param  description the group's description (optionally
943             *         <code>null</code>)
944             * @param  params the finder params (optionally <code>null</code>). To
945             *         include the user's inherited organizations and user groups in the
946             *         search, add entries having &quot;usersGroups&quot; and
947             *         &quot;inherit&quot; as keys mapped to the the user's ID. For more
948             *         information see {@link
949             *         com.liferay.portal.service.persistence.GroupFinder}.
950             * @return the number of matching groups
951             */
952            @Override
953            public int searchCount(
954                    long companyId, String name, String description, String[] params) {
955    
956                    if (params == null) {
957                            params = new String[0];
958                    }
959    
960                    LinkedHashMap<String, Object> paramsObj = MapUtil.toLinkedHashMap(
961                            params);
962    
963                    return groupLocalService.searchCount(
964                            companyId, name, description, paramsObj, true);
965            }
966    
967            /**
968             * Sets the groups associated with the role, removing and adding
969             * associations as necessary.
970             *
971             * @param roleId the primary key of the role
972             * @param groupIds the primary keys of the groups
973             */
974            @Override
975            public void setRoleGroups(long roleId, long[] groupIds)
976                    throws PortalException {
977    
978                    RolePermissionUtil.check(
979                            getPermissionChecker(), roleId, ActionKeys.ASSIGN_MEMBERS);
980    
981                    groupLocalService.setRoleGroups(roleId, groupIds);
982            }
983    
984            /**
985             * Removes the groups from the role.
986             *
987             * @param roleId the primary key of the role
988             * @param groupIds the primary keys of the groups
989             */
990            @Override
991            public void unsetRoleGroups(long roleId, long[] groupIds)
992                    throws PortalException {
993    
994                    RolePermissionUtil.check(
995                            getPermissionChecker(), roleId, ActionKeys.ASSIGN_MEMBERS);
996    
997                    groupLocalService.unsetRoleGroups(roleId, groupIds);
998            }
999    
1000            /**
1001             * Updates the group's friendly URL.
1002             *
1003             * @param  groupId the primary key of the group
1004             * @param  friendlyURL the group's new friendlyURL (optionally
1005             *         <code>null</code>)
1006             * @return the group
1007             */
1008            @Override
1009            public Group updateFriendlyURL(long groupId, String friendlyURL)
1010                    throws PortalException {
1011    
1012                    GroupPermissionUtil.check(
1013                            getPermissionChecker(), groupId, ActionKeys.UPDATE);
1014    
1015                    return groupLocalService.updateFriendlyURL(groupId, friendlyURL);
1016            }
1017    
1018            @Override
1019            public Group updateGroup(
1020                            long groupId, long parentGroupId, Map<Locale, String> nameMap,
1021                            Map<Locale, String> descriptionMap, int type,
1022                            boolean manualMembership, int membershipRestriction,
1023                            String friendlyURL, boolean inheritContent, boolean active,
1024                            ServiceContext serviceContext)
1025                    throws PortalException {
1026    
1027                    Group group = groupPersistence.findByPrimaryKey(groupId);
1028    
1029                    GroupPermissionUtil.check(
1030                            getPermissionChecker(), group, ActionKeys.UPDATE);
1031    
1032                    if (group.getParentGroupId() != parentGroupId) {
1033                            if (parentGroupId == GroupConstants.DEFAULT_PARENT_GROUP_ID) {
1034                                    PortalPermissionUtil.check(
1035                                            getPermissionChecker(), ActionKeys.ADD_COMMUNITY);
1036                            }
1037                            else {
1038                                    GroupPermissionUtil.check(
1039                                            getPermissionChecker(), parentGroupId,
1040                                            ActionKeys.ADD_COMMUNITY);
1041                            }
1042                    }
1043    
1044                    if (group.isSite()) {
1045                            Group oldGroup = group;
1046    
1047                            List<AssetCategory> oldAssetCategories =
1048                                    assetCategoryLocalService.getCategories(
1049                                            Group.class.getName(), groupId);
1050    
1051                            List<AssetTag> oldAssetTags = assetTagLocalService.getTags(
1052                                    Group.class.getName(), groupId);
1053    
1054                            ExpandoBridge oldExpandoBridge = oldGroup.getExpandoBridge();
1055    
1056                            Map<String, Serializable> oldExpandoAttributes =
1057                                    oldExpandoBridge.getAttributes();
1058    
1059                            group = groupLocalService.updateGroup(
1060                                    groupId, parentGroupId, nameMap, descriptionMap, type,
1061                                    manualMembership, membershipRestriction, friendlyURL,
1062                                    inheritContent, active, serviceContext);
1063    
1064                            SiteMembershipPolicyUtil.verifyPolicy(
1065                                    group, oldGroup, oldAssetCategories, oldAssetTags,
1066                                    oldExpandoAttributes, null);
1067    
1068                            return group;
1069                    }
1070                    else {
1071                            return groupLocalService.updateGroup(
1072                                    groupId, parentGroupId, nameMap, descriptionMap, type,
1073                                    manualMembership, membershipRestriction, friendlyURL,
1074                                    inheritContent, active, serviceContext);
1075                    }
1076            }
1077    
1078            /**
1079             * Updates the group.
1080             *
1081             * @param      groupId the primary key of the group
1082             * @param      parentGroupId the primary key of the parent group
1083             * @param      name the group's name
1084             * @param      description the group's new description (optionally
1085             *             <code>null</code>)
1086             * @param      type the group's new type. For more information see {@link
1087             *             GroupConstants}.
1088             * @param      manualMembership whether manual membership is allowed for the
1089             *             group
1090             * @param      membershipRestriction the group's membership restriction. For
1091             *             more information see {@link GroupConstants}.
1092             * @param      friendlyURL the group's new friendlyURL (optionally
1093             *             <code>null</code>)
1094             * @param      active whether the group is active
1095             * @param      serviceContext the service context to be applied (optionally
1096             *             <code>null</code>). Can set the asset category IDs and asset
1097             *             tag names for the group.
1098             * @return     the group
1099             * @deprecated As of 7.0.0, replaced by {@link #updateGroup(long, long, Map,
1100             *             Map, int, boolean, int, String, boolean, boolean,
1101             *             ServiceContext)}
1102             */
1103            @Deprecated
1104            @Override
1105            public Group updateGroup(
1106                            long groupId, long parentGroupId, String name, String description,
1107                            int type, boolean manualMembership, int membershipRestriction,
1108                            String friendlyURL, boolean inheritContent, boolean active,
1109                            ServiceContext serviceContext)
1110                    throws PortalException {
1111    
1112                    return updateGroup(
1113                            groupId, parentGroupId, getLocalizationMap(name),
1114                            getLocalizationMap(description), type, manualMembership,
1115                            membershipRestriction, friendlyURL, inheritContent, active,
1116                            serviceContext);
1117            }
1118    
1119            /**
1120             * Updates the group's type settings.
1121             *
1122             * @param  groupId the primary key of the group
1123             * @param  typeSettings the group's new type settings (optionally
1124             *         <code>null</code>)
1125             * @return the group
1126             */
1127            @Override
1128            public Group updateGroup(long groupId, String typeSettings)
1129                    throws PortalException {
1130    
1131                    Group group = groupPersistence.findByPrimaryKey(groupId);
1132    
1133                    GroupPermissionUtil.check(
1134                            getPermissionChecker(), group, ActionKeys.UPDATE);
1135    
1136                    if (group.isSite()) {
1137                            Group oldGroup = group;
1138    
1139                            UnicodeProperties oldTypeSettingsProperties =
1140                                    oldGroup.getTypeSettingsProperties();
1141    
1142                            group = groupLocalService.updateGroup(groupId, typeSettings);
1143    
1144                            RatingsDataTransformerUtil.transformGroupRatingsData(
1145                                    groupId, oldTypeSettingsProperties,
1146                                    group.getTypeSettingsProperties());
1147    
1148                            SiteMembershipPolicyUtil.verifyPolicy(
1149                                    group, oldGroup, null, null, null, oldTypeSettingsProperties);
1150    
1151                            return group;
1152                    }
1153                    else {
1154                            return groupLocalService.updateGroup(groupId, typeSettings);
1155                    }
1156            }
1157    
1158            @Override
1159            public void updateStagedPortlets(
1160                            long groupId, Map<String, String> stagedPortletIds)
1161                    throws PortalException {
1162    
1163                    Group group = groupPersistence.findByPrimaryKey(groupId);
1164    
1165                    GroupPermissionUtil.check(
1166                            getPermissionChecker(), group, ActionKeys.UPDATE);
1167    
1168                    UnicodeProperties typeSettingsProperties =
1169                            group.getTypeSettingsProperties();
1170    
1171                    for (String stagedPortletId : stagedPortletIds.keySet()) {
1172                            typeSettingsProperties.setProperty(
1173                                    StagingUtil.getStagedPortletId(stagedPortletId),
1174                                    stagedPortletIds.get(stagedPortletId));
1175                    }
1176    
1177                    groupLocalService.updateGroup(group);
1178            }
1179    
1180            protected List<Group> filterGroups(List<Group> groups)
1181                    throws PortalException {
1182    
1183                    List<Group> filteredGroups = new ArrayList<>();
1184    
1185                    for (Group group : groups) {
1186                            if (GroupPermissionUtil.contains(
1187                                            getPermissionChecker(), group, ActionKeys.VIEW)) {
1188    
1189                                    filteredGroups.add(group);
1190                            }
1191                    }
1192    
1193                    return filteredGroups;
1194            }
1195    
1196            protected Map<Locale, String> getLocalizationMap(String value) {
1197                    Map<Locale, String> map = new HashMap<>();
1198    
1199                    map.put(LocaleUtil.getDefault(), value);
1200    
1201                    return map;
1202            }
1203    
1204    }