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                    if (user.isDefaultUser()) {
539                            return Collections.emptyList();
540                    }
541    
542                    Set<Group> userSiteGroups = new LinkedHashSet<>();
543    
544                    if (classNames == null) {
545                            classNames = new String[] {
546                                    Company.class.getName(), Group.class.getName(),
547                                    Organization.class.getName(), User.class.getName()
548                            };
549                    }
550    
551                    if (ArrayUtil.contains(classNames, User.class.getName())) {
552                            if (PropsValues.LAYOUT_USER_PRIVATE_LAYOUTS_ENABLED ||
553                                    PropsValues.LAYOUT_USER_PUBLIC_LAYOUTS_ENABLED) {
554    
555                                    userSiteGroups.add(user.getGroup());
556    
557                                    if (userSiteGroups.size() == max) {
558                                            return new ArrayList<>(userSiteGroups);
559                                    }
560                            }
561                    }
562    
563                    if (ArrayUtil.contains(classNames, Company.class.getName())) {
564                            Group companyGroup = groupLocalService.getCompanyGroup(
565                                    user.getCompanyId());
566    
567                            if (GroupPermissionUtil.contains(
568                                            getPermissionChecker(), companyGroup,
569                                            ActionKeys.VIEW_SITE_ADMINISTRATION)) {
570    
571                                    userSiteGroups.add(companyGroup);
572    
573                                    if (userSiteGroups.size() == max) {
574                                            return new ArrayList<>(userSiteGroups);
575                                    }
576                            }
577                    }
578    
579                    if (ArrayUtil.contains(classNames, Group.class.getName()) ||
580                            ArrayUtil.contains(classNames, Organization.class.getName())) {
581    
582                            UserBag userBag = UserBagFactoryUtil.create(userId);
583    
584                            if (ArrayUtil.contains(classNames, Group.class.getName())) {
585                                    for (Group group : userBag.getUserGroups()) {
586                                            if (group.isActive() && group.isSite()) {
587                                                    if (userSiteGroups.add(group) &&
588                                                            (userSiteGroups.size() == max)) {
589    
590                                                            return new ArrayList<>(userSiteGroups);
591                                                    }
592                                            }
593                                    }
594                            }
595    
596                            if (ArrayUtil.contains(classNames, Organization.class.getName())) {
597                                    for (Group group : userBag.getUserOrgGroups()) {
598                                            if (group.isActive() && group.isSite()) {
599                                                    if (userSiteGroups.add(group) &&
600                                                            (userSiteGroups.size() == max)) {
601    
602                                                            return new ArrayList<>(userSiteGroups);
603                                                    }
604                                            }
605                                    }
606                            }
607                    }
608    
609                    return new ArrayList<>(userSiteGroups);
610            }
611    
612            /**
613             * Returns the guest or current user's groups &quot;sites&quot; associated
614             * with the group entity class names, including the Control Panel group if
615             * the user is permitted to view the Control Panel.
616             *
617             * <ul>
618             * <li>
619             * Class name &quot;User&quot; includes the user's layout set
620             * group.
621             * </li>
622             * <li>
623             * Class name &quot;Organization&quot; includes the user's
624             * immediate organization groups and inherited organization groups.
625             * </li>
626             * <li>
627             * Class name &quot;Group&quot; includes the user's immediate
628             * organization groups and site groups.
629             * </li>
630             * <li>
631             * A <code>classNames</code>
632             * value of <code>null</code> includes the user's layout set group,
633             * organization groups, inherited organization groups, and site groups.
634             * </li>
635             * </ul>
636             *
637             * @param  classNames the group entity class names (optionally
638             *         <code>null</code>). For more information see {@link
639             *         #getUserSitesGroups(long, String[], int)}.
640             * @param  max the maximum number of groups to return
641             * @return the user's groups &quot;sites&quot;
642             * @throws PortalException if a portal exception occurred
643             */
644            @Override
645            public List<Group> getUserSitesGroups(String[] classNames, int max)
646                    throws PortalException {
647    
648                    return getUserSitesGroups(getGuestOrUserId(), classNames, max);
649            }
650    
651            /**
652             * Returns the number of the guest or current user's groups
653             * &quot;sites&quot; associated with the group entity class names, including
654             * the Control Panel group if the user is permitted to view the Control
655             * Panel.
656             *
657             * @return the number of user's groups &quot;sites&quot;
658             * @throws PortalException if a portal exception occurred
659             */
660            @Override
661            public int getUserSitesGroupsCount() throws PortalException {
662                    List<Group> userSitesGroups = getUserSitesGroups(
663                            getGuestOrUserId(), null, QueryUtil.ALL_POS);
664    
665                    return userSitesGroups.size();
666            }
667    
668            /**
669             * Returns <code>true</code> if the user is associated with the group,
670             * including the user's inherited organizations and user groups. System and
671             * staged groups are not included.
672             *
673             * @param  userId the primary key of the user
674             * @param  groupId the primary key of the group
675             * @return <code>true</code> if the user is associated with the group;
676             *         <code>false</code> otherwise
677             * @throws PortalException if a portal exception occurred
678             */
679            @Override
680            public boolean hasUserGroup(long userId, long groupId)
681                    throws PortalException {
682    
683                    try {
684                            UserPermissionUtil.check(
685                                    getPermissionChecker(), userId, ActionKeys.VIEW);
686                    }
687                    catch (PrincipalException pe) {
688                            GroupPermissionUtil.check(
689                                    getPermissionChecker(), groupId, ActionKeys.VIEW_MEMBERS);
690                    }
691    
692                    return groupLocalService.hasUserGroup(userId, groupId);
693            }
694    
695            @Override
696            public List<Group> search(
697                            long companyId, long[] classNameIds, String keywords,
698                            LinkedHashMap<String, Object> params, int start, int end,
699                            OrderByComparator<Group> obc)
700                    throws PortalException {
701    
702                    List<Group> groups = groupLocalService.search(
703                            companyId, classNameIds, keywords, params, start, end, obc);
704    
705                    return filterGroups(groups);
706            }
707    
708            @Override
709            public List<Group> search(
710                            long companyId, long[] classNameIds, String name,
711                            String description, LinkedHashMap<String, Object> params,
712                            boolean andOperator, int start, int end,
713                            OrderByComparator<Group> obc)
714                    throws PortalException {
715    
716                    List<Group> groups = groupLocalService.search(
717                            companyId, classNameIds, name, description, params, andOperator,
718                            start, end, obc);
719    
720                    return filterGroups(groups);
721            }
722    
723            /**
724             * Returns an ordered range of all the site groups and organization groups
725             * that match the name and description, optionally including the user's
726             * inherited organization groups and user groups. System and staged groups
727             * are not included.
728             *
729             * <p>
730             * Useful when paginating results. Returns a maximum of <code>end -
731             * start</code> instances. <code>start</code> and <code>end</code> are not
732             * primary keys, they are indexes in the result set. Thus, <code>0</code>
733             * refers to the first result in the set. Setting both <code>start</code>
734             * and <code>end</code> to {@link QueryUtil#ALL_POS} will return the full
735             * result set.
736             * </p>
737             *
738             * @param  companyId the primary key of the company
739             * @param  name the group's name (optionally <code>null</code>)
740             * @param  description the group's description (optionally
741             *         <code>null</code>)
742             * @param  params the finder params (optionally <code>null</code>). To
743             *         include the user's inherited organizations and user groups in the
744             *         search, add entries having &quot;usersGroups&quot; and
745             *         &quot;inherit&quot; as keys mapped to the the user's ID. For more
746             *         information see {@link
747             *         com.liferay.portal.kernel.service.persistence.GroupFinder}.
748             * @param  start the lower bound of the range of groups to return
749             * @param  end the upper bound of the range of groups to return (not
750             *         inclusive)
751             * @return the matching groups ordered by name
752             * @throws PortalException if a portal exception occurred
753             */
754            @Override
755            public List<Group> search(
756                            long companyId, String name, String description, String[] params,
757                            int start, int end)
758                    throws PortalException {
759    
760                    if (params == null) {
761                            params = new String[0];
762                    }
763    
764                    LinkedHashMap<String, Object> paramsObj = MapUtil.toLinkedHashMap(
765                            params);
766    
767                    List<Group> groups = groupLocalService.search(
768                            companyId, name, description, paramsObj, true, start, end);
769    
770                    return filterGroups(groups);
771            }
772    
773            /**
774             * Returns the number of groups and organization groups that match the name
775             * and description, optionally including the user's inherited organizations
776             * and user groups. System and staged groups are not included.
777             *
778             * @param  companyId the primary key of the company
779             * @param  name the group's name (optionally <code>null</code>)
780             * @param  description the group's description (optionally
781             *         <code>null</code>)
782             * @param  params the finder params (optionally <code>null</code>). To
783             *         include the user's inherited organizations and user groups in the
784             *         search, add entries having &quot;usersGroups&quot; and
785             *         &quot;inherit&quot; as keys mapped to the the user's ID. For more
786             *         information see {@link
787             *         com.liferay.portal.kernel.service.persistence.GroupFinder}.
788             * @return the number of matching groups
789             */
790            @Override
791            public int searchCount(
792                    long companyId, String name, String description, String[] params) {
793    
794                    if (params == null) {
795                            params = new String[0];
796                    }
797    
798                    LinkedHashMap<String, Object> paramsObj = MapUtil.toLinkedHashMap(
799                            params);
800    
801                    return groupLocalService.searchCount(
802                            companyId, name, description, paramsObj, true);
803            }
804    
805            /**
806             * Sets the groups associated with the role, removing and adding
807             * associations as necessary.
808             *
809             * @param  roleId the primary key of the role
810             * @param  groupIds the primary keys of the groups
811             * @throws PortalException if a portal exception occurred
812             */
813            @Override
814            public void setRoleGroups(long roleId, long[] groupIds)
815                    throws PortalException {
816    
817                    RolePermissionUtil.check(
818                            getPermissionChecker(), roleId, ActionKeys.ASSIGN_MEMBERS);
819    
820                    groupLocalService.setRoleGroups(roleId, groupIds);
821            }
822    
823            /**
824             * Removes the groups from the role.
825             *
826             * @param  roleId the primary key of the role
827             * @param  groupIds the primary keys of the groups
828             * @throws PortalException if a portal exception occurred
829             */
830            @Override
831            public void unsetRoleGroups(long roleId, long[] groupIds)
832                    throws PortalException {
833    
834                    RolePermissionUtil.check(
835                            getPermissionChecker(), roleId, ActionKeys.ASSIGN_MEMBERS);
836    
837                    groupLocalService.unsetRoleGroups(roleId, groupIds);
838            }
839    
840            /**
841             * Updates the group's friendly URL.
842             *
843             * @param  groupId the primary key of the group
844             * @param  friendlyURL the group's new friendlyURL (optionally
845             *         <code>null</code>)
846             * @return the group
847             * @throws PortalException if a portal exception occurred
848             */
849            @Override
850            public Group updateFriendlyURL(long groupId, String friendlyURL)
851                    throws PortalException {
852    
853                    GroupPermissionUtil.check(
854                            getPermissionChecker(), groupId, ActionKeys.UPDATE);
855    
856                    return groupLocalService.updateFriendlyURL(groupId, friendlyURL);
857            }
858    
859            @Override
860            public Group updateGroup(
861                            long groupId, long parentGroupId, Map<Locale, String> nameMap,
862                            Map<Locale, String> descriptionMap, int type,
863                            boolean manualMembership, int membershipRestriction,
864                            String friendlyURL, boolean inheritContent, boolean active,
865                            ServiceContext serviceContext)
866                    throws PortalException {
867    
868                    Group group = groupPersistence.findByPrimaryKey(groupId);
869    
870                    GroupPermissionUtil.check(
871                            getPermissionChecker(), group, ActionKeys.UPDATE);
872    
873                    if (group.getParentGroupId() != parentGroupId) {
874                            if (parentGroupId == GroupConstants.DEFAULT_PARENT_GROUP_ID) {
875                                    PortalPermissionUtil.check(
876                                            getPermissionChecker(), ActionKeys.ADD_COMMUNITY);
877                            }
878                            else {
879                                    GroupPermissionUtil.check(
880                                            getPermissionChecker(), parentGroupId,
881                                            ActionKeys.ADD_COMMUNITY);
882                            }
883                    }
884    
885                    if (group.isSite()) {
886                            Group oldGroup = group;
887    
888                            List<AssetCategory> oldAssetCategories =
889                                    assetCategoryLocalService.getCategories(
890                                            Group.class.getName(), groupId);
891    
892                            List<AssetTag> oldAssetTags = assetTagLocalService.getTags(
893                                    Group.class.getName(), groupId);
894    
895                            ExpandoBridge oldExpandoBridge = oldGroup.getExpandoBridge();
896    
897                            Map<String, Serializable> oldExpandoAttributes =
898                                    oldExpandoBridge.getAttributes();
899    
900                            group = groupLocalService.updateGroup(
901                                    groupId, parentGroupId, nameMap, descriptionMap, type,
902                                    manualMembership, membershipRestriction, friendlyURL,
903                                    inheritContent, active, serviceContext);
904    
905                            SiteMembershipPolicyUtil.verifyPolicy(
906                                    group, oldGroup, oldAssetCategories, oldAssetTags,
907                                    oldExpandoAttributes, null);
908    
909                            return group;
910                    }
911                    else {
912                            return groupLocalService.updateGroup(
913                                    groupId, parentGroupId, nameMap, descriptionMap, type,
914                                    manualMembership, membershipRestriction, friendlyURL,
915                                    inheritContent, active, serviceContext);
916                    }
917            }
918    
919            /**
920             * Updates the group.
921             *
922             * @param      groupId the primary key of the group
923             * @param      parentGroupId the primary key of the parent group
924             * @param      name the group's name
925             * @param      description the group's new description (optionally
926             *             <code>null</code>)
927             * @param      type the group's new type. For more information see {@link
928             *             GroupConstants}.
929             * @param      manualMembership whether manual membership is allowed for the
930             *             group
931             * @param      membershipRestriction the group's membership restriction. For
932             *             more information see {@link GroupConstants}.
933             * @param      friendlyURL the group's new friendlyURL (optionally
934             *             <code>null</code>)
935             * @param      inheritContent whether to inherit content from the parent
936             *             group
937             * @param      active whether the group is active
938             * @param      serviceContext the service context to be applied (optionally
939             *             <code>null</code>). Can set the asset category IDs and asset
940             *             tag names for the group.
941             * @return     the group
942             * @throws     PortalException if a portal exception occurred
943             * @deprecated As of 7.0.0, replaced by {@link #updateGroup(long, long, Map,
944             *             Map, int, boolean, int, String, boolean, boolean,
945             *             ServiceContext)}
946             */
947            @Deprecated
948            @Override
949            public Group updateGroup(
950                            long groupId, long parentGroupId, String name, String description,
951                            int type, boolean manualMembership, int membershipRestriction,
952                            String friendlyURL, boolean inheritContent, boolean active,
953                            ServiceContext serviceContext)
954                    throws PortalException {
955    
956                    return updateGroup(
957                            groupId, parentGroupId, getLocalizationMap(name),
958                            getLocalizationMap(description), type, manualMembership,
959                            membershipRestriction, friendlyURL, inheritContent, active,
960                            serviceContext);
961            }
962    
963            /**
964             * Updates the group's type settings.
965             *
966             * @param  groupId the primary key of the group
967             * @param  typeSettings the group's new type settings (optionally
968             *         <code>null</code>)
969             * @return the group
970             * @throws PortalException if a portal exception occurred
971             */
972            @Override
973            public Group updateGroup(long groupId, String typeSettings)
974                    throws PortalException {
975    
976                    Group group = groupPersistence.findByPrimaryKey(groupId);
977    
978                    GroupPermissionUtil.check(
979                            getPermissionChecker(), group, ActionKeys.UPDATE);
980    
981                    if (group.isSite()) {
982                            Group oldGroup = group;
983    
984                            UnicodeProperties oldTypeSettingsProperties =
985                                    oldGroup.getTypeSettingsProperties();
986    
987                            group = groupLocalService.updateGroup(groupId, typeSettings);
988    
989                            RatingsDataTransformerUtil.transformGroupRatingsData(
990                                    groupId, oldTypeSettingsProperties,
991                                    group.getTypeSettingsProperties());
992    
993                            SiteMembershipPolicyUtil.verifyPolicy(
994                                    group, oldGroup, null, null, null, oldTypeSettingsProperties);
995    
996                            return group;
997                    }
998                    else {
999                            return groupLocalService.updateGroup(groupId, typeSettings);
1000                    }
1001            }
1002    
1003            @Override
1004            public void updateStagedPortlets(
1005                            long groupId, Map<String, String> stagedPortletIds)
1006                    throws PortalException {
1007    
1008                    Group group = groupPersistence.findByPrimaryKey(groupId);
1009    
1010                    GroupPermissionUtil.check(
1011                            getPermissionChecker(), group, ActionKeys.UPDATE);
1012    
1013                    UnicodeProperties typeSettingsProperties =
1014                            group.getTypeSettingsProperties();
1015    
1016                    for (String stagedPortletId : stagedPortletIds.keySet()) {
1017                            typeSettingsProperties.setProperty(
1018                                    StagingUtil.getStagedPortletId(stagedPortletId),
1019                                    stagedPortletIds.get(stagedPortletId));
1020                    }
1021    
1022                    groupLocalService.updateGroup(group);
1023            }
1024    
1025            protected List<Group> filterGroups(List<Group> groups)
1026                    throws PortalException {
1027    
1028                    List<Group> filteredGroups = new ArrayList<>();
1029    
1030                    for (Group group : groups) {
1031                            if (GroupPermissionUtil.contains(
1032                                            getPermissionChecker(), group, ActionKeys.VIEW)) {
1033    
1034                                    filteredGroups.add(group);
1035                            }
1036                    }
1037    
1038                    return filteredGroups;
1039            }
1040    
1041            protected Map<Locale, String> getLocalizationMap(String value) {
1042                    Map<Locale, String> map = new HashMap<>();
1043    
1044                    map.put(LocaleUtil.getDefault(), value);
1045    
1046                    return map;
1047            }
1048    
1049    }