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