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