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