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