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