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