1   /**
2    * Copyright (c) 2000-2010 Liferay, Inc. All rights reserved.
3    *
4    * The contents of this file are subject to the terms of the Liferay Enterprise
5    * Subscription License ("License"). You may not use this file except in
6    * compliance with the License. You can obtain a copy of the License by
7    * contacting Liferay, Inc. See the License for the specific language governing
8    * permissions and limitations under the License, including but not limited to
9    * distribution rights of the Software.
10   *
11   *
12   * 
13   */
14  
15  package com.liferay.portal.service.impl;
16  
17  import com.liferay.portal.DuplicateGroupException;
18  import com.liferay.portal.GroupFriendlyURLException;
19  import com.liferay.portal.GroupNameException;
20  import com.liferay.portal.NoSuchGroupException;
21  import com.liferay.portal.NoSuchLayoutSetException;
22  import com.liferay.portal.NoSuchRoleException;
23  import com.liferay.portal.PortalException;
24  import com.liferay.portal.RequiredGroupException;
25  import com.liferay.portal.SystemException;
26  import com.liferay.portal.kernel.annotation.Propagation;
27  import com.liferay.portal.kernel.annotation.Transactional;
28  import com.liferay.portal.kernel.dao.orm.QueryUtil;
29  import com.liferay.portal.kernel.log.Log;
30  import com.liferay.portal.kernel.log.LogFactoryUtil;
31  import com.liferay.portal.kernel.messaging.DestinationNames;
32  import com.liferay.portal.kernel.scheduler.SchedulerEngineUtil;
33  import com.liferay.portal.kernel.scheduler.messaging.SchedulerRequest;
34  import com.liferay.portal.kernel.util.GetterUtil;
35  import com.liferay.portal.kernel.util.OrderByComparator;
36  import com.liferay.portal.kernel.util.PropsKeys;
37  import com.liferay.portal.kernel.util.StringPool;
38  import com.liferay.portal.kernel.util.StringUtil;
39  import com.liferay.portal.kernel.util.UnicodeProperties;
40  import com.liferay.portal.kernel.util.Validator;
41  import com.liferay.portal.lar.PortletDataHandlerKeys;
42  import com.liferay.portal.model.Company;
43  import com.liferay.portal.model.Group;
44  import com.liferay.portal.model.GroupConstants;
45  import com.liferay.portal.model.Layout;
46  import com.liferay.portal.model.LayoutConstants;
47  import com.liferay.portal.model.LayoutSet;
48  import com.liferay.portal.model.LayoutTypePortlet;
49  import com.liferay.portal.model.Organization;
50  import com.liferay.portal.model.Resource;
51  import com.liferay.portal.model.ResourceConstants;
52  import com.liferay.portal.model.Role;
53  import com.liferay.portal.model.RoleConstants;
54  import com.liferay.portal.model.User;
55  import com.liferay.portal.model.UserGroup;
56  import com.liferay.portal.model.impl.LayoutImpl;
57  import com.liferay.portal.security.permission.PermissionCacheUtil;
58  import com.liferay.portal.service.ServiceContext;
59  import com.liferay.portal.service.base.GroupLocalServiceBaseImpl;
60  import com.liferay.portal.util.FriendlyURLNormalizer;
61  import com.liferay.portal.util.PortalUtil;
62  import com.liferay.portal.util.PropsUtil;
63  import com.liferay.portal.util.PropsValues;
64  import com.liferay.portal.util.comparator.GroupNameComparator;
65  import com.liferay.portlet.communities.util.StagingUtil;
66  import com.liferay.util.UniqueList;
67  
68  import java.io.File;
69  
70  import java.util.ArrayList;
71  import java.util.HashMap;
72  import java.util.Iterator;
73  import java.util.LinkedHashMap;
74  import java.util.List;
75  import java.util.Map;
76  
77  /**
78   * <a href="GroupLocalServiceImpl.java.html"><b><i>View Source</i></b></a>
79   *
80   * @author Brian Wing Shun Chan
81   * @author Alexander Chow
82   * @author Bruno Farache
83   * @author Wesley Gong
84   */
85  public class GroupLocalServiceImpl extends GroupLocalServiceBaseImpl {
86  
87      public GroupLocalServiceImpl() {
88          initImportLARFile();
89      }
90  
91      public Group addGroup(
92              long userId, String className, long classPK, String name,
93              String description, int type, String friendlyURL, boolean active,
94              ServiceContext serviceContext)
95          throws PortalException, SystemException {
96  
97          return addGroup(
98              userId, className, classPK, GroupConstants.DEFAULT_LIVE_GROUP_ID,
99              name, description, type, friendlyURL, active, serviceContext);
100     }
101 
102     public Group addGroup(
103             long userId, String className, long classPK, long liveGroupId,
104             String name, String description, int type, String friendlyURL,
105             boolean active, ServiceContext serviceContext)
106         throws PortalException, SystemException {
107 
108         // Group
109 
110         User user = userPersistence.findByPrimaryKey(userId);
111         className = GetterUtil.getString(className);
112         long classNameId = PortalUtil.getClassNameId(className);
113 
114         String friendlyName = name;
115 
116         if (className.equals(Organization.class.getName())) {
117             Organization organization =
118                 organizationPersistence.findByPrimaryKey(classPK);
119 
120             friendlyName = organization.getName();
121         }
122 
123         long groupId = 0;
124 
125         while (true) {
126             groupId = counterLocalService.increment();
127 
128             User userScreenName = userPersistence.fetchByC_SN(
129                 user.getCompanyId(), String.valueOf(groupId));
130 
131             if (userScreenName == null) {
132                 break;
133             }
134         }
135 
136         long groupClassNameId = PortalUtil.getClassNameId(Group.class);
137 
138         if ((classNameId <= 0) || className.equals(Group.class.getName())) {
139             validateName(groupId, user.getCompanyId(), name);
140 
141             classNameId = groupClassNameId;
142             classPK = groupId;
143         }
144         else {
145             name = String.valueOf(classPK);
146         }
147 
148         long parentGroupId = GroupConstants.DEFAULT_PARENT_GROUP_ID;
149 
150         if (className.equals(Layout.class.getName())) {
151             Layout layout = layoutLocalService.getLayout(classPK);
152 
153             parentGroupId = layout.getGroupId();
154         }
155 
156         friendlyURL = getFriendlyURL(
157             user.getCompanyId(), groupId, classNameId, classPK, friendlyName,
158             friendlyURL);
159 
160         validateFriendlyURL(
161             user.getCompanyId(), groupId, classNameId, classPK, friendlyURL);
162 
163         Group group = groupPersistence.create(groupId);
164 
165         group.setCompanyId(user.getCompanyId());
166         group.setCreatorUserId(userId);
167         group.setClassNameId(classNameId);
168         group.setClassPK(classPK);
169         group.setParentGroupId(parentGroupId);
170         group.setLiveGroupId(liveGroupId);
171         group.setName(name);
172         group.setDescription(description);
173         group.setType(type);
174         group.setFriendlyURL(friendlyURL);
175         group.setActive(active);
176 
177         groupPersistence.update(group, false);
178 
179         // Layout sets
180 
181         layoutSetLocalService.addLayoutSet(groupId, true);
182 
183         layoutSetLocalService.addLayoutSet(groupId, false);
184 
185         if ((classNameId == groupClassNameId) && !user.isDefaultUser()) {
186 
187             // Resources
188 
189             resourceLocalService.addResources(
190                 group.getCompanyId(), 0, 0, Group.class.getName(),
191                 group.getGroupId(), false, false, false);
192 
193             // Community roles
194 
195             Role role = roleLocalService.getRole(
196                 group.getCompanyId(), RoleConstants.COMMUNITY_OWNER);
197 
198             userGroupRoleLocalService.addUserGroupRoles(
199                 userId, groupId, new long[] {role.getRoleId()});
200 
201             // User
202 
203             userLocalService.addGroupUsers(
204                 group.getGroupId(), new long[] {userId});
205 
206             // Tags
207 
208             if (serviceContext != null) {
209                 updateTagsAsset(
210                     userId, group, serviceContext.getTagsCategories(),
211                     serviceContext.getTagsEntries());
212             }
213         }
214         else if (className.equals(Organization.class.getName()) &&
215                  !user.isDefaultUser()) {
216 
217             // Resources
218 
219             resourceLocalService.addResources(
220                 group.getCompanyId(), 0, 0, Group.class.getName(),
221                 group.getGroupId(), false, false, false);
222         }
223 
224         return group;
225     }
226 
227     public void addRoleGroups(long roleId, long[] groupIds)
228         throws SystemException {
229 
230         rolePersistence.addGroups(roleId, groupIds);
231 
232         PermissionCacheUtil.clearCache();
233     }
234 
235     public void addUserGroups(long userId, long[] groupIds)
236         throws SystemException {
237 
238         userPersistence.addGroups(userId, groupIds);
239 
240         PermissionCacheUtil.clearCache();
241     }
242 
243     @Transactional(propagation = Propagation.SUPPORTS, readOnly = true)
244     public void checkSystemGroups(long companyId)
245         throws PortalException, SystemException {
246 
247         for (Group group : groupFinder.findBySystem(companyId)) {
248             _systemGroupsMap.put(companyId + group.getName(), group);
249         }
250 
251         long defaultUserId = userLocalService.getDefaultUserId(companyId);
252 
253         String[] systemGroups = PortalUtil.getSystemGroups();
254 
255         for (String name : systemGroups) {
256             Group group = _systemGroupsMap.get(companyId + name);
257 
258             try {
259                 if (group == null) {
260                     group = groupPersistence.findByC_N(companyId, name);
261                 }
262             }
263             catch (NoSuchGroupException nsge) {
264                 int type = GroupConstants.TYPE_COMMUNITY_OPEN;
265                 String friendlyURL = null;
266 
267                 if (name.equals(GroupConstants.CONTROL_PANEL)) {
268                     type = GroupConstants.TYPE_COMMUNITY_PRIVATE;
269                     friendlyURL = GroupConstants.CONTROL_PANEL_FRIENDLY_URL;
270                 }
271                 else if (name.equals(GroupConstants.GUEST)) {
272                     friendlyURL = "/guest";
273                 }
274 
275                 group = groupLocalService.addGroup(
276                     defaultUserId, null, 0, name, null, type, friendlyURL,
277                     true, null);
278             }
279 
280             if (group.isControlPanel()) {
281                 LayoutSet layoutSet = layoutSetLocalService.getLayoutSet(
282                     group.getGroupId(), true);
283 
284                 if (layoutSet.getPageCount() == 0) {
285                     addControlPanelLayouts(group);
286                 }
287             }
288 
289             if (group.getName().equals(GroupConstants.GUEST)) {
290                 LayoutSet layoutSet = layoutSetLocalService.getLayoutSet(
291                     group.getGroupId(), false);
292 
293                 if (layoutSet.getPageCount() == 0) {
294                     addDefaultGuestPublicLayouts(group);
295                 }
296             }
297 
298             _systemGroupsMap.put(companyId + name, group);
299         }
300     }
301 
302     public void deleteGroup(long groupId)
303         throws PortalException, SystemException {
304 
305         Group group = groupPersistence.findByPrimaryKey(groupId);
306 
307         if (PortalUtil.isSystemGroup(group.getName())) {
308             throw new RequiredGroupException(String.valueOf(groupId));
309         }
310 
311         // Layout sets
312 
313         try {
314             layoutSetLocalService.deleteLayoutSet(groupId, true);
315         }
316         catch (NoSuchLayoutSetException nslse) {
317         }
318 
319         try {
320             layoutSetLocalService.deleteLayoutSet(groupId, false);
321         }
322         catch (NoSuchLayoutSetException nslse) {
323         }
324 
325         // Role
326 
327         try {
328             Role role = roleLocalService.getGroupRole(
329                 group.getCompanyId(), groupId);
330 
331             roleLocalService.deleteRole(role.getRoleId());
332         }
333         catch (NoSuchRoleException nsre) {
334         }
335 
336         // Group roles
337 
338         userGroupRoleLocalService.deleteUserGroupRolesByGroupId(groupId);
339 
340         // User group roles
341 
342         userGroupGroupRoleLocalService.deleteUserGroupGroupRolesByGroupId(
343             groupId);
344 
345         // Membership requests
346 
347         membershipRequestLocalService.deleteMembershipRequests(
348             group.getGroupId());
349 
350         // Staging
351 
352         unscheduleStaging(group);
353 
354         if (group.hasStagingGroup()) {
355             deleteGroup(group.getStagingGroup().getGroupId());
356         }
357 
358         // Blogs
359 
360         blogsEntryLocalService.deleteEntries(groupId);
361         blogsStatsUserLocalService.deleteStatsUserByGroupId(groupId);
362 
363         // Bookmarks
364 
365         bookmarksFolderLocalService.deleteFolders(groupId);
366 
367         // Calendar
368 
369         calEventLocalService.deleteEvents(groupId);
370 
371         // Document library
372 
373         dlFolderLocalService.deleteFolders(groupId);
374 
375         // Image gallery
376 
377         igFolderLocalService.deleteFolders(groupId);
378 
379         // Journal
380 
381         journalArticleLocalService.deleteArticles(groupId);
382         journalTemplateLocalService.deleteTemplates(groupId);
383         journalStructureLocalService.deleteStructures(groupId);
384 
385         // Message boards
386 
387         mbBanLocalService.deleteBansByGroupId(groupId);
388         mbCategoryLocalService.deleteCategories(groupId);
389         mbStatsUserLocalService.deleteStatsUsersByGroupId(groupId);
390 
391         // Polls
392 
393         pollsQuestionLocalService.deleteQuestions(groupId);
394 
395         // Shopping
396 
397         shoppingCartLocalService.deleteGroupCarts(groupId);
398         shoppingCategoryLocalService.deleteCategories(groupId);
399         shoppingCouponLocalService.deleteCoupons(groupId);
400         shoppingOrderLocalService.deleteOrders(groupId);
401 
402         // Software catalog
403 
404         scFrameworkVersionLocalService.deleteFrameworkVersions(groupId);
405         scProductEntryLocalService.deleteProductEntries(groupId);
406 
407         // Tags
408 
409         if (group.isCommunity()) {
410             tagsAssetLocalService.deleteAsset(Group.class.getName(), groupId);
411         }
412 
413         // Wiki
414 
415         wikiNodeLocalService.deleteNodes(groupId);
416 
417         // Resources
418 
419         Iterator<Resource> itr = resourceFinder.findByC_P(
420             group.getCompanyId(), String.valueOf(groupId)).iterator();
421 
422         while (itr.hasNext()) {
423             Resource resource = itr.next();
424 
425             resourceLocalService.deleteResource(resource);
426         }
427 
428         if (!group.isStagingGroup() &&
429             (group.isCommunity() || group.isOrganization())) {
430 
431             resourceLocalService.deleteResource(
432                 group.getCompanyId(), Group.class.getName(),
433                 ResourceConstants.SCOPE_INDIVIDUAL, group.getGroupId());
434         }
435 
436         // Group
437 
438         groupPersistence.remove(group);
439 
440         // Permission cache
441 
442         PermissionCacheUtil.clearCache();
443     }
444 
445     public List<Group> getCompanyGroups(long companyId, int start, int end)
446         throws SystemException {
447 
448         return groupPersistence.findByCompanyId(companyId, start, end);
449     }
450 
451     public int getCompanyGroupsCount(long companyId) throws SystemException {
452         return groupPersistence.countByCompanyId(companyId);
453     }
454 
455     public Group getFriendlyURLGroup(long companyId, String friendlyURL)
456         throws PortalException, SystemException {
457 
458         if (Validator.isNull(friendlyURL)) {
459             throw new NoSuchGroupException();
460         }
461 
462         friendlyURL = getFriendlyURL(friendlyURL);
463 
464         return groupPersistence.findByC_F(companyId, friendlyURL);
465     }
466 
467     public Group getGroup(long groupId)
468         throws PortalException, SystemException {
469 
470         return groupPersistence.findByPrimaryKey(groupId);
471     }
472 
473     public Group getGroup(long companyId, String name)
474         throws PortalException, SystemException {
475 
476         Group group = _systemGroupsMap.get(companyId + name);
477 
478         if (group != null) {
479             return group;
480         }
481 
482         return groupPersistence.findByC_N(companyId, name);
483     }
484 
485     public List<Group> getGroups(long[] groupIds)
486         throws PortalException, SystemException {
487 
488         List<Group> groups = new ArrayList<Group>(groupIds.length);
489 
490         for (long groupId : groupIds) {
491             Group group = getGroup(groupId);
492 
493             groups.add(group);
494         }
495 
496         return groups;
497     }
498 
499     public Group getLayoutGroup(long companyId, long plid)
500         throws PortalException, SystemException {
501 
502         long classNameId = PortalUtil.getClassNameId(Layout.class);
503 
504         return groupPersistence.findByC_C_C(companyId, classNameId, plid);
505     }
506 
507     public List<Group> getNoLayoutsGroups(
508             String className, boolean privateLayout, int start, int end)
509         throws SystemException {
510 
511         long classNameId = PortalUtil.getClassNameId(className);
512 
513         return groupFinder.findByNoLayouts(
514             classNameId, privateLayout, start, end);
515     }
516 
517     public List<Group> getNullFriendlyURLGroups() throws SystemException {
518         return groupFinder.findByNullFriendlyURL();
519     }
520 
521     public Group getOrganizationGroup(long companyId, long organizationId)
522         throws PortalException, SystemException {
523 
524         long classNameId = PortalUtil.getClassNameId(Organization.class);
525 
526         return groupPersistence.findByC_C_C(
527             companyId, classNameId, organizationId);
528     }
529 
530     public List<Group> getOrganizationsGroups(
531         List<Organization> organizations) {
532 
533         List<Group> organizationGroups = new ArrayList<Group>();
534 
535         for (int i = 0; i < organizations.size(); i++) {
536             Organization organization = organizations.get(i);
537 
538             Group group = organization.getGroup();
539 
540             organizationGroups.add(group);
541         }
542 
543         return organizationGroups;
544     }
545 
546     public List<Group> getRoleGroups(long roleId) throws SystemException {
547         return rolePersistence.getGroups(roleId);
548     }
549 
550     public Group getStagingGroup(long liveGroupId)
551         throws PortalException, SystemException {
552 
553         return groupPersistence.findByLiveGroupId(liveGroupId);
554     }
555 
556     public Group getUserGroup(long companyId, long userId)
557         throws PortalException, SystemException {
558 
559         long classNameId = PortalUtil.getClassNameId(User.class);
560 
561         return groupPersistence.findByC_C_C(companyId, classNameId, userId);
562     }
563 
564     public Group getUserGroupGroup(long companyId, long userGroupId)
565         throws PortalException, SystemException {
566 
567         long classNameId = PortalUtil.getClassNameId(UserGroup.class);
568 
569         return groupPersistence.findByC_C_C(
570             companyId, classNameId, userGroupId);
571     }
572 
573     public List<Group> getUserGroups(long userId)
574         throws PortalException, SystemException {
575 
576         return getUserGroups(userId, false);
577     }
578 
579     public List<Group> getUserGroups(long userId, boolean inherit)
580         throws PortalException, SystemException {
581 
582         return getUserGroups(
583             userId, inherit, QueryUtil.ALL_POS, QueryUtil.ALL_POS);
584     }
585 
586     public List<Group> getUserGroups(long userId, int start, int end)
587         throws PortalException, SystemException {
588 
589         return getUserGroups(userId, false, start, end);
590     }
591 
592     public List<Group> getUserGroups(
593             long userId, boolean inherit, int start, int end)
594         throws PortalException, SystemException {
595 
596         if (inherit) {
597             User user = userPersistence.findByPrimaryKey(userId);
598 
599             LinkedHashMap<String, Object> groupParams =
600                 new LinkedHashMap<String, Object>();
601 
602             groupParams.put("usersGroups", new Long(userId));
603 
604             return search(
605                 user.getCompanyId(), null, null, groupParams, start, end);
606         }
607         else {
608             return userPersistence.getGroups(userId);
609         }
610     }
611 
612     public List<Group> getUserGroupsGroups(List<UserGroup> userGroups) {
613         List<Group> userGroupGroups = new ArrayList<Group>();
614 
615         for (int i = 0; i < userGroups.size(); i++) {
616             UserGroup userGroup = userGroups.get(i);
617 
618             Group group = userGroup.getGroup();
619 
620             userGroupGroups.add(group);
621         }
622 
623         return userGroupGroups;
624     }
625 
626     public List<Group> getUserOrganizationsGroups(
627             long userId, int start, int end)
628         throws PortalException, SystemException {
629 
630         List<Group> userOrgsGroups = new UniqueList<Group>();
631 
632         List<Organization> userOrgs =
633             organizationLocalService.getUserOrganizations(
634                 userId, true, start, end);
635 
636         for (Organization organization : userOrgs) {
637             userOrgsGroups.add(0, organization.getGroup());
638 
639             if (!PropsValues.ORGANIZATIONS_MEMBERSHIP_STRICT) {
640                 for (Organization ancestorOrganization :
641                         organization.getAncestors()) {
642 
643                     userOrgsGroups.add(0, ancestorOrganization.getGroup());
644                 }
645             }
646         }
647 
648         return userOrgsGroups;
649     }
650 
651     public boolean hasRoleGroup(long roleId, long groupId)
652         throws SystemException {
653 
654         return rolePersistence.containsGroup(roleId, groupId);
655     }
656 
657     public boolean hasStagingGroup(long liveGroupId) throws SystemException {
658         if (groupPersistence.fetchByLiveGroupId(liveGroupId) != null) {
659             return true;
660         }
661         else {
662             return false;
663         }
664     }
665 
666     public boolean hasUserGroup(long userId, long groupId)
667         throws SystemException {
668 
669         if (groupFinder.countByG_U(groupId, userId) > 0) {
670             return true;
671         }
672         else {
673             return false;
674         }
675     }
676 
677     public List<Group> search(
678             long companyId, String name, String description,
679             LinkedHashMap<String, Object> params, int start, int end)
680         throws SystemException {
681 
682         return search(companyId, name, description, params, start, end, null);
683     }
684 
685     public List<Group> search(
686             long companyId, String name, String description,
687             LinkedHashMap<String, Object> params, int start, int end,
688             OrderByComparator obc)
689         throws SystemException {
690 
691         if (obc == null) {
692             obc = new GroupNameComparator(true);
693         }
694 
695         return groupFinder.findByC_N_D(
696             companyId, name, description, params, start, end, obc);
697     }
698 
699     public int searchCount(
700             long companyId, String name, String description,
701             LinkedHashMap<String, Object> params)
702         throws SystemException {
703 
704         return groupFinder.countByC_N_D(companyId, name, description, params);
705     }
706 
707     public void setRoleGroups(long roleId, long[] groupIds)
708         throws SystemException {
709 
710         rolePersistence.setGroups(roleId, groupIds);
711 
712         PermissionCacheUtil.clearCache();
713     }
714 
715     public void unsetRoleGroups(long roleId, long[] groupIds)
716         throws SystemException {
717 
718         rolePersistence.removeGroups(roleId, groupIds);
719 
720         PermissionCacheUtil.clearCache();
721     }
722 
723     public void unsetUserGroups(long userId, long[] groupIds)
724         throws SystemException {
725 
726         userGroupRoleLocalService.deleteUserGroupRoles(userId, groupIds);
727 
728         userPersistence.removeGroups(userId, groupIds);
729 
730         PermissionCacheUtil.clearCache();
731     }
732 
733     public Group updateFriendlyURL(long groupId, String friendlyURL)
734         throws PortalException, SystemException {
735 
736         Group group = groupPersistence.findByPrimaryKey(groupId);
737 
738         if (group.isUser()) {
739             User user = userPersistence.findByPrimaryKey(group.getClassPK());
740 
741             friendlyURL = StringPool.SLASH + user.getScreenName();
742 
743             if (group.getFriendlyURL().equals(friendlyURL)) {
744                 return group;
745             }
746         }
747 
748         friendlyURL = getFriendlyURL(
749             group.getCompanyId(), groupId, group.getClassNameId(),
750             group.getClassPK(), StringPool.BLANK, friendlyURL);
751 
752         validateFriendlyURL(
753             group.getCompanyId(), group.getGroupId(), group.getClassNameId(),
754             group.getClassPK(), friendlyURL);
755 
756         group.setFriendlyURL(friendlyURL);
757 
758         groupPersistence.update(group, false);
759 
760         return group;
761     }
762 
763     public Group updateGroup(
764             long groupId, String name, String description, int type,
765             String friendlyURL, boolean active, ServiceContext serviceContext)
766         throws PortalException, SystemException {
767 
768         Group group = groupPersistence.findByPrimaryKey(groupId);
769 
770         String className = group.getClassName();
771         long classNameId = group.getClassNameId();
772         long classPK = group.getClassPK();
773         friendlyURL = getFriendlyURL(
774             group.getCompanyId(), groupId, classNameId, classPK,
775             StringPool.BLANK, friendlyURL);
776 
777         if ((classNameId <= 0) || className.equals(Group.class.getName())) {
778             validateName(group.getGroupId(), group.getCompanyId(), name);
779         }
780         else {
781             name = String.valueOf(classPK);
782         }
783 
784         if (PortalUtil.isSystemGroup(group.getName()) &&
785             !group.getName().equals(name)) {
786 
787             throw new RequiredGroupException();
788         }
789 
790         validateFriendlyURL(
791             group.getCompanyId(), group.getGroupId(), group.getClassNameId(),
792             group.getClassPK(), friendlyURL);
793 
794         group.setName(name);
795         group.setDescription(description);
796         group.setType(type);
797         group.setFriendlyURL(friendlyURL);
798         group.setActive(active);
799 
800         groupPersistence.update(group, false);
801 
802         // Tags
803 
804         if ((serviceContext != null) && group.isCommunity()) {
805             updateTagsAsset(
806                 group.getCreatorUserId(), group,
807                 serviceContext.getTagsCategories(),
808                 serviceContext.getTagsEntries());
809         }
810 
811         return group;
812     }
813 
814     public Group updateGroup(long groupId, String typeSettings)
815         throws PortalException, SystemException {
816 
817         Group group = groupPersistence.findByPrimaryKey(groupId);
818 
819         group.setTypeSettings(typeSettings);
820 
821         groupPersistence.update(group, false);
822 
823         return group;
824     }
825 
826     public void updateTagsAsset(
827             long userId, Group group, String[] tagsCategories,
828             String[] tagsEntries)
829         throws PortalException, SystemException {
830 
831         tagsAssetLocalService.updateAsset(
832             userId, group.getGroupId(), Group.class.getName(),
833             group.getGroupId(), tagsCategories, tagsEntries, true, null, null,
834             null, null, null, group.getDescriptiveName(),
835             group.getDescription(), null, null, 0, 0, null, false);
836     }
837 
838     public Group updateWorkflow(
839             long groupId, boolean workflowEnabled, int workflowStages,
840             String workflowRoleNames)
841         throws PortalException, SystemException {
842 
843         Group group = groupPersistence.findByPrimaryKey(groupId);
844 
845         UnicodeProperties props = group.getTypeSettingsProperties();
846 
847         props.setProperty("workflowEnabled", String.valueOf(workflowEnabled));
848 
849         if (workflowEnabled) {
850             if (workflowStages < PropsValues.TASKS_DEFAULT_STAGES) {
851                 workflowStages = PropsValues.TASKS_DEFAULT_STAGES;
852             }
853 
854             if (Validator.isNull(workflowRoleNames)) {
855                 workflowRoleNames = PropsValues.TASKS_DEFAULT_ROLE_NAMES;
856             }
857 
858             props.setProperty("workflowStages", String.valueOf(workflowStages));
859             props.setProperty("workflowRoleNames", workflowRoleNames);
860         }
861 
862         group.setTypeSettings(group.getTypeSettings());
863 
864         groupPersistence.update(group, false);
865 
866         if (!workflowEnabled) {
867             tasksProposalLocalService.deleteProposals(groupId);
868         }
869 
870         return group;
871     }
872 
873     protected void addControlPanelLayouts(Group group)
874         throws PortalException, SystemException {
875 
876         long defaultUserId = userLocalService.getDefaultUserId(
877             group.getCompanyId());
878 
879         String friendlyURL = getFriendlyURL(
880             PropsValues.CONTROL_PANEL_LAYOUT_FRIENDLY_URL);
881 
882         layoutLocalService.addLayout(
883             defaultUserId, group.getGroupId(), true,
884             LayoutConstants.DEFAULT_PARENT_LAYOUT_ID,
885             PropsValues.CONTROL_PANEL_LAYOUT_NAME, StringPool.BLANK,
886             StringPool.BLANK, LayoutConstants.TYPE_CONTROL_PANEL, false,
887             friendlyURL);
888     }
889 
890     protected void addDefaultGuestPublicLayoutByProperties(Group group)
891         throws PortalException, SystemException {
892 
893         long defaultUserId = userLocalService.getDefaultUserId(
894             group.getCompanyId());
895         String friendlyURL = getFriendlyURL(
896             PropsValues.DEFAULT_GUEST_PUBLIC_LAYOUT_FRIENDLY_URL);
897 
898         Layout layout = layoutLocalService.addLayout(
899             defaultUserId, group.getGroupId(), false,
900             LayoutConstants.DEFAULT_PARENT_LAYOUT_ID,
901             PropsValues.DEFAULT_GUEST_PUBLIC_LAYOUT_NAME, StringPool.BLANK,
902             StringPool.BLANK, LayoutConstants.TYPE_PORTLET, false, friendlyURL);
903 
904         LayoutTypePortlet layoutTypePortlet =
905             (LayoutTypePortlet)layout.getLayoutType();
906 
907         layoutTypePortlet.setLayoutTemplateId(
908             0, PropsValues.DEFAULT_GUEST_PUBLIC_LAYOUT_TEMPLATE_ID, false);
909 
910         for (int i = 0; i < 10; i++) {
911             String columnId = "column-" + i;
912             String portletIds = PropsUtil.get(
913                 PropsKeys.DEFAULT_GUEST_PUBLIC_LAYOUT_COLUMN + i);
914 
915             layoutTypePortlet.addPortletIds(
916                 0, StringUtil.split(portletIds), columnId, false);
917         }
918 
919         layoutLocalService.updateLayout(
920             layout.getGroupId(), layout.isPrivateLayout(), layout.getLayoutId(),
921             layout.getTypeSettings());
922 
923         boolean updateLayoutSet = false;
924 
925         LayoutSet layoutSet = layout.getLayoutSet();
926 
927         if (Validator.isNotNull(
928                 PropsValues.DEFAULT_GUEST_PUBLIC_LAYOUT_REGULAR_THEME_ID)) {
929 
930             layoutSet.setThemeId(
931                 PropsValues.DEFAULT_GUEST_PUBLIC_LAYOUT_REGULAR_THEME_ID);
932 
933             updateLayoutSet = true;
934         }
935 
936         if (Validator.isNotNull(
937                 PropsValues.
938                     DEFAULT_GUEST_PUBLIC_LAYOUT_REGULAR_COLOR_SCHEME_ID)) {
939 
940             layoutSet.setColorSchemeId(
941                 PropsValues.
942                     DEFAULT_GUEST_PUBLIC_LAYOUT_REGULAR_COLOR_SCHEME_ID);
943 
944             updateLayoutSet = true;
945         }
946 
947         if (Validator.isNotNull(
948                 PropsValues.DEFAULT_GUEST_PUBLIC_LAYOUT_WAP_THEME_ID)) {
949 
950             layoutSet.setWapThemeId(
951                 PropsValues.DEFAULT_GUEST_PUBLIC_LAYOUT_WAP_THEME_ID);
952 
953             updateLayoutSet = true;
954         }
955 
956         if (Validator.isNotNull(
957                 PropsValues.DEFAULT_GUEST_PUBLIC_LAYOUT_WAP_COLOR_SCHEME_ID)) {
958 
959             layoutSet.setWapColorSchemeId(
960                 PropsValues.DEFAULT_GUEST_PUBLIC_LAYOUT_WAP_COLOR_SCHEME_ID);
961 
962             updateLayoutSet = true;
963         }
964 
965         if (updateLayoutSet) {
966             layoutSetLocalService.updateLayoutSet(layoutSet);
967         }
968     }
969 
970     protected void addDefaultGuestPublicLayouts(Group group)
971         throws PortalException, SystemException {
972 
973         if (publicLARFile != null) {
974             addDefaultGuestPublicLayoutsByLAR(group, publicLARFile);
975         }
976         else {
977             addDefaultGuestPublicLayoutByProperties(group);
978         }
979     }
980 
981     protected void addDefaultGuestPublicLayoutsByLAR(Group group, File larFile)
982         throws PortalException, SystemException {
983 
984         long defaultUserId = userLocalService.getDefaultUserId(
985             group.getCompanyId());
986 
987         Map<String, String[]> parameterMap = new HashMap<String, String[]>();
988 
989         parameterMap.put(
990             PortletDataHandlerKeys.CATEGORIES,
991             new String[] {Boolean.TRUE.toString()});
992         parameterMap.put(
993             PortletDataHandlerKeys.PERMISSIONS,
994             new String[] {Boolean.TRUE.toString()});
995         parameterMap.put(
996             PortletDataHandlerKeys.PORTLET_DATA,
997             new String[] {Boolean.TRUE.toString()});
998         parameterMap.put(
999             PortletDataHandlerKeys.PORTLET_DATA_CONTROL_DEFAULT,
1000            new String[] {Boolean.TRUE.toString()});
1001        parameterMap.put(
1002            PortletDataHandlerKeys.PORTLET_SETUP,
1003            new String[] {Boolean.TRUE.toString()});
1004        parameterMap.put(
1005            PortletDataHandlerKeys.USER_PERMISSIONS,
1006            new String[] {Boolean.FALSE.toString()});
1007
1008        layoutLocalService.importLayouts(
1009            defaultUserId, group.getGroupId(), false, parameterMap, larFile);
1010    }
1011
1012    protected String getFriendlyURL(String friendlyURL) {
1013        return FriendlyURLNormalizer.normalize(friendlyURL);
1014    }
1015
1016    protected String getFriendlyURL(
1017            long companyId, long groupId, long classNameId, long classPK,
1018            String friendlyName, String friendlyURL)
1019        throws PortalException, SystemException {
1020
1021        friendlyURL = getFriendlyURL(friendlyURL);
1022
1023        if (Validator.isNull(friendlyURL)) {
1024            friendlyURL = StringPool.SLASH + getFriendlyURL(friendlyName);
1025
1026            String originalFriendlyURL = friendlyURL;
1027
1028            for (int i = 1;; i++) {
1029                try {
1030                    validateFriendlyURL(
1031                        companyId, groupId, classNameId, classPK, friendlyURL);
1032
1033                    break;
1034                }
1035                catch (GroupFriendlyURLException gfurle) {
1036                    int type = gfurle.getType();
1037
1038                    if (type == GroupFriendlyURLException.DUPLICATE) {
1039                        friendlyURL = originalFriendlyURL + i;
1040                    }
1041                    else {
1042                        friendlyURL = StringPool.SLASH + classPK;
1043
1044                        break;
1045                    }
1046                }
1047            }
1048        }
1049
1050        return friendlyURL;
1051    }
1052
1053    protected void initImportLARFile() {
1054        String publicLARFileName = PropsValues.DEFAULT_GUEST_PUBLIC_LAYOUTS_LAR;
1055
1056        if (_log.isDebugEnabled()) {
1057            _log.debug("Reading public LAR file " + publicLARFileName);
1058        }
1059
1060        if (Validator.isNotNull(publicLARFileName)) {
1061            publicLARFile = new File(publicLARFileName);
1062
1063            if (!publicLARFile.exists()) {
1064                _log.error(
1065                    "Public LAR file " + publicLARFile + " does not exist");
1066
1067                publicLARFile = null;
1068            }
1069            else {
1070                if (_log.isDebugEnabled()) {
1071                    _log.debug("Using public LAR file " + publicLARFileName);
1072                }
1073            }
1074        }
1075    }
1076
1077    protected void unscheduleStaging(Group group) {
1078        try {
1079
1080            // Remote publishing
1081
1082            String groupName = StagingUtil.getSchedulerGroupName(
1083                DestinationNames.LAYOUTS_REMOTE_PUBLISHER, group.getGroupId());
1084
1085            List<SchedulerRequest> schedulerRequests =
1086                SchedulerEngineUtil.getScheduledJobs(groupName);
1087
1088            for (SchedulerRequest schedulerRequest : schedulerRequests) {
1089                SchedulerEngineUtil.unschedule(
1090                    schedulerRequest.getJobName(), groupName);
1091            }
1092
1093            long liveGroupId = 0;
1094            long stagingGroupId = 0;
1095
1096            if (group.isStagingGroup()) {
1097                liveGroupId = group.getLiveGroupId();
1098
1099                stagingGroupId = group.getGroupId();
1100            }
1101            else if (group.hasStagingGroup()) {
1102                liveGroupId = group.getGroupId();
1103
1104                stagingGroupId = group.getStagingGroup().getGroupId();
1105            }
1106
1107            if ((liveGroupId != 0) && (stagingGroupId != 0)) {
1108
1109                // Publish to live
1110
1111                groupName = StagingUtil.getSchedulerGroupName(
1112                    DestinationNames.LAYOUTS_LOCAL_PUBLISHER, liveGroupId);
1113
1114                schedulerRequests = SchedulerEngineUtil.getScheduledJobs(
1115                    groupName);
1116
1117                for (SchedulerRequest schedulerRequest : schedulerRequests) {
1118                    SchedulerEngineUtil.unschedule(
1119                        schedulerRequest.getJobName(), groupName);
1120                }
1121
1122                // Copy from live
1123
1124                groupName = StagingUtil.getSchedulerGroupName(
1125                    DestinationNames.LAYOUTS_LOCAL_PUBLISHER, stagingGroupId);
1126
1127                schedulerRequests = SchedulerEngineUtil.getScheduledJobs(
1128                    groupName);
1129
1130                for (SchedulerRequest schedulerRequest : schedulerRequests) {
1131                    SchedulerEngineUtil.unschedule(
1132                        schedulerRequest.getJobName(), groupName);
1133                }
1134            }
1135        }
1136        catch (Exception e) {
1137            _log.error(
1138                "Unable to unschedule events for group: " + group.getGroupId());
1139        }
1140    }
1141
1142    protected void validateFriendlyURL(
1143            long companyId, long groupId, long classNameId, long classPK,
1144            String friendlyURL)
1145        throws PortalException, SystemException {
1146
1147        Company company = companyPersistence.findByPrimaryKey(companyId);
1148
1149        if (company.isSystem()) {
1150            return;
1151        }
1152
1153        if (Validator.isNull(friendlyURL)) {
1154            return;
1155        }
1156
1157        int exceptionType = LayoutImpl.validateFriendlyURL(friendlyURL);
1158
1159        if (exceptionType != -1) {
1160            throw new GroupFriendlyURLException(exceptionType);
1161        }
1162
1163        Group group = groupPersistence.fetchByC_F(companyId, friendlyURL);
1164
1165        if ((group != null) && (group.getGroupId() != groupId)) {
1166            throw new GroupFriendlyURLException(
1167                GroupFriendlyURLException.DUPLICATE);
1168        }
1169
1170        String groupIdFriendlyURL = friendlyURL.substring(1);
1171
1172        if (Validator.isNumber(groupIdFriendlyURL)) {
1173            long groupClassNameId = PortalUtil.getClassNameId(Group.class);
1174
1175            if (((classNameId != groupClassNameId) &&
1176                 (!groupIdFriendlyURL.equals(String.valueOf(classPK))) &&
1177                 (!PropsValues.USERS_SCREEN_NAME_ALLOW_NUMERIC)) ||
1178                ((classNameId == groupClassNameId) &&
1179                 (!groupIdFriendlyURL.equals(String.valueOf(groupId))))) {
1180
1181                GroupFriendlyURLException gfurle =
1182                    new GroupFriendlyURLException(
1183                        GroupFriendlyURLException.POSSIBLE_DUPLICATE);
1184
1185                gfurle.setKeywordConflict(groupIdFriendlyURL);
1186
1187                throw gfurle;
1188            }
1189        }
1190
1191        String screenName = friendlyURL.substring(1);
1192
1193        User user = userPersistence.fetchByC_SN(companyId, screenName);
1194
1195        if (user != null) {
1196            long userClassNameId = PortalUtil.getClassNameId(User.class);
1197
1198            if ((classNameId == userClassNameId) &&
1199                (classPK == user.getUserId())) {
1200            }
1201            else {
1202                throw new GroupFriendlyURLException(
1203                    GroupFriendlyURLException.DUPLICATE);
1204            }
1205        }
1206
1207        if (StringUtil.count(friendlyURL, StringPool.SLASH) > 1) {
1208            throw new GroupFriendlyURLException(
1209                GroupFriendlyURLException.TOO_DEEP);
1210        }
1211    }
1212
1213    protected void validateName(long groupId, long companyId, String name)
1214        throws PortalException, SystemException {
1215
1216        if ((Validator.isNull(name)) || (Validator.isNumber(name)) ||
1217            (name.indexOf(StringPool.COMMA) != -1) ||
1218            (name.indexOf(StringPool.STAR) != -1)) {
1219
1220            throw new GroupNameException();
1221        }
1222
1223        try {
1224            Group group = groupFinder.findByC_N(companyId, name);
1225
1226            if ((groupId <= 0) || (group.getGroupId() != groupId)) {
1227                throw new DuplicateGroupException();
1228            }
1229        }
1230        catch (NoSuchGroupException nsge) {
1231        }
1232    }
1233
1234    protected File publicLARFile;
1235
1236    private static Log _log = LogFactoryUtil.getLog(
1237        GroupLocalServiceImpl.class);
1238
1239    private Map<String, Group> _systemGroupsMap = new HashMap<String, Group>();
1240
1241}