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