001    /**
002     * Copyright (c) 2000-2012 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.DuplicateGroupException;
018    import com.liferay.portal.GroupFriendlyURLException;
019    import com.liferay.portal.GroupNameException;
020    import com.liferay.portal.NoSuchGroupException;
021    import com.liferay.portal.NoSuchLayoutSetException;
022    import com.liferay.portal.NoSuchUserException;
023    import com.liferay.portal.RequiredGroupException;
024    import com.liferay.portal.kernel.cache.ThreadLocalCachable;
025    import com.liferay.portal.kernel.dao.orm.QueryUtil;
026    import com.liferay.portal.kernel.exception.PortalException;
027    import com.liferay.portal.kernel.exception.SystemException;
028    import com.liferay.portal.kernel.language.LanguageUtil;
029    import com.liferay.portal.kernel.lar.PortletDataContext;
030    import com.liferay.portal.kernel.lar.PortletDataHandler;
031    import com.liferay.portal.kernel.lar.PortletDataHandlerKeys;
032    import com.liferay.portal.kernel.log.Log;
033    import com.liferay.portal.kernel.log.LogFactoryUtil;
034    import com.liferay.portal.kernel.messaging.DestinationNames;
035    import com.liferay.portal.kernel.scheduler.SchedulerEngineHelperUtil;
036    import com.liferay.portal.kernel.scheduler.StorageType;
037    import com.liferay.portal.kernel.spring.aop.Skip;
038    import com.liferay.portal.kernel.staging.StagingUtil;
039    import com.liferay.portal.kernel.transaction.Propagation;
040    import com.liferay.portal.kernel.transaction.Transactional;
041    import com.liferay.portal.kernel.util.FileUtil;
042    import com.liferay.portal.kernel.util.FriendlyURLNormalizerUtil;
043    import com.liferay.portal.kernel.util.GetterUtil;
044    import com.liferay.portal.kernel.util.OrderByComparator;
045    import com.liferay.portal.kernel.util.ParamUtil;
046    import com.liferay.portal.kernel.util.PropsKeys;
047    import com.liferay.portal.kernel.util.StringPool;
048    import com.liferay.portal.kernel.util.StringUtil;
049    import com.liferay.portal.kernel.util.UniqueList;
050    import com.liferay.portal.kernel.util.Validator;
051    import com.liferay.portal.lar.PortletDataContextImpl;
052    import com.liferay.portal.model.Account;
053    import com.liferay.portal.model.Company;
054    import com.liferay.portal.model.Group;
055    import com.liferay.portal.model.GroupConstants;
056    import com.liferay.portal.model.Layout;
057    import com.liferay.portal.model.LayoutConstants;
058    import com.liferay.portal.model.LayoutPrototype;
059    import com.liferay.portal.model.LayoutSet;
060    import com.liferay.portal.model.LayoutSetPrototype;
061    import com.liferay.portal.model.LayoutTypePortlet;
062    import com.liferay.portal.model.Organization;
063    import com.liferay.portal.model.Portlet;
064    import com.liferay.portal.model.ResourceConstants;
065    import com.liferay.portal.model.ResourcePermission;
066    import com.liferay.portal.model.Role;
067    import com.liferay.portal.model.RoleConstants;
068    import com.liferay.portal.model.User;
069    import com.liferay.portal.model.UserGroup;
070    import com.liferay.portal.model.UserPersonalSite;
071    import com.liferay.portal.model.impl.LayoutImpl;
072    import com.liferay.portal.security.permission.ActionKeys;
073    import com.liferay.portal.security.permission.PermissionCacheUtil;
074    import com.liferay.portal.security.permission.ResourceActionsUtil;
075    import com.liferay.portal.service.ServiceContext;
076    import com.liferay.portal.service.base.GroupLocalServiceBaseImpl;
077    import com.liferay.portal.theme.ThemeLoader;
078    import com.liferay.portal.theme.ThemeLoaderFactory;
079    import com.liferay.portal.util.PortalUtil;
080    import com.liferay.portal.util.PortletCategoryKeys;
081    import com.liferay.portal.util.PortletKeys;
082    import com.liferay.portal.util.PropsUtil;
083    import com.liferay.portal.util.PropsValues;
084    import com.liferay.portal.util.comparator.GroupNameComparator;
085    import com.liferay.portlet.blogs.model.BlogsEntry;
086    import com.liferay.portlet.journal.model.JournalArticle;
087    
088    import java.io.File;
089    
090    import java.util.ArrayList;
091    import java.util.Arrays;
092    import java.util.HashMap;
093    import java.util.HashSet;
094    import java.util.LinkedHashMap;
095    import java.util.List;
096    import java.util.Locale;
097    import java.util.Map;
098    
099    /**
100     * The group local service is responsible for accessing, creating, modifying and
101     * deleting groups.
102     *
103     * <p>
104     * Groups are mostly used in Liferay as a resource container for permissioning
105     * and content scoping purposes as described in {@link
106     * com.liferay.portal.model.impl.GroupImpl}.
107     * </p>
108     *
109     * <p>
110     * Groups are also the entity to which LayoutSets are generally associated.
111     * Since LayoutSets are the parent entities of Layouts (i.e. pages), no entity
112     * can have associated pages without also having an associated Group. This
113     * relationship can be depicted as ... Layout -> LayoutSet -> Group[type] [->
114     * Entity]. Note, the Entity part is optional.
115     * </p>
116     *
117     * <p>
118     * Group has a "type" definition that is typically identified by two fields of
119     * the entity - <code>String className</code>, and <code>int type </code>.
120     * </p>
121     *
122     * <p>
123     * The <code>className</code> field helps create the group's association with
124     * other entities (e.g. Organization, User, Company, UserGroup, ... etc.). The
125     * value of <code>className</code> is the full name of the entity's class and
126     * the primary key of the associated entity instance. A site has
127     * <code>className="Group"</code> and has no associated entity.
128     * </p>
129     *
130     * <p>
131     * The <code>type</code> field helps distinguish between a group used strictly
132     * for scoping and a group that also has pages (in which case the type is
133     * <code>SITE</code>). For a list of types, see {@link
134     * com.liferay.portal.model.GroupConstants}.
135     * </p>
136     *
137     * <p>
138     * Here is a listing of how Group is related to some portal entities ...
139     * </p>
140     *
141     * <ul>
142     * <li>
143     * Site is a Group with <code>className="Group"</code>
144     * </li>
145     * <li>
146     * Company has 1 Group (this is the global scope, but never has pages)
147     * </li>
148     * <li>
149     * User has 1 Group (pages are optional based on the behavior configuration for
150     * personal pages)
151     * </li>
152     * <li>
153     * Layout Template (<code>LayoutPrototype</code>) has 1 Group which uses only 1
154     * of it's 2 LayoutSets to store a single page which can later be used to
155     * derive a single page in any Site
156     * </li>
157     * <li>
158     * Site Template (<code>LayoutSetPrototype</code>) has 1 Group which uses only
159     * 1 of it's 2 LayoutSets to store many pages which can later be used to derive
160     * entire Sites or pulled into an existing Site
161     * </li>
162     * <li>
163     * Organization has 1 Group, but can also be associated to a Site at any point
164     * in it's life cycle in order to support having pages
165     * </li>
166     * <li>
167     * UserGroup has 1 Group that can have pages in both of the group's LayoutSets
168     * which are later inherited by users assigned to the UserGroup
169     * </li>
170     * </ul>
171     *
172     * @author Brian Wing Shun Chan
173     * @author Alexander Chow
174     * @author Bruno Farache
175     * @author Wesley Gong
176     */
177    public class GroupLocalServiceImpl extends GroupLocalServiceBaseImpl {
178    
179            public static final String ORGANIZATION_NAME_SUFFIX = " LFR_ORGANIZATION";
180    
181            /**
182             * Constructs a group local service.
183             */
184            public GroupLocalServiceImpl() {
185                    initImportLARFile();
186            }
187    
188            /**
189             * Adds a group.
190             *
191             * @param  userId the primary key of the group's creator/owner
192             * @param  parentGroupId the primary key of the parent group
193             * @param  className the entity's class name
194             * @param  classPK the primary key of the entity's instance
195             * @param  liveGroupId the primary key of the live group
196             * @param  name the entity's name
197             * @param  description the group's description (optionally
198             *         <code>null</code>)
199             * @param  type the group's type. For more information see {@link
200             *         com.liferay.portal.model.GroupConstants}
201             * @param  friendlyURL the group's friendlyURL (optionally
202             *         <code>null</code>)
203             * @param  site whether the group is to be associated with a main site
204             * @param  active whether the group is active
205             * @param  serviceContext the service context to be applied (optionally
206             *         <code>null</code>). Can set asset category IDs and asset tag
207             *         names for the group, and whether the group is for staging.
208             * @return the group
209             * @throws PortalException if a creator could not be found, if the group's
210             *         information was invalid, if a layout could not be found, or if a
211             *         valid friendly URL could not be created for the group
212             * @throws SystemException if a system exception occurred
213             */
214            public Group addGroup(
215                            long userId, long parentGroupId, String className, long classPK,
216                            long liveGroupId, String name, String description, int type,
217                            String friendlyURL, boolean site, boolean active,
218                            ServiceContext serviceContext)
219                    throws PortalException, SystemException {
220    
221                    // Group
222    
223                    User user = userPersistence.findByPrimaryKey(userId);
224                    className = GetterUtil.getString(className);
225                    long classNameId = PortalUtil.getClassNameId(className);
226                    String friendlyName = name;
227    
228                    long groupId = 0;
229    
230                    while (true) {
231                            groupId = counterLocalService.increment();
232    
233                            User screenNameUser = userPersistence.fetchByC_SN(
234                                    user.getCompanyId(), String.valueOf(groupId));
235    
236                            if (screenNameUser == null) {
237                                    break;
238                            }
239                    }
240    
241                    boolean staging = isStaging(serviceContext);
242    
243                    long groupClassNameId = PortalUtil.getClassNameId(Group.class);
244    
245                    if ((classNameId <= 0) || className.equals(Group.class.getName())) {
246                            className = Group.class.getName();
247                            classNameId = groupClassNameId;
248                            classPK = groupId;
249                    }
250                    else if (className.equals(Organization.class.getName())) {
251                            name = getOrgGroupName(name);
252                    }
253                    else if (!GroupConstants.USER_PERSONAL_SITE.equals(name)) {
254                            name = String.valueOf(classPK);
255                    }
256    
257                    if (className.equals(Organization.class.getName()) && staging) {
258                            classPK = liveGroupId;
259                    }
260    
261                    if (className.equals(Layout.class.getName())) {
262                            Layout layout = layoutLocalService.getLayout(classPK);
263    
264                            parentGroupId = layout.getGroupId();
265                    }
266    
267                    friendlyURL = getFriendlyURL(
268                            user.getCompanyId(), groupId, classNameId, classPK, friendlyName,
269                            friendlyURL);
270    
271                    if (staging) {
272                            name = name.concat(" (Staging)");
273                            friendlyURL = friendlyURL.concat("-staging");
274                    }
275    
276                    if (className.equals(Group.class.getName())) {
277                            if (!site && (liveGroupId == 0) &&
278                                    !name.equals(GroupConstants.CONTROL_PANEL)) {
279    
280                                    throw new IllegalArgumentException();
281                            }
282                    }
283                    else if (!className.equals(Organization.class.getName()) &&
284                                     className.startsWith("com.liferay.portal.model.")) {
285    
286                            if (site) {
287                                    throw new IllegalArgumentException();
288                            }
289                    }
290    
291                    if ((classNameId <= 0) || className.equals(Group.class.getName())) {
292                            validateName(groupId, user.getCompanyId(), name, site);
293                    }
294    
295                    validateFriendlyURL(
296                            user.getCompanyId(), groupId, classNameId, classPK, friendlyURL);
297    
298                    Group group = groupPersistence.create(groupId);
299    
300                    group.setCompanyId(user.getCompanyId());
301                    group.setCreatorUserId(userId);
302                    group.setClassNameId(classNameId);
303                    group.setClassPK(classPK);
304                    group.setParentGroupId(parentGroupId);
305                    group.setLiveGroupId(liveGroupId);
306                    group.setName(name);
307                    group.setDescription(description);
308                    group.setType(type);
309                    group.setFriendlyURL(friendlyURL);
310                    group.setSite(site);
311                    group.setActive(active);
312    
313                    if ((serviceContext != null) && (classNameId == groupClassNameId) &&
314                            !user.isDefaultUser()) {
315    
316                            group.setExpandoBridgeAttributes(serviceContext);
317                    }
318    
319                    groupPersistence.update(group);
320    
321                    // Layout sets
322    
323                    layoutSetLocalService.addLayoutSet(groupId, true);
324    
325                    layoutSetLocalService.addLayoutSet(groupId, false);
326    
327                    if ((classNameId == groupClassNameId) && !user.isDefaultUser()) {
328    
329                            // Resources
330    
331                            resourceLocalService.addResources(
332                                    group.getCompanyId(), 0, 0, Group.class.getName(),
333                                    group.getGroupId(), false, false, false);
334    
335                            // Site roles
336    
337                            Role role = roleLocalService.getRole(
338                                    group.getCompanyId(), RoleConstants.SITE_OWNER);
339    
340                            userGroupRoleLocalService.addUserGroupRoles(
341                                    userId, groupId, new long[] {role.getRoleId()});
342    
343                            // User
344    
345                            userLocalService.addGroupUsers(
346                                    group.getGroupId(), new long[] {userId});
347    
348                            // Asset
349    
350                            if (serviceContext != null) {
351                                    updateAsset(
352                                            userId, group, serviceContext.getAssetCategoryIds(),
353                                            serviceContext.getAssetTagNames());
354                            }
355                    }
356                    else if (className.equals(Organization.class.getName()) &&
357                                     !user.isDefaultUser()) {
358    
359                            // Resources
360    
361                            resourceLocalService.addResources(
362                                    group.getCompanyId(), 0, 0, Group.class.getName(),
363                                    group.getGroupId(), false, false, false);
364                    }
365    
366                    return group;
367            }
368    
369            /**
370             * Adds the group using the default live group.
371             *
372             * @param      userId the primary key of the group's creator/owner
373             * @param      parentGroupId the primary key of the parent group
374             * @param      className the entity's class name
375             * @param      classPK the primary key of the entity's instance
376             * @param      name the entity's name
377             * @param      description the group's description (optionally
378             *             <code>null</code>)
379             * @param      type the group's type. For more information see {@link
380             *             com.liferay.portal.model.GroupConstants}
381             * @param      friendlyURL the group's friendlyURL
382             * @param      site whether the group is to be associated with a main site
383             * @param      active whether the group is active
384             * @param      serviceContext the service context to be applied (optionally
385             *             <code>null</code>). Can set asset category IDs and asset tag
386             *             names for the group, and whether the group is for staging.
387             * @return     the group
388             * @throws     PortalException if a creator could not be found, if the
389             *             group's information was invalid, if a layout could not be
390             *             found, or if a valid friendly URL could not be created for
391             *             the group
392             * @throws     SystemException if a system exception occurred
393             * @deprecated {@link #addGroup(long, long, String, long, long, String,
394             *             String, int, String, boolean, boolean, ServiceContext)}
395             */
396            public Group addGroup(
397                            long userId, long parentGroupId, String className, long classPK,
398                            String name, String description, int type, String friendlyURL,
399                            boolean site, boolean active, ServiceContext serviceContext)
400                    throws PortalException, SystemException {
401    
402                    return addGroup(
403                            userId, parentGroupId, className, classPK,
404                            GroupConstants.DEFAULT_LIVE_GROUP_ID, name, description, type,
405                            friendlyURL, site, active, serviceContext);
406            }
407    
408            /**
409             * Adds the groups to the role.
410             *
411             * @param  roleId the primary key of the role
412             * @param  groupIds the primary keys of the groups
413             * @throws SystemException if a system exception occurred
414             */
415            public void addRoleGroups(long roleId, long[] groupIds)
416                    throws SystemException {
417    
418                    rolePersistence.addGroups(roleId, groupIds);
419    
420                    PermissionCacheUtil.clearCache();
421            }
422    
423            /**
424             * Adds the user to the groups.
425             *
426             * @param  userId the primary key of the user
427             * @param  groupIds the primary keys of the groups
428             * @throws SystemException if a system exception occurred
429             */
430            public void addUserGroups(long userId, long[] groupIds)
431                    throws SystemException {
432    
433                    userPersistence.addGroups(userId, groupIds);
434    
435                    PermissionCacheUtil.clearCache();
436            }
437    
438            /**
439             * Adds a company group if it does not exist. This method is typically used
440             * when a virtual host is added.
441             *
442             * @param  companyId the primary key of the company
443             * @throws PortalException if a default user for the company could not be
444             *         found, if the group's information was invalid, if a layout could
445             *         not be found, or if a valid friendly URL could not be created for
446             *         the group
447             * @throws SystemException if a system exception occurred
448             */
449            @Transactional(propagation = Propagation.SUPPORTS, readOnly = true)
450            public void checkCompanyGroup(long companyId)
451                    throws PortalException, SystemException {
452    
453                    long classNameId = PortalUtil.getClassNameId(Company.class);
454    
455                    int count = groupPersistence.countByC_C_C(
456                            companyId, classNameId, companyId);
457    
458                    if (count == 0) {
459                            long defaultUserId = userLocalService.getDefaultUserId(companyId);
460    
461                            groupLocalService.addGroup(
462                                    defaultUserId, GroupConstants.DEFAULT_PARENT_GROUP_ID,
463                                    Company.class.getName(), companyId,
464                                    GroupConstants.DEFAULT_LIVE_GROUP_ID, GroupConstants.GLOBAL,
465                                    null, 0, GroupConstants.GLOBAL_FRIENDLY_URL, false, true, null);
466                    }
467            }
468    
469            /**
470             * Creates systems groups and other related data needed by the system on the
471             * very first startup. Also takes care of creating the control panel groups
472             * and layouts.
473             *
474             * @param  companyId the primary key of the company
475             * @throws PortalException if a new system group could not be created
476             * @throws SystemException if a system exception occurred
477             */
478            @Transactional(propagation = Propagation.SUPPORTS, readOnly = true)
479            public void checkSystemGroups(long companyId)
480                    throws PortalException, SystemException {
481    
482                    String companyIdHexString = StringUtil.toHexString(companyId);
483    
484                    for (Group group : groupFinder.findBySystem(companyId)) {
485                            _systemGroupsMap.put(
486                                    companyIdHexString.concat(group.getName()), group);
487                    }
488    
489                    long defaultUserId = userLocalService.getDefaultUserId(companyId);
490    
491                    String[] systemGroups = PortalUtil.getSystemGroups();
492    
493                    for (String name : systemGroups) {
494                            String groupCacheKey = companyIdHexString.concat(name);
495    
496                            Group group = _systemGroupsMap.get(groupCacheKey);
497    
498                            if (group == null) {
499                                    group = groupPersistence.fetchByC_N(companyId, name);
500                            }
501    
502                            if (group == null) {
503                                    String className = null;
504                                    long classPK = 0;
505                                    int type = GroupConstants.TYPE_SITE_OPEN;
506                                    String friendlyURL = null;
507                                    boolean site = true;
508    
509                                    if (name.equals(GroupConstants.CONTROL_PANEL)) {
510                                            type = GroupConstants.TYPE_SITE_PRIVATE;
511                                            friendlyURL = GroupConstants.CONTROL_PANEL_FRIENDLY_URL;
512                                            site = false;
513                                    }
514                                    else if (name.equals(GroupConstants.GUEST)) {
515                                            friendlyURL = "/guest";
516                                    }
517                                    else if (name.equals(GroupConstants.USER_PERSONAL_SITE)) {
518                                            className = UserPersonalSite.class.getName();
519                                            classPK = defaultUserId;
520                                            type = GroupConstants.TYPE_SITE_PRIVATE;
521                                            friendlyURL =
522                                                    GroupConstants.USER_PERSONAL_SITE_FRIENDLY_URL;
523                                            site = false;
524                                    }
525    
526                                    group = groupLocalService.addGroup(
527                                            defaultUserId, GroupConstants.DEFAULT_PARENT_GROUP_ID,
528                                            className, classPK, GroupConstants.DEFAULT_LIVE_GROUP_ID,
529                                            name, null, type, friendlyURL, site, true, null);
530    
531                                    if (name.equals(GroupConstants.USER_PERSONAL_SITE)) {
532                                            initUserPersonalSitePermissions(group);
533                                    }
534                            }
535    
536                            if (group.isControlPanel()) {
537                                    LayoutSet layoutSet = layoutSetLocalService.getLayoutSet(
538                                            group.getGroupId(), true);
539    
540                                    if (layoutSet.getPageCount() == 0) {
541                                            addControlPanelLayouts(group);
542                                    }
543                            }
544    
545                            if (group.getName().equals(GroupConstants.GUEST)) {
546                                    LayoutSet layoutSet = layoutSetLocalService.getLayoutSet(
547                                            group.getGroupId(), false);
548    
549                                    if (layoutSet.getPageCount() == 0) {
550                                            addDefaultGuestPublicLayouts(group);
551                                    }
552                            }
553    
554                            _systemGroupsMap.put(groupCacheKey, group);
555                    }
556            }
557    
558            /**
559             * Deletes the group and its associated data.
560             *
561             * <p>
562             * The group is unstaged and its assets and resources including layouts,
563             * membership requests, subscriptions, teams, blogs, bookmarks, calendar
564             * events, image gallery, journals, message boards, polls, shopping related
565             * entities, software catalog, and wikis are also deleted.
566             * </p>
567             *
568             * @param  group the group
569             * @return the deleted group
570             * @throws PortalException if the group was a system group, or if the user
571             *         did not have permission to delete the group or its assets or its
572             *         resources
573             * @throws SystemException if a system exception occurred
574             */
575            @Override
576            public Group deleteGroup(Group group)
577                    throws PortalException, SystemException {
578    
579                    if (PortalUtil.isSystemGroup(group.getName())) {
580                            throw new RequiredGroupException(
581                                    String.valueOf(group.getGroupId()),
582                                    RequiredGroupException.SYSTEM_GROUP);
583                    }
584    
585                    if (groupPersistence.countByC_P_S(
586                                    group.getCompanyId(), group.getGroupId(), true) > 0) {
587    
588                            throw new RequiredGroupException(
589                                    String.valueOf(group.getGroupId()),
590                                    RequiredGroupException.PARENT_GROUP);
591                    }
592    
593                    // Layout set branches
594    
595                    layoutSetBranchLocalService.deleteLayoutSetBranches(
596                            group.getGroupId(), true, true);
597    
598                    layoutSetBranchLocalService.deleteLayoutSetBranches(
599                            group.getGroupId(), false, true);
600    
601                    // Layout sets
602    
603                    ServiceContext serviceContext = new ServiceContext();
604    
605                    try {
606                            layoutSetLocalService.deleteLayoutSet(
607                                    group.getGroupId(), true, serviceContext);
608                    }
609                    catch (NoSuchLayoutSetException nslse) {
610                    }
611    
612                    try {
613                            layoutSetLocalService.deleteLayoutSet(
614                                    group.getGroupId(), false, serviceContext);
615                    }
616                    catch (NoSuchLayoutSetException nslse) {
617                    }
618    
619                    // Group roles
620    
621                    userGroupRoleLocalService.deleteUserGroupRolesByGroupId(
622                            group.getGroupId());
623    
624                    // User group roles
625    
626                    userGroupGroupRoleLocalService.deleteUserGroupGroupRolesByGroupId(
627                            group.getGroupId());
628    
629                    // Membership requests
630    
631                    membershipRequestLocalService.deleteMembershipRequests(
632                            group.getGroupId());
633    
634                    // Subscriptions
635    
636                    subscriptionLocalService.deleteSubscriptions(
637                            group.getCompanyId(), BlogsEntry.class.getName(),
638                            group.getGroupId());
639                    subscriptionLocalService.deleteSubscriptions(
640                            group.getCompanyId(), JournalArticle.class.getName(),
641                            group.getGroupId());
642    
643                    // Teams
644    
645                    teamLocalService.deleteTeams(group.getGroupId());
646    
647                    // Staging
648    
649                    unscheduleStaging(group);
650    
651                    if (group.hasStagingGroup()) {
652                            try {
653                                    StagingUtil.disableStaging(group, serviceContext);
654                            }
655                            catch (Exception e) {
656                                    _log.error(
657                                            "Unable to disable staging for group " +
658                                                    group.getGroupId());
659                            }
660                    }
661    
662                    // Themes
663    
664                    ThemeLoader themeLoader = ThemeLoaderFactory.getDefaultThemeLoader();
665    
666                    if (themeLoader != null) {
667                            String themePath =
668                                    themeLoader.getFileStorage() + StringPool.SLASH +
669                                            group.getGroupId();
670    
671                            FileUtil.deltree(themePath + "-private");
672                            FileUtil.deltree(themePath + "-public");
673                    }
674    
675                    // Portlet data
676    
677                    deletePortletData(group);
678    
679                    // Asset
680    
681                    if (group.isRegularSite()) {
682                            assetEntryLocalService.deleteEntry(
683                                    Group.class.getName(), group.getGroupId());
684                    }
685    
686                    assetVocabularyLocalService.deleteVocabularies(group.getGroupId());
687    
688                    // Shopping
689    
690                    shoppingCartLocalService.deleteGroupCarts(group.getGroupId());
691                    shoppingCategoryLocalService.deleteCategories(group.getGroupId());
692                    shoppingCouponLocalService.deleteCoupons(group.getGroupId());
693                    shoppingOrderLocalService.deleteOrders(group.getGroupId());
694    
695                    // Social
696    
697                    socialActivitySettingLocalService.deleteActivitySettings(
698                            group.getGroupId());
699    
700                    // Software catalog
701    
702                    scFrameworkVersionLocalService.deleteFrameworkVersions(
703                            group.getGroupId());
704                    scProductEntryLocalService.deleteProductEntries(group.getGroupId());
705    
706                    // Resources
707    
708                    List<ResourcePermission> resourcePermissions =
709                            resourcePermissionPersistence.findByC_P(
710                                    group.getCompanyId(), String.valueOf(group.getGroupId()));
711    
712                    for (ResourcePermission resourcePermission : resourcePermissions) {
713                            resourcePermissionLocalService.deleteResourcePermission(
714                                    resourcePermission);
715                    }
716    
717                    if (!group.isStagingGroup() &&
718                            (group.isOrganization() || group.isRegularSite())) {
719    
720                            resourceLocalService.deleteResource(
721                                    group.getCompanyId(), Group.class.getName(),
722                                    ResourceConstants.SCOPE_INDIVIDUAL, group.getGroupId());
723                    }
724    
725                    // Group
726    
727                    if (!group.isStagingGroup() && group.isOrganization() &&
728                            group.isSite()) {
729    
730                            group.setSite(false);
731    
732                            groupPersistence.update(group);
733                    }
734                    else {
735                            groupPersistence.remove(group);
736                    }
737    
738                    // Permission cache
739    
740                    PermissionCacheUtil.clearCache();
741    
742                    return group;
743            }
744    
745            /**
746             * Deletes the group and its associated data.
747             *
748             * <p>
749             * The group is unstaged and its assets and resources including layouts,
750             * membership requests, subscriptions, teams, blogs, bookmarks, calendar
751             * events, image gallery, journals, message boards, polls, shopping related
752             * entities, software catalog, and wikis are also deleted.
753             * </p>
754             *
755             * @param  groupId the primary key of the group
756             * @return the deleted group
757             * @throws PortalException if a group with the primary key could not be
758             *         found, if the group was a system group, or if the user did not
759             *         have permission to delete the group, its assets, or its resources
760             * @throws SystemException if a system exception occurred
761             */
762            @Override
763            public Group deleteGroup(long groupId)
764                    throws PortalException, SystemException {
765    
766                    Group group = groupPersistence.findByPrimaryKey(groupId);
767    
768                    return deleteGroup(group);
769            }
770    
771            /**
772             * Returns the group with the matching friendly URL.
773             *
774             * @param  companyId the primary key of the company
775             * @param  friendlyURL the friendly URL
776             * @return the group with the friendly URL, or <code>null</code> if a
777             *         matching group could not be found
778             * @throws SystemException if a system exception occurred
779             */
780            public Group fetchFriendlyURLGroup(long companyId, String friendlyURL)
781                    throws SystemException {
782    
783                    if (Validator.isNull(friendlyURL)) {
784                            return null;
785                    }
786    
787                    friendlyURL = getFriendlyURL(friendlyURL);
788    
789                    return groupPersistence.fetchByC_F(companyId, friendlyURL);
790            }
791    
792            /**
793             * Returns the group with the matching group name by first searching the
794             * system groups and then using the finder cache.
795             *
796             * @param  companyId the primary key of the company
797             * @param  name the group's name
798             * @return the group with the name and associated company, or
799             *         <code>null</code> if a matching group could not be found
800             * @throws SystemException if a system exception occurred
801             */
802            @Skip
803            public Group fetchGroup(long companyId, String name)
804                    throws SystemException {
805    
806                    Group group = _systemGroupsMap.get(
807                            StringUtil.toHexString(companyId).concat(name));
808    
809                    if (group != null) {
810                            return group;
811                    }
812    
813                    return groupLocalService.loadFetchGroup(companyId, name);
814            }
815    
816            /**
817             * Returns the company group.
818             *
819             * @param  companyId the primary key of the company
820             * @return the group associated with the company
821             * @throws PortalException if a matching group could not be found
822             * @throws SystemException if a system exception occurred
823             */
824            public Group getCompanyGroup(long companyId)
825                    throws PortalException, SystemException {
826    
827                    long classNameId = PortalUtil.getClassNameId(Company.class);
828    
829                    return groupPersistence.findByC_C_C(companyId, classNameId, companyId);
830            }
831    
832            /**
833             * Returns a range of all the groups associated with the company.
834             *
835             * <p>
836             * Useful when paginating results. Returns a maximum of <code>end -
837             * start</code> instances. <code>start</code> and <code>end</code> are not
838             * primary keys, they are indexes in the result set. Thus, <code>0</code>
839             * refers to the first result in the set. Setting both <code>start</code>
840             * and <code>end</code> to {@link
841             * com.liferay.portal.kernel.dao.orm.QueryUtil#ALL_POS} will return the full
842             * result set.
843             * </p>
844             *
845             * @param  companyId the primary key of the company
846             * @param  start the lower bound of the range of groups to return
847             * @param  end the upper bound of the range of groups to return (not
848             *         inclusive)
849             * @return the range of groups associated with the company
850             * @throws SystemException if a system exception occurred
851             */
852            public List<Group> getCompanyGroups(long companyId, int start, int end)
853                    throws SystemException {
854    
855                    return groupPersistence.findByCompanyId(companyId, start, end);
856            }
857    
858            /**
859             * Returns the number of groups associated with the company.
860             *
861             * @param  companyId the primary key of the company
862             * @return the number of groups associated with the company
863             * @throws SystemException if a system exception occurred
864             */
865            public int getCompanyGroupsCount(long companyId) throws SystemException {
866                    return groupPersistence.countByCompanyId(companyId);
867            }
868    
869            /**
870             * Returns the group with the matching friendly URL.
871             *
872             * @param  companyId the primary key of the company
873             * @param  friendlyURL the group's friendlyURL
874             * @return the group with the friendly URL
875             * @throws PortalException if a matching group could not be found, or if the
876             *         friendly URL was invalid
877             * @throws SystemException if a system exception occurred
878             */
879            public Group getFriendlyURLGroup(long companyId, String friendlyURL)
880                    throws PortalException, SystemException {
881    
882                    if (Validator.isNull(friendlyURL)) {
883                            throw new NoSuchGroupException();
884                    }
885    
886                    friendlyURL = getFriendlyURL(friendlyURL);
887    
888                    return groupPersistence.findByC_F(companyId, friendlyURL);
889            }
890    
891            /**
892             * Returns the group with the matching primary key.
893             *
894             * @param  groupId the primary key of the group
895             * @return the group with the primary key
896             * @throws PortalException if a group with the primary key could not be
897             *         found
898             * @throws SystemException if a system exception occurred
899             */
900            @Override
901            @ThreadLocalCachable
902            public Group getGroup(long groupId)
903                    throws PortalException, SystemException {
904    
905                    return groupPersistence.findByPrimaryKey(groupId);
906            }
907    
908            /**
909             * Returns the group with the matching group name.
910             *
911             * @param  companyId the primary key of the company
912             * @param  name the group's name
913             * @return the group with the name
914             * @throws PortalException if a matching group could not be found
915             * @throws SystemException if a system exception occurred
916             */
917            @Skip
918            public Group getGroup(long companyId, String name)
919                    throws PortalException, SystemException {
920    
921                    Group group = _systemGroupsMap.get(
922                            StringUtil.toHexString(companyId).concat(name));
923    
924                    if (group != null) {
925                            return group;
926                    }
927    
928                    return groupLocalService.loadGetGroup(companyId, name);
929            }
930    
931            public String getGroupDescriptiveName(Group group, Locale locale)
932                    throws PortalException, SystemException {
933    
934                    String name = group.getName();
935    
936                    if (group.isCompany()) {
937                            name = LanguageUtil.get(locale, "global");
938                    }
939                    else if (group.isControlPanel()) {
940                            name = LanguageUtil.get(locale, "control-panel");
941                    }
942                    else if (group.isLayout()) {
943                            Layout layout = layoutLocalService.getLayout(group.getClassPK());
944    
945                            name = layout.getName(locale);
946                    }
947                    else if (group.isLayoutPrototype()) {
948                            LayoutPrototype layoutPrototype =
949                                    layoutPrototypeLocalService.getLayoutPrototype(
950                                            group.getClassPK());
951    
952                            name = layoutPrototype.getName(locale);
953                    }
954                    else if (group.isLayoutSetPrototype()) {
955                            LayoutSetPrototype layoutSetPrototype =
956                                    layoutSetPrototypePersistence.findByPrimaryKey(
957                                            group.getClassPK());
958    
959                            name = layoutSetPrototype.getName(locale);
960                    }
961                    else if (group.isOrganization()) {
962                            long organizationId = group.getOrganizationId();
963    
964                            Organization organization =
965                                    organizationPersistence.findByPrimaryKey(organizationId);
966    
967                            name = organization.getName();
968    
969                            Group organizationGroup = organization.getGroup();
970    
971                            if (organizationGroup.isStaged() && group.isStagingGroup()) {
972                                    name = name + " (" + LanguageUtil.get(locale, "staging") + ")";
973                            }
974                    }
975                    else if (group.isUser()) {
976                            long userId = group.getClassPK();
977    
978                            User user = userPersistence.findByPrimaryKey(userId);
979    
980                            name = user.getFullName();
981                    }
982                    else if (group.isUserGroup()) {
983                            long userGroupId = group.getClassPK();
984    
985                            UserGroup userGroup = userGroupPersistence.findByPrimaryKey(
986                                    userGroupId);
987    
988                            name = userGroup.getName();
989                    }
990                    else if (group.isUserPersonalSite()) {
991                            name = LanguageUtil.get(locale, "user-personal-site");
992                    }
993                    else if (name.equals(GroupConstants.GUEST)) {
994                            Company company = companyPersistence.findByPrimaryKey(
995                                    group.getCompanyId());
996    
997                            Account account = company.getAccount();
998    
999                            name = account.getName();
1000                    }
1001    
1002                    return name;
1003            }
1004    
1005            public String getGroupDescriptiveName(long groupId, Locale locale)
1006                    throws PortalException, SystemException {
1007    
1008                    Group group = groupPersistence.findByPrimaryKey(groupId);
1009    
1010                    return getGroupDescriptiveName(group, locale);
1011            }
1012    
1013            /**
1014             * Returns all the sites that are children of the parent group.
1015             *
1016             * @param  companyId the primary key of the company
1017             * @param  parentGroupId the primary key of the parent group
1018             * @param  site whether the group is to be associated with a main site
1019             * @return the matching groups, or <code>null</code> if no matches were
1020             *         found
1021             * @throws SystemException if a system exception occurred
1022             */
1023            public List<Group> getGroups(
1024                            long companyId, long parentGroupId, boolean site)
1025                    throws SystemException {
1026    
1027                    return groupPersistence.findByC_P_S(companyId, parentGroupId, site);
1028            }
1029    
1030            /**
1031             * Returns the groups with the matching primary keys.
1032             *
1033             * @param  groupIds the primary keys of the groups
1034             * @return the groups with the primary keys
1035             * @throws PortalException if any one of the groups could not be found
1036             * @throws SystemException if a system exception occurred
1037             */
1038            public List<Group> getGroups(long[] groupIds)
1039                    throws PortalException, SystemException {
1040    
1041                    List<Group> groups = new ArrayList<Group>(groupIds.length);
1042    
1043                    for (long groupId : groupIds) {
1044                            Group group = getGroup(groupId);
1045    
1046                            groups.add(group);
1047                    }
1048    
1049                    return groups;
1050            }
1051    
1052            /**
1053             * Returns the group associated with the layout.
1054             *
1055             * @param  companyId the primary key of the company
1056             * @param  plid the primary key of the layout
1057             * @return the group associated with the layout
1058             * @throws PortalException if a matching group could not be found
1059             * @throws SystemException if a system exception occurred
1060             */
1061            public Group getLayoutGroup(long companyId, long plid)
1062                    throws PortalException, SystemException {
1063    
1064                    long classNameId = PortalUtil.getClassNameId(Layout.class);
1065    
1066                    return groupPersistence.findByC_C_C(companyId, classNameId, plid);
1067            }
1068    
1069            /**
1070             * Returns the group associated with the layout prototype.
1071             *
1072             * @param  companyId the primary key of the company
1073             * @param  layoutPrototypeId the primary key of the layout prototype
1074             * @return the group associated with the layout prototype
1075             * @throws PortalException if a matching group could not be found
1076             * @throws SystemException if a system exception occurred
1077             */
1078            public Group getLayoutPrototypeGroup(long companyId, long layoutPrototypeId)
1079                    throws PortalException, SystemException {
1080    
1081                    long classNameId = PortalUtil.getClassNameId(LayoutPrototype.class);
1082    
1083                    return groupPersistence.findByC_C_C(
1084                            companyId, classNameId, layoutPrototypeId);
1085            }
1086    
1087            /**
1088             * Returns the group associated with the layout set prototype.
1089             *
1090             * @param  companyId the primary key of the company
1091             * @param  layoutSetPrototypeId the primary key of the layout set prototype
1092             * @return the group associated with the layout set prototype
1093             * @throws PortalException if a matching group could not be found
1094             * @throws SystemException if a system exception occurred
1095             */
1096            public Group getLayoutSetPrototypeGroup(
1097                            long companyId, long layoutSetPrototypeId)
1098                    throws PortalException, SystemException {
1099    
1100                    long classNameId = PortalUtil.getClassNameId(LayoutSetPrototype.class);
1101    
1102                    return groupPersistence.findByC_C_C(
1103                            companyId, classNameId, layoutSetPrototypeId);
1104            }
1105    
1106            /**
1107             * Returns a range of all groups that are children of the parent group and
1108             * that have at least one layout.
1109             *
1110             * <p>
1111             * Useful when paginating results. Returns a maximum of <code>end -
1112             * start</code> instances. <code>start</code> and <code>end</code> are not
1113             * primary keys, they are indexes in the result set. Thus, <code>0</code>
1114             * refers to the first result in the set. Setting both <code>start</code>
1115             * and <code>end</code> to {@link
1116             * com.liferay.portal.kernel.dao.orm.QueryUtil#ALL_POS} will return the full
1117             * result set.
1118             * </p>
1119             *
1120             * @param  companyId the primary key of the company
1121             * @param  parentGroupId the primary key of the parent group
1122             * @param  site whether the group is to be associated with a main site
1123             * @param  start the lower bound of the range of groups to return
1124             * @param  end the upper bound of the range of groups to return (not
1125             *         inclusive)
1126             * @return the range of matching groups
1127             * @throws SystemException if a system exception occurred
1128             */
1129            public List<Group> getLayoutsGroups(
1130                            long companyId, long parentGroupId, boolean site, int start,
1131                            int end)
1132                    throws SystemException {
1133    
1134                    return groupFinder.findByLayouts(
1135                            companyId, parentGroupId, site, start, end);
1136            }
1137    
1138            /**
1139             * Returns the number of groups that are children or the parent group and
1140             * that have at least one layout
1141             *
1142             * @param  companyId the primary key of the company
1143             * @param  parentGroupId the primary key of the parent group
1144             * @param  site whether the group is to be associated with a main site
1145             * @return the number of matching groups
1146             * @throws SystemException if a system exception occurred
1147             */
1148            public int getLayoutsGroupsCount(
1149                            long companyId, long parentGroupId, boolean site)
1150                    throws SystemException {
1151    
1152                    return groupFinder.countByLayouts(companyId, parentGroupId, site);
1153            }
1154    
1155            /**
1156             * Returns all live groups.
1157             *
1158             * @return all live groups
1159             * @throws SystemException if a system exception occurred
1160             */
1161            public List<Group> getLiveGroups() throws SystemException {
1162                    return groupFinder.findByLiveGroups();
1163            }
1164    
1165            /**
1166             * Returns a range of all non-system groups of a specified type (className)
1167             * that have no layouts.
1168             *
1169             * <p>
1170             * Useful when paginating results. Returns a maximum of <code>end -
1171             * start</code> instances. <code>start</code> and <code>end</code> are not
1172             * primary keys, they are indexes in the result set. Thus, <code>0</code>
1173             * refers to the first result in the set. Setting both <code>start</code>
1174             * and <code>end</code> to {@link
1175             * com.liferay.portal.kernel.dao.orm.QueryUtil#ALL_POS} will return the full
1176             * result set.
1177             * </p>
1178             *
1179             * @param  className the entity's class name
1180             * @param  privateLayout whether to include groups with private layout sets
1181             *         or non-private layout sets
1182             * @param  start the lower bound of the range of groups to return
1183             * @param  end the upper bound of the range of groups to return (not
1184             *         inclusive)
1185             * @return the range of matching groups
1186             * @throws SystemException if a system exception occurred
1187             */
1188            public List<Group> getNoLayoutsGroups(
1189                            String className, boolean privateLayout, int start, int end)
1190                    throws SystemException {
1191    
1192                    long classNameId = PortalUtil.getClassNameId(className);
1193    
1194                    return groupFinder.findByNoLayouts(
1195                            classNameId, privateLayout, start, end);
1196            }
1197    
1198            /**
1199             * Returns all non-system groups having <code>null</code> or empty friendly
1200             * URLs.
1201             *
1202             * @return the non-system groups having <code>null</code> or empty friendly
1203             *         URLs
1204             * @throws SystemException if a system exception occurred
1205             */
1206            public List<Group> getNullFriendlyURLGroups() throws SystemException {
1207                    return groupFinder.findByNullFriendlyURL();
1208            }
1209    
1210            /**
1211             * Returns the specified organization group.
1212             *
1213             * @param  companyId the primary key of the company
1214             * @param  organizationId the primary key of the organization
1215             * @return the group associated with the organization
1216             * @throws PortalException if a matching group could not be found
1217             * @throws SystemException if a system exception occurred
1218             */
1219            public Group getOrganizationGroup(long companyId, long organizationId)
1220                    throws PortalException, SystemException {
1221    
1222                    long classNameId = PortalUtil.getClassNameId(Organization.class);
1223    
1224                    return groupPersistence.findByC_C_C(
1225                            companyId, classNameId, organizationId);
1226            }
1227    
1228            /**
1229             * Returns the specified organization groups.
1230             *
1231             * @param  organizations the organizations
1232             * @return the groups associated with the organizations
1233             */
1234            public List<Group> getOrganizationsGroups(
1235                    List<Organization> organizations) {
1236    
1237                    List<Group> organizationGroups = new ArrayList<Group>();
1238    
1239                    for (int i = 0; i < organizations.size(); i++) {
1240                            Organization organization = organizations.get(i);
1241    
1242                            Group group = organization.getGroup();
1243    
1244                            organizationGroups.add(group);
1245                    }
1246    
1247                    return organizationGroups;
1248            }
1249    
1250            /**
1251             * Returns all the groups related to the organizations.
1252             *
1253             * @param  organizations the organizations
1254             * @return the groups related to the organizations
1255             * @throws SystemException if a system exception occurred
1256             */
1257            public List<Group> getOrganizationsRelatedGroups(
1258                            List<Organization> organizations)
1259                    throws SystemException {
1260    
1261                    List<Group> organizationGroups = new ArrayList<Group>();
1262    
1263                    for (int i = 0; i < organizations.size(); i++) {
1264                            Organization organization = organizations.get(i);
1265    
1266                            List<Group> groups = organizationPersistence.getGroups(
1267                                    organization.getOrganizationId());
1268    
1269                            organizationGroups.addAll(groups);
1270                    }
1271    
1272                    return organizationGroups;
1273            }
1274    
1275            /**
1276             * Returns all the groups associated with the role.
1277             *
1278             * @param  roleId the primary key of the role
1279             * @return the groups associated with the role
1280             * @throws SystemException if a system exception occurred
1281             */
1282            public List<Group> getRoleGroups(long roleId) throws SystemException {
1283                    return rolePersistence.getGroups(roleId);
1284            }
1285    
1286            /**
1287             * Returns the staging group.
1288             *
1289             * @param  liveGroupId the primary key of the live group
1290             * @return the staging group
1291             * @throws PortalException if a matching staging group could not be found
1292             * @throws SystemException if a system exception occurred
1293             */
1294            public Group getStagingGroup(long liveGroupId)
1295                    throws PortalException, SystemException {
1296    
1297                    return groupPersistence.findByLiveGroupId(liveGroupId);
1298            }
1299    
1300            /**
1301             * Returns the group associated with the user.
1302             *
1303             * @param  companyId the primary key of the company
1304             * @param  userId the primary key of the user
1305             * @return the group associated with the user
1306             * @throws PortalException if a matching group could not be found
1307             * @throws SystemException if a system exception occurred
1308             */
1309            public Group getUserGroup(long companyId, long userId)
1310                    throws PortalException, SystemException {
1311    
1312                    long classNameId = PortalUtil.getClassNameId(User.class);
1313    
1314                    return groupPersistence.findByC_C_C(companyId, classNameId, userId);
1315            }
1316    
1317            /**
1318             * Returns the specified "user group" group. That is, the group that
1319             * represents the {@link com.liferay.portal.model.UserGroup} entity.
1320             *
1321             * @param  companyId the primary key of the company
1322             * @param  userGroupId the primary key of the user group
1323             * @return the group associated with the user group
1324             * @throws PortalException if a matching group could not be found
1325             * @throws SystemException if a system exception occurred
1326             */
1327            public Group getUserGroupGroup(long companyId, long userGroupId)
1328                    throws PortalException, SystemException {
1329    
1330                    long classNameId = PortalUtil.getClassNameId(UserGroup.class);
1331    
1332                    return groupPersistence.findByC_C_C(
1333                            companyId, classNameId, userGroupId);
1334            }
1335    
1336            /**
1337             * Returns all the user's site groups and immediate organization groups.
1338             * System and staged groups are not included.
1339             *
1340             * @param  userId the primary key of the user
1341             * @return the user's groups and organization groups
1342             * @throws PortalException if a user with the primary key could not be found
1343             * @throws SystemException if a system exception occurred
1344             */
1345            public List<Group> getUserGroups(long userId)
1346                    throws PortalException, SystemException {
1347    
1348                    return getUserGroups(userId, false);
1349            }
1350    
1351            /**
1352             * Returns all the user's site groups and immediate organization groups,
1353             * optionally including the user's inherited organization groups and user
1354             * groups. System and staged groups are not included.
1355             *
1356             * @param  userId the primary key of the user
1357             * @param  inherit whether to include the user's inherited organization
1358             *         groups and user groups
1359             * @return the user's groups and immediate organization groups
1360             * @throws PortalException if a user with the primary key could not be found
1361             * @throws SystemException if a system exception occurred
1362             */
1363            public List<Group> getUserGroups(long userId, boolean inherit)
1364                    throws PortalException, SystemException {
1365    
1366                    return getUserGroups(
1367                            userId, inherit, QueryUtil.ALL_POS, QueryUtil.ALL_POS);
1368            }
1369    
1370            /**
1371             * Returns an ordered range of all the user's site groups and immediate
1372             * organization groups, optionally including the user's inherited
1373             * organization groups and user groups. System and staged groups are not
1374             * included.
1375             *
1376             * <p>
1377             * Useful when paginating results. Returns a maximum of <code>end -
1378             * start</code> instances. <code>start</code> and <code>end</code> are not
1379             * primary keys, they are indexes in the result set. Thus, <code>0</code>
1380             * refers to the first result in the set. Setting both <code>start</code>
1381             * and <code>end</code> to {@link
1382             * com.liferay.portal.kernel.dao.orm.QueryUtil#ALL_POS} will return the full
1383             * result set.
1384             * </p>
1385             *
1386             * @param  userId the primary key of the user
1387             * @param  inherit whether to include the user's inherited organization
1388             *         groups and user groups
1389             * @param  start the lower bound of the range of groups to return
1390             * @param  end the upper bound of the range of groups to return (not
1391             *         inclusive)
1392             * @return the range of the user's groups and immediate organization groups
1393             *         ordered by name
1394             * @throws PortalException if a user with the primary key could not be found
1395             * @throws SystemException if a system exception occurred
1396             */
1397            public List<Group> getUserGroups(
1398                            long userId, boolean inherit, int start, int end)
1399                    throws PortalException, SystemException {
1400    
1401                    if (inherit) {
1402                            User user = userPersistence.findByPrimaryKey(userId);
1403    
1404                            LinkedHashMap<String, Object> groupParams =
1405                                    new LinkedHashMap<String, Object>();
1406    
1407                            groupParams.put("usersGroups", new Long(userId));
1408    
1409                            return search(
1410                                    user.getCompanyId(), null, null, groupParams, start, end);
1411                    }
1412                    else {
1413                            return userPersistence.getGroups(userId, start, end);
1414                    }
1415            }
1416    
1417            /**
1418             * Returns an ordered range of all the user's site groups and immediate
1419             * organization groups. System and staged groups are not included.
1420             *
1421             * <p>
1422             * Useful when paginating results. Returns a maximum of <code>end -
1423             * start</code> instances. <code>start</code> and <code>end</code> are not
1424             * primary keys, they are indexes in the result set. Thus, <code>0</code>
1425             * refers to the first result in the set. Setting both <code>start</code>
1426             * and <code>end</code> to {@link
1427             * com.liferay.portal.kernel.dao.orm.QueryUtil#ALL_POS} will return the full
1428             * result set.
1429             * </p>
1430             *
1431             * @param  userId the primary key of the user
1432             * @param  start the lower bound of the range of groups to return
1433             * @param  end the upper bound of the range of groups to return (not
1434             *         inclusive)
1435             * @return the range of the user's groups and organization groups ordered by
1436             *         name
1437             * @throws PortalException if a user with the primary key could not be found
1438             * @throws SystemException if a system exception occurred
1439             */
1440            public List<Group> getUserGroups(long userId, int start, int end)
1441                    throws PortalException, SystemException {
1442    
1443                    return getUserGroups(userId, false, start, end);
1444            }
1445    
1446            /**
1447             * Returns the groups associated with the user groups.
1448             *
1449             * @param  userGroups the user groups
1450             * @return the groups associated with the user groups
1451             * @throws PortalException if any one of the user group's group could not be
1452             *         found
1453             * @throws SystemException if a system exception occurred
1454             */
1455            public List<Group> getUserGroupsGroups(List<UserGroup> userGroups)
1456                    throws PortalException, SystemException {
1457    
1458                    List<Group> userGroupGroups = new ArrayList<Group>();
1459    
1460                    for (int i = 0; i < userGroups.size(); i++) {
1461                            UserGroup userGroup = userGroups.get(i);
1462    
1463                            Group group = userGroup.getGroup();
1464    
1465                            userGroupGroups.add(group);
1466                    }
1467    
1468                    return userGroupGroups;
1469            }
1470    
1471            /**
1472             * Returns all the groups related to the user groups.
1473             *
1474             * @param  userGroups the user groups
1475             * @return the groups related to the user groups
1476             * @throws SystemException if a system exception occurred
1477             */
1478            public List<Group> getUserGroupsRelatedGroups(List<UserGroup> userGroups)
1479                    throws SystemException {
1480    
1481                    List<Group> userGroupGroups = new ArrayList<Group>();
1482    
1483                    for (int i = 0; i < userGroups.size(); i++) {
1484                            UserGroup userGroup = userGroups.get(i);
1485    
1486                            List<Group> groups = userGroupPersistence.getGroups(
1487                                    userGroup.getUserGroupId());
1488    
1489                            userGroupGroups.addAll(groups);
1490                    }
1491    
1492                    return userGroupGroups;
1493            }
1494    
1495            /**
1496             * Returns the range of all groups associated with the user's organization
1497             * groups, including the ancestors of the organization groups, unless portal
1498             * property <code>organizations.membership.strict</code> is set to
1499             * <code>true</code>.
1500             *
1501             * <p>
1502             * Useful when paginating results. Returns a maximum of <code>end -
1503             * start</code> instances. <code>start</code> and <code>end</code> are not
1504             * primary keys, they are indexes in the result set. Thus, <code>0</code>
1505             * refers to the first result in the set. Setting both <code>start</code>
1506             * and <code>end</code> to {@link
1507             * com.liferay.portal.kernel.dao.orm.QueryUtil#ALL_POS} will return the full
1508             * result set.
1509             * </p>
1510             *
1511             * @param  userId the primary key of the user
1512             * @param  start the lower bound of the range of groups to consider
1513             * @param  end the upper bound of the range of groups to consider (not
1514             *         inclusive)
1515             * @return the range of groups associated with the user's organization
1516             *         groups
1517             * @throws PortalException if a user with the primary key could not be found
1518             *         or if another portal exception occurred
1519             * @throws SystemException if a system exception occurred
1520             */
1521            public List<Group> getUserOrganizationsGroups(
1522                            long userId, int start, int end)
1523                    throws PortalException, SystemException {
1524    
1525                    List<Group> userOrgsGroups = new UniqueList<Group>();
1526    
1527                    List<Organization> userOrgs =
1528                            organizationLocalService.getUserOrganizations(userId, start, end);
1529    
1530                    for (Organization organization : userOrgs) {
1531                            userOrgsGroups.add(0, organization.getGroup());
1532    
1533                            if (!PropsValues.ORGANIZATIONS_MEMBERSHIP_STRICT) {
1534                                    for (Organization ancestorOrganization :
1535                                                    organization.getAncestors()) {
1536    
1537                                            userOrgsGroups.add(0, ancestorOrganization.getGroup());
1538                                    }
1539                            }
1540                    }
1541    
1542                    return userOrgsGroups;
1543            }
1544    
1545            /**
1546             * Returns <code>true</code> if the group is associated with the role.
1547             *
1548             * @param  roleId the primary key of the role
1549             * @param  groupId the primary key of the group
1550             * @return <code>true</code> if the group is associated with the role;
1551             *         <code>false</code> otherwise
1552             * @throws SystemException if a system exception occurred
1553             */
1554            public boolean hasRoleGroup(long roleId, long groupId)
1555                    throws SystemException {
1556    
1557                    return rolePersistence.containsGroup(roleId, groupId);
1558            }
1559    
1560            /**
1561             * Returns <code>true</code> if the live group has a staging group.
1562             *
1563             * @param  liveGroupId the primary key of the live group
1564             * @return <code>true</code> if the live group has a staging group;
1565             *         <code>false</code> otherwise
1566             * @throws SystemException if a system exception occurred
1567             */
1568            public boolean hasStagingGroup(long liveGroupId) throws SystemException {
1569                    if (groupPersistence.fetchByLiveGroupId(liveGroupId) != null) {
1570                            return true;
1571                    }
1572                    else {
1573                            return false;
1574                    }
1575            }
1576    
1577            /**
1578             * Returns <code>true</code> if the user is immediately associated with the
1579             * group, or associated with the group via the user's organizations,
1580             * inherited organizations, or user groups.
1581             *
1582             * @param  userId the primary key of the user
1583             * @param  groupId the primary key of the group
1584             * @return <code>true</code> if the user is associated with the group;
1585             *         <code>false</code> otherwise
1586             * @throws SystemException if a system exception occurred
1587             */
1588            public boolean hasUserGroup(long userId, long groupId)
1589                    throws SystemException {
1590    
1591                    return hasUserGroup(userId, groupId, true);
1592            }
1593    
1594            /**
1595             * Returns <code>true</code> if the user is immediately associated with the
1596             * group, or optionally if the user is associated with the group via the
1597             * user's organizations, inherited organizations, or user groups.
1598             *
1599             * @param  userId the primary key of the user
1600             * @param  groupId the primary key of the group
1601             * @param  inherit whether to include organization groups and user groups to
1602             *         which the user belongs in the determination
1603             * @return <code>true</code> if the user is associated with the group;
1604             *         <code>false</code> otherwise
1605             * @throws SystemException if a system exception occurred
1606             */
1607            public boolean hasUserGroup(long userId, long groupId, boolean inherit)
1608                    throws SystemException {
1609    
1610                    if (groupFinder.countByG_U(groupId, userId, inherit) > 0) {
1611                            return true;
1612                    }
1613                    else {
1614                            return false;
1615                    }
1616            }
1617    
1618            /**
1619             * Returns the group with the matching group name by first searching the
1620             * system groups and then using the finder cache.
1621             *
1622             * @param  companyId the primary key of the company
1623             * @param  name the group's name
1624             * @return the group with the name and associated company, or
1625             *         <code>null</code> if a matching group could not be found
1626             * @throws SystemException if a system exception occurred
1627             */
1628            public Group loadFetchGroup(long companyId, String name)
1629                    throws SystemException {
1630    
1631                    return groupPersistence.fetchByC_N(companyId, name);
1632            }
1633    
1634            /**
1635             * Returns the group with the matching group name.
1636             *
1637             * @param  companyId the primary key of the company
1638             * @param  name the group's name
1639             * @return the group with the name and associated company
1640             * @throws PortalException if a matching group could not be found
1641             * @throws SystemException if a system exception occurred
1642             */
1643            public Group loadGetGroup(long companyId, String name)
1644                    throws PortalException, SystemException {
1645    
1646                    return groupPersistence.findByC_N(companyId, name);
1647            }
1648    
1649            /**
1650             * Returns an ordered range of all the company's groups, optionally
1651             * including the user's inherited organization groups and user groups.
1652             * System and staged groups are not included.
1653             *
1654             * <p>
1655             * Useful when paginating results. Returns a maximum of <code>end -
1656             * start</code> instances. <code>start</code> and <code>end</code> are not
1657             * primary keys, they are indexes in the result set. Thus, <code>0</code>
1658             * refers to the first result in the set. Setting both <code>start</code>
1659             * and <code>end</code> to {@link
1660             * com.liferay.portal.kernel.dao.orm.QueryUtil#ALL_POS} will return the full
1661             * result set.
1662             * </p>
1663             *
1664             * @param  companyId the primary key of the company
1665             * @param  params the finder params (optionally <code>null</code>). To
1666             *         include a user's organizations, inherited organizations, and user
1667             *         groups in the search, add an entry with key
1668             *         &quot;usersGroups&quot; mapped to the user's ID and an entry with
1669             *         key &quot;inherit&quot; mapped to a non-<code>null</code> object.
1670             *         For more information see {@link
1671             *         com.liferay.portal.service.persistence.GroupFinder}
1672             * @param  start the lower bound of the range of groups to return
1673             * @param  end the upper bound of the range of groups to return (not
1674             *         inclusive)
1675             * @return the matching groups ordered by name
1676             * @throws SystemException if a system exception occurred
1677             */
1678            public List<Group> search(
1679                            long companyId, LinkedHashMap<String, Object> params, int start,
1680                            int end)
1681                    throws SystemException {
1682    
1683                    return groupFinder.findByCompanyId(
1684                            companyId, params, start, end, new GroupNameComparator(true));
1685            }
1686    
1687            /**
1688             * Returns an ordered range of all the groups belonging to the parent group
1689             * that match the keywords, optionally including the user's inherited
1690             * organization groups and user groups. System and staged groups are not
1691             * included.
1692             *
1693             * <p>
1694             * Useful when paginating results. Returns a maximum of <code>end -
1695             * start</code> instances. <code>start</code> and <code>end</code> are not
1696             * primary keys, they are indexes in the result set. Thus, <code>0</code>
1697             * refers to the first result in the set. Setting both <code>start</code>
1698             * and <code>end</code> to {@link
1699             * com.liferay.portal.kernel.dao.orm.QueryUtil#ALL_POS} will return the full
1700             * result set.
1701             * </p>
1702             *
1703             * @param  companyId the primary key of the company
1704             * @param  parentGroupId the primary key of the parent group
1705             * @param  keywords the keywords (space separated), which may occur in the
1706             *         sites's name, or description (optionally <code>null</code>)
1707             * @param  params the finder params (optionally <code>null</code>). To
1708             *         include the user's inherited organizations and user groups in the
1709             *         search, add entries having &quot;usersGroups&quot; and
1710             *         &quot;inherit&quot; as keys mapped to the the user's ID. For more
1711             *         information see {@link
1712             *         com.liferay.portal.service.persistence.GroupFinder}
1713             * @param  start the lower bound of the range of groups to return
1714             * @param  end the upper bound of the range of groups to return (not
1715             *         inclusive)
1716             * @return the matching groups ordered by name
1717             * @throws SystemException if a system exception occurred
1718             */
1719            public List<Group> search(
1720                            long companyId, long parentGroupId, String keywords,
1721                            LinkedHashMap<String, Object> params, int start, int end)
1722                    throws SystemException {
1723    
1724                    return search(
1725                            companyId, parentGroupId, keywords, params, start, end, null);
1726            }
1727    
1728            /**
1729             * Returns an ordered range of all the groups belonging to the parent group
1730             * that match the keywords, optionally including the user's inherited
1731             * organization groups and user groups. System and staged groups are not
1732             * included.
1733             *
1734             * <p>
1735             * Useful when paginating results. Returns a maximum of <code>end -
1736             * start</code> instances. <code>start</code> and <code>end</code> are not
1737             * primary keys, they are indexes in the result set. Thus, <code>0</code>
1738             * refers to the first result in the set. Setting both <code>start</code>
1739             * and <code>end</code> to {@link
1740             * com.liferay.portal.kernel.dao.orm.QueryUtil#ALL_POS} will return the full
1741             * result set.
1742             * </p>
1743             *
1744             * @param  companyId the primary key of the company
1745             * @param  parentGroupId the primary key of the parent group
1746             * @param  keywords the keywords (space separated), which may occur in the
1747             *         sites's name, or description (optionally <code>null</code>)
1748             * @param  params the finder params (optionally <code>null</code>). To
1749             *         include the user's inherited organizations and user groups in the
1750             *         search, add entries having &quot;usersGroups&quot; and
1751             *         &quot;inherit&quot; as keys mapped to the the user's ID. For more
1752             *         information see {@link
1753             *         com.liferay.portal.service.persistence.GroupFinder}
1754             * @param  start the lower bound of the range of groups to return
1755             * @param  end the upper bound of the range of groups to return (not
1756             *         inclusive)
1757             * @param  obc the comparator to order the groups (optionally
1758             *         <code>null</code>)
1759             * @return the matching groups ordered by comparator <code>obc</code>
1760             * @throws SystemException if a system exception occurred
1761             */
1762            public List<Group> search(
1763                            long companyId, long parentGroupId, String keywords,
1764                            LinkedHashMap<String, Object> params, int start, int end,
1765                            OrderByComparator obc)
1766                    throws SystemException {
1767    
1768                    String parentGroupIdComparator = StringPool.EQUAL;
1769    
1770                    if (parentGroupId == GroupConstants.ANY_PARENT_GROUP_ID) {
1771                            parentGroupIdComparator = StringPool.NOT_EQUAL;
1772                    }
1773    
1774                    if (obc == null) {
1775                            obc = new GroupNameComparator(true);
1776                    }
1777    
1778                    return groupFinder.findByKeywords(
1779                            companyId, parentGroupId, parentGroupIdComparator, keywords, params,
1780                            start, end, obc);
1781            }
1782    
1783            /**
1784             * Returns an ordered range of all the site groups belonging to the parent
1785             * group and organization groups that match the name and description,
1786             * optionally including the user's inherited organization groups and user
1787             * groups. System and staged groups are not included.
1788             *
1789             * <p>
1790             * Useful when paginating results. Returns a maximum of <code>end -
1791             * start</code> instances. <code>start</code> and <code>end</code> are not
1792             * primary keys, they are indexes in the result set. Thus, <code>0</code>
1793             * refers to the first result in the set. Setting both <code>start</code>
1794             * and <code>end</code> to {@link
1795             * com.liferay.portal.kernel.dao.orm.QueryUtil#ALL_POS} will return the full
1796             * result set.
1797             * </p>
1798             *
1799             * @param  companyId the primary key of the company
1800             * @param  parentGroupId the primary key of the parent group
1801             * @param  name the group's name (optionally <code>null</code>)
1802             * @param  description the group's description (optionally
1803             *         <code>null</code>)
1804             * @param  params the finder params (optionally <code>null</code>). To
1805             *         include the user's inherited organizations and user groups in the
1806             *         search, add entries having &quot;usersGroups&quot; and
1807             *         &quot;inherit&quot; as keys mapped to the the user's ID. For more
1808             *         information see {@link
1809             *         com.liferay.portal.service.persistence.GroupFinder}
1810             * @param  andOperator whether every field must match its keywords, or just
1811             *         one field.
1812             * @param  start the lower bound of the range of groups to return
1813             * @param  end the upper bound of the range of groups to return (not
1814             *         inclusive)
1815             * @return the matching groups ordered by name
1816             * @throws SystemException if a system exception occurred
1817             */
1818            public List<Group> search(
1819                            long companyId, long parentGroupId, String name, String description,
1820                            LinkedHashMap<String, Object> params, boolean andOperator,
1821                            int start, int end)
1822                    throws SystemException {
1823    
1824                    return search(
1825                            companyId, parentGroupId, name, description, params, andOperator,
1826                            start, end, null);
1827            }
1828    
1829            /**
1830             * Returns an ordered range of all the site groups belonging to the parent
1831             * group and organization groups that match the name and description,
1832             * optionally including the user's inherited organization groups and user
1833             * groups. System and staged groups are not included.
1834             *
1835             * <p>
1836             * Useful when paginating results. Returns a maximum of <code>end -
1837             * start</code> instances. <code>start</code> and <code>end</code> are not
1838             * primary keys, they are indexes in the result set. Thus, <code>0</code>
1839             * refers to the first result in the set. Setting both <code>start</code>
1840             * and <code>end</code> to {@link
1841             * com.liferay.portal.kernel.dao.orm.QueryUtil#ALL_POS} will return the full
1842             * result set.
1843             * </p>
1844             *
1845             * @param  companyId the primary key of the company
1846             * @param  parentGroupId the primary key of the parent group
1847             * @param  name the group's name (optionally <code>null</code>)
1848             * @param  description the group's description (optionally
1849             *         <code>null</code>)
1850             * @param  params the finder params (optionally <code>null</code>). To
1851             *         include the user's inherited organizations and user groups in the
1852             *         search, add entries having &quot;usersGroups&quot; and
1853             *         &quot;inherit&quot; as keys mapped to the the user's ID. For more
1854             *         information see {@link
1855             *         com.liferay.portal.service.persistence.GroupFinder}
1856             * @param  andOperator whether every field must match its keywords, or just
1857             *         one field.
1858             * @param  start the lower bound of the range of groups to return
1859             * @param  end the upper bound of the range of groups to return (not
1860             *         inclusive)
1861             * @param  obc the comparator to order the groups (optionally
1862             *         <code>null</code>)
1863             * @return the matching groups ordered by comparator <code>obc</code>
1864             * @throws SystemException if a system exception occurred
1865             */
1866            public List<Group> search(
1867                            long companyId, long parentGroupId, String name, String description,
1868                            LinkedHashMap<String, Object> params, boolean andOperator,
1869                            int start, int end, OrderByComparator obc)
1870                    throws SystemException {
1871    
1872                    String parentGroupIdComparator = StringPool.EQUAL;
1873    
1874                    if (parentGroupId == GroupConstants.ANY_PARENT_GROUP_ID) {
1875                            parentGroupIdComparator = StringPool.NOT_EQUAL;
1876                    }
1877    
1878                    if (obc == null) {
1879                            obc = new GroupNameComparator(true);
1880                    }
1881    
1882                    String realName = getRealName(companyId, name);
1883    
1884                    return groupFinder.findByC_PG_N_D(
1885                            companyId, parentGroupId, parentGroupIdComparator, name, realName,
1886                            description, params, andOperator, start, end, obc);
1887            }
1888    
1889            /**
1890             * Returns an ordered range of all the groups belonging to the parent group
1891             * that match the class name IDs and keywords, optionally including the
1892             * user's inherited organization groups and user groups. System and staged
1893             * groups are not included.
1894             *
1895             * <p>
1896             * Useful when paginating results. Returns a maximum of <code>end -
1897             * start</code> instances. <code>start</code> and <code>end</code> are not
1898             * primary keys, they are indexes in the result set. Thus, <code>0</code>
1899             * refers to the first result in the set. Setting both <code>start</code>
1900             * and <code>end</code> to {@link
1901             * com.liferay.portal.kernel.dao.orm.QueryUtil#ALL_POS} will return the full
1902             * result set.
1903             * </p>
1904             *
1905             * @param  companyId the primary key of the company
1906             * @param  classNameIds the class names of entities to include in the search
1907             *         (optionally <code>null</code>)
1908             * @param  parentGroupId the primary key of the parent group
1909             * @param  keywords the keywords (space separated), which may occur in the
1910             *         sites's name, or description (optionally <code>null</code>)
1911             * @param  params the finder params (optionally <code>null</code>). To
1912             *         include a user's organizations, inherited organizations, and user
1913             *         groups in the search, add an entry with key
1914             *         &quot;usersGroups&quot; mapped to the user's ID and an entry with
1915             *         key &quot;inherit&quot; mapped to a non-<code>null</code> object.
1916             *         For more information see {@link
1917             *         com.liferay.portal.service.persistence.GroupFinder}
1918             * @param  start the lower bound of the range of groups to return
1919             * @param  end the upper bound of the range of groups to return (not
1920             *         inclusive)
1921             * @return the matching groups ordered by name
1922             * @throws SystemException if a system exception occurred
1923             */
1924            public List<Group> search(
1925                            long companyId, long[] classNameIds, long parentGroupId,
1926                            String keywords, LinkedHashMap<String, Object> params, int start,
1927                            int end)
1928                    throws SystemException {
1929    
1930                    return search(
1931                            companyId, classNameIds, parentGroupId, keywords, params, start,
1932                            end, null);
1933            }
1934    
1935            /**
1936             * Returns an ordered range of all the groups belonging to the parent group
1937             * that match the class name IDs and keywords, optionally including the
1938             * user's inherited organization groups and user groups. System and staged
1939             * groups are not included.
1940             *
1941             * <p>
1942             * Useful when paginating results. Returns a maximum of <code>end -
1943             * start</code> instances. <code>start</code> and <code>end</code> are not
1944             * primary keys, they are indexes in the result set. Thus, <code>0</code>
1945             * refers to the first result in the set. Setting both <code>start</code>
1946             * and <code>end</code> to {@link
1947             * com.liferay.portal.kernel.dao.orm.QueryUtil#ALL_POS} will return the full
1948             * result set.
1949             * </p>
1950             *
1951             * @param  companyId the primary key of the company
1952             * @param  classNameIds the group's class name IDs (optionally
1953             *         <code>null</code>)
1954             * @param  parentGroupId the primary key of the parent group
1955             * @param  keywords the keywords (space separated), which may occur in the
1956             *         sites's name, or description (optionally <code>null</code>)
1957             * @param  params the finder params (optionally <code>null</code>). To
1958             *         include a user's organizations, inherited organizations, and user
1959             *         groups in the search, add an entry with key
1960             *         &quot;usersGroups&quot; mapped to the user's ID and an entry with
1961             *         key &quot;inherit&quot; mapped to a non-<code>null</code> object.
1962             *         For more information see {@link
1963             *         com.liferay.portal.service.persistence.GroupFinder}
1964             * @param  start the lower bound of the range of groups to return
1965             * @param  end the upper bound of the range of groups to return (not
1966             *         inclusive)
1967             * @param  obc the comparator to order the groups (optionally
1968             *         <code>null</code>)
1969             * @return the matching groups ordered by comparator <code>obc</code>
1970             * @throws SystemException if a system exception occurred
1971             */
1972            public List<Group> search(
1973                            long companyId, long[] classNameIds, long parentGroupId,
1974                            String keywords, LinkedHashMap<String, Object> params, int start,
1975                            int end, OrderByComparator obc)
1976                    throws SystemException {
1977    
1978                    String parentGroupIdComparator = StringPool.EQUAL;
1979    
1980                    if (parentGroupId == GroupConstants.ANY_PARENT_GROUP_ID) {
1981                            parentGroupIdComparator = StringPool.NOT_EQUAL;
1982                    }
1983    
1984                    if (obc == null) {
1985                            obc = new GroupNameComparator(true);
1986                    }
1987    
1988                    return groupFinder.findByKeywords(
1989                            companyId, classNameIds, parentGroupId, parentGroupIdComparator,
1990                            keywords, params, start, end, obc);
1991            }
1992    
1993            /**
1994             * Returns an ordered range of all the groups belonging to the parent group
1995             * that match the class name IDs, name, and description, optionally
1996             * including the user's inherited organization groups and user groups.
1997             * System and staged groups are not included.
1998             *
1999             * <p>
2000             * Useful when paginating results. Returns a maximum of <code>end -
2001             * start</code> instances. <code>start</code> and <code>end</code> are not
2002             * primary keys, they are indexes in the result set. Thus, <code>0</code>
2003             * refers to the first result in the set. Setting both <code>start</code>
2004             * and <code>end</code> to {@link
2005             * com.liferay.portal.kernel.dao.orm.QueryUtil#ALL_POS} will return the full
2006             * result set.
2007             * </p>
2008             *
2009             * @param  companyId the primary key of the company
2010             * @param  classNameIds the class names of entities to include in the search
2011             *         (optionally <code>null</code>)
2012             * @param  parentGroupId the primary key of the parent group
2013             * @param  name the group's name (optionally <code>null</code>)
2014             * @param  description the group's description (optionally
2015             *         <code>null</code>)
2016             * @param  params the finder params (optionally <code>null</code>). To
2017             *         include a user's organizations, inherited organizations, and user
2018             *         groups in the search, add an entry with key
2019             *         &quot;usersGroups&quot; mapped to the user's ID and an entry with
2020             *         key &quot;inherit&quot; mapped to a non-<code>null</code> object.
2021             *         For more information see {@link
2022             *         com.liferay.portal.service.persistence.GroupFinder}
2023             * @param  andOperator whether every field must match its keywords, or just
2024             *         one field.
2025             * @param  start the lower bound of the range of groups to return
2026             * @param  end the upper bound of the range of groups to return (not
2027             *         inclusive)
2028             * @return the matching groups ordered by name
2029             * @throws SystemException if a system exception occurred
2030             */
2031            public List<Group> search(
2032                            long companyId, long[] classNameIds, long parentGroupId,
2033                            String name, String description,
2034                            LinkedHashMap<String, Object> params, boolean andOperator,
2035                            int start, int end)
2036                    throws SystemException {
2037    
2038                    return search(
2039                            companyId, classNameIds, parentGroupId, name, description, params,
2040                            andOperator, start, end, null);
2041            }
2042    
2043            /**
2044             * Returns an ordered range of all the groups belonging to the parent group
2045             * that match the class name IDs, name, and description, optionally
2046             * including the user's inherited organization groups and user groups.
2047             * System and staged groups are not included.
2048             *
2049             * <p>
2050             * Useful when paginating results. Returns a maximum of <code>end -
2051             * start</code> instances. <code>start</code> and <code>end</code> are not
2052             * primary keys, they are indexes in the result set. Thus, <code>0</code>
2053             * refers to the first result in the set. Setting both <code>start</code>
2054             * and <code>end</code> to {@link
2055             * com.liferay.portal.kernel.dao.orm.QueryUtil#ALL_POS} will return the full
2056             * result set.
2057             * </p>
2058             *
2059             * @param  companyId the primary key of the company
2060             * @param  classNameIds the group's class name IDs (optionally
2061             *         <code>null</code>)
2062             * @param  parentGroupId the primary key of the parent group
2063             * @param  name the group's name (optionally <code>null</code>)
2064             * @param  description the group's description (optionally
2065             *         <code>null</code>)
2066             * @param  params the finder params (optionally <code>null</code>). To
2067             *         include a user's organizations, inherited organizations, and user
2068             *         groups in the search, add an entry with key
2069             *         &quot;usersGroups&quot; mapped to the user's ID and an entry with
2070             *         key &quot;inherit&quot; mapped to a non-<code>null</code> object.
2071             *         For more information see {@link
2072             *         com.liferay.portal.service.persistence.GroupFinder}
2073             * @param  andOperator whether every field must match its keywords, or just
2074             *         one field.
2075             * @param  start the lower bound of the range of groups to return
2076             * @param  end the upper bound of the range of groups to return (not
2077             *         inclusive)
2078             * @param  obc the comparator to order the groups (optionally
2079             *         <code>null</code>)
2080             * @return the matching groups ordered by comparator <code>obc</code>
2081             * @throws SystemException if a system exception occurred
2082             */
2083            public List<Group> search(
2084                            long companyId, long[] classNameIds, long parentGroupId,
2085                            String name, String description,
2086                            LinkedHashMap<String, Object> params, boolean andOperator,
2087                            int start, int end, OrderByComparator obc)
2088                    throws SystemException {
2089    
2090                    String parentGroupIdComparator = StringPool.EQUAL;
2091    
2092                    if (parentGroupId == GroupConstants.ANY_PARENT_GROUP_ID) {
2093                            parentGroupIdComparator = StringPool.NOT_EQUAL;
2094                    }
2095    
2096                    if (obc == null) {
2097                            obc = new GroupNameComparator(true);
2098                    }
2099    
2100                    String realName = getRealName(companyId, name);
2101    
2102                    return groupFinder.findByC_C_PG_N_D(
2103                            companyId, classNameIds, parentGroupId, parentGroupIdComparator,
2104                            name, realName, description, params, andOperator, start, end, obc);
2105            }
2106    
2107            /**
2108             * Returns an ordered range of all the groups that match the class name IDs
2109             * and keywords, optionally including the user's inherited organization
2110             * groups and user groups. System and staged groups are not included.
2111             *
2112             * <p>
2113             * Useful when paginating results. Returns a maximum of <code>end -
2114             * start</code> instances. <code>start</code> and <code>end</code> are not
2115             * primary keys, they are indexes in the result set. Thus, <code>0</code>
2116             * refers to the first result in the set. Setting both <code>start</code>
2117             * and <code>end</code> to {@link
2118             * com.liferay.portal.kernel.dao.orm.QueryUtil#ALL_POS} will return the full
2119             * result set.
2120             * </p>
2121             *
2122             * @param  companyId the primary key of the company
2123             * @param  classNameIds the class names of entities to include in the search
2124             *         (optionally <code>null</code>)
2125             * @param  keywords the keywords (space separated), which may occur in the
2126             *         sites's name, or description (optionally <code>null</code>)
2127             * @param  params the finder params (optionally <code>null</code>). To
2128             *         include a user's organizations, inherited organizations, and user
2129             *         groups in the search, add an entry with key
2130             *         &quot;usersGroups&quot; mapped to the user's ID and an entry with
2131             *         key &quot;inherit&quot; mapped to a non-<code>null</code> object.
2132             *         For more information see {@link
2133             *         com.liferay.portal.service.persistence.GroupFinder}
2134             * @param  start the lower bound of the range of groups to return
2135             * @param  end the upper bound of the range of groups to return (not
2136             *         inclusive)
2137             * @return the matching groups ordered by name
2138             * @throws SystemException if a system exception occurred
2139             */
2140            public List<Group> search(
2141                            long companyId, long[] classNameIds, String keywords,
2142                            LinkedHashMap<String, Object> params, int start, int end)
2143                    throws SystemException {
2144    
2145                    return search(
2146                            companyId, classNameIds, keywords, params, start, end, null);
2147            }
2148    
2149            /**
2150             * Returns an ordered range of all the groups that match the class name IDs
2151             * and keywords, optionally including the user's inherited organization
2152             * groups and user groups. System and staged groups are not included.
2153             *
2154             * <p>
2155             * Useful when paginating results. Returns a maximum of <code>end -
2156             * start</code> instances. <code>start</code> and <code>end</code> are not
2157             * primary keys, they are indexes in the result set. Thus, <code>0</code>
2158             * refers to the first result in the set. Setting both <code>start</code>
2159             * and <code>end</code> to {@link
2160             * com.liferay.portal.kernel.dao.orm.QueryUtil#ALL_POS} will return the full
2161             * result set.
2162             * </p>
2163             *
2164             * @param  companyId the primary key of the company
2165             * @param  classNameIds the group's class name IDs (optionally
2166             *         <code>null</code>)
2167             * @param  keywords the keywords (space separated), which may occur in the
2168             *         sites's name, or description (optionally <code>null</code>)
2169             * @param  params the finder params (optionally <code>null</code>). To
2170             *         include a user's organizations, inherited organizations, and user
2171             *         groups in the search, add an entry with key
2172             *         &quot;usersGroups&quot; mapped to the user's ID and an entry with
2173             *         key &quot;inherit&quot; mapped to a non-<code>null</code> object.
2174             *         For more information see {@link
2175             *         com.liferay.portal.service.persistence.GroupFinder}
2176             * @param  start the lower bound of the range of groups to return
2177             * @param  end the upper bound of the range of groups to return (not
2178             *         inclusive)
2179             * @param  obc the comparator to order the groups (optionally
2180             *         <code>null</code>)
2181             * @return the matching groups ordered by comparator <code>obc</code>
2182             * @throws SystemException if a system exception occurred
2183             */
2184            public List<Group> search(
2185                            long companyId, long[] classNameIds, String keywords,
2186                            LinkedHashMap<String, Object> params, int start, int end,
2187                            OrderByComparator obc)
2188                    throws SystemException {
2189    
2190                    if (obc == null) {
2191                            obc = new GroupNameComparator(true);
2192                    }
2193    
2194                    return groupFinder.findByKeywords(
2195                            companyId, classNameIds, keywords, params, start, end, obc);
2196            }
2197    
2198            /**
2199             * Returns an ordered range of all the groups that match the class name IDs,
2200             * name, and description, optionally including the user's inherited
2201             * organization groups and user groups. System and staged groups are not
2202             * included.
2203             *
2204             * <p>
2205             * Useful when paginating results. Returns a maximum of <code>end -
2206             * start</code> instances. <code>start</code> and <code>end</code> are not
2207             * primary keys, they are indexes in the result set. Thus, <code>0</code>
2208             * refers to the first result in the set. Setting both <code>start</code>
2209             * and <code>end</code> to {@link
2210             * com.liferay.portal.kernel.dao.orm.QueryUtil#ALL_POS} will return the full
2211             * result set.
2212             * </p>
2213             *
2214             * @param  companyId the primary key of the company
2215             * @param  classNameIds the class names of entities to include in the search
2216             *         (optionally <code>null</code>)
2217             * @param  name the group's name (optionally <code>null</code>)
2218             * @param  description the group's description (optionally
2219             *         <code>null</code>)
2220             * @param  params the finder params (optionally <code>null</code>). To
2221             *         include a user's organizations, inherited organizations, and user
2222             *         groups in the search, add an entry with key
2223             *         &quot;usersGroups&quot; mapped to the user's ID and an entry with
2224             *         key &quot;inherit&quot; mapped to a non-<code>null</code> object.
2225             *         For more information see {@link
2226             *         com.liferay.portal.service.persistence.GroupFinder}
2227             * @param  andOperator whether every field must match its keywords, or just
2228             *         one field.
2229             * @param  start the lower bound of the range of groups to return
2230             * @param  end the upper bound of the range of groups to return (not
2231             *         inclusive)
2232             * @return the matching groups ordered by name
2233             * @throws SystemException if a system exception occurred
2234             */
2235            public List<Group> search(
2236                            long companyId, long[] classNameIds, String name,
2237                            String description, LinkedHashMap<String, Object> params,
2238                            boolean andOperator, int start, int end)
2239                    throws SystemException {
2240    
2241                    return search(
2242                            companyId, classNameIds, name, description, params, andOperator,
2243                            start, end, null);
2244            }
2245    
2246            /**
2247             * Returns an ordered range of all the groups that match the class name IDs,
2248             * name, and description, optionally including the user's inherited
2249             * organization groups and user groups. System and staged groups are not
2250             * included.
2251             *
2252             * <p>
2253             * Useful when paginating results. Returns a maximum of <code>end -
2254             * start</code> instances. <code>start</code> and <code>end</code> are not
2255             * primary keys, they are indexes in the result set. Thus, <code>0</code>
2256             * refers to the first result in the set. Setting both <code>start</code>
2257             * and <code>end</code> to {@link
2258             * com.liferay.portal.kernel.dao.orm.QueryUtil#ALL_POS} will return the full
2259             * result set.
2260             * </p>
2261             *
2262             * @param  companyId the primary key of the company
2263             * @param  classNameIds the group's class name IDs (optionally
2264             *         <code>null</code>)
2265             * @param  name the group's name (optionally <code>null</code>)
2266             * @param  description the group's description (optionally
2267             *         <code>null</code>)
2268             * @param  params the finder params (optionally <code>null</code>). To
2269             *         include a user's organizations, inherited organizations, and user
2270             *         groups in the search, add an entry with key
2271             *         &quot;usersGroups&quot; mapped to the user's ID and an entry with
2272             *         key &quot;inherit&quot; mapped to a non-<code>null</code> object.
2273             *         For more information see {@link
2274             *         com.liferay.portal.service.persistence.GroupFinder}
2275             * @param  andOperator whether every field must match its keywords, or just
2276             *         one field.
2277             * @param  start the lower bound of the range of groups to return
2278             * @param  end the upper bound of the range of groups to return (not
2279             *         inclusive)
2280             * @param  obc the comparator to order the groups (optionally
2281             *         <code>null</code>)
2282             * @return the matching groups ordered by comparator <code>obc</code>
2283             * @throws SystemException if a system exception occurred
2284             */
2285            public List<Group> search(
2286                            long companyId, long[] classNameIds, String name,
2287                            String description, LinkedHashMap<String, Object> params,
2288                            boolean andOperator, int start, int end, OrderByComparator obc)
2289                    throws SystemException {
2290    
2291                    if (obc == null) {
2292                            obc = new GroupNameComparator(true);
2293                    }
2294    
2295                    String realName = getRealName(companyId, name);
2296    
2297                    return groupFinder.findByC_C_N_D(
2298                            companyId, classNameIds, name, realName, description, params,
2299                            andOperator, start, end, obc);
2300            }
2301    
2302            /**
2303             * Returns an ordered range of all the groups that match the keywords,
2304             * optionally including the user's inherited organization groups and user
2305             * groups. System and staged groups are not included.
2306             *
2307             * <p>
2308             * Useful when paginating results. Returns a maximum of <code>end -
2309             * start</code> instances. <code>start</code> and <code>end</code> are not
2310             * primary keys, they are indexes in the result set. Thus, <code>0</code>
2311             * refers to the first result in the set. Setting both <code>start</code>
2312             * and <code>end</code> to {@link
2313             * com.liferay.portal.kernel.dao.orm.QueryUtil#ALL_POS} will return the full
2314             * result set.
2315             * </p>
2316             *
2317             * @param  companyId the primary key of the company
2318             * @param  keywords the keywords (space separated), which may occur in the
2319             *         sites's name, or description (optionally <code>null</code>)
2320             * @param  params the finder params (optionally <code>null</code>). To
2321             *         include the user's inherited organizations and user groups in the
2322             *         search, add entries having &quot;usersGroups&quot; and
2323             *         &quot;inherit&quot; as keys mapped to the the user's ID. For more
2324             *         information see {@link
2325             *         com.liferay.portal.service.persistence.GroupFinder}
2326             * @param  start the lower bound of the range of groups to return
2327             * @param  end the upper bound of the range of groups to return (not
2328             *         inclusive)
2329             * @return the matching groups ordered by name
2330             * @throws SystemException if a system exception occurred
2331             */
2332            public List<Group> search(
2333                            long companyId, String keywords,
2334                            LinkedHashMap<String, Object> params, int start, int end)
2335                    throws SystemException {
2336    
2337                    return search(companyId, keywords, params, start, end, null);
2338            }
2339    
2340            /**
2341             * Returns an ordered range of all the groups that match the keywords,
2342             * optionally including the user's inherited organization groups and user
2343             * groups. System and staged groups are not included.
2344             *
2345             * <p>
2346             * Useful when paginating results. Returns a maximum of <code>end -
2347             * start</code> instances. <code>start</code> and <code>end</code> are not
2348             * primary keys, they are indexes in the result set. Thus, <code>0</code>
2349             * refers to the first result in the set. Setting both <code>start</code>
2350             * and <code>end</code> to {@link
2351             * com.liferay.portal.kernel.dao.orm.QueryUtil#ALL_POS} will return the full
2352             * result set.
2353             * </p>
2354             *
2355             * @param  companyId the primary key of the company
2356             * @param  keywords the keywords (space separated), which may occur in the
2357             *         sites's name, or description (optionally <code>null</code>)
2358             * @param  params the finder params (optionally <code>null</code>). To
2359             *         include the user's inherited organizations and user groups in the
2360             *         search, add entries having &quot;usersGroups&quot; and
2361             *         &quot;inherit&quot; as keys mapped to the the user's ID. For more
2362             *         information see {@link
2363             *         com.liferay.portal.service.persistence.GroupFinder}
2364             * @param  start the lower bound of the range of groups to return
2365             * @param  end the upper bound of the range of groups to return (not
2366             *         inclusive)
2367             * @param  obc the comparator to order the groups (optionally
2368             *         <code>null</code>)
2369             * @return the matching groups ordered by comparator <code>obc</code>
2370             * @throws SystemException if a system exception occurred
2371             */
2372            public List<Group> search(
2373                            long companyId, String keywords,
2374                            LinkedHashMap<String, Object> params, int start, int end,
2375                            OrderByComparator obc)
2376                    throws SystemException {
2377    
2378                    if (obc == null) {
2379                            obc = new GroupNameComparator(true);
2380                    }
2381    
2382                    return groupFinder.findByKeywords(
2383                            companyId, keywords, params, start, end, obc);
2384            }
2385    
2386            /**
2387             * Returns an ordered range of all the site groups and organization groups
2388             * that match the name and description, optionally including the user's
2389             * inherited organization groups and user groups. System and staged groups
2390             * are not included.
2391             *
2392             * <p>
2393             * Useful when paginating results. Returns a maximum of <code>end -
2394             * start</code> instances. <code>start</code> and <code>end</code> are not
2395             * primary keys, they are indexes in the result set. Thus, <code>0</code>
2396             * refers to the first result in the set. Setting both <code>start</code>
2397             * and <code>end</code> to {@link
2398             * com.liferay.portal.kernel.dao.orm.QueryUtil#ALL_POS} will return the full
2399             * result set.
2400             * </p>
2401             *
2402             * @param  companyId the primary key of the company
2403             * @param  name the group's name (optionally <code>null</code>)
2404             * @param  description the group's description (optionally
2405             *         <code>null</code>)
2406             * @param  params the finder params (optionally <code>null</code>). To
2407             *         include the user's inherited organizations and user groups in the
2408             *         search, add entries having &quot;usersGroups&quot; and
2409             *         &quot;inherit&quot; as keys mapped to the the user's ID. For more
2410             *         information see {@link
2411             *         com.liferay.portal.service.persistence.GroupFinder}
2412             * @param  andOperator whether every field must match its keywords, or just
2413             *         one field.
2414             * @param  start the lower bound of the range of groups to return
2415             * @param  end the upper bound of the range of groups to return (not
2416             *         inclusive)
2417             * @return the matching groups ordered by name
2418             * @throws SystemException if a system exception occurred
2419             */
2420            public List<Group> search(
2421                            long companyId, String name, String description,
2422                            LinkedHashMap<String, Object> params, boolean andOperator,
2423                            int start, int end)
2424                    throws SystemException {
2425    
2426                    return search(
2427                            companyId, name, description, params, andOperator, start, end,
2428                            null);
2429            }
2430    
2431            /**
2432             * Returns an ordered range of all the site groups and organization groups
2433             * that match the name and description, optionally including the user's
2434             * inherited organization groups and user groups. System and staged groups
2435             * are not included.
2436             *
2437             * <p>
2438             * Useful when paginating results. Returns a maximum of <code>end -
2439             * start</code> instances. <code>start</code> and <code>end</code> are not
2440             * primary keys, they are indexes in the result set. Thus, <code>0</code>
2441             * refers to the first result in the set. Setting both <code>start</code>
2442             * and <code>end</code> to {@link
2443             * com.liferay.portal.kernel.dao.orm.QueryUtil#ALL_POS} will return the full
2444             * result set.
2445             * </p>
2446             *
2447             * @param  companyId the primary key of the company
2448             * @param  name the group's name (optionally <code>null</code>)
2449             * @param  description the group's description (optionally
2450             *         <code>null</code>)
2451             * @param  params the finder params (optionally <code>null</code>). To
2452             *         include the user's inherited organizations and user groups in the
2453             *         search, add entries having &quot;usersGroups&quot; and
2454             *         &quot;inherit&quot; as keys mapped to the the user's ID. For more
2455             *         information see {@link
2456             *         com.liferay.portal.service.persistence.GroupFinder}
2457             * @param  andOperator whether every field must match its keywords, or just
2458             *         one field.
2459             * @param  start the lower bound of the range of groups to return
2460             * @param  end the upper bound of the range of groups to return (not
2461             *         inclusive)
2462             * @param  obc the comparator to order the groups (optionally
2463             *         <code>null</code>)
2464             * @return the matching groups ordered by comparator <code>obc</code>
2465             * @throws SystemException if a system exception occurred
2466             */
2467            public List<Group> search(
2468                            long companyId, String name, String description,
2469                            LinkedHashMap<String, Object> params, boolean andOperator,
2470                            int start, int end, OrderByComparator obc)
2471                    throws SystemException {
2472    
2473                    if (obc == null) {
2474                            obc = new GroupNameComparator(true);
2475                    }
2476    
2477                    String realName = getRealName(companyId, name);
2478    
2479                    return groupFinder.findByC_N_D(
2480                            companyId, name, realName, description, params, andOperator, start,
2481                            end, obc);
2482            }
2483    
2484            /**
2485             * Returns the number of groups belonging to the parent group that match the
2486             * keywords, optionally including the user's inherited organization groups
2487             * and user groups. System and staged groups are not included.
2488             *
2489             * @param  companyId the primary key of the company
2490             * @param  parentGroupId the primary key of the parent group
2491             * @param  keywords the keywords (space separated), which may occur in the
2492             *         sites's name, or description (optionally <code>null</code>)
2493             * @param  params the finder params (optionally <code>null</code>). To
2494             *         include the user's inherited organization groups and user groups
2495             *         in the search, add entries having &quot;usersGroups&quot; and
2496             *         &quot;inherit&quot; as keys mapped to the the user's ID. For more
2497             *         information see {@link
2498             *         com.liferay.portal.service.persistence.GroupFinder}
2499             * @return the number of matching groups
2500             * @throws SystemException if a system exception occurred
2501             */
2502            @ThreadLocalCachable
2503            public int searchCount(
2504                            long companyId, long parentGroupId, String keywords,
2505                            LinkedHashMap<String, Object> params)
2506                    throws SystemException {
2507    
2508                    String parentGroupIdComparator = StringPool.EQUAL;
2509    
2510                    if (parentGroupId == GroupConstants.ANY_PARENT_GROUP_ID) {
2511                            parentGroupIdComparator = StringPool.NOT_EQUAL;
2512                    }
2513    
2514                    return groupFinder.countByKeywords(
2515                            companyId, parentGroupId, parentGroupIdComparator, keywords,
2516                            params);
2517            }
2518    
2519            /**
2520             * Returns the number of groups belonging to the parent group and immediate
2521             * organization groups that match the name and description, optionally
2522             * including the user's inherited organization groups and user groups.
2523             * System and staged groups are not included.
2524             *
2525             * @param  companyId the primary key of the company
2526             * @param  parentGroupId the primary key of the parent group
2527             * @param  name the group's name (optionally <code>null</code>)
2528             * @param  description the group's description (optionally
2529             *         <code>null</code>)
2530             * @param  params the finder params (optionally <code>null</code>). To
2531             *         include the user's inherited organization groups and user groups
2532             *         in the search, add entries having &quot;usersGroups&quot; and
2533             *         &quot;inherit&quot; as keys mapped to the the user's ID. For more
2534             *         information see {@link
2535             *         com.liferay.portal.service.persistence.GroupFinder}
2536             * @param  andOperator whether every field must match its keywords, or just
2537             *         one field.
2538             * @return the number of matching groups
2539             * @throws SystemException if a system exception occurred
2540             */
2541            @ThreadLocalCachable
2542            public int searchCount(
2543                            long companyId, long parentGroupId, String name, String description,
2544                            LinkedHashMap<String, Object> params, boolean andOperator)
2545                    throws SystemException {
2546    
2547                    String parentGroupIdComparator = StringPool.EQUAL;
2548    
2549                    if (parentGroupId == GroupConstants.ANY_PARENT_GROUP_ID) {
2550                            parentGroupIdComparator = StringPool.NOT_EQUAL;
2551                    }
2552    
2553                    String realName = getRealName(companyId, name);
2554    
2555                    return groupFinder.countByC_PG_N_D(
2556                            companyId, parentGroupId, parentGroupIdComparator, name, realName,
2557                            description, params, andOperator);
2558            }
2559    
2560            /**
2561             * Returns the number of groups belonging to the parent group that match the
2562             * class name IDs, and keywords, optionally including the user's inherited
2563             * organization groups and user groups. System and staged groups are not
2564             * included.
2565             *
2566             * @param  companyId the primary key of the company
2567             * @param  classNameIds the class names of entities to include in the search
2568             *         (optionally <code>null</code>)
2569             * @param  parentGroupId the primary key of the parent group
2570             * @param  keywords the keywords (space separated), which may occur in the
2571             *         sites's name, or description (optionally <code>null</code>)
2572             * @param  params the finder params (optionally <code>null</code>). To
2573             *         include the user's inherited organization groups and user groups
2574             *         in the search, add entries having &quot;usersGroups&quot; and
2575             *         &quot;inherit&quot; as keys mapped to the the user's ID. For more
2576             *         information see {@link
2577             *         com.liferay.portal.service.persistence.GroupFinder}
2578             * @return the number of matching groups
2579             * @throws SystemException if a system exception occurred
2580             */
2581            @ThreadLocalCachable
2582            public int searchCount(
2583                            long companyId, long[] classNameIds, long parentGroupId,
2584                            String keywords, LinkedHashMap<String, Object> params)
2585                    throws SystemException {
2586    
2587                    String parentGroupIdComparator = StringPool.EQUAL;
2588    
2589                    if (parentGroupId == GroupConstants.ANY_PARENT_GROUP_ID) {
2590                            parentGroupIdComparator = StringPool.NOT_EQUAL;
2591                    }
2592    
2593                    return groupFinder.countByKeywords(
2594                            companyId, classNameIds, parentGroupId, parentGroupIdComparator,
2595                            keywords, params);
2596            }
2597    
2598            /**
2599             * Returns the number of groups belonging to the parent group that match the
2600             * class name IDs, name, and description, optionally including the user's
2601             * inherited organization groups and user groups. System and staged groups
2602             * are not included.
2603             *
2604             * @param  companyId the primary key of the company
2605             * @param  classNameIds the class names of entities to include in the search
2606             *         (optionally <code>null</code>)
2607             * @param  parentGroupId the primary key of the parent group
2608             * @param  name the group's name (optionally <code>null</code>)
2609             * @param  description the group's description (optionally
2610             *         <code>null</code>)
2611             * @param  params the finder params (optionally <code>null</code>). To
2612             *         include the user's inherited organization groups and user groups
2613             *         in the search, add entries having &quot;usersGroups&quot; and
2614             *         &quot;inherit&quot; as keys mapped to the the user's ID. For more
2615             *         information see {@link
2616             *         com.liferay.portal.service.persistence.GroupFinder}
2617             * @param  andOperator whether every field must match its keywords, or just
2618             *         one field.
2619             * @return the number of matching groups
2620             * @throws SystemException if a system exception occurred
2621             */
2622            @ThreadLocalCachable
2623            public int searchCount(
2624                            long companyId, long[] classNameIds, long parentGroupId,
2625                            String name, String description,
2626                            LinkedHashMap<String, Object> params, boolean andOperator)
2627                    throws SystemException {
2628    
2629                    String parentGroupIdComparator = StringPool.EQUAL;
2630    
2631                    if (parentGroupId == GroupConstants.ANY_PARENT_GROUP_ID) {
2632                            parentGroupIdComparator = StringPool.NOT_EQUAL;
2633                    }
2634    
2635                    String realName = getRealName(companyId, name);
2636    
2637                    return groupFinder.countByC_C_PG_N_D(
2638                            companyId, classNameIds, parentGroupId, parentGroupIdComparator,
2639                            name, realName, description, params, andOperator);
2640            }
2641    
2642            /**
2643             * Returns the number of groups that match the class name IDs, and keywords,
2644             * optionally including the user's inherited organization groups and user
2645             * groups. System and staged groups are not included.
2646             *
2647             * @param  companyId the primary key of the company
2648             * @param  classNameIds the class names of entities to include in the search
2649             *         (optionally <code>null</code>)
2650             * @param  keywords the keywords (space separated), which may occur in the
2651             *         sites's name, or description (optionally <code>null</code>)
2652             * @param  params the finder params (optionally <code>null</code>). To
2653             *         include the user's inherited organization groups and user groups
2654             *         in the search, add entries having &quot;usersGroups&quot; and
2655             *         &quot;inherit&quot; as keys mapped to the the user's ID. For more
2656             *         information see {@link
2657             *         com.liferay.portal.service.persistence.GroupFinder}
2658             * @return the number of matching groups
2659             * @throws SystemException if a system exception occurred
2660             */
2661            @ThreadLocalCachable
2662            public int searchCount(
2663                            long companyId, long[] classNameIds, String keywords,
2664                            LinkedHashMap<String, Object> params)
2665                    throws SystemException {
2666    
2667                    return groupFinder.countByKeywords(
2668                            companyId, classNameIds, keywords, params);
2669            }
2670    
2671            /**
2672             * Returns the number of groups that match the class name IDs, name, and
2673             * description, optionally including the user's inherited organization
2674             * groups and user groups. System and staged groups are not included.
2675             *
2676             * @param  companyId the primary key of the company
2677             * @param  classNameIds the class names of entities to include in the search
2678             *         (optionally <code>null</code>)
2679             * @param  name the group's name (optionally <code>null</code>)
2680             * @param  description the group's description (optionally
2681             *         <code>null</code>)
2682             * @param  params the finder params (optionally <code>null</code>). To
2683             *         include the user's inherited organization groups and user groups
2684             *         in the search, add entries having &quot;usersGroups&quot; and
2685             *         &quot;inherit&quot; as keys mapped to the the user's ID. For more
2686             *         information see {@link
2687             *         com.liferay.portal.service.persistence.GroupFinder}
2688             * @param  andOperator whether every field must match its keywords, or just
2689             *         one field.
2690             * @return the number of matching groups
2691             * @throws SystemException if a system exception occurred
2692             */
2693            @ThreadLocalCachable
2694            public int searchCount(
2695                            long companyId, long[] classNameIds, String name,
2696                            String description, LinkedHashMap<String, Object> params,
2697                            boolean andOperator)
2698                    throws SystemException {
2699    
2700                    String realName = getRealName(companyId, name);
2701    
2702                    return groupFinder.countByC_C_N_D(
2703                            companyId, classNameIds, name, realName, description, params,
2704                            andOperator);
2705            }
2706    
2707            /**
2708             * Returns the number of groups that match the keywords, optionally
2709             * including the user's inherited organization groups and user groups.
2710             * System and staged groups are not included.
2711             *
2712             * @param  companyId the primary key of the company
2713             * @param  keywords the keywords (space separated), which may occur in the
2714             *         sites's name, or description (optionally <code>null</code>)
2715             * @param  params the finder params (optionally <code>null</code>). To
2716             *         include the user's inherited organization groups and user groups
2717             *         in the search, add entries having &quot;usersGroups&quot; and
2718             *         &quot;inherit&quot; as keys mapped to the the user's ID. For more
2719             *         information see {@link
2720             *         com.liferay.portal.service.persistence.GroupFinder}
2721             * @return the number of matching groups
2722             * @throws SystemException if a system exception occurred
2723             */
2724            @ThreadLocalCachable
2725            public int searchCount(
2726                            long companyId, String keywords,
2727                            LinkedHashMap<String, Object> params)
2728                    throws SystemException {
2729    
2730                    return groupFinder.countByKeywords(companyId, keywords, params);
2731            }
2732    
2733            /**
2734             * Returns the number of groups and immediate organization groups that match
2735             * the name and description, optionally including the user's inherited
2736             * organization groups and user groups. System and staged groups are not
2737             * included.
2738             *
2739             * @param  companyId the primary key of the company
2740             * @param  name the group's name (optionally <code>null</code>)
2741             * @param  description the group's description (optionally
2742             *         <code>null</code>)
2743             * @param  params the finder params (optionally <code>null</code>). To
2744             *         include the user's inherited organization groups and user groups
2745             *         in the search, add entries having &quot;usersGroups&quot; and
2746             *         &quot;inherit&quot; as keys mapped to the the user's ID. For more
2747             *         information see {@link
2748             *         com.liferay.portal.service.persistence.GroupFinder}
2749             * @param  andOperator whether every field must match its keywords, or just
2750             *         one field.
2751             * @return the number of matching groups
2752             * @throws SystemException if a system exception occurred
2753             */
2754            @ThreadLocalCachable
2755            public int searchCount(
2756                            long companyId, String name, String description,
2757                            LinkedHashMap<String, Object> params, boolean andOperator)
2758                    throws SystemException {
2759    
2760                    String realName = getRealName(companyId, name);
2761    
2762                    return groupFinder.countByC_N_D(
2763                            companyId, name, realName, description, params, andOperator);
2764            }
2765    
2766            /**
2767             * Sets the groups associated with the role, removing and adding
2768             * associations as necessary.
2769             *
2770             * @param  roleId the primary key of the role
2771             * @param  groupIds the primary keys of the groups
2772             * @throws SystemException if a system exception occurred
2773             */
2774            public void setRoleGroups(long roleId, long[] groupIds)
2775                    throws SystemException {
2776    
2777                    rolePersistence.setGroups(roleId, groupIds);
2778    
2779                    PermissionCacheUtil.clearCache();
2780            }
2781    
2782            /**
2783             * Removes the groups from the role.
2784             *
2785             * @param  roleId the primary key of the role
2786             * @param  groupIds the primary keys of the groups
2787             * @throws SystemException if a system exception occurred
2788             */
2789            public void unsetRoleGroups(long roleId, long[] groupIds)
2790                    throws SystemException {
2791    
2792                    rolePersistence.removeGroups(roleId, groupIds);
2793    
2794                    PermissionCacheUtil.clearCache();
2795            }
2796    
2797            /**
2798             * Removes the user from the groups.
2799             *
2800             * @param  userId the primary key of the user
2801             * @param  groupIds the primary keys of the groups
2802             * @throws SystemException if a system exception occurred
2803             */
2804            public void unsetUserGroups(long userId, long[] groupIds)
2805                    throws SystemException {
2806    
2807                    userGroupRoleLocalService.deleteUserGroupRoles(userId, groupIds);
2808    
2809                    userPersistence.removeGroups(userId, groupIds);
2810    
2811                    PermissionCacheUtil.clearCache();
2812            }
2813    
2814            /**
2815             * Updates the group's asset replacing categories and tag names.
2816             *
2817             * @param  userId the primary key of the user
2818             * @param  group the group
2819             * @param  assetCategoryIds the primary keys of the asset categories
2820             *         (optionally <code>null</code>)
2821             * @param  assetTagNames the asset tag names (optionally <code>null</code>)
2822             * @throws PortalException if a user with the primary key could not be found
2823             * @throws SystemException if a system exception occurred
2824             */
2825            public void updateAsset(
2826                            long userId, Group group, long[] assetCategoryIds,
2827                            String[] assetTagNames)
2828                    throws PortalException, SystemException {
2829    
2830                    User user = userPersistence.findByPrimaryKey(userId);
2831    
2832                    Company company = companyPersistence.findByPrimaryKey(
2833                            user.getCompanyId());
2834    
2835                    Group companyGroup = company.getGroup();
2836    
2837                    assetEntryLocalService.updateEntry(
2838                            userId, companyGroup.getGroupId(), null, null,
2839                            Group.class.getName(), group.getGroupId(), null, 0,
2840                            assetCategoryIds, assetTagNames, false, null, null, null, null,
2841                            group.getDescriptiveName(), group.getDescription(), null, null,
2842                            null, 0, 0, null, false);
2843            }
2844    
2845            /**
2846             * Updates the group's friendly URL.
2847             *
2848             * @param  groupId the primary key of the group
2849             * @param  friendlyURL the group's new friendlyURL (optionally
2850             *         <code>null</code>)
2851             * @return the group
2852             * @throws PortalException if a group with the primary key could not be
2853             *         found or if a valid friendly URL could not be created for the
2854             *         group
2855             * @throws SystemException if a system exception occurred
2856             */
2857            public Group updateFriendlyURL(long groupId, String friendlyURL)
2858                    throws PortalException, SystemException {
2859    
2860                    Group group = groupPersistence.findByPrimaryKey(groupId);
2861    
2862                    if (group.isUser()) {
2863                            User user = userPersistence.findByPrimaryKey(group.getClassPK());
2864    
2865                            friendlyURL = StringPool.SLASH + user.getScreenName();
2866    
2867                            if (group.getFriendlyURL().equals(friendlyURL)) {
2868                                    return group;
2869                            }
2870                    }
2871    
2872                    friendlyURL = getFriendlyURL(
2873                            group.getCompanyId(), groupId, group.getClassNameId(),
2874                            group.getClassPK(), StringPool.BLANK, friendlyURL);
2875    
2876                    validateFriendlyURL(
2877                            group.getCompanyId(), group.getGroupId(), group.getClassNameId(),
2878                            group.getClassPK(), friendlyURL);
2879    
2880                    group.setFriendlyURL(friendlyURL);
2881    
2882                    groupPersistence.update(group);
2883    
2884                    return group;
2885            }
2886    
2887            /**
2888             * Updates the group.
2889             *
2890             * @param  groupId the primary key of the group
2891             * @param  parentGroupId the primary key of the parent group
2892             * @param  name the group's new name
2893             * @param  description the group's new description (optionally
2894             *         <code>null</code>)
2895             * @param  type the group's new type. For more information see {@link
2896             *         com.liferay.portal.model.GroupConstants}
2897             * @param  friendlyURL the group's new friendlyURL (optionally
2898             *         <code>null</code>)
2899             * @param  active whether the group is active
2900             * @param  serviceContext the service context to be applied (optionally
2901             *         <code>null</code>). Can set asset category IDs and asset tag
2902             *         names for the group.
2903             * @return the group
2904             * @throws PortalException if a group with the primary key could not be
2905             *         found or if the friendly URL was invalid or could one not be
2906             *         created
2907             * @throws SystemException if a system exception occurred
2908             */
2909            public Group updateGroup(
2910                            long groupId, long parentGroupId, String name, String description,
2911                            int type, String friendlyURL, boolean active,
2912                            ServiceContext serviceContext)
2913                    throws PortalException, SystemException {
2914    
2915                    Group group = groupPersistence.findByPrimaryKey(groupId);
2916    
2917                    String className = group.getClassName();
2918                    long classNameId = group.getClassNameId();
2919                    long classPK = group.getClassPK();
2920                    friendlyURL = getFriendlyURL(
2921                            group.getCompanyId(), groupId, classNameId, classPK,
2922                            StringPool.BLANK, friendlyURL);
2923    
2924                    if ((classNameId <= 0) || className.equals(Group.class.getName())) {
2925                            validateName(
2926                                    group.getGroupId(), group.getCompanyId(), name, group.isSite());
2927                    }
2928                    else if (className.equals(Organization.class.getName())) {
2929                            Organization organization =
2930                                    organizationPersistence.findByPrimaryKey(classPK);
2931    
2932                            name = getOrgGroupName(organization.getName());
2933                    }
2934                    else if (!GroupConstants.USER_PERSONAL_SITE.equals(name)) {
2935                            name = String.valueOf(classPK);
2936                    }
2937    
2938                    if (PortalUtil.isSystemGroup(group.getName()) &&
2939                            !name.equals(group.getName())) {
2940    
2941                            throw new RequiredGroupException(
2942                                    String.valueOf(group.getGroupId()),
2943                                    RequiredGroupException.SYSTEM_GROUP);
2944                    }
2945    
2946                    validateFriendlyURL(
2947                            group.getCompanyId(), group.getGroupId(), group.getClassNameId(),
2948                            group.getClassPK(), friendlyURL);
2949    
2950                    group.setParentGroupId(parentGroupId);
2951                    group.setName(name);
2952                    group.setDescription(description);
2953                    group.setType(type);
2954                    group.setFriendlyURL(friendlyURL);
2955                    group.setActive(active);
2956    
2957                    if ((serviceContext != null) && group.isSite()) {
2958                            group.setExpandoBridgeAttributes(serviceContext);
2959                    }
2960    
2961                    groupPersistence.update(group);
2962    
2963                    // Asset
2964    
2965                    if ((serviceContext != null) && group.isSite()) {
2966                            User user = null;
2967    
2968                            try {
2969                                    user = userPersistence.findByPrimaryKey(
2970                                            group.getCreatorUserId());
2971    
2972                            }
2973                            catch (NoSuchUserException nsue1) {
2974                                    try {
2975                                            user = userPersistence.findByPrimaryKey(
2976                                                    serviceContext.getUserId());
2977                                    }
2978                                    catch (NoSuchUserException nsue2) {
2979                                            user = userLocalService.getDefaultUser(
2980                                                    group.getCompanyId());
2981                                    }
2982                            }
2983    
2984                            updateAsset(
2985                                    user.getUserId(), group, serviceContext.getAssetCategoryIds(),
2986                                    serviceContext.getAssetTagNames());
2987                    }
2988    
2989                    return group;
2990            }
2991    
2992            /**
2993             * Updates the group's type settings.
2994             *
2995             * @param  groupId the primary key of the group
2996             * @param  typeSettings the group's new type settings (optionally
2997             *         <code>null</code>)
2998             * @return the group
2999             * @throws PortalException if a group with the primary key could not be
3000             *         found
3001             * @throws SystemException if a system exception occurred
3002             */
3003            public Group updateGroup(long groupId, String typeSettings)
3004                    throws PortalException, SystemException {
3005    
3006                    Group group = groupPersistence.findByPrimaryKey(groupId);
3007    
3008                    group.setTypeSettings(typeSettings);
3009    
3010                    groupPersistence.update(group);
3011    
3012                    return group;
3013            }
3014    
3015            /**
3016             * Associates the group with a main site if the group is an organization.
3017             *
3018             * @param  groupId the primary key of the group
3019             * @param  site whether the group is to be associated with a main site
3020             * @return the group
3021             * @throws PortalException if a group with the primary key could not be
3022             *         found
3023             * @throws SystemException if a system exception occurred
3024             */
3025            public Group updateSite(long groupId, boolean site)
3026                    throws PortalException, SystemException {
3027    
3028                    Group group = groupPersistence.findByPrimaryKey(groupId);
3029    
3030                    if (!group.isOrganization()) {
3031                            return group;
3032                    }
3033    
3034                    group.setSite(site);
3035    
3036                    groupPersistence.update(group);
3037    
3038                    return group;
3039            }
3040    
3041            protected void addControlPanelLayouts(Group group)
3042                    throws PortalException, SystemException {
3043    
3044                    long defaultUserId = userLocalService.getDefaultUserId(
3045                            group.getCompanyId());
3046    
3047                    String friendlyURL = getFriendlyURL(
3048                            PropsValues.CONTROL_PANEL_LAYOUT_FRIENDLY_URL);
3049    
3050                    ServiceContext serviceContext = new ServiceContext();
3051    
3052                    layoutLocalService.addLayout(
3053                            defaultUserId, group.getGroupId(), true,
3054                            LayoutConstants.DEFAULT_PARENT_LAYOUT_ID,
3055                            PropsValues.CONTROL_PANEL_LAYOUT_NAME, StringPool.BLANK,
3056                            StringPool.BLANK, LayoutConstants.TYPE_CONTROL_PANEL, false,
3057                            friendlyURL, serviceContext);
3058            }
3059    
3060            protected void addDefaultGuestPublicLayoutByProperties(Group group)
3061                    throws PortalException, SystemException {
3062    
3063                    long defaultUserId = userLocalService.getDefaultUserId(
3064                            group.getCompanyId());
3065                    String friendlyURL = getFriendlyURL(
3066                            PropsValues.DEFAULT_GUEST_PUBLIC_LAYOUT_FRIENDLY_URL);
3067    
3068                    ServiceContext serviceContext = new ServiceContext();
3069    
3070                    Layout layout = layoutLocalService.addLayout(
3071                            defaultUserId, group.getGroupId(), false,
3072                            LayoutConstants.DEFAULT_PARENT_LAYOUT_ID,
3073                            PropsValues.DEFAULT_GUEST_PUBLIC_LAYOUT_NAME, StringPool.BLANK,
3074                            StringPool.BLANK, LayoutConstants.TYPE_PORTLET, false, friendlyURL,
3075                            serviceContext);
3076    
3077                    LayoutTypePortlet layoutTypePortlet =
3078                            (LayoutTypePortlet)layout.getLayoutType();
3079    
3080                    layoutTypePortlet.setLayoutTemplateId(
3081                            0, PropsValues.DEFAULT_GUEST_PUBLIC_LAYOUT_TEMPLATE_ID, false);
3082    
3083                    for (int i = 0; i < 10; i++) {
3084                            String columnId = "column-" + i;
3085                            String portletIds = PropsUtil.get(
3086                                    PropsKeys.DEFAULT_GUEST_PUBLIC_LAYOUT_COLUMN + i);
3087    
3088                            layoutTypePortlet.addPortletIds(
3089                                    0, StringUtil.split(portletIds), columnId, false);
3090                    }
3091    
3092                    layoutLocalService.updateLayout(
3093                            layout.getGroupId(), layout.isPrivateLayout(), layout.getLayoutId(),
3094                            layout.getTypeSettings());
3095    
3096                    boolean updateLayoutSet = false;
3097    
3098                    LayoutSet layoutSet = layout.getLayoutSet();
3099    
3100                    if (Validator.isNotNull(
3101                                    PropsValues.DEFAULT_GUEST_PUBLIC_LAYOUT_REGULAR_THEME_ID)) {
3102    
3103                            layoutSet.setThemeId(
3104                                    PropsValues.DEFAULT_GUEST_PUBLIC_LAYOUT_REGULAR_THEME_ID);
3105    
3106                            updateLayoutSet = true;
3107                    }
3108    
3109                    if (Validator.isNotNull(
3110                                    PropsValues.
3111                                            DEFAULT_GUEST_PUBLIC_LAYOUT_REGULAR_COLOR_SCHEME_ID)) {
3112    
3113                            layoutSet.setColorSchemeId(
3114                                    PropsValues.
3115                                            DEFAULT_GUEST_PUBLIC_LAYOUT_REGULAR_COLOR_SCHEME_ID);
3116    
3117                            updateLayoutSet = true;
3118                    }
3119    
3120                    if (Validator.isNotNull(
3121                                    PropsValues.DEFAULT_GUEST_PUBLIC_LAYOUT_WAP_THEME_ID)) {
3122    
3123                            layoutSet.setWapThemeId(
3124                                    PropsValues.DEFAULT_GUEST_PUBLIC_LAYOUT_WAP_THEME_ID);
3125    
3126                            updateLayoutSet = true;
3127                    }
3128    
3129                    if (Validator.isNotNull(
3130                                    PropsValues.DEFAULT_GUEST_PUBLIC_LAYOUT_WAP_COLOR_SCHEME_ID)) {
3131    
3132                            layoutSet.setWapColorSchemeId(
3133                                    PropsValues.DEFAULT_GUEST_PUBLIC_LAYOUT_WAP_COLOR_SCHEME_ID);
3134    
3135                            updateLayoutSet = true;
3136                    }
3137    
3138                    if (updateLayoutSet) {
3139                            layoutSetLocalService.updateLayoutSet(layoutSet);
3140                    }
3141            }
3142    
3143            protected void addDefaultGuestPublicLayouts(Group group)
3144                    throws PortalException, SystemException {
3145    
3146                    if (publicLARFile != null) {
3147                            addDefaultGuestPublicLayoutsByLAR(group, publicLARFile);
3148                    }
3149                    else {
3150                            addDefaultGuestPublicLayoutByProperties(group);
3151                    }
3152            }
3153    
3154            protected void addDefaultGuestPublicLayoutsByLAR(Group group, File larFile)
3155                    throws PortalException, SystemException {
3156    
3157                    long defaultUserId = userLocalService.getDefaultUserId(
3158                            group.getCompanyId());
3159    
3160                    Map<String, String[]> parameterMap = new HashMap<String, String[]>();
3161    
3162                    parameterMap.put(
3163                            PortletDataHandlerKeys.CATEGORIES,
3164                            new String[] {Boolean.TRUE.toString()});
3165                    parameterMap.put(
3166                            PortletDataHandlerKeys.PERMISSIONS,
3167                            new String[] {Boolean.TRUE.toString()});
3168                    parameterMap.put(
3169                            PortletDataHandlerKeys.PORTLET_DATA,
3170                            new String[] {Boolean.TRUE.toString()});
3171                    parameterMap.put(
3172                            PortletDataHandlerKeys.PORTLET_DATA_CONTROL_DEFAULT,
3173                            new String[] {Boolean.TRUE.toString()});
3174                    parameterMap.put(
3175                            PortletDataHandlerKeys.PORTLET_SETUP,
3176                            new String[] {Boolean.TRUE.toString()});
3177    
3178                    layoutLocalService.importLayouts(
3179                            defaultUserId, group.getGroupId(), false, parameterMap, larFile);
3180            }
3181    
3182            protected void deletePortletData(Group group)
3183                    throws PortalException, SystemException {
3184    
3185                    List<Portlet> portlets = portletLocalService.getPortlets(
3186                            group.getCompanyId());
3187    
3188                    for (Portlet portlet : portlets) {
3189                            if (!portlet.isActive()) {
3190                                    continue;
3191                            }
3192    
3193                            PortletDataHandler portletDataHandler =
3194                                    portlet.getPortletDataHandlerInstance();
3195    
3196                            if (portletDataHandler == null) {
3197                                    continue;
3198                            }
3199    
3200                            PortletDataContext portletDataContext = new PortletDataContextImpl(
3201                                    group.getCompanyId(), group.getGroupId(), null,
3202                                    new HashSet<String>(), null, null, null);
3203    
3204                            // For now, we are going to throw an exception if one portlet data
3205                            // handler has an exception to ensure that the transaction is
3206                            // rolled back for data integrity. We may decide that this is not
3207                            // the best behavior in the future because a bad plugin could
3208                            // disallow deletion of groups.
3209    
3210                            //try {
3211                                    portletDataHandler.deleteData(
3212                                            portletDataContext, portlet.getPortletId(), null);
3213                            /*}
3214                            catch (Exception e) {
3215                                    _log.error(
3216                                            "Unable to delete data for portlet " +
3217                                                    portlet.getPortletId() + " in group " +
3218                                                            group.getGroupId());
3219                            }*/
3220                    }
3221            }
3222    
3223            protected String getFriendlyURL(
3224                            long companyId, long groupId, long classNameId, long classPK,
3225                            String friendlyName, String friendlyURL)
3226                    throws PortalException, SystemException {
3227    
3228                    friendlyURL = getFriendlyURL(friendlyURL);
3229    
3230                    if (Validator.isNotNull(friendlyURL)) {
3231                            return friendlyURL;
3232                    }
3233    
3234                    friendlyURL = StringPool.SLASH + getFriendlyURL(friendlyName);
3235    
3236                    String originalFriendlyURL = friendlyURL;
3237    
3238                    for (int i = 1;; i++) {
3239                            try {
3240                                    validateFriendlyURL(
3241                                            companyId, groupId, classNameId, classPK, friendlyURL);
3242    
3243                                    break;
3244                            }
3245                            catch (GroupFriendlyURLException gfurle) {
3246                                    int type = gfurle.getType();
3247    
3248                                    if (type == GroupFriendlyURLException.DUPLICATE) {
3249                                            friendlyURL = originalFriendlyURL + i;
3250                                    }
3251                                    else {
3252                                            friendlyURL = StringPool.SLASH + classPK;
3253    
3254                                            break;
3255                                    }
3256                            }
3257                    }
3258    
3259                    return friendlyURL;
3260            }
3261    
3262            protected String getFriendlyURL(String friendlyURL) {
3263                    return FriendlyURLNormalizerUtil.normalize(friendlyURL);
3264            }
3265    
3266            protected String getOrgGroupName(String name) {
3267                    return name + ORGANIZATION_NAME_SUFFIX;
3268            }
3269    
3270            protected String getRealName(long companyId, String name)
3271                    throws SystemException {
3272    
3273                    if (Validator.isNull(name)) {
3274                            return name;
3275                    }
3276    
3277                    String realName = name;
3278    
3279                    try {
3280                            Company company = companyLocalService.getCompany(companyId);
3281    
3282                            Account account = company.getAccount();
3283    
3284                            String companyName = account.getName();
3285    
3286                            name = StringUtil.replace(
3287                                    name, StringPool.PERCENT, StringPool.BLANK);
3288    
3289                            if (companyName.contains(name)) {
3290                                    realName =
3291                                            StringPool.PERCENT + GroupConstants.GUEST +
3292                                                    StringPool.PERCENT;
3293                            }
3294                    }
3295                    catch (PortalException pe) {
3296                    }
3297    
3298                    return realName;
3299            }
3300    
3301            protected void initImportLARFile() {
3302                    String publicLARFileName = PropsValues.DEFAULT_GUEST_PUBLIC_LAYOUTS_LAR;
3303    
3304                    if (_log.isDebugEnabled()) {
3305                            _log.debug("Reading public LAR file " + publicLARFileName);
3306                    }
3307    
3308                    if (Validator.isNotNull(publicLARFileName)) {
3309                            publicLARFile = new File(publicLARFileName);
3310    
3311                            if (!publicLARFile.exists()) {
3312                                    _log.error(
3313                                            "Public LAR file " + publicLARFile + " does not exist");
3314    
3315                                    publicLARFile = null;
3316                            }
3317                            else {
3318                                    if (_log.isDebugEnabled()) {
3319                                            _log.debug("Using public LAR file " + publicLARFileName);
3320                                    }
3321                            }
3322                    }
3323            }
3324    
3325            protected void initUserPersonalSitePermissions(Group group)
3326                    throws PortalException, SystemException {
3327    
3328                    // User role
3329    
3330                    Role role = roleLocalService.getRole(
3331                            group.getCompanyId(), RoleConstants.USER);
3332    
3333                    setCompanyPermissions(
3334                            role, PortletKeys.PORTAL,
3335                            new String[] {ActionKeys.VIEW_CONTROL_PANEL});
3336    
3337                    List<Portlet> portlets = portletLocalService.getPortlets(
3338                            group.getCompanyId(), false, false);
3339    
3340                    for (Portlet portlet : portlets) {
3341                            setRolePermissions(
3342                                    group, role, portlet.getPortletId(),
3343                                    new String[] {ActionKeys.VIEW});
3344                    }
3345    
3346                    setRolePermissions(
3347                            group, role, Layout.class.getName(),
3348                            new String[] {ActionKeys.VIEW});
3349    
3350                    setRolePermissions(
3351                            group, role, "com.liferay.portlet.blogs",
3352                            new String[] {
3353                                    ActionKeys.ADD_ENTRY, ActionKeys.PERMISSIONS,
3354                                    ActionKeys.SUBSCRIBE});
3355    
3356                    setRolePermissions(
3357                            group, role, "com.liferay.portlet.calendar",
3358                            new String[] {
3359                                    ActionKeys.ADD_EVENT, ActionKeys.EXPORT_ALL_EVENTS,
3360                                    ActionKeys.PERMISSIONS});
3361    
3362                    // Power User role
3363    
3364                    role = roleLocalService.getRole(
3365                            group.getCompanyId(), RoleConstants.POWER_USER);
3366    
3367                    for (Portlet portlet : portlets) {
3368                            List<String> actions =
3369                                    ResourceActionsUtil.getPortletResourceActions(
3370                                            portlet.getPortletId());
3371    
3372                            String controlPanelEntryCategory = GetterUtil.getString(
3373                                    portlet.getControlPanelEntryCategory());
3374    
3375                            if (actions.contains(ActionKeys.ACCESS_IN_CONTROL_PANEL) &&
3376                                    controlPanelEntryCategory.equals(PortletCategoryKeys.CONTENT)) {
3377    
3378                                    setRolePermissions(
3379                                            group, role, portlet.getPortletId(),
3380                                            new String[] {ActionKeys.ACCESS_IN_CONTROL_PANEL});
3381                            }
3382                    }
3383    
3384                    setRolePermissions(
3385                            group, role, Group.class.getName(),
3386                            new String[] {ActionKeys.MANAGE_LAYOUTS});
3387    
3388                    setRolePermissions(group, role, "com.liferay.portlet.asset");
3389                    setRolePermissions(group, role, "com.liferay.portlet.blogs");
3390                    setRolePermissions(group, role, "com.liferay.portlet.bookmarks");
3391                    setRolePermissions(group, role, "com.liferay.portlet.calendar");
3392                    setRolePermissions(group, role, "com.liferay.portlet.documentlibrary");
3393                    setRolePermissions(group, role, "com.liferay.portlet.imagegallery");
3394                    setRolePermissions(group, role, "com.liferay.portlet.messageboards");
3395                    setRolePermissions(group, role, "com.liferay.portlet.polls");
3396                    setRolePermissions(group, role, "com.liferay.portlet.wiki");
3397            }
3398    
3399            protected boolean isStaging(ServiceContext serviceContext) {
3400                    if (serviceContext != null) {
3401                            return ParamUtil.getBoolean(serviceContext, "staging");
3402                    }
3403    
3404                    return false;
3405            }
3406    
3407            protected void setCompanyPermissions(
3408                            Role role, String name, String[] actionIds)
3409                    throws PortalException, SystemException {
3410    
3411                    if (resourceBlockLocalService.isSupported(name)) {
3412                            resourceBlockLocalService.setCompanyScopePermissions(
3413                                    role.getCompanyId(), name, role.getRoleId(),
3414                                    Arrays.asList(actionIds));
3415                    }
3416                    else {
3417                            resourcePermissionLocalService.setResourcePermissions(
3418                                    role.getCompanyId(), name, ResourceConstants.SCOPE_COMPANY,
3419                                    String.valueOf(role.getCompanyId()), role.getRoleId(),
3420                                    actionIds);
3421                    }
3422            }
3423    
3424            protected void setRolePermissions(Group group, Role role, String name)
3425                    throws PortalException, SystemException {
3426    
3427                    List<String> actions = ResourceActionsUtil.getModelResourceActions(
3428                            name);
3429    
3430                    setRolePermissions(
3431                            group, role, name, actions.toArray(new String[actions.size()]));
3432            }
3433    
3434            protected void setRolePermissions(
3435                            Group group, Role role, String name, String[] actionIds)
3436                    throws PortalException, SystemException {
3437    
3438                    if (resourceBlockLocalService.isSupported(name)) {
3439                            resourceBlockLocalService.setGroupScopePermissions(
3440                                    role.getCompanyId(), group.getGroupId(), name, role.getRoleId(),
3441                                    Arrays.asList(actionIds));
3442                    }
3443                    else {
3444                            resourcePermissionLocalService.setResourcePermissions(
3445                                    group.getCompanyId(), name, ResourceConstants.SCOPE_GROUP,
3446                                    String.valueOf(group.getGroupId()), role.getRoleId(),
3447                                    actionIds);
3448                    }
3449            }
3450    
3451            protected void unscheduleStaging(Group group) {
3452                    try {
3453    
3454                            // Remote publishing
3455    
3456                            String groupName = StagingUtil.getSchedulerGroupName(
3457                                    DestinationNames.LAYOUTS_REMOTE_PUBLISHER, group.getGroupId());
3458    
3459                            SchedulerEngineHelperUtil.delete(groupName, StorageType.PERSISTED);
3460    
3461                            long liveGroupId = 0;
3462                            long stagingGroupId = 0;
3463    
3464                            if (group.isStagingGroup()) {
3465                                    liveGroupId = group.getLiveGroupId();
3466    
3467                                    stagingGroupId = group.getGroupId();
3468                            }
3469                            else if (group.hasStagingGroup()) {
3470                                    liveGroupId = group.getGroupId();
3471    
3472                                    stagingGroupId = group.getStagingGroup().getGroupId();
3473                            }
3474    
3475                            if ((liveGroupId != 0) && (stagingGroupId != 0)) {
3476    
3477                                    // Publish to live
3478    
3479                                    groupName = StagingUtil.getSchedulerGroupName(
3480                                            DestinationNames.LAYOUTS_LOCAL_PUBLISHER, liveGroupId);
3481    
3482                                    SchedulerEngineHelperUtil.delete(
3483                                            groupName, StorageType.PERSISTED);
3484    
3485                                    // Copy from live
3486    
3487                                    groupName = StagingUtil.getSchedulerGroupName(
3488                                            DestinationNames.LAYOUTS_LOCAL_PUBLISHER, stagingGroupId);
3489    
3490                                    SchedulerEngineHelperUtil.delete(
3491                                            groupName, StorageType.PERSISTED);
3492                            }
3493                    }
3494                    catch (Exception e) {
3495                            _log.error(
3496                                    "Unable to unschedule events for group: " + group.getGroupId());
3497                    }
3498            }
3499    
3500            protected void validateFriendlyURL(
3501                            long companyId, long groupId, long classNameId, long classPK,
3502                            String friendlyURL)
3503                    throws PortalException, SystemException {
3504    
3505                    Company company = companyPersistence.findByPrimaryKey(companyId);
3506    
3507                    if (company.isSystem()) {
3508                            return;
3509                    }
3510    
3511                    if (Validator.isNull(friendlyURL)) {
3512                            return;
3513                    }
3514    
3515                    int exceptionType = LayoutImpl.validateFriendlyURL(friendlyURL);
3516    
3517                    if (exceptionType != -1) {
3518                            throw new GroupFriendlyURLException(exceptionType);
3519                    }
3520    
3521                    Group group = groupPersistence.fetchByC_F(companyId, friendlyURL);
3522    
3523                    if ((group != null) && (group.getGroupId() != groupId)) {
3524                            throw new GroupFriendlyURLException(
3525                                    GroupFriendlyURLException.DUPLICATE);
3526                    }
3527    
3528                    String groupIdFriendlyURL = friendlyURL.substring(1);
3529    
3530                    if (Validator.isNumber(groupIdFriendlyURL)) {
3531                            long groupClassNameId = PortalUtil.getClassNameId(Group.class);
3532    
3533                            if (((classNameId != groupClassNameId) &&
3534                                     !groupIdFriendlyURL.equals(String.valueOf(classPK)) &&
3535                                     !PropsValues.USERS_SCREEN_NAME_ALLOW_NUMERIC) ||
3536                                    ((classNameId == groupClassNameId) &&
3537                                     !groupIdFriendlyURL.equals(String.valueOf(groupId)))) {
3538    
3539                                    GroupFriendlyURLException gfurle =
3540                                            new GroupFriendlyURLException(
3541                                                    GroupFriendlyURLException.POSSIBLE_DUPLICATE);
3542    
3543                                    gfurle.setKeywordConflict(groupIdFriendlyURL);
3544    
3545                                    throw gfurle;
3546                            }
3547                    }
3548    
3549                    String screenName = friendlyURL.substring(1);
3550    
3551                    User user = userPersistence.fetchByC_SN(companyId, screenName);
3552    
3553                    if (user != null) {
3554                            long userClassNameId = PortalUtil.getClassNameId(User.class);
3555    
3556                            if ((classNameId == userClassNameId) &&
3557                                    (classPK == user.getUserId())) {
3558                            }
3559                            else {
3560                                    throw new GroupFriendlyURLException(
3561                                            GroupFriendlyURLException.DUPLICATE);
3562                            }
3563                    }
3564    
3565                    if (StringUtil.count(friendlyURL, StringPool.SLASH) > 1) {
3566                            throw new GroupFriendlyURLException(
3567                                    GroupFriendlyURLException.TOO_DEEP);
3568                    }
3569            }
3570    
3571            protected void validateName(
3572                            long groupId, long companyId, String name, boolean site)
3573                    throws PortalException, SystemException {
3574    
3575                    if (Validator.isNull(name) || Validator.isNumber(name) ||
3576                            name.contains(StringPool.STAR) ||
3577                            name.contains(ORGANIZATION_NAME_SUFFIX)) {
3578    
3579                            throw new GroupNameException();
3580                    }
3581    
3582                    try {
3583                            Group group = groupFinder.findByC_N(companyId, name);
3584    
3585                            if ((groupId <= 0) || (group.getGroupId() != groupId)) {
3586                                    throw new DuplicateGroupException();
3587                            }
3588                    }
3589                    catch (NoSuchGroupException nsge) {
3590                    }
3591    
3592                    if (site) {
3593                            Company company = companyLocalService.getCompany(companyId);
3594    
3595                            if (name.equals(company.getName())) {
3596                                    throw new DuplicateGroupException();
3597                            }
3598                    }
3599            }
3600    
3601            protected File publicLARFile;
3602    
3603            private static Log _log = LogFactoryUtil.getLog(
3604                    GroupLocalServiceImpl.class);
3605    
3606            private Map<String, Group> _systemGroupsMap = new HashMap<String, Group>();
3607    
3608    }