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