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