001    /**
002     * Copyright (c) 2000-2010 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.annotation.Propagation;
025    import com.liferay.portal.kernel.annotation.Transactional;
026    import com.liferay.portal.kernel.cache.ThreadLocalCachable;
027    import com.liferay.portal.kernel.dao.orm.QueryUtil;
028    import com.liferay.portal.kernel.exception.PortalException;
029    import com.liferay.portal.kernel.exception.SystemException;
030    import com.liferay.portal.kernel.lar.PortletDataHandlerKeys;
031    import com.liferay.portal.kernel.log.Log;
032    import com.liferay.portal.kernel.log.LogFactoryUtil;
033    import com.liferay.portal.kernel.messaging.DestinationNames;
034    import com.liferay.portal.kernel.scheduler.SchedulerEngineUtil;
035    import com.liferay.portal.kernel.scheduler.messaging.SchedulerRequest;
036    import com.liferay.portal.kernel.staging.StagingUtil;
037    import com.liferay.portal.kernel.util.GetterUtil;
038    import com.liferay.portal.kernel.util.OrderByComparator;
039    import com.liferay.portal.kernel.util.PropsKeys;
040    import com.liferay.portal.kernel.util.StringPool;
041    import com.liferay.portal.kernel.util.StringUtil;
042    import com.liferay.portal.kernel.util.UnicodeProperties;
043    import com.liferay.portal.kernel.util.Validator;
044    import com.liferay.portal.model.Account;
045    import com.liferay.portal.model.Company;
046    import com.liferay.portal.model.Group;
047    import com.liferay.portal.model.GroupConstants;
048    import com.liferay.portal.model.Layout;
049    import com.liferay.portal.model.LayoutConstants;
050    import com.liferay.portal.model.LayoutPrototype;
051    import com.liferay.portal.model.LayoutSet;
052    import com.liferay.portal.model.LayoutSetPrototype;
053    import com.liferay.portal.model.LayoutTypePortlet;
054    import com.liferay.portal.model.Organization;
055    import com.liferay.portal.model.Resource;
056    import com.liferay.portal.model.ResourceConstants;
057    import com.liferay.portal.model.Role;
058    import com.liferay.portal.model.RoleConstants;
059    import com.liferay.portal.model.User;
060    import com.liferay.portal.model.UserGroup;
061    import com.liferay.portal.model.impl.LayoutImpl;
062    import com.liferay.portal.security.permission.PermissionCacheUtil;
063    import com.liferay.portal.service.ServiceContext;
064    import com.liferay.portal.service.base.GroupLocalServiceBaseImpl;
065    import com.liferay.portal.util.FriendlyURLNormalizer;
066    import com.liferay.portal.util.PortalUtil;
067    import com.liferay.portal.util.PropsUtil;
068    import com.liferay.portal.util.PropsValues;
069    import com.liferay.portal.util.comparator.GroupNameComparator;
070    import com.liferay.portlet.blogs.model.BlogsEntry;
071    import com.liferay.portlet.journal.model.JournalArticle;
072    import com.liferay.util.UniqueList;
073    
074    import java.io.File;
075    
076    import java.util.ArrayList;
077    import java.util.HashMap;
078    import java.util.Iterator;
079    import java.util.LinkedHashMap;
080    import java.util.List;
081    import java.util.Map;
082    
083    /**
084     * @author Brian Wing Shun Chan
085     * @author Alexander Chow
086     * @author Bruno Farache
087     * @author Wesley Gong
088     */
089    public class GroupLocalServiceImpl extends GroupLocalServiceBaseImpl {
090    
091            public GroupLocalServiceImpl() {
092                    initImportLARFile();
093            }
094    
095            public Group addGroup(
096                            long userId, String className, long classPK, String name,
097                            String description, int type, String friendlyURL, boolean active,
098                            ServiceContext serviceContext)
099                    throws PortalException, SystemException {
100    
101                    return addGroup(
102                            userId, className, classPK, GroupConstants.DEFAULT_LIVE_GROUP_ID,
103                            name, description, type, friendlyURL, active, serviceContext);
104            }
105    
106            public Group addGroup(
107                            long userId, String className, long classPK, long liveGroupId,
108                            String name, String description, int type, String friendlyURL,
109                            boolean active, ServiceContext serviceContext)
110                    throws PortalException, SystemException {
111    
112                    // Group
113    
114                    User user = userPersistence.findByPrimaryKey(userId);
115                    className = GetterUtil.getString(className);
116                    long classNameId = PortalUtil.getClassNameId(className);
117    
118                    String friendlyName = name;
119    
120                    if (className.equals(Organization.class.getName())) {
121                            Organization organization =
122                                    organizationPersistence.findByPrimaryKey(classPK);
123    
124                            friendlyName = organization.getName();
125                    }
126    
127                    long groupId = 0;
128    
129                    while (true) {
130                            groupId = counterLocalService.increment();
131    
132                            User userScreenName = userPersistence.fetchByC_SN(
133                                    user.getCompanyId(), String.valueOf(groupId));
134    
135                            if (userScreenName == null) {
136                                    break;
137                            }
138                    }
139    
140                    long groupClassNameId = PortalUtil.getClassNameId(Group.class);
141    
142                    if ((classNameId <= 0) || className.equals(Group.class.getName())) {
143                            validateName(groupId, user.getCompanyId(), name);
144    
145                            classNameId = groupClassNameId;
146                            classPK = groupId;
147                    }
148                    else {
149                            name = String.valueOf(classPK);
150                    }
151    
152                    long parentGroupId = GroupConstants.DEFAULT_PARENT_GROUP_ID;
153    
154                    if (className.equals(Layout.class.getName())) {
155                            Layout layout = layoutLocalService.getLayout(classPK);
156    
157                            parentGroupId = layout.getGroupId();
158                    }
159    
160                    friendlyURL = getFriendlyURL(
161                            user.getCompanyId(), groupId, classNameId, classPK, friendlyName,
162                            friendlyURL);
163    
164                    validateFriendlyURL(
165                            user.getCompanyId(), groupId, classNameId, classPK, friendlyURL);
166    
167                    Group group = groupPersistence.create(groupId);
168    
169                    group.setCompanyId(user.getCompanyId());
170                    group.setCreatorUserId(userId);
171                    group.setClassNameId(classNameId);
172                    group.setClassPK(classPK);
173                    group.setParentGroupId(parentGroupId);
174                    group.setLiveGroupId(liveGroupId);
175                    group.setName(name);
176                    group.setDescription(description);
177                    group.setType(type);
178                    group.setFriendlyURL(friendlyURL);
179                    group.setActive(active);
180    
181                    groupPersistence.update(group, false);
182    
183                    // Layout sets
184    
185                    layoutSetLocalService.addLayoutSet(groupId, true);
186    
187                    layoutSetLocalService.addLayoutSet(groupId, false);
188    
189                    if ((classNameId == groupClassNameId) && !user.isDefaultUser()) {
190    
191                            // Resources
192    
193                            resourceLocalService.addResources(
194                                    group.getCompanyId(), 0, 0, Group.class.getName(),
195                                    group.getGroupId(), false, false, false);
196    
197                            // Community roles
198    
199                            Role role = roleLocalService.getRole(
200                                    group.getCompanyId(), RoleConstants.COMMUNITY_OWNER);
201    
202                            userGroupRoleLocalService.addUserGroupRoles(
203                                    userId, groupId, new long[] {role.getRoleId()});
204    
205                            // User
206    
207                            userLocalService.addGroupUsers(
208                                    group.getGroupId(), new long[] {userId});
209    
210                            // Asset
211    
212                            if (serviceContext != null) {
213                                    updateAsset(
214                                            userId, group, serviceContext.getAssetCategoryIds(),
215                                            serviceContext.getAssetTagNames());
216                            }
217                    }
218                    else if (className.equals(Organization.class.getName()) &&
219                                     !user.isDefaultUser()) {
220    
221                            // Resources
222    
223                            resourceLocalService.addResources(
224                                    group.getCompanyId(), 0, 0, Group.class.getName(),
225                                    group.getGroupId(), false, false, false);
226                    }
227    
228                    return group;
229            }
230    
231            public void addRoleGroups(long roleId, long[] groupIds)
232                    throws SystemException {
233    
234                    rolePersistence.addGroups(roleId, groupIds);
235    
236                    PermissionCacheUtil.clearCache();
237            }
238    
239            public void addUserGroups(long userId, long[] groupIds)
240                    throws SystemException {
241    
242                    userPersistence.addGroups(userId, groupIds);
243    
244                    PermissionCacheUtil.clearCache();
245            }
246    
247            @Transactional(propagation = Propagation.SUPPORTS, readOnly = true)
248            public void checkCompanyGroup(long companyId)
249                    throws PortalException, SystemException {
250    
251                    long classNameId = PortalUtil.getClassNameId(Company.class);
252    
253                    int count = groupPersistence.countByC_C_C(
254                            companyId, classNameId, companyId);
255    
256                    if (count == 0) {
257                            long defaultUserId = userLocalService.getDefaultUserId(companyId);
258    
259                            groupLocalService.addGroup(
260                                    defaultUserId, Company.class.getName(), companyId, null, null,
261                                    0, null, true, null);
262                    }
263            }
264    
265            @Transactional(propagation = Propagation.SUPPORTS, readOnly = true)
266            public void checkSystemGroups(long companyId)
267                    throws PortalException, SystemException {
268    
269                    for (Group group : groupFinder.findBySystem(companyId)) {
270                            _systemGroupsMap.put(companyId + group.getName(), group);
271                    }
272    
273                    long defaultUserId = userLocalService.getDefaultUserId(companyId);
274    
275                    String[] systemGroups = PortalUtil.getSystemGroups();
276    
277                    for (String name : systemGroups) {
278                            Group group = _systemGroupsMap.get(companyId + name);
279    
280                            try {
281                                    if (group == null) {
282                                            group = groupPersistence.findByC_N(companyId, name);
283                                    }
284                            }
285                            catch (NoSuchGroupException nsge) {
286                                    int type = GroupConstants.TYPE_COMMUNITY_OPEN;
287                                    String friendlyURL = null;
288    
289                                    if (name.equals(GroupConstants.CONTROL_PANEL)) {
290                                            type = GroupConstants.TYPE_COMMUNITY_PRIVATE;
291                                            friendlyURL = GroupConstants.CONTROL_PANEL_FRIENDLY_URL;
292                                    }
293                                    else if (name.equals(GroupConstants.GUEST)) {
294                                            friendlyURL = "/guest";
295                                    }
296    
297                                    group = groupLocalService.addGroup(
298                                            defaultUserId, null, 0, name, null, type, friendlyURL,
299                                            true, null);
300                            }
301    
302                            if (group.isControlPanel()) {
303                                    LayoutSet layoutSet = layoutSetLocalService.getLayoutSet(
304                                            group.getGroupId(), true);
305    
306                                    if (layoutSet.getPageCount() == 0) {
307                                            addControlPanelLayouts(group);
308                                    }
309                            }
310    
311                            if (group.getName().equals(GroupConstants.GUEST)) {
312                                    LayoutSet layoutSet = layoutSetLocalService.getLayoutSet(
313                                            group.getGroupId(), false);
314    
315                                    if (layoutSet.getPageCount() == 0) {
316                                            addDefaultGuestPublicLayouts(group);
317                                    }
318                            }
319    
320                            _systemGroupsMap.put(companyId + name, group);
321                    }
322            }
323    
324            public void deleteGroup(long groupId)
325                    throws PortalException, SystemException {
326    
327                    Group group = groupPersistence.findByPrimaryKey(groupId);
328    
329                    if (PortalUtil.isSystemGroup(group.getName())) {
330                            throw new RequiredGroupException(String.valueOf(groupId));
331                    }
332    
333                    // Layout sets
334    
335                    try {
336                            layoutSetLocalService.deleteLayoutSet(groupId, true);
337                    }
338                    catch (NoSuchLayoutSetException nslse) {
339                    }
340    
341                    try {
342                            layoutSetLocalService.deleteLayoutSet(groupId, false);
343                    }
344                    catch (NoSuchLayoutSetException nslse) {
345                    }
346    
347                    // Group roles
348    
349                    userGroupRoleLocalService.deleteUserGroupRolesByGroupId(groupId);
350    
351                    // User group roles
352    
353                    userGroupGroupRoleLocalService.deleteUserGroupGroupRolesByGroupId(
354                            groupId);
355    
356                    // Membership requests
357    
358                    membershipRequestLocalService.deleteMembershipRequests(
359                            group.getGroupId());
360    
361                    // Subscriptions
362    
363                    subscriptionLocalService.deleteSubscriptions(
364                            group.getCompanyId(), BlogsEntry.class.getName(),
365                            group.getGroupId());
366                    subscriptionLocalService.deleteSubscriptions(
367                            group.getCompanyId(), JournalArticle.class.getName(),
368                            group.getGroupId());
369    
370                    /// Teams
371    
372                    teamLocalService.deleteTeams(group.getGroupId());
373    
374                    // Staging
375    
376                    unscheduleStaging(group);
377    
378                    if (group.hasStagingGroup()) {
379                            deleteGroup(group.getStagingGroup().getGroupId());
380                    }
381    
382                    // Asset
383    
384                    if (group.isCommunity()) {
385                            assetEntryLocalService.deleteEntry(Group.class.getName(), groupId);
386                    }
387    
388                    // Blogs
389    
390                    blogsEntryLocalService.deleteEntries(groupId);
391                    blogsStatsUserLocalService.deleteStatsUserByGroupId(groupId);
392    
393                    // Bookmarks
394    
395                    bookmarksFolderLocalService.deleteFolders(groupId);
396    
397                    // Calendar
398    
399                    calEventLocalService.deleteEvents(groupId);
400    
401                    // Document library
402    
403                    dlFolderLocalService.deleteFolders(groupId);
404    
405                    // Image gallery
406    
407                    igFolderLocalService.deleteFolders(groupId);
408    
409                    // Journal
410    
411                    journalArticleLocalService.deleteArticles(groupId);
412                    journalTemplateLocalService.deleteTemplates(groupId);
413                    journalStructureLocalService.deleteStructures(groupId);
414    
415                    // Message boards
416    
417                    mbBanLocalService.deleteBansByGroupId(groupId);
418                    mbCategoryLocalService.deleteCategories(groupId);
419                    mbStatsUserLocalService.deleteStatsUsersByGroupId(groupId);
420    
421                    // Polls
422    
423                    pollsQuestionLocalService.deleteQuestions(groupId);
424    
425                    // Shopping
426    
427                    shoppingCartLocalService.deleteGroupCarts(groupId);
428                    shoppingCategoryLocalService.deleteCategories(groupId);
429                    shoppingCouponLocalService.deleteCoupons(groupId);
430                    shoppingOrderLocalService.deleteOrders(groupId);
431    
432                    // Software catalog
433    
434                    scFrameworkVersionLocalService.deleteFrameworkVersions(groupId);
435                    scProductEntryLocalService.deleteProductEntries(groupId);
436    
437                    // Wiki
438    
439                    wikiNodeLocalService.deleteNodes(groupId);
440    
441                    // Resources
442    
443                    Iterator<Resource> itr = resourceFinder.findByC_P(
444                            group.getCompanyId(), String.valueOf(groupId)).iterator();
445    
446                    while (itr.hasNext()) {
447                            Resource resource = itr.next();
448    
449                            resourceLocalService.deleteResource(resource);
450                    }
451    
452                    if (!group.isStagingGroup() &&
453                            (group.isCommunity() || group.isOrganization())) {
454    
455                            resourceLocalService.deleteResource(
456                                    group.getCompanyId(), Group.class.getName(),
457                                    ResourceConstants.SCOPE_INDIVIDUAL, group.getGroupId());
458                    }
459    
460                    // Group
461    
462                    groupPersistence.remove(group);
463    
464                    // Permission cache
465    
466                    PermissionCacheUtil.clearCache();
467            }
468    
469            public Group getCompanyGroup(long companyId)
470                    throws PortalException, SystemException {
471    
472                    long classNameId = PortalUtil.getClassNameId(Company.class);
473    
474                    return groupPersistence.findByC_C_C(companyId, classNameId, companyId);
475            }
476    
477            public List<Group> getCompanyGroups(long companyId, int start, int end)
478                    throws SystemException {
479    
480                    return groupPersistence.findByCompanyId(companyId, start, end);
481            }
482    
483            public int getCompanyGroupsCount(long companyId) throws SystemException {
484                    return groupPersistence.countByCompanyId(companyId);
485            }
486    
487            public Group getFriendlyURLGroup(long companyId, String friendlyURL)
488                    throws PortalException, SystemException {
489    
490                    if (Validator.isNull(friendlyURL)) {
491                            throw new NoSuchGroupException();
492                    }
493    
494                    friendlyURL = getFriendlyURL(friendlyURL);
495    
496                    return groupPersistence.findByC_F(companyId, friendlyURL);
497            }
498    
499            public Group getGroup(long groupId)
500                    throws PortalException, SystemException {
501    
502                    return groupPersistence.findByPrimaryKey(groupId);
503            }
504    
505            public Group getGroup(long companyId, String name)
506                    throws PortalException, SystemException {
507    
508                    Group group = _systemGroupsMap.get(companyId + name);
509    
510                    if (group != null) {
511                            return group;
512                    }
513    
514                    return groupPersistence.findByC_N(companyId, name);
515            }
516    
517            public List<Group> getGroups(long[] groupIds)
518                    throws PortalException, SystemException {
519    
520                    List<Group> groups = new ArrayList<Group>(groupIds.length);
521    
522                    for (long groupId : groupIds) {
523                            Group group = getGroup(groupId);
524    
525                            groups.add(group);
526                    }
527    
528                    return groups;
529            }
530    
531            public Group getLayoutGroup(long companyId, long plid)
532                    throws PortalException, SystemException {
533    
534                    long classNameId = PortalUtil.getClassNameId(Layout.class);
535    
536                    return groupPersistence.findByC_C_C(companyId, classNameId, plid);
537            }
538    
539            public Group getLayoutPrototypeGroup(long companyId, long layoutPrototypeId)
540                    throws PortalException, SystemException {
541    
542                    long classNameId = PortalUtil.getClassNameId(LayoutPrototype.class);
543    
544                    return groupPersistence.findByC_C_C(
545                            companyId, classNameId, layoutPrototypeId);
546            }
547    
548            public Group getLayoutSetPrototypeGroup(
549                            long companyId, long layoutSetPrototypeId)
550                    throws PortalException, SystemException {
551    
552                    long classNameId = PortalUtil.getClassNameId(LayoutSetPrototype.class);
553    
554                    return groupPersistence.findByC_C_C(
555                            companyId, classNameId, layoutSetPrototypeId);
556            }
557    
558            public List<Group> getLiveGroups() throws SystemException {
559                    return groupFinder.findByLiveGroups();
560            }
561    
562            public List<Group> getNoLayoutsGroups(
563                            String className, boolean privateLayout, int start, int end)
564                    throws SystemException {
565    
566                    long classNameId = PortalUtil.getClassNameId(className);
567    
568                    return groupFinder.findByNoLayouts(
569                            classNameId, privateLayout, start, end);
570            }
571    
572            public List<Group> getNullFriendlyURLGroups() throws SystemException {
573                    return groupFinder.findByNullFriendlyURL();
574            }
575    
576            public Group getOrganizationGroup(long companyId, long organizationId)
577                    throws PortalException, SystemException {
578    
579                    long classNameId = PortalUtil.getClassNameId(Organization.class);
580    
581                    return groupPersistence.findByC_C_C(
582                            companyId, classNameId, organizationId);
583            }
584    
585            public List<Group> getOrganizationsGroups(
586                    List<Organization> organizations) {
587    
588                    List<Group> organizationGroups = new ArrayList<Group>();
589    
590                    for (int i = 0; i < organizations.size(); i++) {
591                            Organization organization = organizations.get(i);
592    
593                            Group group = organization.getGroup();
594    
595                            organizationGroups.add(group);
596                    }
597    
598                    return organizationGroups;
599            }
600    
601            public List<Group> getOrganizationsRelatedGroups(
602                            List<Organization> organizations)
603                    throws SystemException {
604    
605                    List<Group> organizationGroups = new ArrayList<Group>();
606    
607                    for (int i = 0; i < organizations.size(); i++) {
608                            Organization organization = organizations.get(i);
609    
610                            List<Group> groups = organizationPersistence.getGroups(
611                                    organization.getOrganizationId());
612    
613                            organizationGroups.addAll(groups);
614                    }
615    
616                    return organizationGroups;
617            }
618    
619            public List<Group> getRoleGroups(long roleId) throws SystemException {
620                    return rolePersistence.getGroups(roleId);
621            }
622    
623            public Group getStagingGroup(long liveGroupId)
624                    throws PortalException, SystemException {
625    
626                    return groupPersistence.findByLiveGroupId(liveGroupId);
627            }
628    
629            public Group getUserGroup(long companyId, long userId)
630                    throws PortalException, SystemException {
631    
632                    long classNameId = PortalUtil.getClassNameId(User.class);
633    
634                    return groupPersistence.findByC_C_C(companyId, classNameId, userId);
635            }
636    
637            public Group getUserGroupGroup(long companyId, long userGroupId)
638                    throws PortalException, SystemException {
639    
640                    long classNameId = PortalUtil.getClassNameId(UserGroup.class);
641    
642                    return groupPersistence.findByC_C_C(
643                            companyId, classNameId, userGroupId);
644            }
645    
646            public List<Group> getUserGroups(long userId)
647                    throws PortalException, SystemException {
648    
649                    return getUserGroups(userId, false);
650            }
651    
652            public List<Group> getUserGroups(long userId, boolean inherit)
653                    throws PortalException, SystemException {
654    
655                    return getUserGroups(
656                            userId, inherit, QueryUtil.ALL_POS, QueryUtil.ALL_POS);
657            }
658    
659            public List<Group> getUserGroups(long userId, int start, int end)
660                    throws PortalException, SystemException {
661    
662                    return getUserGroups(userId, false, start, end);
663            }
664    
665            public List<Group> getUserGroups(
666                            long userId, boolean inherit, int start, int end)
667                    throws PortalException, SystemException {
668    
669                    if (inherit) {
670                            User user = userPersistence.findByPrimaryKey(userId);
671    
672                            LinkedHashMap<String, Object> groupParams =
673                                    new LinkedHashMap<String, Object>();
674    
675                            groupParams.put("usersGroups", new Long(userId));
676    
677                            return search(
678                                    user.getCompanyId(), null, null, groupParams, start, end);
679                    }
680                    else {
681                            return userPersistence.getGroups(userId);
682                    }
683            }
684    
685            public List<Group> getUserGroupsGroups(List<UserGroup> userGroups)
686                    throws PortalException, SystemException {
687    
688                    List<Group> userGroupGroups = new ArrayList<Group>();
689    
690                    for (int i = 0; i < userGroups.size(); i++) {
691                            UserGroup userGroup = userGroups.get(i);
692    
693                            Group group = userGroup.getGroup();
694    
695                            userGroupGroups.add(group);
696                    }
697    
698                    return userGroupGroups;
699            }
700    
701            public List<Group> getUserGroupsRelatedGroups(List<UserGroup> userGroups)
702                    throws SystemException {
703    
704                    List<Group> userGroupGroups = new ArrayList<Group>();
705    
706                    for (int i = 0; i < userGroups.size(); i++) {
707                            UserGroup userGroup = userGroups.get(i);
708    
709                            List<Group> groups = userGroupPersistence.getGroups(
710                                    userGroup.getUserGroupId());
711    
712                            userGroupGroups.addAll(groups);
713                    }
714    
715                    return userGroupGroups;
716            }
717    
718            public List<Group> getUserOrganizationsGroups(
719                            long userId, int start, int end)
720                    throws PortalException, SystemException {
721    
722                    List<Group> userOrgsGroups = new UniqueList<Group>();
723    
724                    List<Organization> userOrgs =
725                            organizationLocalService.getUserOrganizations(
726                                    userId, true, start, end);
727    
728                    for (Organization organization : userOrgs) {
729                            userOrgsGroups.add(0, organization.getGroup());
730    
731                            if (!PropsValues.ORGANIZATIONS_MEMBERSHIP_STRICT) {
732                                    for (Organization ancestorOrganization :
733                                                    organization.getAncestors()) {
734    
735                                            userOrgsGroups.add(0, ancestorOrganization.getGroup());
736                                    }
737                            }
738                    }
739    
740                    return userOrgsGroups;
741            }
742    
743            public boolean hasRoleGroup(long roleId, long groupId)
744                    throws SystemException {
745    
746                    return rolePersistence.containsGroup(roleId, groupId);
747            }
748    
749            public boolean hasStagingGroup(long liveGroupId) throws SystemException {
750                    if (groupPersistence.fetchByLiveGroupId(liveGroupId) != null) {
751                            return true;
752                    }
753                    else {
754                            return false;
755                    }
756            }
757    
758            public boolean hasUserGroup(long userId, long groupId)
759                    throws SystemException {
760    
761                    if (groupFinder.countByG_U(groupId, userId) > 0) {
762                            return true;
763                    }
764                    else {
765                            return false;
766                    }
767            }
768    
769            public List<Group> search(
770                            long companyId, String name, String description,
771                            LinkedHashMap<String, Object> params, int start, int end)
772                    throws SystemException {
773    
774                    return search(companyId, name, description, params, start, end, null);
775            }
776    
777            public List<Group> search(
778                            long companyId, String name, String description,
779                            LinkedHashMap<String, Object> params, int start, int end,
780                            OrderByComparator obc)
781                    throws SystemException {
782    
783                    if (obc == null) {
784                            obc = new GroupNameComparator(true);
785                    }
786    
787                    String realName = getRealName(companyId, name);
788    
789                    return groupFinder.findByC_N_D(
790                            companyId, name, realName, description, params, start, end, obc);
791            }
792    
793            @ThreadLocalCachable
794            public int searchCount(
795                            long companyId, String name, String description,
796                            LinkedHashMap<String, Object> params)
797                    throws SystemException {
798    
799                    String realName = getRealName(companyId, name);
800    
801                    return groupFinder.countByC_N_D(
802                            companyId, name, realName, description, params);
803            }
804    
805            public void setRoleGroups(long roleId, long[] groupIds)
806                    throws SystemException {
807    
808                    rolePersistence.setGroups(roleId, groupIds);
809    
810                    PermissionCacheUtil.clearCache();
811            }
812    
813            public void unsetRoleGroups(long roleId, long[] groupIds)
814                    throws SystemException {
815    
816                    rolePersistence.removeGroups(roleId, groupIds);
817    
818                    PermissionCacheUtil.clearCache();
819            }
820    
821            public void unsetUserGroups(long userId, long[] groupIds)
822                    throws SystemException {
823    
824                    userGroupRoleLocalService.deleteUserGroupRoles(userId, groupIds);
825    
826                    userPersistence.removeGroups(userId, groupIds);
827    
828                    PermissionCacheUtil.clearCache();
829            }
830    
831            public void updateAsset(
832                            long userId, Group group, long[] assetCategoryIds,
833                            String[] assetTagNames)
834                    throws PortalException, SystemException {
835    
836                    User user = userPersistence.findByPrimaryKey(userId);
837    
838                    Company company = companyPersistence.findByPrimaryKey(
839                            user.getCompanyId());
840    
841                    Group companyGroup = company.getGroup();
842    
843                    assetEntryLocalService.updateEntry(
844                            userId, companyGroup.getGroupId(), Group.class.getName(),
845                            group.getGroupId(), null, assetCategoryIds, assetTagNames, false,
846                            null, null, null, null, null, group.getDescriptiveName(),
847                            group.getDescription(), null, null, 0, 0, null, false);
848            }
849    
850            public Group updateFriendlyURL(long groupId, String friendlyURL)
851                    throws PortalException, SystemException {
852    
853                    Group group = groupPersistence.findByPrimaryKey(groupId);
854    
855                    if (group.isUser()) {
856                            User user = userPersistence.findByPrimaryKey(group.getClassPK());
857    
858                            friendlyURL = StringPool.SLASH + user.getScreenName();
859    
860                            if (group.getFriendlyURL().equals(friendlyURL)) {
861                                    return group;
862                            }
863                    }
864    
865                    friendlyURL = getFriendlyURL(
866                            group.getCompanyId(), groupId, group.getClassNameId(),
867                            group.getClassPK(), StringPool.BLANK, friendlyURL);
868    
869                    validateFriendlyURL(
870                            group.getCompanyId(), group.getGroupId(), group.getClassNameId(),
871                            group.getClassPK(), friendlyURL);
872    
873                    group.setFriendlyURL(friendlyURL);
874    
875                    groupPersistence.update(group, false);
876    
877                    return group;
878            }
879    
880            public Group updateGroup(
881                            long groupId, String name, String description, int type,
882                            String friendlyURL, boolean active, ServiceContext serviceContext)
883                    throws PortalException, SystemException {
884    
885                    Group group = groupPersistence.findByPrimaryKey(groupId);
886    
887                    String className = group.getClassName();
888                    long classNameId = group.getClassNameId();
889                    long classPK = group.getClassPK();
890                    friendlyURL = getFriendlyURL(
891                            group.getCompanyId(), groupId, classNameId, classPK,
892                            StringPool.BLANK, friendlyURL);
893    
894                    if ((classNameId <= 0) || className.equals(Group.class.getName())) {
895                            validateName(group.getGroupId(), group.getCompanyId(), name);
896                    }
897                    else {
898                            name = String.valueOf(classPK);
899                    }
900    
901                    if (PortalUtil.isSystemGroup(group.getName()) &&
902                            !group.getName().equals(name)) {
903    
904                            throw new RequiredGroupException();
905                    }
906    
907                    validateFriendlyURL(
908                            group.getCompanyId(), group.getGroupId(), group.getClassNameId(),
909                            group.getClassPK(), friendlyURL);
910    
911                    group.setName(name);
912                    group.setDescription(description);
913                    group.setType(type);
914                    group.setFriendlyURL(friendlyURL);
915                    group.setActive(active);
916    
917                    groupPersistence.update(group, false);
918    
919                    // Asset
920    
921                    if ((serviceContext != null) && group.isCommunity()) {
922                            User user = null;
923    
924                            try {
925                                    user = userPersistence.findByPrimaryKey(
926                                            group.getCreatorUserId());
927    
928                            }
929                            catch (NoSuchUserException nsue1) {
930                                    try {
931                                            user = userPersistence.findByPrimaryKey(
932                                                    serviceContext.getUserId());
933                                    }
934                                    catch (NoSuchUserException nsue2) {
935                                            user = userLocalService.getDefaultUser(
936                                                    group.getCompanyId());
937                                    }
938                            }
939    
940                            updateAsset(
941                                    user.getUserId(), group, serviceContext.getAssetCategoryIds(),
942                                    serviceContext.getAssetTagNames());
943                    }
944    
945                    return group;
946            }
947    
948            public Group updateGroup(long groupId, String typeSettings)
949                    throws PortalException, SystemException {
950    
951                    Group group = groupPersistence.findByPrimaryKey(groupId);
952    
953                    group.setTypeSettings(typeSettings);
954    
955                    groupPersistence.update(group, false);
956    
957                    return group;
958            }
959    
960            public Group updateWorkflow(
961                            long groupId, boolean workflowEnabled, int workflowStages,
962                            String workflowRoleNames)
963                    throws PortalException, SystemException {
964    
965                    Group group = groupPersistence.findByPrimaryKey(groupId);
966    
967                    UnicodeProperties props = group.getTypeSettingsProperties();
968    
969                    props.setProperty("workflowEnabled", String.valueOf(workflowEnabled));
970    
971                    if (workflowEnabled) {
972                            if (workflowStages < PropsValues.TASKS_DEFAULT_STAGES) {
973                                    workflowStages = PropsValues.TASKS_DEFAULT_STAGES;
974                            }
975    
976                            if (Validator.isNull(workflowRoleNames)) {
977                                    workflowRoleNames = PropsValues.TASKS_DEFAULT_ROLE_NAMES;
978                            }
979    
980                            props.setProperty("workflowStages", String.valueOf(workflowStages));
981                            props.setProperty("workflowRoleNames", workflowRoleNames);
982                    }
983    
984                    group.setTypeSettings(group.getTypeSettings());
985    
986                    groupPersistence.update(group, false);
987    
988                    if (!workflowEnabled) {
989                            tasksProposalLocalService.deleteProposals(groupId);
990                    }
991    
992                    return group;
993            }
994    
995            protected void addControlPanelLayouts(Group group)
996                    throws PortalException, SystemException {
997    
998                    long defaultUserId = userLocalService.getDefaultUserId(
999                            group.getCompanyId());
1000    
1001                    String friendlyURL = getFriendlyURL(
1002                            PropsValues.CONTROL_PANEL_LAYOUT_FRIENDLY_URL);
1003    
1004                    ServiceContext serviceContext = new ServiceContext();
1005    
1006                    layoutLocalService.addLayout(
1007                            defaultUserId, group.getGroupId(), true,
1008                            LayoutConstants.DEFAULT_PARENT_LAYOUT_ID,
1009                            PropsValues.CONTROL_PANEL_LAYOUT_NAME, StringPool.BLANK,
1010                            StringPool.BLANK, LayoutConstants.TYPE_CONTROL_PANEL, false,
1011                            friendlyURL, serviceContext);
1012            }
1013    
1014            protected void addDefaultGuestPublicLayoutByProperties(Group group)
1015                    throws PortalException, SystemException {
1016    
1017                    long defaultUserId = userLocalService.getDefaultUserId(
1018                            group.getCompanyId());
1019                    String friendlyURL = getFriendlyURL(
1020                            PropsValues.DEFAULT_GUEST_PUBLIC_LAYOUT_FRIENDLY_URL);
1021    
1022                    ServiceContext serviceContext = new ServiceContext();
1023    
1024                    Layout layout = layoutLocalService.addLayout(
1025                            defaultUserId, group.getGroupId(), false,
1026                            LayoutConstants.DEFAULT_PARENT_LAYOUT_ID,
1027                            PropsValues.DEFAULT_GUEST_PUBLIC_LAYOUT_NAME, StringPool.BLANK,
1028                            StringPool.BLANK, LayoutConstants.TYPE_PORTLET, false, friendlyURL,
1029                            serviceContext);
1030    
1031                    LayoutTypePortlet layoutTypePortlet =
1032                            (LayoutTypePortlet)layout.getLayoutType();
1033    
1034                    layoutTypePortlet.setLayoutTemplateId(
1035                            0, PropsValues.DEFAULT_GUEST_PUBLIC_LAYOUT_TEMPLATE_ID, false);
1036    
1037                    for (int i = 0; i < 10; i++) {
1038                            String columnId = "column-" + i;
1039                            String portletIds = PropsUtil.get(
1040                                    PropsKeys.DEFAULT_GUEST_PUBLIC_LAYOUT_COLUMN + i);
1041    
1042                            layoutTypePortlet.addPortletIds(
1043                                    0, StringUtil.split(portletIds), columnId, false);
1044                    }
1045    
1046                    layoutLocalService.updateLayout(
1047                            layout.getGroupId(), layout.isPrivateLayout(), layout.getLayoutId(),
1048                            layout.getTypeSettings());
1049    
1050                    boolean updateLayoutSet = false;
1051    
1052                    LayoutSet layoutSet = layout.getLayoutSet();
1053    
1054                    if (Validator.isNotNull(
1055                                    PropsValues.DEFAULT_GUEST_PUBLIC_LAYOUT_REGULAR_THEME_ID)) {
1056    
1057                            layoutSet.setThemeId(
1058                                    PropsValues.DEFAULT_GUEST_PUBLIC_LAYOUT_REGULAR_THEME_ID);
1059    
1060                            updateLayoutSet = true;
1061                    }
1062    
1063                    if (Validator.isNotNull(
1064                                    PropsValues.
1065                                            DEFAULT_GUEST_PUBLIC_LAYOUT_REGULAR_COLOR_SCHEME_ID)) {
1066    
1067                            layoutSet.setColorSchemeId(
1068                                    PropsValues.
1069                                            DEFAULT_GUEST_PUBLIC_LAYOUT_REGULAR_COLOR_SCHEME_ID);
1070    
1071                            updateLayoutSet = true;
1072                    }
1073    
1074                    if (Validator.isNotNull(
1075                                    PropsValues.DEFAULT_GUEST_PUBLIC_LAYOUT_WAP_THEME_ID)) {
1076    
1077                            layoutSet.setWapThemeId(
1078                                    PropsValues.DEFAULT_GUEST_PUBLIC_LAYOUT_WAP_THEME_ID);
1079    
1080                            updateLayoutSet = true;
1081                    }
1082    
1083                    if (Validator.isNotNull(
1084                                    PropsValues.DEFAULT_GUEST_PUBLIC_LAYOUT_WAP_COLOR_SCHEME_ID)) {
1085    
1086                            layoutSet.setWapColorSchemeId(
1087                                    PropsValues.DEFAULT_GUEST_PUBLIC_LAYOUT_WAP_COLOR_SCHEME_ID);
1088    
1089                            updateLayoutSet = true;
1090                    }
1091    
1092                    if (updateLayoutSet) {
1093                            layoutSetLocalService.updateLayoutSet(layoutSet);
1094                    }
1095            }
1096    
1097            protected void addDefaultGuestPublicLayouts(Group group)
1098                    throws PortalException, SystemException {
1099    
1100                    if (publicLARFile != null) {
1101                            addDefaultGuestPublicLayoutsByLAR(group, publicLARFile);
1102                    }
1103                    else {
1104                            addDefaultGuestPublicLayoutByProperties(group);
1105                    }
1106            }
1107    
1108            protected void addDefaultGuestPublicLayoutsByLAR(Group group, File larFile)
1109                    throws PortalException, SystemException {
1110    
1111                    long defaultUserId = userLocalService.getDefaultUserId(
1112                            group.getCompanyId());
1113    
1114                    Map<String, String[]> parameterMap = new HashMap<String, String[]>();
1115    
1116                    parameterMap.put(
1117                            PortletDataHandlerKeys.CATEGORIES,
1118                            new String[] {Boolean.TRUE.toString()});
1119                    parameterMap.put(
1120                            PortletDataHandlerKeys.PERMISSIONS,
1121                            new String[] {Boolean.TRUE.toString()});
1122                    parameterMap.put(
1123                            PortletDataHandlerKeys.PORTLET_DATA,
1124                            new String[] {Boolean.TRUE.toString()});
1125                    parameterMap.put(
1126                            PortletDataHandlerKeys.PORTLET_DATA_CONTROL_DEFAULT,
1127                            new String[] {Boolean.TRUE.toString()});
1128                    parameterMap.put(
1129                            PortletDataHandlerKeys.PORTLET_SETUP,
1130                            new String[] {Boolean.TRUE.toString()});
1131                    parameterMap.put(
1132                            PortletDataHandlerKeys.USER_PERMISSIONS,
1133                            new String[] {Boolean.FALSE.toString()});
1134    
1135                    layoutLocalService.importLayouts(
1136                            defaultUserId, group.getGroupId(), false, parameterMap, larFile);
1137            }
1138    
1139            protected String getFriendlyURL(String friendlyURL) {
1140                    return FriendlyURLNormalizer.normalize(friendlyURL);
1141            }
1142    
1143            protected String getFriendlyURL(
1144                            long companyId, long groupId, long classNameId, long classPK,
1145                            String friendlyName, String friendlyURL)
1146                    throws PortalException, SystemException {
1147    
1148                    friendlyURL = getFriendlyURL(friendlyURL);
1149    
1150                    if (Validator.isNull(friendlyURL)) {
1151                            friendlyURL = StringPool.SLASH + getFriendlyURL(friendlyName);
1152    
1153                            String originalFriendlyURL = friendlyURL;
1154    
1155                            for (int i = 1;; i++) {
1156                                    try {
1157                                            validateFriendlyURL(
1158                                                    companyId, groupId, classNameId, classPK, friendlyURL);
1159    
1160                                            break;
1161                                    }
1162                                    catch (GroupFriendlyURLException gfurle) {
1163                                            int type = gfurle.getType();
1164    
1165                                            if (type == GroupFriendlyURLException.DUPLICATE) {
1166                                                    friendlyURL = originalFriendlyURL + i;
1167                                            }
1168                                            else {
1169                                                    friendlyURL = StringPool.SLASH + classPK;
1170    
1171                                                    break;
1172                                            }
1173                                    }
1174                            }
1175                    }
1176    
1177                    return friendlyURL;
1178            }
1179    
1180            protected String getRealName(long companyId, String name)
1181                    throws SystemException {
1182    
1183                    if (Validator.isNull(name)) {
1184                            return name;
1185                    }
1186    
1187                    String realName = name;
1188    
1189                    try {
1190                            Company company = companyLocalService.getCompany(companyId);
1191    
1192                            Account account = company.getAccount();
1193    
1194                            String companyName = account.getName();
1195    
1196                            name = StringUtil.replace(
1197                                    name, StringPool.PERCENT, StringPool.BLANK);
1198    
1199                            if (companyName.indexOf(name) != -1) {
1200                                    realName = StringPool.PERCENT + GroupConstants.GUEST +
1201                                            StringPool.PERCENT;
1202                            }
1203                    }
1204                    catch (PortalException pe) {
1205                    }
1206    
1207                    return realName;
1208            }
1209    
1210            protected void initImportLARFile() {
1211                    String publicLARFileName = PropsValues.DEFAULT_GUEST_PUBLIC_LAYOUTS_LAR;
1212    
1213                    if (_log.isDebugEnabled()) {
1214                            _log.debug("Reading public LAR file " + publicLARFileName);
1215                    }
1216    
1217                    if (Validator.isNotNull(publicLARFileName)) {
1218                            publicLARFile = new File(publicLARFileName);
1219    
1220                            if (!publicLARFile.exists()) {
1221                                    _log.error(
1222                                            "Public LAR file " + publicLARFile + " does not exist");
1223    
1224                                    publicLARFile = null;
1225                            }
1226                            else {
1227                                    if (_log.isDebugEnabled()) {
1228                                            _log.debug("Using public LAR file " + publicLARFileName);
1229                                    }
1230                            }
1231                    }
1232            }
1233    
1234            protected void unscheduleStaging(Group group) {
1235                    try {
1236    
1237                            // Remote publishing
1238    
1239                            String groupName = StagingUtil.getSchedulerGroupName(
1240                                    DestinationNames.LAYOUTS_REMOTE_PUBLISHER, group.getGroupId());
1241    
1242                            List<SchedulerRequest> schedulerRequests =
1243                                    SchedulerEngineUtil.getScheduledJobs(groupName);
1244    
1245                            for (SchedulerRequest schedulerRequest : schedulerRequests) {
1246                                    SchedulerEngineUtil.unschedule(schedulerRequest.getTrigger());
1247                            }
1248    
1249                            long liveGroupId = 0;
1250                            long stagingGroupId = 0;
1251    
1252                            if (group.isStagingGroup()) {
1253                                    liveGroupId = group.getLiveGroupId();
1254    
1255                                    stagingGroupId = group.getGroupId();
1256                            }
1257                            else if (group.hasStagingGroup()) {
1258                                    liveGroupId = group.getGroupId();
1259    
1260                                    stagingGroupId = group.getStagingGroup().getGroupId();
1261                            }
1262    
1263                            if ((liveGroupId != 0) && (stagingGroupId != 0)) {
1264    
1265                                    // Publish to live
1266    
1267                                    groupName = StagingUtil.getSchedulerGroupName(
1268                                            DestinationNames.LAYOUTS_LOCAL_PUBLISHER, liveGroupId);
1269    
1270                                    schedulerRequests = SchedulerEngineUtil.getScheduledJobs(
1271                                            groupName);
1272    
1273                                    for (SchedulerRequest schedulerRequest : schedulerRequests) {
1274                                            SchedulerEngineUtil.unschedule(
1275                                                    schedulerRequest.getTrigger());
1276                                    }
1277    
1278                                    // Copy from live
1279    
1280                                    groupName = StagingUtil.getSchedulerGroupName(
1281                                            DestinationNames.LAYOUTS_LOCAL_PUBLISHER, stagingGroupId);
1282    
1283                                    schedulerRequests = SchedulerEngineUtil.getScheduledJobs(
1284                                            groupName);
1285    
1286                                    for (SchedulerRequest schedulerRequest : schedulerRequests) {
1287                                            SchedulerEngineUtil.unschedule(
1288                                                    schedulerRequest.getTrigger());
1289                                    }
1290                            }
1291                    }
1292                    catch (Exception e) {
1293                            _log.error(
1294                                    "Unable to unschedule events for group: " + group.getGroupId());
1295                    }
1296            }
1297    
1298            protected void validateFriendlyURL(
1299                            long companyId, long groupId, long classNameId, long classPK,
1300                            String friendlyURL)
1301                    throws PortalException, SystemException {
1302    
1303                    Company company = companyPersistence.findByPrimaryKey(companyId);
1304    
1305                    if (company.isSystem()) {
1306                            return;
1307                    }
1308    
1309                    if (Validator.isNull(friendlyURL)) {
1310                            return;
1311                    }
1312    
1313                    int exceptionType = LayoutImpl.validateFriendlyURL(friendlyURL);
1314    
1315                    if (exceptionType != -1) {
1316                            throw new GroupFriendlyURLException(exceptionType);
1317                    }
1318    
1319                    Group group = groupPersistence.fetchByC_F(companyId, friendlyURL);
1320    
1321                    if ((group != null) && (group.getGroupId() != groupId)) {
1322                            throw new GroupFriendlyURLException(
1323                                    GroupFriendlyURLException.DUPLICATE);
1324                    }
1325    
1326                    String groupIdFriendlyURL = friendlyURL.substring(1);
1327    
1328                    if (Validator.isNumber(groupIdFriendlyURL)) {
1329                            long groupClassNameId = PortalUtil.getClassNameId(Group.class);
1330    
1331                            if (((classNameId != groupClassNameId) &&
1332                                     (!groupIdFriendlyURL.equals(String.valueOf(classPK))) &&
1333                                     (!PropsValues.USERS_SCREEN_NAME_ALLOW_NUMERIC)) ||
1334                                    ((classNameId == groupClassNameId) &&
1335                                     (!groupIdFriendlyURL.equals(String.valueOf(groupId))))) {
1336    
1337                                    GroupFriendlyURLException gfurle =
1338                                            new GroupFriendlyURLException(
1339                                                    GroupFriendlyURLException.POSSIBLE_DUPLICATE);
1340    
1341                                    gfurle.setKeywordConflict(groupIdFriendlyURL);
1342    
1343                                    throw gfurle;
1344                            }
1345                    }
1346    
1347                    String screenName = friendlyURL.substring(1);
1348    
1349                    User user = userPersistence.fetchByC_SN(companyId, screenName);
1350    
1351                    if (user != null) {
1352                            long userClassNameId = PortalUtil.getClassNameId(User.class);
1353    
1354                            if ((classNameId == userClassNameId) &&
1355                                    (classPK == user.getUserId())) {
1356                            }
1357                            else {
1358                                    throw new GroupFriendlyURLException(
1359                                            GroupFriendlyURLException.DUPLICATE);
1360                            }
1361                    }
1362    
1363                    if (StringUtil.count(friendlyURL, StringPool.SLASH) > 1) {
1364                            throw new GroupFriendlyURLException(
1365                                    GroupFriendlyURLException.TOO_DEEP);
1366                    }
1367            }
1368    
1369            protected void validateName(long groupId, long companyId, String name)
1370                    throws PortalException, SystemException {
1371    
1372                    if ((Validator.isNull(name)) || (Validator.isNumber(name)) ||
1373                            (name.indexOf(StringPool.STAR) != -1)) {
1374    
1375                            throw new GroupNameException();
1376                    }
1377    
1378                    try {
1379                            Group group = groupFinder.findByC_N(companyId, name);
1380    
1381                            if ((groupId <= 0) || (group.getGroupId() != groupId)) {
1382                                    throw new DuplicateGroupException();
1383                            }
1384                    }
1385                    catch (NoSuchGroupException nsge) {
1386                    }
1387            }
1388    
1389            protected File publicLARFile;
1390    
1391            private static Log _log = LogFactoryUtil.getLog(
1392                    GroupLocalServiceImpl.class);
1393    
1394            private Map<String, Group> _systemGroupsMap = new HashMap<String, Group>();
1395    
1396    }