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