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