001    /**
002     * Copyright (c) 2000-2012 Liferay, Inc. All rights reserved.
003     *
004     * This library is free software; you can redistribute it and/or modify it under
005     * the terms of the GNU Lesser General Public License as published by the Free
006     * Software Foundation; either version 2.1 of the License, or (at your option)
007     * any later version.
008     *
009     * This library is distributed in the hope that it will be useful, but WITHOUT
010     * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
011     * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
012     * details.
013     */
014    
015    package com.liferay.portal.service.impl;
016    
017    import com.liferay.portal.DuplicateGroupException;
018    import com.liferay.portal.GroupFriendlyURLException;
019    import com.liferay.portal.GroupNameException;
020    import com.liferay.portal.NoSuchGroupException;
021    import com.liferay.portal.NoSuchLayoutSetException;
022    import com.liferay.portal.NoSuchUserException;
023    import com.liferay.portal.RequiredGroupException;
024    import com.liferay.portal.kernel.cache.ThreadLocalCachable;
025    import com.liferay.portal.kernel.dao.orm.QueryUtil;
026    import com.liferay.portal.kernel.exception.PortalException;
027    import com.liferay.portal.kernel.exception.SystemException;
028    import com.liferay.portal.kernel.lar.PortletDataHandlerKeys;
029    import com.liferay.portal.kernel.log.Log;
030    import com.liferay.portal.kernel.log.LogFactoryUtil;
031    import com.liferay.portal.kernel.messaging.DestinationNames;
032    import com.liferay.portal.kernel.scheduler.SchedulerEngineUtil;
033    import com.liferay.portal.kernel.scheduler.StorageType;
034    import com.liferay.portal.kernel.spring.aop.Skip;
035    import com.liferay.portal.kernel.staging.StagingUtil;
036    import com.liferay.portal.kernel.transaction.Propagation;
037    import com.liferay.portal.kernel.transaction.Transactional;
038    import com.liferay.portal.kernel.util.CharPool;
039    import com.liferay.portal.kernel.util.FileUtil;
040    import com.liferay.portal.kernel.util.FriendlyURLNormalizerUtil;
041    import com.liferay.portal.kernel.util.GetterUtil;
042    import com.liferay.portal.kernel.util.OrderByComparator;
043    import com.liferay.portal.kernel.util.ParamUtil;
044    import com.liferay.portal.kernel.util.PropsKeys;
045    import com.liferay.portal.kernel.util.StringPool;
046    import com.liferay.portal.kernel.util.StringUtil;
047    import com.liferay.portal.kernel.util.Validator;
048    import com.liferay.portal.model.Account;
049    import com.liferay.portal.model.Company;
050    import com.liferay.portal.model.Group;
051    import com.liferay.portal.model.GroupConstants;
052    import com.liferay.portal.model.Layout;
053    import com.liferay.portal.model.LayoutConstants;
054    import com.liferay.portal.model.LayoutPrototype;
055    import com.liferay.portal.model.LayoutSet;
056    import com.liferay.portal.model.LayoutSetPrototype;
057    import com.liferay.portal.model.LayoutTypePortlet;
058    import com.liferay.portal.model.Organization;
059    import com.liferay.portal.model.Portlet;
060    import com.liferay.portal.model.Resource;
061    import com.liferay.portal.model.ResourceConstants;
062    import com.liferay.portal.model.ResourcePermission;
063    import com.liferay.portal.model.Role;
064    import com.liferay.portal.model.RoleConstants;
065    import com.liferay.portal.model.User;
066    import com.liferay.portal.model.UserGroup;
067    import com.liferay.portal.model.UserPersonalSite;
068    import com.liferay.portal.model.impl.LayoutImpl;
069    import com.liferay.portal.security.permission.ActionKeys;
070    import com.liferay.portal.security.permission.PermissionCacheUtil;
071    import com.liferay.portal.security.permission.ResourceActionsUtil;
072    import com.liferay.portal.service.ServiceContext;
073    import com.liferay.portal.service.base.GroupLocalServiceBaseImpl;
074    import com.liferay.portal.theme.ThemeLoader;
075    import com.liferay.portal.theme.ThemeLoaderFactory;
076    import com.liferay.portal.util.PortalUtil;
077    import com.liferay.portal.util.PortletCategoryKeys;
078    import com.liferay.portal.util.PortletKeys;
079    import com.liferay.portal.util.PropsUtil;
080    import com.liferay.portal.util.PropsValues;
081    import com.liferay.portal.util.comparator.GroupNameComparator;
082    import com.liferay.portlet.blogs.model.BlogsEntry;
083    import com.liferay.portlet.journal.model.JournalArticle;
084    import com.liferay.util.UniqueList;
085    
086    import java.io.File;
087    
088    import java.util.ArrayList;
089    import java.util.Arrays;
090    import java.util.HashMap;
091    import java.util.LinkedHashMap;
092    import java.util.List;
093    import java.util.Map;
094    
095    /**
096     * The group local service is responsible for accessing, creating, modifying and
097     * deleting groups.
098     *
099     * <p>
100     * Groups are mostly used in Liferay as a resource container for permissioning
101     * and content scoping purposes as described in {@link
102     * com.liferay.portal.model.impl.GroupImpl}.
103     * </p>
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     */
173    public class GroupLocalServiceImpl extends GroupLocalServiceBaseImpl {
174    
175            /**
176             * Constructs a group local service.
177             */
178            public GroupLocalServiceImpl() {
179                    initImportLARFile();
180            }
181    
182            /**
183             * Adds a group.
184             *
185             * @param  userId the primary key of the group's creator/owner
186             * @param  className the entity's class name
187             * @param  classPK the primary key of the entity's instance
188             * @param  liveGroupId the primary key of the live group
189             * @param  name the entity's name
190             * @param  description the group's description (optionally
191             *         <code>null</code>)
192             * @param  type the group's type. For more information see {@link
193             *         com.liferay.portal.model.GroupConstants}
194             * @param  friendlyURL the group's friendlyURL (optionally
195             *         <code>null</code>)
196             * @param  site whether the group is to be associated with a main site
197             * @param  active whether the group is active
198             * @param  serviceContext the service context to be applied (optionally
199             *         <code>null</code>). Can set asset category IDs and asset tag
200             *         names for the group, and whether the group is for staging.
201             * @return the group
202             * @throws PortalException if a creator could not be found, if the group's
203             *         information was invalid, if a layout could not be found, or if a
204             *         valid friendly URL could not be created for the group
205             * @throws SystemException if a system exception occurred
206             */
207            public Group addGroup(
208                            long userId, String className, long classPK, long liveGroupId,
209                            String name, String description, int type, String friendlyURL,
210                            boolean site, boolean active, ServiceContext serviceContext)
211                    throws PortalException, SystemException {
212    
213                    // Group
214    
215                    User user = userPersistence.findByPrimaryKey(userId);
216                    className = GetterUtil.getString(className);
217                    long classNameId = PortalUtil.getClassNameId(className);
218                    String friendlyName = name;
219    
220                    long groupId = 0;
221    
222                    while (true) {
223                            groupId = counterLocalService.increment();
224    
225                            User screenNameUser = userPersistence.fetchByC_SN(
226                                    user.getCompanyId(), String.valueOf(groupId));
227    
228                            if (screenNameUser == null) {
229                                    break;
230                            }
231                    }
232    
233                    boolean staging = isStaging(serviceContext);
234    
235                    long groupClassNameId = PortalUtil.getClassNameId(Group.class);
236    
237                    if ((classNameId <= 0) || className.equals(Group.class.getName())) {
238                            className = Group.class.getName();
239                            classNameId = groupClassNameId;
240                            classPK = groupId;
241                    }
242                    else if (className.equals(Organization.class.getName())) {
243                            name = getOrgGroupName(classPK, name);
244                    }
245                    else if (!GroupConstants.USER_PERSONAL_SITE.equals(name)) {
246                            name = String.valueOf(classPK);
247                    }
248    
249                    if (className.equals(Organization.class.getName()) && staging) {
250                            classPK = liveGroupId;
251                    }
252    
253                    long parentGroupId = GroupConstants.DEFAULT_PARENT_GROUP_ID;
254    
255                    if (className.equals(Layout.class.getName())) {
256                            Layout layout = layoutLocalService.getLayout(classPK);
257    
258                            parentGroupId = layout.getGroupId();
259                    }
260    
261                    friendlyURL = getFriendlyURL(
262                            user.getCompanyId(), groupId, classNameId, classPK, friendlyName,
263                            friendlyURL);
264    
265                    if (staging) {
266                            name = name.concat(" (Staging)");
267                            friendlyURL = friendlyURL.concat("-staging");
268                    }
269    
270                    if (className.equals(Group.class.getName())) {
271                            if (!site && (liveGroupId == 0)) {
272                                    throw new IllegalArgumentException();
273                            }
274                    }
275                    else if (!className.equals(Organization.class.getName()) &&
276                                     className.startsWith("com.liferay.portal.model.")) {
277    
278                            if (site) {
279                                    throw new IllegalArgumentException();
280                            }
281                    }
282    
283                    if ((classNameId <= 0) || className.equals(Group.class.getName())) {
284                            validateName(groupId, user.getCompanyId(), name);
285                    }
286    
287                    validateFriendlyURL(
288                            user.getCompanyId(), groupId, classNameId, classPK, friendlyURL);
289    
290                    Group group = groupPersistence.create(groupId);
291    
292                    group.setCompanyId(user.getCompanyId());
293                    group.setCreatorUserId(userId);
294                    group.setClassNameId(classNameId);
295                    group.setClassPK(classPK);
296                    group.setParentGroupId(parentGroupId);
297                    group.setLiveGroupId(liveGroupId);
298                    group.setName(name);
299                    group.setDescription(description);
300                    group.setType(type);
301                    group.setFriendlyURL(friendlyURL);
302                    group.setSite(site);
303                    group.setActive(active);
304    
305                    groupPersistence.update(group, false);
306    
307                    // Layout sets
308    
309                    layoutSetLocalService.addLayoutSet(groupId, true);
310    
311                    layoutSetLocalService.addLayoutSet(groupId, false);
312    
313                    if ((classNameId == groupClassNameId) && !user.isDefaultUser()) {
314    
315                            // Resources
316    
317                            resourceLocalService.addResources(
318                                    group.getCompanyId(), 0, 0, Group.class.getName(),
319                                    group.getGroupId(), false, false, false);
320    
321                            // Site roles
322    
323                            Role role = roleLocalService.getRole(
324                                    group.getCompanyId(), RoleConstants.SITE_OWNER);
325    
326                            userGroupRoleLocalService.addUserGroupRoles(
327                                    userId, groupId, new long[] {role.getRoleId()});
328    
329                            // User
330    
331                            userLocalService.addGroupUsers(
332                                    group.getGroupId(), new long[] {userId});
333    
334                            // Asset
335    
336                            if (serviceContext != null) {
337                                    updateAsset(
338                                            userId, group, serviceContext.getAssetCategoryIds(),
339                                            serviceContext.getAssetTagNames());
340                            }
341                    }
342                    else if (className.equals(Organization.class.getName()) &&
343                                     !user.isDefaultUser()) {
344    
345                            // Resources
346    
347                            resourceLocalService.addResources(
348                                    group.getCompanyId(), 0, 0, Group.class.getName(),
349                                    group.getGroupId(), false, false, false);
350                    }
351    
352                    return group;
353            }
354    
355            /**
356             * Adds the group using the default live group.
357             *
358             * @param  userId the primary key of the group's creator/owner
359             * @param  className the entity's class name
360             * @param  classPK the primary key of the entity's instance
361             * @param  name the entity's name
362             * @param  description the group's description (optionally
363             *         <code>null</code>)
364             * @param  type the group's type. For more information see {@link
365             *         com.liferay.portal.model.GroupConstants}
366             * @param  friendlyURL the group's friendlyURL
367             * @param  site whether the group is to be associated with a main site
368             * @param  active whether the group is active
369             * @param  serviceContext the service context to be applied (optionally
370             *         <code>null</code>). Can set asset category IDs and asset tag
371             *         names for the group, and whether the group is for staging.
372             * @return the group
373             * @throws PortalException if a creator could not be found, if the group's
374             *         information was invalid, if a layout could not be found, or if a
375             *         valid friendly URL could not be created for the group
376             * @throws SystemException if a system exception occurred
377             */
378            public Group addGroup(
379                            long userId, String className, long classPK, String name,
380                            String description, int type, String friendlyURL, boolean site,
381                            boolean active, ServiceContext serviceContext)
382                    throws PortalException, SystemException {
383    
384                    return addGroup(
385                            userId, className, classPK, GroupConstants.DEFAULT_LIVE_GROUP_ID,
386                            name, description, type, friendlyURL, site, active, serviceContext);
387            }
388    
389            /**
390             * Adds the groups to the role.
391             *
392             * @param  roleId the primary key of the role
393             * @param  groupIds the primary keys of the groups
394             * @throws SystemException if a system exception occurred
395             */
396            public void addRoleGroups(long roleId, long[] groupIds)
397                    throws SystemException {
398    
399                    rolePersistence.addGroups(roleId, groupIds);
400    
401                    PermissionCacheUtil.clearCache();
402            }
403    
404            /**
405             * Adds the user to the groups.
406             *
407             * @param  userId the primary key of the user
408             * @param  groupIds the primary keys of the groups
409             * @throws SystemException if a system exception occurred
410             */
411            public void addUserGroups(long userId, long[] groupIds)
412                    throws SystemException {
413    
414                    userPersistence.addGroups(userId, groupIds);
415    
416                    PermissionCacheUtil.clearCache();
417            }
418    
419            /**
420             * Adds a company group if it does not exist. This method is typically used
421             * when a virtual host is added.
422             *
423             * @param  companyId the primary key of the company
424             * @throws PortalException if a default user for the company could not be
425             *         found, if the group's information was invalid, if a layout could
426             *         not be found, or if a valid friendly URL could not be created for
427             *         the group
428             * @throws SystemException if a system exception occurred
429             */
430            @Transactional(propagation = Propagation.SUPPORTS, readOnly = true)
431            public void checkCompanyGroup(long companyId)
432                    throws PortalException, SystemException {
433    
434                    long classNameId = PortalUtil.getClassNameId(Company.class);
435    
436                    int count = groupPersistence.countByC_C_C(
437                            companyId, classNameId, companyId);
438    
439                    if (count == 0) {
440                            long defaultUserId = userLocalService.getDefaultUserId(companyId);
441    
442                            groupLocalService.addGroup(
443                                    defaultUserId, Company.class.getName(), companyId, null, null,
444                                    0, null, false, true, null);
445                    }
446            }
447    
448            /**
449             * Creates systems groups and other related data needed by the system on the
450             * very first startup. Also takes care of creating the control panel groups
451             * and layouts.
452             *
453             * @param  companyId the primary key of the company
454             * @throws PortalException if a new system group could not be created
455             * @throws SystemException if a system exception occurred
456             */
457            @Transactional(propagation = Propagation.SUPPORTS, readOnly = true)
458            public void checkSystemGroups(long companyId)
459                    throws PortalException, SystemException {
460    
461                    String companyIdHexString = StringUtil.toHexString(companyId);
462    
463                    for (Group group : groupFinder.findBySystem(companyId)) {
464                            _systemGroupsMap.put(
465                                    companyIdHexString.concat(group.getName()), group);
466                    }
467    
468                    long defaultUserId = userLocalService.getDefaultUserId(companyId);
469    
470                    String[] systemGroups = PortalUtil.getSystemGroups();
471    
472                    for (String name : systemGroups) {
473                            String groupCacheKey = companyIdHexString.concat(name);
474    
475                            Group group = _systemGroupsMap.get(groupCacheKey);
476    
477                            if (group == null) {
478                                    group = groupPersistence.fetchByC_N(companyId, name);
479                            }
480    
481                            if (group == null) {
482                                    String className = null;
483                                    long classPK = 0;
484                                    int type = GroupConstants.TYPE_SITE_OPEN;
485                                    String friendlyURL = null;
486                                    boolean site = true;
487    
488                                    if (name.equals(GroupConstants.CONTROL_PANEL)) {
489                                            type = GroupConstants.TYPE_SITE_PRIVATE;
490                                            friendlyURL = GroupConstants.CONTROL_PANEL_FRIENDLY_URL;
491                                    }
492                                    else if (name.equals(GroupConstants.GUEST)) {
493                                            friendlyURL = "/guest";
494                                    }
495                                    else if (name.equals(GroupConstants.USER_PERSONAL_SITE)) {
496                                            className = UserPersonalSite.class.getName();
497                                            classPK = defaultUserId;
498                                            type = GroupConstants.TYPE_SITE_PRIVATE;
499                                            friendlyURL =
500                                                    GroupConstants.USER_PERSONAL_SITE_FRIENDLY_URL;
501                                            site = false;
502                                    }
503    
504                                    group = groupLocalService.addGroup(
505                                            defaultUserId, className, classPK, name, null, type,
506                                            friendlyURL, site, true, null);
507    
508                                    if (name.equals(GroupConstants.USER_PERSONAL_SITE)) {
509                                            initUserPersonalSitePermissions(group);
510                                    }
511                            }
512    
513                            if (group.isControlPanel()) {
514                                    LayoutSet layoutSet = layoutSetLocalService.getLayoutSet(
515                                            group.getGroupId(), true);
516    
517                                    if (layoutSet.getPageCount() == 0) {
518                                            addControlPanelLayouts(group);
519                                    }
520                            }
521    
522                            if (group.getName().equals(GroupConstants.GUEST)) {
523                                    LayoutSet layoutSet = layoutSetLocalService.getLayoutSet(
524                                            group.getGroupId(), false);
525    
526                                    if (layoutSet.getPageCount() == 0) {
527                                            addDefaultGuestPublicLayouts(group);
528                                    }
529                            }
530    
531                            _systemGroupsMap.put(groupCacheKey, group);
532                    }
533            }
534    
535            /**
536             * Deletes the group and its associated data.
537             *
538             * <p>
539             * The group is unstaged and its assets and resources including layouts,
540             * membership requests, subscriptions, teams, blogs, bookmarks, calendar
541             * events, image gallery, journals, message boards, polls, shopping related
542             * entities, software catalog, and wikis are also deleted.
543             * </p>
544             *
545             * @param  group the group
546             * @throws PortalException if the group was a system group, or if the user
547             *         did not have permission to delete the group or its assets or its
548             *         resources
549             * @throws SystemException if a system exception occurred
550             */
551            @Override
552            public void deleteGroup(Group group)
553                    throws PortalException, SystemException {
554    
555                    if (PortalUtil.isSystemGroup(group.getName())) {
556                            throw new RequiredGroupException(
557                                    String.valueOf(group.getGroupId()));
558                    }
559    
560                    // Layout set branches
561    
562                    layoutSetBranchLocalService.deleteLayoutSetBranches(
563                            group.getGroupId(), true, true);
564    
565                    layoutSetBranchLocalService.deleteLayoutSetBranches(
566                            group.getGroupId(), false, true);
567    
568                    // Layout sets
569    
570                    ServiceContext serviceContext = new ServiceContext();
571    
572                    try {
573                            layoutSetLocalService.deleteLayoutSet(
574                                    group.getGroupId(), true, serviceContext);
575                    }
576                    catch (NoSuchLayoutSetException nslse) {
577                    }
578    
579                    try {
580                            layoutSetLocalService.deleteLayoutSet(
581                                    group.getGroupId(), false, serviceContext);
582                    }
583                    catch (NoSuchLayoutSetException nslse) {
584                    }
585    
586                    // Group roles
587    
588                    userGroupRoleLocalService.deleteUserGroupRolesByGroupId(
589                            group.getGroupId());
590    
591                    // User group roles
592    
593                    userGroupGroupRoleLocalService.deleteUserGroupGroupRolesByGroupId(
594                            group.getGroupId());
595    
596                    // Membership requests
597    
598                    membershipRequestLocalService.deleteMembershipRequests(
599                            group.getGroupId());
600    
601                    // Subscriptions
602    
603                    subscriptionLocalService.deleteSubscriptions(
604                            group.getCompanyId(), BlogsEntry.class.getName(),
605                            group.getGroupId());
606                    subscriptionLocalService.deleteSubscriptions(
607                            group.getCompanyId(), JournalArticle.class.getName(),
608                            group.getGroupId());
609    
610                    /// Teams
611    
612                    teamLocalService.deleteTeams(group.getGroupId());
613    
614                    // Staging
615    
616                    unscheduleStaging(group);
617    
618                    if (group.hasStagingGroup()) {
619                            deleteGroup(group.getStagingGroup().getGroupId());
620                    }
621    
622                    // Themes
623    
624                    ThemeLoader themeLoader = ThemeLoaderFactory.getDefaultThemeLoader();
625    
626                    if (themeLoader != null) {
627                            String themePath =
628                                    themeLoader.getFileStorage() + StringPool.SLASH +
629                                            group.getGroupId();
630    
631                            FileUtil.deltree(themePath + "-private");
632                            FileUtil.deltree(themePath + "-public");
633                    }
634    
635                    // Asset
636    
637                    if (group.isRegularSite()) {
638                            assetEntryLocalService.deleteEntry(
639                                    Group.class.getName(), group.getGroupId());
640                    }
641    
642                    assetVocabularyLocalService.deleteVocabularies(group.getGroupId());
643    
644                    // Blogs
645    
646                    blogsEntryLocalService.deleteEntries(group.getGroupId());
647                    blogsStatsUserLocalService.deleteStatsUserByGroupId(group.getGroupId());
648    
649                    // Bookmarks
650    
651                    bookmarksFolderLocalService.deleteFolders(group.getGroupId());
652    
653                    // Calendar
654    
655                    calEventLocalService.deleteEvents(group.getGroupId());
656    
657                    // Document library
658    
659                    dlFileEntryTypeLocalService.deleteFileEntryTypes(group.getGroupId());
660                    repositoryLocalService.deleteRepositories(group.getGroupId());
661    
662                    // Journal
663    
664                    journalArticleLocalService.deleteArticles(group.getGroupId());
665                    journalTemplateLocalService.deleteTemplates(group.getGroupId());
666                    journalStructureLocalService.deleteStructures(group.getGroupId());
667    
668                    // Message boards
669    
670                    mbBanLocalService.deleteBansByGroupId(group.getGroupId());
671                    mbCategoryLocalService.deleteCategories(group.getGroupId());
672                    mbStatsUserLocalService.deleteStatsUsersByGroupId(group.getGroupId());
673    
674                    // Polls
675    
676                    pollsQuestionLocalService.deleteQuestions(group.getGroupId());
677    
678                    // Shopping
679    
680                    shoppingCartLocalService.deleteGroupCarts(group.getGroupId());
681                    shoppingCategoryLocalService.deleteCategories(group.getGroupId());
682                    shoppingCouponLocalService.deleteCoupons(group.getGroupId());
683                    shoppingOrderLocalService.deleteOrders(group.getGroupId());
684    
685                    // Software catalog
686    
687                    scFrameworkVersionLocalService.deleteFrameworkVersions(
688                            group.getGroupId());
689                    scProductEntryLocalService.deleteProductEntries(group.getGroupId());
690    
691                    // Wiki
692    
693                    wikiNodeLocalService.deleteNodes(group.getGroupId());
694    
695                    // Resources
696    
697                    if (PropsValues.PERMISSIONS_USER_CHECK_ALGORITHM == 6) {
698                            List<ResourcePermission> resourcePermissions =
699                                    resourcePermissionPersistence.findByC_P(
700                                            group.getCompanyId(), String.valueOf(group.getGroupId()));
701    
702                            for (ResourcePermission resourcePermission : resourcePermissions) {
703                                    resourcePermissionLocalService.deleteResourcePermission(
704                                            resourcePermission);
705                            }
706                    }
707                    else {
708                            List<Resource> resources = resourceFinder.findByC_P(
709                                    group.getCompanyId(), String.valueOf(group.getGroupId()));
710    
711                            for (Resource resource : resources) {
712                                    resourceLocalService.deleteResource(resource);
713                            }
714                    }
715    
716                    if (!group.isStagingGroup() &&
717                            (group.isOrganization()) || group.isRegularSite()) {
718    
719                            resourceLocalService.deleteResource(
720                                    group.getCompanyId(), Group.class.getName(),
721                                    ResourceConstants.SCOPE_INDIVIDUAL, group.getGroupId());
722                    }
723    
724                    // Group
725    
726                    if (group.isOrganization() && group.isSite()) {
727                            group.setSite(false);
728    
729                            groupPersistence.update(group, false);
730                    }
731                    else {
732                            groupPersistence.remove(group);
733                    }
734    
735                    // Permission cache
736    
737                    PermissionCacheUtil.clearCache();
738            }
739    
740            /**
741             * Deletes the group and its associated data.
742             *
743             * <p>
744             * The group is unstaged and its assets and resources including layouts,
745             * membership requests, subscriptions, teams, blogs, bookmarks, calendar
746             * events, image gallery, journals, message boards, polls, shopping related
747             * entities, software catalog, and wikis are also deleted.
748             * </p>
749             *
750             * @param  groupId the primary key of the group
751             * @throws PortalException if a group with the primary key could not be
752             *         found, if the group was a system group, or if the user did not
753             *         have permission to delete the group, its assets, or its resources
754             * @throws SystemException if a system exception occurred
755             */
756            @Override
757            public void deleteGroup(long groupId)
758                    throws PortalException, SystemException {
759    
760                    Group group = groupPersistence.findByPrimaryKey(groupId);
761    
762                    deleteGroup(group);
763            }
764    
765            /**
766             * Returns the group with the matching friendly URL.
767             *
768             * @param  companyId the primary key of the company
769             * @param  friendlyURL the friendly URL
770             * @return the group with the friendly URL, or <code>null</code> if a
771             *         matching group could not be found
772             * @throws SystemException if a system exception occurred
773             */
774            public Group fetchFriendlyURLGroup(long companyId, String friendlyURL)
775                    throws SystemException {
776    
777                    if (Validator.isNull(friendlyURL)) {
778                            return null;
779                    }
780    
781                    friendlyURL = getFriendlyURL(friendlyURL);
782    
783                    return groupPersistence.fetchByC_F(companyId, friendlyURL);
784            }
785    
786            /**
787             * Returns the group with the matching group name.
788             *
789             * @param  companyId the primary key of the company
790             * @param  name the group's name
791             * @return the group with the name and associated company, or
792             *         <code>null</code> if a matching group could not be found
793             * @throws SystemException if a system exception occurred
794             */
795            @Skip
796            public Group fetchGroup(long companyId, String name)
797                    throws SystemException {
798    
799                    Group group = _systemGroupsMap.get(
800                            StringUtil.toHexString(companyId).concat(name));
801    
802                    if (group != null) {
803                            return group;
804                    }
805    
806                    return groupLocalService.loadFetchGroup(companyId, name);
807            }
808    
809            /**
810             * Returns the company group.
811             *
812             * @param  companyId the primary key of the company
813             * @return the group associated with the company
814             * @throws PortalException if a matching group could not be found
815             * @throws SystemException if a system exception occurred
816             */
817            public Group getCompanyGroup(long companyId)
818                    throws PortalException, SystemException {
819    
820                    long classNameId = PortalUtil.getClassNameId(Company.class);
821    
822                    return groupPersistence.findByC_C_C(companyId, classNameId, companyId);
823            }
824    
825            /**
826             * Returns a range of all the groups associated with the company.
827             *
828             * <p>
829             * Useful when paginating results. Returns a maximum of <code>end -
830             * start</code> instances. <code>start</code> and <code>end</code> are not
831             * primary keys, they are indexes in the result set. Thus, <code>0</code>
832             * refers to the first result in the set. Setting both <code>start</code>
833             * and <code>end</code> to {@link
834             * com.liferay.portal.kernel.dao.orm.QueryUtil#ALL_POS} will return the full
835             * result set.
836             * </p>
837             *
838             * @param  companyId the primary key of the company
839             * @param  start the lower bound of the range of groups to return
840             * @param  end the upper bound of the range of groups to return (not
841             *         inclusive)
842             * @return the range of groups associated with the company
843             * @throws SystemException if a system exception occurred
844             */
845            public List<Group> getCompanyGroups(long companyId, int start, int end)
846                    throws SystemException {
847    
848                    return groupPersistence.findByCompanyId(companyId, start, end);
849            }
850    
851            /**
852             * Returns the number of groups associated with the company.
853             *
854             * @param  companyId the primary key of the company
855             * @return the number of groups associated with the company
856             * @throws SystemException if a system exception occurred
857             */
858            public int getCompanyGroupsCount(long companyId) throws SystemException {
859                    return groupPersistence.countByCompanyId(companyId);
860            }
861    
862            /**
863             * Returns the group with the matching friendly URL.
864             *
865             * @param  companyId the primary key of the company
866             * @param  friendlyURL the group's friendlyURL
867             * @return the group with the friendly URL
868             * @throws PortalException if a matching group could not be found, or if the
869             *         friendly URL was invalid
870             * @throws SystemException if a system exception occurred
871             */
872            public Group getFriendlyURLGroup(long companyId, String friendlyURL)
873                    throws PortalException, SystemException {
874    
875                    if (Validator.isNull(friendlyURL)) {
876                            throw new NoSuchGroupException();
877                    }
878    
879                    friendlyURL = getFriendlyURL(friendlyURL);
880    
881                    return groupPersistence.findByC_F(companyId, friendlyURL);
882            }
883    
884            /**
885             * Returns the group with the matching primary key.
886             *
887             * @param  groupId the primary key of the group
888             * @return the group with the primary key
889             * @throws PortalException if a group with the primary key could not be
890             *         found
891             * @throws SystemException if a system exception occurred
892             */
893            @Override
894            @ThreadLocalCachable
895            public Group getGroup(long groupId)
896                    throws PortalException, SystemException {
897    
898                    return groupPersistence.findByPrimaryKey(groupId);
899            }
900    
901            /**
902             * Returns the group with the matching group name.
903             *
904             * @param  companyId the primary key of the company
905             * @param  name the group's name
906             * @return the group with the name
907             * @throws PortalException if a matching group could not be found
908             * @throws SystemException if a system exception occurred
909             */
910            @Skip
911            public Group getGroup(long companyId, String name)
912                    throws PortalException, SystemException {
913    
914                    Group group = _systemGroupsMap.get(
915                            StringUtil.toHexString(companyId).concat(name));
916    
917                    if (group != null) {
918                            return group;
919                    }
920    
921                    return groupLocalService.loadGetGroup(companyId, name);
922            }
923    
924            /**
925             * Returns the groups with the matching primary keys.
926             *
927             * @param  groupIds the primary keys of the groups
928             * @return the groups with the primary keys
929             * @throws PortalException if any one of the groups could not be found
930             * @throws SystemException if a system exception occurred
931             */
932            public List<Group> getGroups(long[] groupIds)
933                    throws PortalException, SystemException {
934    
935                    List<Group> groups = new ArrayList<Group>(groupIds.length);
936    
937                    for (long groupId : groupIds) {
938                            Group group = getGroup(groupId);
939    
940                            groups.add(group);
941                    }
942    
943                    return groups;
944            }
945    
946            /**
947             * Returns the group associated with the layout.
948             *
949             * @param  companyId the primary key of the company
950             * @param  plid the primary key of the layout
951             * @return the group associated with the layout
952             * @throws PortalException if a matching group could not be found
953             * @throws SystemException if a system exception occurred
954             */
955            public Group getLayoutGroup(long companyId, long plid)
956                    throws PortalException, SystemException {
957    
958                    long classNameId = PortalUtil.getClassNameId(Layout.class);
959    
960                    return groupPersistence.findByC_C_C(companyId, classNameId, plid);
961            }
962    
963            /**
964             * Returns the group associated with the layout prototype.
965             *
966             * @param  companyId the primary key of the company
967             * @param  layoutPrototypeId the primary key of the layout prototype
968             * @return the group associated with the layout prototype
969             * @throws PortalException if a matching group could not be found
970             * @throws SystemException if a system exception occurred
971             */
972            public Group getLayoutPrototypeGroup(long companyId, long layoutPrototypeId)
973                    throws PortalException, SystemException {
974    
975                    long classNameId = PortalUtil.getClassNameId(LayoutPrototype.class);
976    
977                    return groupPersistence.findByC_C_C(
978                            companyId, classNameId, layoutPrototypeId);
979            }
980    
981            /**
982             * Returns the group associated with the layout set prototype.
983             *
984             * @param  companyId the primary key of the company
985             * @param  layoutSetPrototypeId the primary key of the layout set prototype
986             * @return the group associated with the layout set prototype
987             * @throws PortalException if a matching group could not be found
988             * @throws SystemException if a system exception occurred
989             */
990            public Group getLayoutSetPrototypeGroup(
991                            long companyId, long layoutSetPrototypeId)
992                    throws PortalException, SystemException {
993    
994                    long classNameId = PortalUtil.getClassNameId(LayoutSetPrototype.class);
995    
996                    return groupPersistence.findByC_C_C(
997                            companyId, classNameId, layoutSetPrototypeId);
998            }
999    
1000            /**
1001             * Returns all live groups.
1002             *
1003             * @return all live groups
1004             * @throws SystemException if a system exception occurred
1005             */
1006            public List<Group> getLiveGroups() throws SystemException {
1007                    return groupFinder.findByLiveGroups();
1008            }
1009    
1010            /**
1011             * Returns a range of all non-system groups of a specified type (className)
1012             * that have no layouts.
1013             *
1014             * <p>
1015             * Useful when paginating results. Returns a maximum of <code>end -
1016             * start</code> instances. <code>start</code> and <code>end</code> are not
1017             * primary keys, they are indexes in the result set. Thus, <code>0</code>
1018             * refers to the first result in the set. Setting both <code>start</code>
1019             * and <code>end</code> to {@link
1020             * com.liferay.portal.kernel.dao.orm.QueryUtil#ALL_POS} will return the full
1021             * result set.
1022             * </p>
1023             *
1024             * @param  className the entity's class name
1025             * @param  privateLayout whether to include groups with private layout sets
1026             *         or non-private layout sets
1027             * @param  start the lower bound of the range of groups to return
1028             * @param  end the upper bound of the range of groups to return (not
1029             *         inclusive)
1030             * @return the range of matching groups
1031             * @throws SystemException if a system exception occurred
1032             */
1033            public List<Group> getNoLayoutsGroups(
1034                            String className, boolean privateLayout, int start, int end)
1035                    throws SystemException {
1036    
1037                    long classNameId = PortalUtil.getClassNameId(className);
1038    
1039                    return groupFinder.findByNoLayouts(
1040                            classNameId, privateLayout, start, end);
1041            }
1042    
1043            /**
1044             * Returns all non-system groups having <code>null</code> or empty friendly
1045             * URLs.
1046             *
1047             * @return the non-system groups having <code>null</code> or empty friendly
1048             *         URLs
1049             * @throws SystemException if a system exception occurred
1050             */
1051            public List<Group> getNullFriendlyURLGroups() throws SystemException {
1052                    return groupFinder.findByNullFriendlyURL();
1053            }
1054    
1055            /**
1056             * Returns the specified organization group.
1057             *
1058             * @param  companyId the primary key of the company
1059             * @param  organizationId the primary key of the organization
1060             * @return the group associated with the organization
1061             * @throws PortalException if a matching group could not be found
1062             * @throws SystemException if a system exception occurred
1063             */
1064            public Group getOrganizationGroup(long companyId, long organizationId)
1065                    throws PortalException, SystemException {
1066    
1067                    long classNameId = PortalUtil.getClassNameId(Organization.class);
1068    
1069                    return groupPersistence.findByC_C_C(
1070                            companyId, classNameId, organizationId);
1071            }
1072    
1073            /**
1074             * Returns the specified organization groups.
1075             *
1076             * @param  organizations the organizations
1077             * @return the groups associated with the organizations
1078             */
1079            public List<Group> getOrganizationsGroups(
1080                    List<Organization> organizations) {
1081    
1082                    List<Group> organizationGroups = new ArrayList<Group>();
1083    
1084                    for (int i = 0; i < organizations.size(); i++) {
1085                            Organization organization = organizations.get(i);
1086    
1087                            Group group = organization.getGroup();
1088    
1089                            organizationGroups.add(group);
1090                    }
1091    
1092                    return organizationGroups;
1093            }
1094    
1095            /**
1096             * Returns all the groups related to the organizations.
1097             *
1098             * @param  organizations the organizations
1099             * @return the groups related to the organizations
1100             * @throws SystemException if a system exception occurred
1101             */
1102            public List<Group> getOrganizationsRelatedGroups(
1103                            List<Organization> organizations)
1104                    throws SystemException {
1105    
1106                    List<Group> organizationGroups = new ArrayList<Group>();
1107    
1108                    for (int i = 0; i < organizations.size(); i++) {
1109                            Organization organization = organizations.get(i);
1110    
1111                            List<Group> groups = organizationPersistence.getGroups(
1112                                    organization.getOrganizationId());
1113    
1114                            organizationGroups.addAll(groups);
1115                    }
1116    
1117                    return organizationGroups;
1118            }
1119    
1120            /**
1121             * Returns all the groups associated with the role.
1122             *
1123             * @param  roleId the primary key of the role
1124             * @return the groups associated with the role
1125             * @throws SystemException if a system exception occurred
1126             */
1127            public List<Group> getRoleGroups(long roleId) throws SystemException {
1128                    return rolePersistence.getGroups(roleId);
1129            }
1130    
1131            /**
1132             * Returns the staging group.
1133             *
1134             * @param  liveGroupId the primary key of the live group
1135             * @return the staging group
1136             * @throws PortalException if a matching staging group could not be found
1137             * @throws SystemException if a system exception occurred
1138             */
1139            public Group getStagingGroup(long liveGroupId)
1140                    throws PortalException, SystemException {
1141    
1142                    return groupPersistence.findByLiveGroupId(liveGroupId);
1143            }
1144    
1145            /**
1146             * Returns the group associated with the user.
1147             *
1148             * @param  companyId the primary key of the company
1149             * @param  userId the primary key of the user
1150             * @return the group associated with the user
1151             * @throws PortalException if a matching group could not be found
1152             * @throws SystemException if a system exception occurred
1153             */
1154            public Group getUserGroup(long companyId, long userId)
1155                    throws PortalException, SystemException {
1156    
1157                    long classNameId = PortalUtil.getClassNameId(User.class);
1158    
1159                    return groupPersistence.findByC_C_C(companyId, classNameId, userId);
1160            }
1161    
1162            /**
1163             * Returns the specified "user group" group. That is, the group that
1164             * represents the {@link com.liferay.portal.model.UserGroup} entity.
1165             *
1166             * @param  companyId the primary key of the company
1167             * @param  userGroupId the primary key of the user group
1168             * @return the group associated with the user group
1169             * @throws PortalException if a matching group could not be found
1170             * @throws SystemException if a system exception occurred
1171             */
1172            public Group getUserGroupGroup(long companyId, long userGroupId)
1173                    throws PortalException, SystemException {
1174    
1175                    long classNameId = PortalUtil.getClassNameId(UserGroup.class);
1176    
1177                    return groupPersistence.findByC_C_C(
1178                            companyId, classNameId, userGroupId);
1179            }
1180    
1181            /**
1182             * Returns all the user's site groups and immediate organization groups.
1183             * System and staged groups are not included.
1184             *
1185             * @param  userId the primary key of the user
1186             * @return the user's groups and organization groups
1187             * @throws PortalException if a user with the primary key could not be found
1188             * @throws SystemException if a system exception occurred
1189             */
1190            public List<Group> getUserGroups(long userId)
1191                    throws PortalException, SystemException {
1192    
1193                    return getUserGroups(userId, false);
1194            }
1195    
1196            /**
1197             * Returns all the user's site groups and immediate organization groups,
1198             * optionally including the user's inherited organization groups and user
1199             * groups. System and staged groups are not included.
1200             *
1201             * @param  userId the primary key of the user
1202             * @param  inherit whether to include the user's inherited organization
1203             *         groups and user groups
1204             * @return the user's groups and immediate organization groups
1205             * @throws PortalException if a user with the primary key could not be found
1206             * @throws SystemException if a system exception occurred
1207             */
1208            public List<Group> getUserGroups(long userId, boolean inherit)
1209                    throws PortalException, SystemException {
1210    
1211                    return getUserGroups(
1212                            userId, inherit, QueryUtil.ALL_POS, QueryUtil.ALL_POS);
1213            }
1214    
1215            /**
1216             * Returns a name ordered range of all the user's site groups and immediate
1217             * organization groups, optionally including the user's inherited
1218             * organization groups and user groups. System and staged groups are not
1219             * included.
1220             *
1221             * <p>
1222             * Useful when paginating results. Returns a maximum of <code>end -
1223             * start</code> instances. <code>start</code> and <code>end</code> are not
1224             * primary keys, they are indexes in the result set. Thus, <code>0</code>
1225             * refers to the first result in the set. Setting both <code>start</code>
1226             * and <code>end</code> to {@link
1227             * com.liferay.portal.kernel.dao.orm.QueryUtil#ALL_POS} will return the full
1228             * result set.
1229             * </p>
1230             *
1231             * @param  userId the primary key of the user
1232             * @param  inherit whether to include the user's inherited organization
1233             *         groups and user groups
1234             * @param  start the lower bound of the range of groups to return
1235             * @param  end the upper bound of the range of groups to return (not
1236             *         inclusive)
1237             * @return the range of the user's groups and immediate organization groups
1238             *         ordered by name
1239             * @throws PortalException if a user with the primary key could not be found
1240             * @throws SystemException if a system exception occurred
1241             */
1242            public List<Group> getUserGroups(
1243                            long userId, boolean inherit, int start, int end)
1244                    throws PortalException, SystemException {
1245    
1246                    if (inherit) {
1247                            User user = userPersistence.findByPrimaryKey(userId);
1248    
1249                            LinkedHashMap<String, Object> groupParams =
1250                                    new LinkedHashMap<String, Object>();
1251    
1252                            groupParams.put("usersGroups", new Long(userId));
1253    
1254                            return search(
1255                                    user.getCompanyId(), null, null, groupParams, start, end);
1256                    }
1257                    else {
1258                            return userPersistence.getGroups(userId, start, end);
1259                    }
1260            }
1261    
1262            /**
1263             * Returns a name ordered range of all the user's site groups and immediate
1264             * organization groups. System and staged groups are not included.
1265             *
1266             * <p>
1267             * Useful when paginating results. Returns a maximum of <code>end -
1268             * start</code> instances. <code>start</code> and <code>end</code> are not
1269             * primary keys, they are indexes in the result set. Thus, <code>0</code>
1270             * refers to the first result in the set. Setting both <code>start</code>
1271             * and <code>end</code> to {@link
1272             * com.liferay.portal.kernel.dao.orm.QueryUtil#ALL_POS} will return the full
1273             * result set.
1274             * </p>
1275             *
1276             * @param  userId the primary key of the user
1277             * @param  start the lower bound of the range of groups to return
1278             * @param  end the upper bound of the range of groups to return (not
1279             *         inclusive)
1280             * @return the range of the user's groups and organization groups ordered by
1281             *         name
1282             * @throws PortalException if a user with the primary key could not be found
1283             * @throws SystemException if a system exception occurred
1284             */
1285            public List<Group> getUserGroups(long userId, int start, int end)
1286                    throws PortalException, SystemException {
1287    
1288                    return getUserGroups(userId, false, start, end);
1289            }
1290    
1291            /**
1292             * Returns the groups associated with the user groups.
1293             *
1294             * @param  userGroups the user groups
1295             * @return the groups associated with the user groups
1296             * @throws PortalException if any one of the user group's group could not be
1297             *         found
1298             * @throws SystemException if a system exception occurred
1299             */
1300            public List<Group> getUserGroupsGroups(List<UserGroup> userGroups)
1301                    throws PortalException, SystemException {
1302    
1303                    List<Group> userGroupGroups = new ArrayList<Group>();
1304    
1305                    for (int i = 0; i < userGroups.size(); i++) {
1306                            UserGroup userGroup = userGroups.get(i);
1307    
1308                            Group group = userGroup.getGroup();
1309    
1310                            userGroupGroups.add(group);
1311                    }
1312    
1313                    return userGroupGroups;
1314            }
1315    
1316            /**
1317             * Returns all the groups related to the user groups.
1318             *
1319             * @param  userGroups the user groups
1320             * @return the groups related to the user groups
1321             * @throws SystemException if a system exception occurred
1322             */
1323            public List<Group> getUserGroupsRelatedGroups(List<UserGroup> userGroups)
1324                    throws SystemException {
1325    
1326                    List<Group> userGroupGroups = new ArrayList<Group>();
1327    
1328                    for (int i = 0; i < userGroups.size(); i++) {
1329                            UserGroup userGroup = userGroups.get(i);
1330    
1331                            List<Group> groups = userGroupPersistence.getGroups(
1332                                    userGroup.getUserGroupId());
1333    
1334                            userGroupGroups.addAll(groups);
1335                    }
1336    
1337                    return userGroupGroups;
1338            }
1339    
1340            /**
1341             * Returns the range of all groups associated with the user's organization
1342             * groups, including the ancestors of the organization groups, unless portal
1343             * property <code>organizations.membership.strict</code> is set to
1344             * <code>true</code>.
1345             *
1346             * <p>
1347             * Useful when paginating results. Returns a maximum of <code>end -
1348             * start</code> instances. <code>start</code> and <code>end</code> are not
1349             * primary keys, they are indexes in the result set. Thus, <code>0</code>
1350             * refers to the first result in the set. Setting both <code>start</code>
1351             * and <code>end</code> to {@link
1352             * com.liferay.portal.kernel.dao.orm.QueryUtil#ALL_POS} will return the full
1353             * result set.
1354             * </p>
1355             *
1356             * @param  userId the primary key of the user
1357             * @param  start the lower bound of the range of groups to consider
1358             * @param  end the upper bound of the range of groups to consider (not
1359             *         inclusive)
1360             * @return the range of groups associated with the user's organization
1361             *         groups
1362             * @throws PortalException if a user with the primary key could not be found
1363             *         or if another portal exception occurred
1364             * @throws SystemException if a system exception occurred
1365             */
1366            public List<Group> getUserOrganizationsGroups(
1367                            long userId, int start, int end)
1368                    throws PortalException, SystemException {
1369    
1370                    List<Group> userOrgsGroups = new UniqueList<Group>();
1371    
1372                    List<Organization> userOrgs =
1373                            organizationLocalService.getUserOrganizations(userId, start, end);
1374    
1375                    for (Organization organization : userOrgs) {
1376                            userOrgsGroups.add(0, organization.getGroup());
1377    
1378                            if (!PropsValues.ORGANIZATIONS_MEMBERSHIP_STRICT) {
1379                                    for (Organization ancestorOrganization :
1380                                                    organization.getAncestors()) {
1381    
1382                                            userOrgsGroups.add(0, ancestorOrganization.getGroup());
1383                                    }
1384                            }
1385                    }
1386    
1387                    return userOrgsGroups;
1388            }
1389    
1390            /**
1391             * Returns <code>true</code> if the group is associated with the role.
1392             *
1393             * @param  roleId the primary key of the role
1394             * @param  groupId the primary key of the group
1395             * @return <code>true</code> if the group is associated with the role;
1396             *         <code>false</code> otherwise
1397             * @throws SystemException if a system exception occurred
1398             */
1399            public boolean hasRoleGroup(long roleId, long groupId)
1400                    throws SystemException {
1401    
1402                    return rolePersistence.containsGroup(roleId, groupId);
1403            }
1404    
1405            /**
1406             * Returns <code>true</code> if the live group has a staging group.
1407             *
1408             * @param  liveGroupId the primary key of the live group
1409             * @return <code>true</code> if the live group has a staging group;
1410             *         <code>false</code> otherwise
1411             * @throws SystemException if a system exception occurred
1412             */
1413            public boolean hasStagingGroup(long liveGroupId) throws SystemException {
1414                    if (groupPersistence.fetchByLiveGroupId(liveGroupId) != null) {
1415                            return true;
1416                    }
1417                    else {
1418                            return false;
1419                    }
1420            }
1421    
1422            /**
1423             * Returns <code>true</code> if the user is immediately associated with the
1424             * group, or associated with the group via the user's organizations,
1425             * inherited organizations, or user groups.
1426             *
1427             * @param  userId the primary key of the user
1428             * @param  groupId the primary key of the group
1429             * @return <code>true</code> if the user is associated with the group;
1430             *         <code>false</code> otherwise
1431             * @throws SystemException if a system exception occurred
1432             */
1433            public boolean hasUserGroup(long userId, long groupId)
1434                    throws SystemException {
1435    
1436                    return hasUserGroup(userId, groupId, true);
1437            }
1438    
1439            /**
1440             * Returns <code>true</code> if the user is immediately associated with the
1441             * group, or optionally if the user is associated with the group via the
1442             * user's organizations, inherited organizations, or user groups.
1443             *
1444             * @param  userId the primary key of the user
1445             * @param  groupId the primary key of the group
1446             * @param  inherit whether to include organization groups and user groups to
1447             *         which the user belongs in the determination
1448             * @return <code>true</code> if the user is associated with the group;
1449             *         <code>false</code> otherwise
1450             * @throws SystemException if a system exception occurred
1451             */
1452            public boolean hasUserGroup(long userId, long groupId, boolean inherit)
1453                    throws SystemException {
1454    
1455                    if (groupFinder.countByG_U(groupId, userId, inherit) > 0) {
1456                            return true;
1457                    }
1458                    else {
1459                            return false;
1460                    }
1461            }
1462    
1463            public Group loadFetchGroup(long companyId, String name)
1464                    throws SystemException {
1465    
1466                    return groupPersistence.fetchByC_N(companyId, name);
1467            }
1468    
1469            public Group loadGetGroup(long companyId, String name)
1470                    throws PortalException, SystemException {
1471    
1472                    return groupPersistence.findByC_N(companyId, name);
1473            }
1474    
1475            public List<Group> search(
1476                            long companyId, LinkedHashMap<String, Object> params, int start,
1477                            int end)
1478                    throws SystemException {
1479    
1480                    return groupFinder.findByCompanyId(
1481                            companyId, params, start, end, new GroupNameComparator(true));
1482            }
1483    
1484            /**
1485             * Returns a name ordered range of all the groups that match the class name
1486             * IDs, name, and description, optionally including the user's inherited
1487             * organization groups and user groups. System and staged groups are not
1488             * included.
1489             *
1490             * <p>
1491             * Useful when paginating results. Returns a maximum of <code>end -
1492             * start</code> instances. <code>start</code> and <code>end</code> are not
1493             * primary keys, they are indexes in the result set. Thus, <code>0</code>
1494             * refers to the first result in the set. Setting both <code>start</code>
1495             * and <code>end</code> to {@link
1496             * com.liferay.portal.kernel.dao.orm.QueryUtil#ALL_POS} will return the full
1497             * result set.
1498             * </p>
1499             *
1500             * @param  companyId the primary key of the company
1501             * @param  classNameIds the class names of entities to include in the search
1502             *         (optionally <code>null</code>)
1503             * @param  name the group's name (optionally <code>null</code>)
1504             * @param  description the group's description (optionally
1505             *         <code>null</code>)
1506             * @param  params the finder params (optionally <code>null</code>). To
1507             *         include a user's organizations, inherited organizations, and user
1508             *         groups in the search, add an entry with key
1509             *         &quot;usersGroups&quot; mapped to the user's ID and an entry with
1510             *         key &quot;inherit&quot; mapped to a non-<code>null</code> object.
1511             *         For more information see {@link
1512             *         com.liferay.portal.service.persistence.GroupFinder}
1513             *         com.liferay.portal.service.persistence.GroupFinder}
1514             * @param  start the lower bound of the range of groups to return
1515             * @param  end the upper bound of the range of groups to return (not
1516             *         inclusive)
1517             * @return the matching groups ordered by name
1518             * @throws SystemException if a system exception occurred
1519             */
1520            public List<Group> search(
1521                            long companyId, long[] classNameIds, String name,
1522                            String description, LinkedHashMap<String, Object> params, int start,
1523                            int end)
1524                    throws SystemException {
1525    
1526                    return search(
1527                            companyId, classNameIds, name, description, params, start, end,
1528                            null);
1529            }
1530    
1531            /**
1532             * Returns an ordered range of all the groups that match the class name IDs,
1533             * name, and description, optionally including the user's inherited
1534             * organization groups and user groups. System and staged groups are not
1535             * included.
1536             *
1537             * <p>
1538             * Useful when paginating results. Returns a maximum of <code>end -
1539             * start</code> instances. <code>start</code> and <code>end</code> are not
1540             * primary keys, they are indexes in the result set. Thus, <code>0</code>
1541             * refers to the first result in the set. Setting both <code>start</code>
1542             * and <code>end</code> to {@link
1543             * com.liferay.portal.kernel.dao.orm.QueryUtil#ALL_POS} will return the full
1544             * result set.
1545             * </p>
1546             *
1547             * @param  companyId the primary key of the company
1548             * @param  classNameIds the group's class name IDs (optionally
1549             *         <code>null</code>)
1550             * @param  name the group's name (optionally <code>null</code>)
1551             * @param  description the group's description (optionally
1552             *         <code>null</code>)
1553             * @param  params the finder params (optionally <code>null</code>). To
1554             *         include a user's organizations, inherited organizations, and user
1555             *         groups in the search, add an entry with key
1556             *         &quot;usersGroups&quot; mapped to the user's ID and an entry with
1557             *         key &quot;inherit&quot; mapped to a non-<code>null</code> object.
1558             *         For more information see {@link
1559             *         com.liferay.portal.service.persistence.GroupFinder}
1560             * @param  start the lower bound of the range of groups to return
1561             * @param  end the upper bound of the range of groups to return (not
1562             *         inclusive)
1563             * @param  obc the comparator to order the groups (optionally
1564             *         <code>null</code>)
1565             * @return the matching groups ordered by comparator <code>obc</code>
1566             * @throws SystemException if a system exception occurred
1567             */
1568            public List<Group> search(
1569                            long companyId, long[] classNameIds, String name,
1570                            String description, LinkedHashMap<String, Object> params, int start,
1571                            int end, OrderByComparator obc)
1572                    throws SystemException {
1573    
1574                    if (obc == null) {
1575                            obc = new GroupNameComparator(true);
1576                    }
1577    
1578                    String realName = getRealName(companyId, name);
1579    
1580                    return groupFinder.findByC_C_N_D(
1581                            companyId, classNameIds, name, realName, description, params, start,
1582                            end, obc);
1583            }
1584    
1585            /**
1586             * Returns a name ordered range of all the site groups and organization
1587             * groups that match the name and description, optionally including the
1588             * user's inherited organization groups and user groups. System and staged
1589             * groups are not included.
1590             *
1591             * <p>
1592             * Useful when paginating results. Returns a maximum of <code>end -
1593             * start</code> instances. <code>start</code> and <code>end</code> are not
1594             * primary keys, they are indexes in the result set. Thus, <code>0</code>
1595             * refers to the first result in the set. Setting both <code>start</code>
1596             * and <code>end</code> to {@link
1597             * com.liferay.portal.kernel.dao.orm.QueryUtil#ALL_POS} will return the full
1598             * result set.
1599             * </p>
1600             *
1601             * @param  companyId the primary key of the company
1602             * @param  name the group's name (optionally <code>null</code>)
1603             * @param  description the group's description (optionally
1604             *         <code>null</code>)
1605             * @param  params the finder params (optionally <code>null</code>). To
1606             *         include the user's inherited organizations and user groups in the
1607             *         search, add entries having &quot;usersGroups&quot; and
1608             *         &quot;inherit&quot; as keys mapped to the the user's ID. For more
1609             *         information see {@link
1610             *         com.liferay.portal.service.persistence.GroupFinder}
1611             * @param  start the lower bound of the range of groups to return
1612             * @param  end the upper bound of the range of groups to return (not
1613             *         inclusive)
1614             * @return the matching groups ordered by name
1615             * @throws SystemException if a system exception occurred
1616             */
1617            public List<Group> search(
1618                            long companyId, String name, String description,
1619                            LinkedHashMap<String, Object> params, int start, int end)
1620                    throws SystemException {
1621    
1622                    return search(companyId, name, description, params, start, end, null);
1623            }
1624    
1625            /**
1626             * Returns an ordered range of all the site groups and organization groups
1627             * that match the name and description, optionally including the user's
1628             * inherited organization groups and user groups. System and staged groups
1629             * are not included.
1630             *
1631             * <p>
1632             * Useful when paginating results. Returns a maximum of <code>end -
1633             * start</code> instances. <code>start</code> and <code>end</code> are not
1634             * primary keys, they are indexes in the result set. Thus, <code>0</code>
1635             * refers to the first result in the set. Setting both <code>start</code>
1636             * and <code>end</code> to {@link
1637             * com.liferay.portal.kernel.dao.orm.QueryUtil#ALL_POS} will return the full
1638             * result set.
1639             * </p>
1640             *
1641             * @param  companyId the primary key of the company
1642             * @param  name the group's name (optionally <code>null</code>)
1643             * @param  description the group's description (optionally
1644             *         <code>null</code>)
1645             * @param  params the finder params (optionally <code>null</code>). To
1646             *         include the user's inherited organizations and user groups in the
1647             *         search, add entries having &quot;usersGroups&quot; and
1648             *         &quot;inherit&quot; as keys mapped to the the user's ID. For more
1649             *         information see {@link
1650             *         com.liferay.portal.service.persistence.GroupFinder}
1651             * @param  start the lower bound of the range of groups to return
1652             * @param  end the upper bound of the range of groups to return (not
1653             *         inclusive)
1654             * @param  obc the comparator to order the groups (optionally
1655             *         <code>null</code>)
1656             * @return the matching groups ordered by comparator <code>obc</code>
1657             * @throws SystemException if a system exception occurred
1658             */
1659            public List<Group> search(
1660                            long companyId, String name, String description,
1661                            LinkedHashMap<String, Object> params, int start, int end,
1662                            OrderByComparator obc)
1663                    throws SystemException {
1664    
1665                    if (obc == null) {
1666                            obc = new GroupNameComparator(true);
1667                    }
1668    
1669                    String realName = getRealName(companyId, name);
1670    
1671                    return groupFinder.findByC_N_D(
1672                            companyId, name, realName, description, params, start, end, obc);
1673            }
1674    
1675            /**
1676             * Returns the number of groups that match the class name IDs, name, and
1677             * description, optionally including the user's inherited organization
1678             * groups and user groups. System and staged groups are not included.
1679             *
1680             * @param  companyId the primary key of the company
1681             * @param  classNameIds the class names of entities to include in the search
1682             *         (optionally <code>null</code>)
1683             * @param  name the group's name (optionally <code>null</code>)
1684             * @param  description the group's description (optionally
1685             *         <code>null</code>)
1686             * @param  params the finder params (optionally <code>null</code>). To
1687             *         include the user's inherited organization groups and user groups
1688             *         in the search, add entries having &quot;usersGroups&quot; and
1689             *         &quot;inherit&quot; as keys mapped to the the user's ID. For more
1690             *         information see {@link
1691             *         com.liferay.portal.service.persistence.GroupFinder}
1692             * @return the number of matching groups
1693             * @throws SystemException if a system exception occurred
1694             */
1695            @ThreadLocalCachable
1696            public int searchCount(
1697                            long companyId, long[] classNameIds, String name,
1698                            String description, LinkedHashMap<String, Object> params)
1699                    throws SystemException {
1700    
1701                    String realName = getRealName(companyId, name);
1702    
1703                    return groupFinder.countByC_C_N_D(
1704                            companyId, classNameIds, name, realName, description, params);
1705            }
1706    
1707            /**
1708             * Returns the number of groups and immediate organization groups that match
1709             * the name and description, optionally including the user's inherited
1710             * organization groups and user groups. System and staged groups are not
1711             * included.
1712             *
1713             * @param  companyId the primary key of the company
1714             * @param  name the group's name (optionally <code>null</code>)
1715             * @param  description the group's description (optionally
1716             *         <code>null</code>)
1717             * @param  params the finder params (optionally <code>null</code>). To
1718             *         include the user's inherited organization groups and user groups
1719             *         in the search, add entries having &quot;usersGroups&quot; and
1720             *         &quot;inherit&quot; as keys mapped to the the user's ID. For more
1721             *         information see {@link
1722             *         com.liferay.portal.service.persistence.GroupFinder}
1723             * @return the number of matching groups
1724             * @throws SystemException if a system exception occurred
1725             */
1726            @ThreadLocalCachable
1727            public int searchCount(
1728                            long companyId, String name, String description,
1729                            LinkedHashMap<String, Object> params)
1730                    throws SystemException {
1731    
1732                    String realName = getRealName(companyId, name);
1733    
1734                    return groupFinder.countByC_N_D(
1735                            companyId, name, realName, description, params);
1736            }
1737    
1738            /**
1739             * Sets the groups associated with the role, removing and adding
1740             * associations as necessary.
1741             *
1742             * @param  roleId the primary key of the role
1743             * @param  groupIds the primary keys of the groups
1744             * @throws SystemException if a system exception occurred
1745             */
1746            public void setRoleGroups(long roleId, long[] groupIds)
1747                    throws SystemException {
1748    
1749                    rolePersistence.setGroups(roleId, groupIds);
1750    
1751                    PermissionCacheUtil.clearCache();
1752            }
1753    
1754            /**
1755             * Removes the groups from the role.
1756             *
1757             * @param  roleId the primary key of the role
1758             * @param  groupIds the primary keys of the groups
1759             * @throws SystemException if a system exception occurred
1760             */
1761            public void unsetRoleGroups(long roleId, long[] groupIds)
1762                    throws SystemException {
1763    
1764                    rolePersistence.removeGroups(roleId, groupIds);
1765    
1766                    PermissionCacheUtil.clearCache();
1767            }
1768    
1769            /**
1770             * Removes the user from the groups.
1771             *
1772             * @param  userId the primary key of the user
1773             * @param  groupIds the primary keys of the groups
1774             * @throws SystemException if a system exception occurred
1775             */
1776            public void unsetUserGroups(long userId, long[] groupIds)
1777                    throws SystemException {
1778    
1779                    userGroupRoleLocalService.deleteUserGroupRoles(userId, groupIds);
1780    
1781                    userPersistence.removeGroups(userId, groupIds);
1782    
1783                    PermissionCacheUtil.clearCache();
1784            }
1785    
1786            /**
1787             * Updates the group's asset replacing categories and tag names.
1788             *
1789             * @param  userId the primary key of the user
1790             * @param  group the group
1791             * @param  assetCategoryIds the primary keys of the asset categories
1792             *         (optionally <code>null</code>)
1793             * @param  assetTagNames the asset tag names (optionally <code>null</code>)
1794             * @throws PortalException if a user with the primary key could not be found
1795             * @throws SystemException if a system exception occurred
1796             */
1797            public void updateAsset(
1798                            long userId, Group group, long[] assetCategoryIds,
1799                            String[] assetTagNames)
1800                    throws PortalException, SystemException {
1801    
1802                    User user = userPersistence.findByPrimaryKey(userId);
1803    
1804                    Company company = companyPersistence.findByPrimaryKey(
1805                            user.getCompanyId());
1806    
1807                    Group companyGroup = company.getGroup();
1808    
1809                    assetEntryLocalService.updateEntry(
1810                            userId, companyGroup.getGroupId(), Group.class.getName(),
1811                            group.getGroupId(), null, 0, assetCategoryIds, assetTagNames, false,
1812                            null, null, null, null, null, group.getDescriptiveName(),
1813                            group.getDescription(), null, null, null, 0, 0, null, false);
1814            }
1815    
1816            /**
1817             * Updates the group's friendly URL.
1818             *
1819             * @param  groupId the primary key of the group
1820             * @param  friendlyURL the group's new friendlyURL (optionally
1821             *         <code>null</code>)
1822             * @return the group
1823             * @throws PortalException if a group with the primary key could not be
1824             *         found or if a valid friendly URL could not be created for the
1825             *         group
1826             * @throws SystemException if a system exception occurred
1827             */
1828            public Group updateFriendlyURL(long groupId, String friendlyURL)
1829                    throws PortalException, SystemException {
1830    
1831                    Group group = groupPersistence.findByPrimaryKey(groupId);
1832    
1833                    if (group.isUser()) {
1834                            User user = userPersistence.findByPrimaryKey(group.getClassPK());
1835    
1836                            friendlyURL = StringPool.SLASH + user.getScreenName();
1837    
1838                            if (group.getFriendlyURL().equals(friendlyURL)) {
1839                                    return group;
1840                            }
1841                    }
1842    
1843                    friendlyURL = getFriendlyURL(
1844                            group.getCompanyId(), groupId, group.getClassNameId(),
1845                            group.getClassPK(), StringPool.BLANK, friendlyURL);
1846    
1847                    validateFriendlyURL(
1848                            group.getCompanyId(), group.getGroupId(), group.getClassNameId(),
1849                            group.getClassPK(), friendlyURL);
1850    
1851                    group.setFriendlyURL(friendlyURL);
1852    
1853                    groupPersistence.update(group, false);
1854    
1855                    return group;
1856            }
1857    
1858            /**
1859             * Updates the group's type settings.
1860             *
1861             * @param  groupId the primary key of the group
1862             * @param  typeSettings the group's new type settings (optionally
1863             *         <code>null</code>)
1864             * @return the group
1865             * @throws PortalException if a group with the primary key could not be
1866             *         found
1867             * @throws SystemException if a system exception occurred
1868             */
1869            public Group updateGroup(long groupId, String typeSettings)
1870                    throws PortalException, SystemException {
1871    
1872                    Group group = groupPersistence.findByPrimaryKey(groupId);
1873    
1874                    group.setTypeSettings(typeSettings);
1875    
1876                    groupPersistence.update(group, false);
1877    
1878                    return group;
1879            }
1880    
1881            /**
1882             * Updates the group.
1883             *
1884             * @param  groupId the primary key of the group
1885             * @param  name the group's new name
1886             * @param  description the group's new description (optionally
1887             *         <code>null</code>)
1888             * @param  type the group's new type. For more information see {@link
1889             *         com.liferay.portal.model.GroupConstants}
1890             * @param  friendlyURL the group's new friendlyURL (optionally
1891             *         <code>null</code>)
1892             * @param  active whether the group is active
1893             * @param  serviceContext the service context to be applied (optionally
1894             *         <code>null</code>). Can set asset category IDs and asset tag
1895             *         names for the group.
1896             * @return the group
1897             * @throws PortalException if a group with the primary key could not be
1898             *         found or if the friendly URL was invalid or could one not be
1899             *         created
1900             * @throws SystemException if a system exception occurred
1901             */
1902            public Group updateGroup(
1903                            long groupId, String name, String description, int type,
1904                            String friendlyURL, boolean active, ServiceContext serviceContext)
1905                    throws PortalException, SystemException {
1906    
1907                    Group group = groupPersistence.findByPrimaryKey(groupId);
1908    
1909                    String className = group.getClassName();
1910                    long classNameId = group.getClassNameId();
1911                    long classPK = group.getClassPK();
1912                    friendlyURL = getFriendlyURL(
1913                            group.getCompanyId(), groupId, classNameId, classPK,
1914                            StringPool.BLANK, friendlyURL);
1915    
1916                    if ((classNameId <= 0) || className.equals(Group.class.getName())) {
1917                            validateName(group.getGroupId(), group.getCompanyId(), name);
1918                    }
1919                    else if (className.equals(Organization.class.getName())) {
1920                            name = getOrgGroupName(classPK, name);
1921                    }
1922                    else if (!GroupConstants.USER_PERSONAL_SITE.equals(name)) {
1923                            name = String.valueOf(classPK);
1924                    }
1925    
1926                    if (PortalUtil.isSystemGroup(group.getName()) &&
1927                            !group.getName().equals(name)) {
1928    
1929                            throw new RequiredGroupException();
1930                    }
1931    
1932                    validateFriendlyURL(
1933                            group.getCompanyId(), group.getGroupId(), group.getClassNameId(),
1934                            group.getClassPK(), friendlyURL);
1935    
1936                    group.setName(name);
1937                    group.setDescription(description);
1938                    group.setType(type);
1939                    group.setFriendlyURL(friendlyURL);
1940                    group.setActive(active);
1941    
1942                    groupPersistence.update(group, false);
1943    
1944                    // Asset
1945    
1946                    if ((serviceContext != null) && group.isSite()) {
1947                            User user = null;
1948    
1949                            try {
1950                                    user = userPersistence.findByPrimaryKey(
1951                                            group.getCreatorUserId());
1952    
1953                            }
1954                            catch (NoSuchUserException nsue1) {
1955                                    try {
1956                                            user = userPersistence.findByPrimaryKey(
1957                                                    serviceContext.getUserId());
1958                                    }
1959                                    catch (NoSuchUserException nsue2) {
1960                                            user = userLocalService.getDefaultUser(
1961                                                    group.getCompanyId());
1962                                    }
1963                            }
1964    
1965                            updateAsset(
1966                                    user.getUserId(), group, serviceContext.getAssetCategoryIds(),
1967                                    serviceContext.getAssetTagNames());
1968                    }
1969    
1970                    return group;
1971            }
1972    
1973            /**
1974             * Associates the group with a main site if the group is an organization.
1975             *
1976             * @param  groupId the primary key of the group
1977             * @param  site whether the group is to be associated with a main site
1978             * @return the group
1979             * @throws PortalException if a group with the primary key could not be
1980             *         found
1981             * @throws SystemException if a system exception occurred
1982             */
1983            public Group updateSite(long groupId, boolean site)
1984                    throws PortalException, SystemException {
1985    
1986                    Group group = groupPersistence.findByPrimaryKey(groupId);
1987    
1988                    if (!group.isOrganization()) {
1989                            return group;
1990                    }
1991    
1992                    group.setSite(site);
1993    
1994                    groupPersistence.update(group, false);
1995    
1996                    return group;
1997            }
1998    
1999            protected void addControlPanelLayouts(Group group)
2000                    throws PortalException, SystemException {
2001    
2002                    long defaultUserId = userLocalService.getDefaultUserId(
2003                            group.getCompanyId());
2004    
2005                    String friendlyURL = getFriendlyURL(
2006                            PropsValues.CONTROL_PANEL_LAYOUT_FRIENDLY_URL);
2007    
2008                    ServiceContext serviceContext = new ServiceContext();
2009    
2010                    layoutLocalService.addLayout(
2011                            defaultUserId, group.getGroupId(), true,
2012                            LayoutConstants.DEFAULT_PARENT_LAYOUT_ID,
2013                            PropsValues.CONTROL_PANEL_LAYOUT_NAME, StringPool.BLANK,
2014                            StringPool.BLANK, LayoutConstants.TYPE_CONTROL_PANEL, false,
2015                            friendlyURL, serviceContext);
2016            }
2017    
2018            protected void addDefaultGuestPublicLayoutByProperties(Group group)
2019                    throws PortalException, SystemException {
2020    
2021                    long defaultUserId = userLocalService.getDefaultUserId(
2022                            group.getCompanyId());
2023                    String friendlyURL = getFriendlyURL(
2024                            PropsValues.DEFAULT_GUEST_PUBLIC_LAYOUT_FRIENDLY_URL);
2025    
2026                    ServiceContext serviceContext = new ServiceContext();
2027    
2028                    Layout layout = layoutLocalService.addLayout(
2029                            defaultUserId, group.getGroupId(), false,
2030                            LayoutConstants.DEFAULT_PARENT_LAYOUT_ID,
2031                            PropsValues.DEFAULT_GUEST_PUBLIC_LAYOUT_NAME, StringPool.BLANK,
2032                            StringPool.BLANK, LayoutConstants.TYPE_PORTLET, false, friendlyURL,
2033                            serviceContext);
2034    
2035                    LayoutTypePortlet layoutTypePortlet =
2036                            (LayoutTypePortlet)layout.getLayoutType();
2037    
2038                    layoutTypePortlet.setLayoutTemplateId(
2039                            0, PropsValues.DEFAULT_GUEST_PUBLIC_LAYOUT_TEMPLATE_ID, false);
2040    
2041                    for (int i = 0; i < 10; i++) {
2042                            String columnId = "column-" + i;
2043                            String portletIds = PropsUtil.get(
2044                                    PropsKeys.DEFAULT_GUEST_PUBLIC_LAYOUT_COLUMN + i);
2045    
2046                            layoutTypePortlet.addPortletIds(
2047                                    0, StringUtil.split(portletIds), columnId, false);
2048                    }
2049    
2050                    layoutLocalService.updateLayout(
2051                            layout.getGroupId(), layout.isPrivateLayout(), layout.getLayoutId(),
2052                            layout.getTypeSettings());
2053    
2054                    boolean updateLayoutSet = false;
2055    
2056                    LayoutSet layoutSet = layout.getLayoutSet();
2057    
2058                    if (Validator.isNotNull(
2059                                    PropsValues.DEFAULT_GUEST_PUBLIC_LAYOUT_REGULAR_THEME_ID)) {
2060    
2061                            layoutSet.setThemeId(
2062                                    PropsValues.DEFAULT_GUEST_PUBLIC_LAYOUT_REGULAR_THEME_ID);
2063    
2064                            updateLayoutSet = true;
2065                    }
2066    
2067                    if (Validator.isNotNull(
2068                                    PropsValues.
2069                                            DEFAULT_GUEST_PUBLIC_LAYOUT_REGULAR_COLOR_SCHEME_ID)) {
2070    
2071                            layoutSet.setColorSchemeId(
2072                                    PropsValues.
2073                                            DEFAULT_GUEST_PUBLIC_LAYOUT_REGULAR_COLOR_SCHEME_ID);
2074    
2075                            updateLayoutSet = true;
2076                    }
2077    
2078                    if (Validator.isNotNull(
2079                                    PropsValues.DEFAULT_GUEST_PUBLIC_LAYOUT_WAP_THEME_ID)) {
2080    
2081                            layoutSet.setWapThemeId(
2082                                    PropsValues.DEFAULT_GUEST_PUBLIC_LAYOUT_WAP_THEME_ID);
2083    
2084                            updateLayoutSet = true;
2085                    }
2086    
2087                    if (Validator.isNotNull(
2088                                    PropsValues.DEFAULT_GUEST_PUBLIC_LAYOUT_WAP_COLOR_SCHEME_ID)) {
2089    
2090                            layoutSet.setWapColorSchemeId(
2091                                    PropsValues.DEFAULT_GUEST_PUBLIC_LAYOUT_WAP_COLOR_SCHEME_ID);
2092    
2093                            updateLayoutSet = true;
2094                    }
2095    
2096                    if (updateLayoutSet) {
2097                            layoutSetLocalService.updateLayoutSet(layoutSet);
2098                    }
2099            }
2100    
2101            protected void addDefaultGuestPublicLayouts(Group group)
2102                    throws PortalException, SystemException {
2103    
2104                    if (publicLARFile != null) {
2105                            addDefaultGuestPublicLayoutsByLAR(group, publicLARFile);
2106                    }
2107                    else {
2108                            addDefaultGuestPublicLayoutByProperties(group);
2109                    }
2110            }
2111    
2112            protected void addDefaultGuestPublicLayoutsByLAR(Group group, File larFile)
2113                    throws PortalException, SystemException {
2114    
2115                    long defaultUserId = userLocalService.getDefaultUserId(
2116                            group.getCompanyId());
2117    
2118                    Map<String, String[]> parameterMap = new HashMap<String, String[]>();
2119    
2120                    parameterMap.put(
2121                            PortletDataHandlerKeys.CATEGORIES,
2122                            new String[] {Boolean.TRUE.toString()});
2123                    parameterMap.put(
2124                            PortletDataHandlerKeys.PERMISSIONS,
2125                            new String[] {Boolean.TRUE.toString()});
2126                    parameterMap.put(
2127                            PortletDataHandlerKeys.PORTLET_DATA,
2128                            new String[] {Boolean.TRUE.toString()});
2129                    parameterMap.put(
2130                            PortletDataHandlerKeys.PORTLET_DATA_CONTROL_DEFAULT,
2131                            new String[] {Boolean.TRUE.toString()});
2132                    parameterMap.put(
2133                            PortletDataHandlerKeys.PORTLET_SETUP,
2134                            new String[] {Boolean.TRUE.toString()});
2135                    parameterMap.put(
2136                            PortletDataHandlerKeys.USER_PERMISSIONS,
2137                            new String[] {Boolean.FALSE.toString()});
2138    
2139                    layoutLocalService.importLayouts(
2140                            defaultUserId, group.getGroupId(), false, parameterMap, larFile);
2141            }
2142    
2143            protected String getFriendlyURL(
2144                            long companyId, long groupId, long classNameId, long classPK,
2145                            String friendlyName, String friendlyURL)
2146                    throws PortalException, SystemException {
2147    
2148                    friendlyURL = getFriendlyURL(friendlyURL);
2149    
2150                    if (Validator.isNotNull(friendlyURL)) {
2151                            return friendlyURL;
2152                    }
2153    
2154                    friendlyURL = StringPool.SLASH + getFriendlyURL(friendlyName);
2155    
2156                    String originalFriendlyURL = friendlyURL;
2157    
2158                    for (int i = 1;; i++) {
2159                            try {
2160                                    validateFriendlyURL(
2161                                            companyId, groupId, classNameId, classPK, friendlyURL);
2162    
2163                                    break;
2164                            }
2165                            catch (GroupFriendlyURLException gfurle) {
2166                                    int type = gfurle.getType();
2167    
2168                                    if (type == GroupFriendlyURLException.DUPLICATE) {
2169                                            friendlyURL = originalFriendlyURL + i;
2170                                    }
2171                                    else {
2172                                            friendlyURL = StringPool.SLASH + classPK;
2173    
2174                                            break;
2175                                    }
2176                            }
2177                    }
2178    
2179                    return friendlyURL;
2180            }
2181    
2182            protected String getFriendlyURL(String friendlyURL) {
2183                    return FriendlyURLNormalizerUtil.normalize(friendlyURL);
2184            }
2185    
2186            protected String getOrgGroupName(long classPK, String name) {
2187                    return classPK + _ORGANIZATION_NAME_DELIMETER + name;
2188            }
2189    
2190            protected String getRealName(long companyId, String name)
2191                    throws SystemException {
2192    
2193                    if (Validator.isNull(name)) {
2194                            return name;
2195                    }
2196    
2197                    String realName = name;
2198    
2199                    try {
2200                            Company company = companyLocalService.getCompany(companyId);
2201    
2202                            Account account = company.getAccount();
2203    
2204                            String companyName = account.getName();
2205    
2206                            name = StringUtil.replace(
2207                                    name, StringPool.PERCENT, StringPool.BLANK);
2208    
2209                            if (companyName.indexOf(name) != -1) {
2210                                    realName = StringPool.PERCENT + GroupConstants.GUEST +
2211                                            StringPool.PERCENT;
2212                            }
2213                    }
2214                    catch (PortalException pe) {
2215                    }
2216    
2217                    return realName;
2218            }
2219    
2220            protected void initImportLARFile() {
2221                    String publicLARFileName = PropsValues.DEFAULT_GUEST_PUBLIC_LAYOUTS_LAR;
2222    
2223                    if (_log.isDebugEnabled()) {
2224                            _log.debug("Reading public LAR file " + publicLARFileName);
2225                    }
2226    
2227                    if (Validator.isNotNull(publicLARFileName)) {
2228                            publicLARFile = new File(publicLARFileName);
2229    
2230                            if (!publicLARFile.exists()) {
2231                                    _log.error(
2232                                            "Public LAR file " + publicLARFile + " does not exist");
2233    
2234                                    publicLARFile = null;
2235                            }
2236                            else {
2237                                    if (_log.isDebugEnabled()) {
2238                                            _log.debug("Using public LAR file " + publicLARFileName);
2239                                    }
2240                            }
2241                    }
2242            }
2243    
2244            protected void initUserPersonalSitePermissions(Group group)
2245                    throws PortalException, SystemException {
2246    
2247                    // User role
2248    
2249                    Role role = roleLocalService.getRole(
2250                            group.getCompanyId(), RoleConstants.USER);
2251    
2252                    setCompanyPermissions(
2253                            role, PortletKeys.PORTAL,
2254                            new String[] {ActionKeys.VIEW_CONTROL_PANEL});
2255    
2256                    List<Portlet> portlets = portletLocalService.getPortlets(
2257                            group.getCompanyId(), false, false);
2258    
2259                    for (Portlet portlet : portlets) {
2260                            setRolePermissions(
2261                                    group, role, portlet.getPortletId(),
2262                                    new String[] {ActionKeys.VIEW});
2263                    }
2264    
2265                    setRolePermissions(
2266                            group, role, Layout.class.getName(),
2267                            new String[] {ActionKeys.VIEW});
2268    
2269                    setRolePermissions(
2270                            group, role, "com.liferay.portlet.blogs",
2271                            new String[] {
2272                                    ActionKeys.ADD_ENTRY, ActionKeys.PERMISSIONS,
2273                                    ActionKeys.SUBSCRIBE});
2274    
2275                    setRolePermissions(
2276                            group, role, "com.liferay.portlet.calendar",
2277                            new String[] {
2278                                    ActionKeys.ADD_EVENT, ActionKeys.EXPORT_ALL_EVENTS,
2279                                    ActionKeys.PERMISSIONS});
2280    
2281                    // Power User role
2282    
2283                    role = roleLocalService.getRole(
2284                            group.getCompanyId(), RoleConstants.POWER_USER);
2285    
2286                    for (Portlet portlet : portlets) {
2287                            List<String> actions =
2288                                    ResourceActionsUtil.getPortletResourceActions(
2289                                            portlet.getPortletId());
2290    
2291                            String controlPanelEntryCategory = GetterUtil.getString(
2292                                    portlet.getControlPanelEntryCategory());
2293    
2294                            if (actions.contains(ActionKeys.ACCESS_IN_CONTROL_PANEL) &&
2295                                    controlPanelEntryCategory.equals(PortletCategoryKeys.CONTENT)) {
2296    
2297                                    setRolePermissions(
2298                                            group, role, portlet.getPortletId(),
2299                                            new String[] {ActionKeys.ACCESS_IN_CONTROL_PANEL});
2300                            }
2301                    }
2302    
2303                    setRolePermissions(
2304                            group, role, Group.class.getName(),
2305                            new String[] {ActionKeys.MANAGE_LAYOUTS});
2306    
2307                    setRolePermissions(group, role, "com.liferay.portlet.asset");
2308                    setRolePermissions(group, role, "com.liferay.portlet.blogs");
2309                    setRolePermissions(group, role, "com.liferay.portlet.bookmarks");
2310                    setRolePermissions(group, role, "com.liferay.portlet.calendar");
2311                    setRolePermissions(group, role, "com.liferay.portlet.documentlibrary");
2312                    setRolePermissions(group, role, "com.liferay.portlet.imagegallery");
2313                    setRolePermissions(group, role, "com.liferay.portlet.messageboards");
2314                    setRolePermissions(group, role, "com.liferay.portlet.polls");
2315                    setRolePermissions(group, role, "com.liferay.portlet.wiki");
2316            }
2317    
2318            protected boolean isStaging(ServiceContext serviceContext) {
2319                    if (serviceContext != null) {
2320                            return ParamUtil.getBoolean(serviceContext, "staging");
2321                    }
2322    
2323                    return false;
2324            }
2325    
2326            protected void setCompanyPermissions(
2327                            Role role, String name, String[] actionIds)
2328                    throws PortalException, SystemException {
2329    
2330                    if (PropsValues.PERMISSIONS_USER_CHECK_ALGORITHM == 6) {
2331                            if (resourceBlockLocalService.isSupported(name)) {
2332                                    resourceBlockLocalService.setCompanyScopePermissions(
2333                                            role.getCompanyId(), name, role.getRoleId(),
2334                                            Arrays.asList(actionIds));
2335                            }
2336                            else {
2337                                    resourcePermissionLocalService.setResourcePermissions(
2338                                            role.getCompanyId(), name, ResourceConstants.SCOPE_COMPANY,
2339                                            String.valueOf(role.getCompanyId()), role.getRoleId(),
2340                                            actionIds);
2341                            }
2342                    }
2343                    else {
2344                            permissionLocalService.setRolePermissions(
2345                                    role.getRoleId(), role.getCompanyId(), name,
2346                                    ResourceConstants.SCOPE_COMPANY,
2347                                    String.valueOf(role.getCompanyId()), actionIds);
2348                    }
2349            }
2350    
2351            protected void setRolePermissions(Group group, Role role, String name)
2352                    throws PortalException, SystemException {
2353    
2354                    List<String> actions = ResourceActionsUtil.getModelResourceActions(
2355                            name);
2356    
2357                    setRolePermissions(
2358                            group, role, name, actions.toArray(new String[actions.size()]));
2359            }
2360    
2361            protected void setRolePermissions(
2362                            Group group, Role role, String name, String[] actionIds)
2363                    throws PortalException, SystemException {
2364    
2365                    if (PropsValues.PERMISSIONS_USER_CHECK_ALGORITHM == 6) {
2366                            if (resourceBlockLocalService.isSupported(name)) {
2367                                    resourceBlockLocalService.setGroupScopePermissions(
2368                                            role.getCompanyId(), group.getGroupId(), name,
2369                                            role.getRoleId(), Arrays.asList(actionIds));
2370                            }
2371                            else {
2372                                    resourcePermissionLocalService.setResourcePermissions(
2373                                            group.getCompanyId(), name, ResourceConstants.SCOPE_GROUP,
2374                                            String.valueOf(group.getGroupId()), role.getRoleId(),
2375                                            actionIds);
2376                            }
2377                    }
2378                    else {
2379                            permissionLocalService.setRolePermissions(
2380                                    role.getRoleId(), group.getCompanyId(), name,
2381                                    ResourceConstants.SCOPE_GROUP,
2382                                    String.valueOf(group.getGroupId()), actionIds);
2383                    }
2384            }
2385    
2386            protected void unscheduleStaging(Group group) {
2387                    try {
2388    
2389                            // Remote publishing
2390    
2391                            String groupName = StagingUtil.getSchedulerGroupName(
2392                                    DestinationNames.LAYOUTS_REMOTE_PUBLISHER, group.getGroupId());
2393    
2394                            SchedulerEngineUtil.delete(groupName, StorageType.PERSISTED);
2395    
2396                            long liveGroupId = 0;
2397                            long stagingGroupId = 0;
2398    
2399                            if (group.isStagingGroup()) {
2400                                    liveGroupId = group.getLiveGroupId();
2401    
2402                                    stagingGroupId = group.getGroupId();
2403                            }
2404                            else if (group.hasStagingGroup()) {
2405                                    liveGroupId = group.getGroupId();
2406    
2407                                    stagingGroupId = group.getStagingGroup().getGroupId();
2408                            }
2409    
2410                            if ((liveGroupId != 0) && (stagingGroupId != 0)) {
2411    
2412                                    // Publish to live
2413    
2414                                    groupName = StagingUtil.getSchedulerGroupName(
2415                                            DestinationNames.LAYOUTS_LOCAL_PUBLISHER, liveGroupId);
2416    
2417                                    SchedulerEngineUtil.delete(groupName, StorageType.PERSISTED);
2418    
2419                                    // Copy from live
2420    
2421                                    groupName = StagingUtil.getSchedulerGroupName(
2422                                            DestinationNames.LAYOUTS_LOCAL_PUBLISHER, stagingGroupId);
2423    
2424                                    SchedulerEngineUtil.delete(groupName, StorageType.PERSISTED);
2425                            }
2426                    }
2427                    catch (Exception e) {
2428                            _log.error(
2429                                    "Unable to unschedule events for group: " + group.getGroupId());
2430                    }
2431            }
2432    
2433            protected void validateFriendlyURL(
2434                            long companyId, long groupId, long classNameId, long classPK,
2435                            String friendlyURL)
2436                    throws PortalException, SystemException {
2437    
2438                    Company company = companyPersistence.findByPrimaryKey(companyId);
2439    
2440                    if (company.isSystem()) {
2441                            return;
2442                    }
2443    
2444                    if (Validator.isNull(friendlyURL)) {
2445                            return;
2446                    }
2447    
2448                    int exceptionType = LayoutImpl.validateFriendlyURL(friendlyURL);
2449    
2450                    if (exceptionType != -1) {
2451                            throw new GroupFriendlyURLException(exceptionType);
2452                    }
2453    
2454                    Group group = groupPersistence.fetchByC_F(companyId, friendlyURL);
2455    
2456                    if ((group != null) && (group.getGroupId() != groupId)) {
2457                            throw new GroupFriendlyURLException(
2458                                    GroupFriendlyURLException.DUPLICATE);
2459                    }
2460    
2461                    String groupIdFriendlyURL = friendlyURL.substring(1);
2462    
2463                    if (Validator.isNumber(groupIdFriendlyURL)) {
2464                            long groupClassNameId = PortalUtil.getClassNameId(Group.class);
2465    
2466                            if (((classNameId != groupClassNameId) &&
2467                                     (!groupIdFriendlyURL.equals(String.valueOf(classPK))) &&
2468                                     (!PropsValues.USERS_SCREEN_NAME_ALLOW_NUMERIC)) ||
2469                                    ((classNameId == groupClassNameId) &&
2470                                     (!groupIdFriendlyURL.equals(String.valueOf(groupId))))) {
2471    
2472                                    GroupFriendlyURLException gfurle =
2473                                            new GroupFriendlyURLException(
2474                                                    GroupFriendlyURLException.POSSIBLE_DUPLICATE);
2475    
2476                                    gfurle.setKeywordConflict(groupIdFriendlyURL);
2477    
2478                                    throw gfurle;
2479                            }
2480                    }
2481    
2482                    String screenName = friendlyURL.substring(1);
2483    
2484                    User user = userPersistence.fetchByC_SN(companyId, screenName);
2485    
2486                    if (user != null) {
2487                            long userClassNameId = PortalUtil.getClassNameId(User.class);
2488    
2489                            if ((classNameId == userClassNameId) &&
2490                                    (classPK == user.getUserId())) {
2491                            }
2492                            else {
2493                                    throw new GroupFriendlyURLException(
2494                                            GroupFriendlyURLException.DUPLICATE);
2495                            }
2496                    }
2497    
2498                    if (StringUtil.count(friendlyURL, StringPool.SLASH) > 1) {
2499                            throw new GroupFriendlyURLException(
2500                                    GroupFriendlyURLException.TOO_DEEP);
2501                    }
2502            }
2503    
2504            protected void validateName(long groupId, long companyId, String name)
2505                    throws PortalException, SystemException {
2506    
2507                    if ((Validator.isNull(name)) || (Validator.isNumber(name)) ||
2508                            (name.indexOf(CharPool.STAR) != -1) ||
2509                            (name.indexOf(_ORGANIZATION_NAME_DELIMETER) != -1)) {
2510    
2511                            throw new GroupNameException();
2512                    }
2513    
2514                    try {
2515                            Group group = groupFinder.findByC_N(companyId, name);
2516    
2517                            if ((groupId <= 0) || (group.getGroupId() != groupId)) {
2518                                    throw new DuplicateGroupException();
2519                            }
2520                    }
2521                    catch (NoSuchGroupException nsge) {
2522                    }
2523            }
2524    
2525            protected File publicLARFile;
2526    
2527            private static final String _ORGANIZATION_NAME_DELIMETER =
2528                    " LFR_ORGANIZATION ";
2529    
2530            private static Log _log = LogFactoryUtil.getLog(
2531                    GroupLocalServiceImpl.class);
2532    
2533            private Map<String, Group> _systemGroupsMap = new HashMap<String, Group>();
2534    
2535    }