1   /**
2    * Copyright (c) 2000-2008 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.util.GetterUtil;
35  import com.liferay.portal.kernel.util.OrderByComparator;
36  import com.liferay.portal.kernel.util.StringPool;
37  import com.liferay.portal.kernel.util.StringUtil;
38  import com.liferay.portal.kernel.util.Validator;
39  import com.liferay.portal.model.Group;
40  import com.liferay.portal.model.Layout;
41  import com.liferay.portal.model.LayoutSet;
42  import com.liferay.portal.model.LayoutTypePortlet;
43  import com.liferay.portal.model.Organization;
44  import com.liferay.portal.model.Resource;
45  import com.liferay.portal.model.Role;
46  import com.liferay.portal.model.User;
47  import com.liferay.portal.model.UserGroup;
48  import com.liferay.portal.model.impl.GroupImpl;
49  import com.liferay.portal.model.impl.LayoutImpl;
50  import com.liferay.portal.model.impl.ResourceImpl;
51  import com.liferay.portal.model.impl.RoleImpl;
52  import com.liferay.portal.security.permission.PermissionCacheUtil;
53  import com.liferay.portal.service.base.GroupLocalServiceBaseImpl;
54  import com.liferay.portal.util.PortalUtil;
55  import com.liferay.portal.util.PropsUtil;
56  import com.liferay.portal.util.comparator.GroupNameComparator;
57  import com.liferay.util.Normalizer;
58  
59  import java.util.ArrayList;
60  import java.util.Iterator;
61  import java.util.LinkedHashMap;
62  import java.util.List;
63  
64  /**
65   * <a href="GroupLocalServiceImpl.java.html"><b><i>View Source</i></b></a>
66   *
67   * @author Brian Wing Shun Chan
68   * @author Alexander Chow
69   *
70   */
71  public class GroupLocalServiceImpl extends GroupLocalServiceBaseImpl {
72  
73      public Group addGroup(
74              long userId, String className, long classPK, String name,
75              String description, int type, String friendlyURL, boolean active)
76          throws PortalException, SystemException {
77  
78          return addGroup(
79              userId, className, classPK, GroupImpl.DEFAULT_LIVE_GROUP_ID, name,
80              description, type, friendlyURL, active);
81      }
82  
83      public Group addGroup(
84              long userId, String className, long classPK, long liveGroupId,
85              String name, String description, int type, String friendlyURL,
86              boolean active)
87          throws PortalException, SystemException {
88  
89          // Group
90  
91          User user = userPersistence.findByPrimaryKey(userId);
92          className = GetterUtil.getString(className);
93          long classNameId = PortalUtil.getClassNameId(className);
94  
95          if ((classNameId <= 0) || (classPK <= 0)) {
96              validateName(0, user.getCompanyId(), name);
97          }
98  
99          friendlyURL = getFriendlyURL(classNameId, friendlyURL);
100 
101         validateFriendlyURL(0, user.getCompanyId(), friendlyURL);
102 
103         long groupId = counterLocalService.increment();
104 
105         if ((classNameId > 0) && (classPK > 0)) {
106             name = String.valueOf(groupId);
107         }
108 
109         Group group = groupPersistence.create(groupId);
110 
111         group.setCompanyId(user.getCompanyId());
112         group.setCreatorUserId(userId);
113         group.setClassNameId(classNameId);
114         group.setClassPK(classPK);
115         group.setParentGroupId(GroupImpl.DEFAULT_PARENT_GROUP_ID);
116         group.setLiveGroupId(liveGroupId);
117         group.setName(name);
118         group.setDescription(description);
119         group.setType(type);
120         group.setFriendlyURL(friendlyURL);
121         group.setActive(active);
122 
123         groupPersistence.update(group);
124 
125         // Layout sets
126 
127         layoutSetLocalService.addLayoutSet(groupId, true);
128 
129         layoutSetLocalService.addLayoutSet(groupId, false);
130 
131         if ((classNameId <= 0) && (classPK <= 0) && !user.isDefaultUser()) {
132 
133             // Resources
134 
135             resourceLocalService.addResources(
136                 group.getCompanyId(), 0, 0, Group.class.getName(),
137                 group.getGroupId(), false, false, false);
138 
139             // Community roles
140 
141             Role role = roleLocalService.getRole(
142                 group.getCompanyId(), RoleImpl.COMMUNITY_OWNER);
143 
144             userGroupRoleLocalService.addUserGroupRoles(
145                 userId, groupId, new long[] {role.getRoleId()});
146 
147             // User
148 
149             userLocalService.addGroupUsers(
150                 group.getGroupId(), new long[] {userId});
151         }
152         else if (className.equals(Organization.class.getName()) &&
153                  !user.isDefaultUser()) {
154 
155             // Resources
156 
157             resourceLocalService.addResources(
158                 group.getCompanyId(), 0, 0, Group.class.getName(),
159                 group.getGroupId(), false, false, false);
160         }
161 
162         return group;
163     }
164 
165     public void addRoleGroups(long roleId, long[] groupIds)
166         throws PortalException, SystemException {
167 
168         rolePersistence.addGroups(roleId, groupIds);
169 
170         PermissionCacheUtil.clearCache();
171     }
172 
173     public void addUserGroups(long userId, long[] groupIds)
174         throws PortalException, SystemException {
175 
176         userPersistence.addGroups(userId, groupIds);
177 
178         User user = userPersistence.findByPrimaryKey(userId);
179 
180         Role role = rolePersistence.findByC_N(
181             user.getCompanyId(), RoleImpl.COMMUNITY_MEMBER);
182 
183         for (int i = 0; i < groupIds.length; i++) {
184             long groupId = groupIds[i];
185 
186             userGroupRoleLocalService.addUserGroupRoles(
187                 userId, groupId, new long[] {role.getRoleId()});
188         }
189 
190         PermissionCacheUtil.clearCache();
191     }
192 
193     public void checkSystemGroups(long companyId)
194         throws PortalException, SystemException {
195 
196         long defaultUserId = userLocalService.getDefaultUserId(companyId);
197 
198         String[] systemGroups = PortalUtil.getSystemGroups();
199 
200         for (int i = 0; i < systemGroups.length; i++) {
201             Group group = null;
202 
203             try {
204                 group = groupFinder.findByC_N(companyId, systemGroups[i]);
205             }
206             catch (NoSuchGroupException nsge) {
207                 String friendlyURL = null;
208 
209                 if (systemGroups[i].equals(GroupImpl.GUEST)) {
210                     friendlyURL = "/guest";
211                 }
212 
213                 group = addGroup(
214                     defaultUserId, null, 0, systemGroups[i], null,
215                     GroupImpl.TYPE_COMMUNITY_OPEN, friendlyURL, true);
216             }
217 
218             if (group.getName().equals(GroupImpl.GUEST)) {
219                 LayoutSet layoutSet = layoutSetLocalService.getLayoutSet(
220                     group.getGroupId(), false);
221 
222                 if (layoutSet.getPageCount() == 0) {
223                     addDefaultLayouts(group);
224                 }
225             }
226         }
227     }
228 
229     public void deleteGroup(long groupId)
230         throws PortalException, SystemException {
231 
232         Group group = groupPersistence.findByPrimaryKey(groupId);
233 
234         if (PortalUtil.isSystemGroup(group.getName())) {
235             throw new RequiredGroupException();
236         }
237 
238         // Layout sets
239 
240         try {
241             layoutSetLocalService.deleteLayoutSet(groupId, true);
242         }
243         catch (NoSuchLayoutSetException nslse) {
244         }
245 
246         try {
247             layoutSetLocalService.deleteLayoutSet(groupId, false);
248         }
249         catch (NoSuchLayoutSetException nslse) {
250         }
251 
252         // Role
253 
254         try {
255             Role role = roleLocalService.getGroupRole(
256                 group.getCompanyId(), groupId);
257 
258             roleLocalService.deleteRole(role.getRoleId());
259         }
260         catch (NoSuchRoleException nsre) {
261         }
262 
263         // Group roles
264 
265         userGroupRoleLocalService.deleteUserGroupRolesByGroupId(groupId);
266 
267         // Membership requests
268 
269         membershipRequestLocalService.deleteMembershipRequests(
270             group.getGroupId());
271 
272         // Blogs
273 
274         blogsEntryLocalService.deleteEntries(groupId);
275         blogsStatsUserLocalService.deleteStatsUserByGroupId(groupId);
276 
277         // Bookmarks
278 
279         bookmarksFolderLocalService.deleteFolders(groupId);
280 
281         // Calendar
282 
283         calEventLocalService.deleteEvents(groupId);
284 
285         // Document library
286 
287         dlFolderLocalService.deleteFolders(groupId);
288 
289         // Image gallery
290 
291         igFolderLocalService.deleteFolders(groupId);
292 
293         // Journal
294 
295         journalArticleLocalService.deleteArticles(groupId);
296         journalTemplateLocalService.deleteTemplates(groupId);
297         journalStructureLocalService.deleteStructures(groupId);
298 
299         // Message boards
300 
301         mbBanLocalService.deleteBansByGroupId(groupId);
302         mbCategoryLocalService.deleteCategories(groupId);
303         mbStatsUserLocalService.deleteStatsUserByGroupId(groupId);
304 
305         // Polls
306 
307         pollsQuestionLocalService.deleteQuestions(groupId);
308 
309         // Shopping
310 
311         shoppingCartLocalService.deleteGroupCarts(groupId);
312         shoppingCategoryLocalService.deleteCategories(groupId);
313         shoppingCouponLocalService.deleteCoupons(groupId);
314         shoppingOrderLocalService.deleteOrders(groupId);
315 
316         // Software catalog
317 
318         scFrameworkVersionLocalService.deleteFrameworkVersions(groupId);
319         scProductEntryLocalService.deleteProductEntries(groupId);
320 
321         // Wiki
322 
323         wikiNodeLocalService.deleteNodes(groupId);
324 
325         // Resources
326 
327         Iterator itr = resourceFinder.findByC_P(
328             group.getCompanyId(), String.valueOf(groupId)).iterator();
329 
330         while (itr.hasNext()) {
331             Resource resource = (Resource)itr.next();
332 
333             resourceLocalService.deleteResource(resource);
334         }
335 
336         long organizationClassNameId = PortalUtil.getClassNameId(
337             Organization.class.getName());
338 
339         if (((group.getClassNameId() <= 0) && (group.getClassPK() <= 0)) ||
340             (group.getClassNameId() == organizationClassNameId)) {
341 
342             resourceLocalService.deleteResource(
343                 group.getCompanyId(), Group.class.getName(),
344                 ResourceImpl.SCOPE_INDIVIDUAL, group.getGroupId());
345         }
346 
347         // Group
348 
349         groupPersistence.remove(groupId);
350 
351         // Permission cache
352 
353         PermissionCacheUtil.clearCache();
354     }
355 
356     public Group getFriendlyURLGroup(long companyId, String friendlyURL)
357         throws PortalException, SystemException {
358 
359         if (Validator.isNull(friendlyURL)) {
360             throw new NoSuchGroupException();
361         }
362 
363         friendlyURL = getFriendlyURL(friendlyURL);
364 
365         return groupPersistence.findByC_F(companyId, friendlyURL);
366     }
367 
368     public Group getGroup(long groupId)
369         throws PortalException, SystemException {
370 
371         return groupPersistence.findByPrimaryKey(groupId);
372     }
373 
374     public Group getGroup(long companyId, String name)
375         throws PortalException, SystemException {
376 
377         return groupFinder.findByC_N(companyId, name);
378     }
379 
380     public Group getOrganizationGroup(long companyId, long organizationId)
381         throws PortalException, SystemException {
382 
383         long classNameId = PortalUtil.getClassNameId(Organization.class);
384 
385         return groupPersistence.findByC_C_C(
386             companyId, classNameId, organizationId);
387     }
388 
389     public List getOrganizationsGroups(List organizations)
390         throws PortalException, SystemException {
391 
392         List organizationGroups = new ArrayList();
393 
394         for (int i = 0; i < organizations.size(); i++) {
395             Organization organization = (Organization)organizations.get(i);
396 
397             Group group = organization.getGroup();
398 
399             organizationGroups.add(group);
400         }
401 
402         return organizationGroups;
403     }
404 
405     public List getRoleGroups(long roleId)
406         throws PortalException, SystemException {
407 
408         return rolePersistence.getGroups(roleId);
409     }
410 
411     public Group getStagingGroup(long liveGroupId)
412         throws PortalException, SystemException {
413 
414         return groupPersistence.findByLiveGroupId(liveGroupId);
415     }
416 
417     public Group getUserGroup(long companyId, long userId)
418         throws PortalException, SystemException {
419 
420         long classNameId = PortalUtil.getClassNameId(User.class);
421 
422         return groupPersistence.findByC_C_C(companyId, classNameId, userId);
423     }
424 
425     public Group getUserGroupGroup(long companyId, long userGroupId)
426         throws PortalException, SystemException {
427 
428         long classNameId = PortalUtil.getClassNameId(UserGroup.class);
429 
430         return groupPersistence.findByC_C_C(
431             companyId, classNameId, userGroupId);
432     }
433 
434     public List getUserGroups(long userId)
435         throws PortalException, SystemException {
436 
437         return userPersistence.getGroups(userId);
438     }
439 
440     public List getUserGroupsGroups(List userGroups)
441         throws PortalException, SystemException {
442 
443         List userGroupGroups = new ArrayList();
444 
445         for (int i = 0; i < userGroups.size(); i++) {
446             UserGroup userGroup = (UserGroup)userGroups.get(i);
447 
448             Group group = userGroup.getGroup();
449 
450             userGroupGroups.add(group);
451         }
452 
453         return userGroupGroups;
454     }
455 
456     public boolean hasRoleGroup(long roleId, long groupId)
457         throws PortalException, SystemException {
458 
459         return rolePersistence.containsGroup(roleId, groupId);
460     }
461 
462     public boolean hasUserGroup(long userId, long groupId)
463         throws SystemException {
464 
465         if (groupFinder.countByG_U(groupId, userId) > 0) {
466             return true;
467         }
468         else {
469             return false;
470         }
471     }
472 
473     public List search(
474             long companyId, String name, String description,
475             LinkedHashMap params, int begin, int end)
476         throws SystemException {
477 
478         return groupFinder.findByC_N_D(
479             companyId, name, description, params, begin, end, null);
480     }
481 
482     public List search(
483             long companyId, String name, String description,
484             LinkedHashMap params, int begin, int end, OrderByComparator obc)
485         throws SystemException {
486 
487         if (obc == null) {
488             obc = new GroupNameComparator(true);
489         }
490 
491         return groupFinder.findByC_N_D(
492             companyId, name, description, params, begin, end, obc);
493     }
494 
495     public int searchCount(
496             long companyId, String name, String description,
497             LinkedHashMap params)
498         throws SystemException {
499 
500         return groupFinder.countByC_N_D(companyId, name, description, params);
501     }
502 
503     public void setRoleGroups(long roleId, long[] groupIds)
504         throws PortalException, SystemException {
505 
506         rolePersistence.setGroups(roleId, groupIds);
507 
508         PermissionCacheUtil.clearCache();
509     }
510 
511     public void unsetRoleGroups(long roleId, long[] groupIds)
512         throws PortalException, SystemException {
513 
514         rolePersistence.removeGroups(roleId, groupIds);
515 
516         PermissionCacheUtil.clearCache();
517     }
518 
519     public void unsetUserGroups(long userId, long[] groupIds)
520         throws PortalException, SystemException {
521 
522         userGroupRoleLocalService.deleteUserGroupRoles(userId, groupIds);
523 
524         userPersistence.removeGroups(userId, groupIds);
525 
526         PermissionCacheUtil.clearCache();
527     }
528 
529     public Group updateGroup(
530             long groupId, String name, String description, int type,
531             String friendlyURL, boolean active)
532         throws PortalException, SystemException {
533 
534         Group group = groupPersistence.findByPrimaryKey(groupId);
535 
536         long classNameId = group.getClassNameId();
537         long classPK = group.getClassPK();
538         friendlyURL = getFriendlyURL(classNameId, friendlyURL);
539 
540         if ((classNameId <= 0) || (classPK <= 0)) {
541             validateName(group.getGroupId(), group.getCompanyId(), name);
542         }
543 
544         if (PortalUtil.isSystemGroup(group.getName()) &&
545             !group.getName().equals(name)) {
546 
547             throw new RequiredGroupException();
548         }
549 
550         validateFriendlyURL(
551             group.getGroupId(), group.getCompanyId(), friendlyURL);
552 
553         group.setName(name);
554         group.setDescription(description);
555         group.setType(type);
556         group.setFriendlyURL(friendlyURL);
557         group.setActive(active);
558 
559         groupPersistence.update(group);
560 
561         return group;
562     }
563 
564     public Group updateGroup(long groupId, String typeSettings)
565         throws PortalException, SystemException {
566 
567         Group group = groupPersistence.findByPrimaryKey(groupId);
568 
569         group.setTypeSettings(typeSettings);
570 
571         groupPersistence.update(group);
572 
573         return group;
574     }
575 
576     protected void addDefaultLayouts(Group group)
577         throws PortalException, SystemException {
578 
579         long defaultUserId = userLocalService.getDefaultUserId(
580             group.getCompanyId());
581         String name = PropsUtil.get(PropsUtil.DEFAULT_GUEST_LAYOUT_NAME);
582 
583         String friendlyURL = StringPool.BLANK;
584 
585         if (Validator.isNotNull(group.getFriendlyURL())) {
586             friendlyURL = PropsUtil.get(PropsUtil.DEFAULT_GUEST_FRIENDLY_URL);
587         }
588 
589         friendlyURL = getFriendlyURL(friendlyURL);
590 
591         Layout layout = layoutLocalService.addLayout(
592             defaultUserId, group.getGroupId(), false,
593             LayoutImpl.DEFAULT_PARENT_LAYOUT_ID, name, StringPool.BLANK,
594             StringPool.BLANK, LayoutImpl.TYPE_PORTLET, false, friendlyURL);
595 
596         LayoutTypePortlet layoutTypePortlet =
597             (LayoutTypePortlet)layout.getLayoutType();
598 
599         String layoutTemplateId = PropsUtil.get(
600             PropsUtil.DEFAULT_GUEST_LAYOUT_TEMPLATE_ID);
601 
602         layoutTypePortlet.setLayoutTemplateId(0, layoutTemplateId, false);
603 
604         for (int i = 0; i < 10; i++) {
605             String columnId = "column-" + i;
606             String portletIds = PropsUtil.get(
607                 PropsUtil.DEFAULT_GUEST_LAYOUT_COLUMN + i);
608 
609             layoutTypePortlet.addPortletIds(
610                 0, StringUtil.split(portletIds), columnId, false);
611         }
612 
613         layoutLocalService.updateLayout(
614             layout.getGroupId(), layout.isPrivateLayout(), layout.getLayoutId(),
615             layout.getTypeSettings());
616     }
617 
618     protected String getFriendlyURL(String friendlyURL) {
619         return Normalizer.normalizeToAscii(friendlyURL.trim().toLowerCase());
620     }
621 
622     protected String getFriendlyURL(long classNameId, String friendlyURL)
623         throws PortalException, SystemException {
624 
625         if (classNameId > 0) {
626             long userClassNameId = PortalUtil.getClassNameId(User.class);
627 
628             if (classNameId == userClassNameId) {
629                 return StringPool.BLANK;
630             }
631         }
632 
633         return getFriendlyURL(GetterUtil.getString(friendlyURL));
634     }
635 
636     protected void validateFriendlyURL(
637             long groupId, long companyId, String friendlyURL)
638         throws PortalException, SystemException {
639 
640         if (Validator.isNotNull(friendlyURL)) {
641             int exceptionType = LayoutImpl.validateFriendlyURL(friendlyURL);
642 
643             if (exceptionType != -1) {
644                 throw new GroupFriendlyURLException(exceptionType);
645             }
646 
647             try {
648                 Group group = groupPersistence.findByC_F(
649                     companyId, friendlyURL);
650 
651                 if ((groupId <= 0) || (group.getGroupId() != groupId)) {
652                     throw new GroupFriendlyURLException(
653                         GroupFriendlyURLException.DUPLICATE);
654                 }
655             }
656             catch (NoSuchGroupException nsge) {
657             }
658 
659             String screenName = friendlyURL;
660 
661             if (screenName.startsWith(StringPool.SLASH)) {
662                 screenName = friendlyURL.substring(1, friendlyURL.length());
663             }
664 
665             User user = userPersistence.fetchByC_SN(companyId, screenName);
666 
667             if (user != null) {
668                 throw new GroupFriendlyURLException(
669                     GroupFriendlyURLException.DUPLICATE);
670             }
671         }
672     }
673 
674     protected void validateName(long groupId, long companyId, String name)
675         throws PortalException, SystemException {
676 
677         if ((Validator.isNull(name)) || (Validator.isNumber(name)) ||
678             (name.indexOf(StringPool.COMMA) != -1) ||
679             (name.indexOf(StringPool.STAR) != -1)) {
680 
681             throw new GroupNameException();
682         }
683 
684         try {
685             Group group = groupFinder.findByC_N(companyId, name);
686 
687             if ((groupId <= 0) || (group.getGroupId() != groupId)) {
688                 throw new DuplicateGroupException();
689             }
690         }
691         catch (NoSuchGroupException nsge) {
692         }
693     }
694 
695 }