001
014
015 package com.liferay.portal.service.impl;
016
017 import com.liferay.portal.DuplicateGroupException;
018 import com.liferay.portal.GroupFriendlyURLException;
019 import com.liferay.portal.GroupNameException;
020 import com.liferay.portal.GroupParentException;
021 import com.liferay.portal.LocaleException;
022 import com.liferay.portal.NoSuchGroupException;
023 import com.liferay.portal.NoSuchLayoutSetException;
024 import com.liferay.portal.PendingBackgroundTaskException;
025 import com.liferay.portal.RequiredGroupException;
026 import com.liferay.portal.kernel.backgroundtask.BackgroundTaskConstants;
027 import com.liferay.portal.kernel.cache.ThreadLocalCachable;
028 import com.liferay.portal.kernel.dao.orm.QueryUtil;
029 import com.liferay.portal.kernel.exception.PortalException;
030 import com.liferay.portal.kernel.exception.SystemException;
031 import com.liferay.portal.kernel.language.LanguageUtil;
032 import com.liferay.portal.kernel.lar.PortletDataContext;
033 import com.liferay.portal.kernel.lar.PortletDataContextFactoryUtil;
034 import com.liferay.portal.kernel.lar.PortletDataHandler;
035 import com.liferay.portal.kernel.lar.PortletDataHandlerKeys;
036 import com.liferay.portal.kernel.log.Log;
037 import com.liferay.portal.kernel.log.LogFactoryUtil;
038 import com.liferay.portal.kernel.messaging.DestinationNames;
039 import com.liferay.portal.kernel.scheduler.SchedulerEngineHelperUtil;
040 import com.liferay.portal.kernel.scheduler.StorageType;
041 import com.liferay.portal.kernel.spring.aop.Skip;
042 import com.liferay.portal.kernel.staging.StagingConstants;
043 import com.liferay.portal.kernel.staging.StagingUtil;
044 import com.liferay.portal.kernel.transaction.Propagation;
045 import com.liferay.portal.kernel.transaction.Transactional;
046 import com.liferay.portal.kernel.util.ArrayUtil;
047 import com.liferay.portal.kernel.util.CharPool;
048 import com.liferay.portal.kernel.util.FileUtil;
049 import com.liferay.portal.kernel.util.FriendlyURLNormalizerUtil;
050 import com.liferay.portal.kernel.util.GetterUtil;
051 import com.liferay.portal.kernel.util.GroupThreadLocal;
052 import com.liferay.portal.kernel.util.ListUtil;
053 import com.liferay.portal.kernel.util.LocaleUtil;
054 import com.liferay.portal.kernel.util.MapUtil;
055 import com.liferay.portal.kernel.util.OrderByComparator;
056 import com.liferay.portal.kernel.util.ParamUtil;
057 import com.liferay.portal.kernel.util.PropsKeys;
058 import com.liferay.portal.kernel.util.StringPool;
059 import com.liferay.portal.kernel.util.StringUtil;
060 import com.liferay.portal.kernel.util.UnicodeProperties;
061 import com.liferay.portal.kernel.util.UniqueList;
062 import com.liferay.portal.kernel.util.Validator;
063 import com.liferay.portal.kernel.workflow.WorkflowHandler;
064 import com.liferay.portal.kernel.workflow.WorkflowHandlerRegistryUtil;
065 import com.liferay.portal.kernel.zip.ZipWriter;
066 import com.liferay.portal.model.Account;
067 import com.liferay.portal.model.BackgroundTask;
068 import com.liferay.portal.model.Company;
069 import com.liferay.portal.model.Group;
070 import com.liferay.portal.model.GroupConstants;
071 import com.liferay.portal.model.Layout;
072 import com.liferay.portal.model.LayoutConstants;
073 import com.liferay.portal.model.LayoutPrototype;
074 import com.liferay.portal.model.LayoutSet;
075 import com.liferay.portal.model.LayoutSetPrototype;
076 import com.liferay.portal.model.LayoutTemplate;
077 import com.liferay.portal.model.LayoutTypePortlet;
078 import com.liferay.portal.model.Organization;
079 import com.liferay.portal.model.Portlet;
080 import com.liferay.portal.model.ResourceAction;
081 import com.liferay.portal.model.ResourceConstants;
082 import com.liferay.portal.model.ResourcePermission;
083 import com.liferay.portal.model.ResourceTypePermission;
084 import com.liferay.portal.model.Role;
085 import com.liferay.portal.model.RoleConstants;
086 import com.liferay.portal.model.User;
087 import com.liferay.portal.model.UserGroup;
088 import com.liferay.portal.model.UserGroupRole;
089 import com.liferay.portal.model.UserPersonalSite;
090 import com.liferay.portal.model.WorkflowDefinitionLink;
091 import com.liferay.portal.model.impl.LayoutImpl;
092 import com.liferay.portal.security.auth.CompanyThreadLocal;
093 import com.liferay.portal.security.permission.ActionKeys;
094 import com.liferay.portal.security.permission.PermissionCacheUtil;
095 import com.liferay.portal.security.permission.ResourceActionsUtil;
096 import com.liferay.portal.service.ServiceContext;
097 import com.liferay.portal.service.base.GroupLocalServiceBaseImpl;
098 import com.liferay.portal.theme.ThemeLoader;
099 import com.liferay.portal.theme.ThemeLoaderFactory;
100 import com.liferay.portal.util.PortalUtil;
101 import com.liferay.portal.util.PortletCategoryKeys;
102 import com.liferay.portal.util.PortletKeys;
103 import com.liferay.portal.util.PropsUtil;
104 import com.liferay.portal.util.PropsValues;
105 import com.liferay.portal.util.comparator.GroupNameComparator;
106 import com.liferay.portlet.blogs.model.BlogsEntry;
107 import com.liferay.portlet.journal.model.JournalArticle;
108 import com.liferay.util.dao.orm.CustomSQLUtil;
109
110 import java.io.File;
111
112 import java.util.ArrayList;
113 import java.util.Arrays;
114 import java.util.Collections;
115 import java.util.Date;
116 import java.util.HashMap;
117 import java.util.HashSet;
118 import java.util.Iterator;
119 import java.util.LinkedHashMap;
120 import java.util.List;
121 import java.util.Locale;
122 import java.util.Map;
123 import java.util.Set;
124
125
199 public class GroupLocalServiceImpl extends GroupLocalServiceBaseImpl {
200
201 public static final String ORGANIZATION_NAME_SUFFIX = " LFR_ORGANIZATION";
202
203
206 public GroupLocalServiceImpl() {
207 initImportLARFile();
208 }
209
210
236 @Override
237 public Group addGroup(
238 long userId, long parentGroupId, String className, long classPK,
239 long liveGroupId, String name, String description, int type,
240 boolean manualMembership, int membershipRestriction,
241 String friendlyURL, boolean site, boolean active,
242 ServiceContext serviceContext)
243 throws PortalException, SystemException {
244
245
246
247 User user = userPersistence.findByPrimaryKey(userId);
248 className = GetterUtil.getString(className);
249 long classNameId = PortalUtil.getClassNameId(className);
250 String friendlyName = name;
251
252 long groupId = 0;
253
254 while (true) {
255 groupId = counterLocalService.increment();
256
257 User screenNameUser = userPersistence.fetchByC_SN(
258 user.getCompanyId(), String.valueOf(groupId));
259
260 if (screenNameUser == null) {
261 break;
262 }
263 }
264
265 boolean staging = isStaging(serviceContext);
266
267 long groupClassNameId = PortalUtil.getClassNameId(Group.class);
268
269 if (((classNameId <= 0) || className.equals(Group.class.getName())) ||
270 (className.equals(Company.class.getName()) && staging)) {
271
272 className = Group.class.getName();
273 classNameId = groupClassNameId;
274 classPK = groupId;
275 }
276 else if (className.equals(Organization.class.getName())) {
277 name = getOrgGroupName(name);
278 }
279 else if (!GroupConstants.USER_PERSONAL_SITE.equals(name)) {
280 name = String.valueOf(classPK);
281 }
282
283 if (className.equals(Organization.class.getName()) && staging) {
284 classPK = liveGroupId;
285 }
286
287 if (className.equals(Layout.class.getName())) {
288 Layout layout = layoutLocalService.getLayout(classPK);
289
290 parentGroupId = layout.getGroupId();
291 }
292
293 friendlyURL = getFriendlyURL(
294 user.getCompanyId(), groupId, classNameId, classPK, friendlyName,
295 friendlyURL);
296
297 if (staging) {
298 name = name.concat(" (Staging)");
299 friendlyURL = friendlyURL.concat("-staging");
300 }
301
302 if (parentGroupId == GroupConstants.DEFAULT_PARENT_GROUP_ID) {
303 membershipRestriction =
304 GroupConstants.DEFAULT_MEMBERSHIP_RESTRICTION;
305 }
306
307 if (className.equals(Group.class.getName())) {
308 if (!site && (liveGroupId == 0) &&
309 !name.equals(GroupConstants.CONTROL_PANEL)) {
310
311 throw new IllegalArgumentException();
312 }
313 }
314 else if (!className.equals(Company.class.getName()) &&
315 !className.equals(Organization.class.getName()) &&
316 className.startsWith("com.liferay.portal.model.")) {
317
318 if (site) {
319 throw new IllegalArgumentException();
320 }
321 }
322
323 if ((classNameId <= 0) || className.equals(Group.class.getName())) {
324 validateName(groupId, user.getCompanyId(), name, site);
325 }
326
327 validateFriendlyURL(
328 user.getCompanyId(), groupId, classNameId, classPK, friendlyURL);
329
330 validateParentGroup(groupId, parentGroupId);
331
332 Group group = groupPersistence.create(groupId);
333
334 if (serviceContext != null) {
335 group.setUuid(serviceContext.getUuid());
336 }
337
338 group.setCompanyId(user.getCompanyId());
339 group.setCreatorUserId(userId);
340 group.setClassNameId(classNameId);
341 group.setClassPK(classPK);
342 group.setParentGroupId(parentGroupId);
343 group.setLiveGroupId(liveGroupId);
344 group.setTreePath(group.buildTreePath());
345 group.setName(name);
346 group.setDescription(description);
347 group.setType(type);
348 group.setManualMembership(manualMembership);
349 group.setMembershipRestriction(membershipRestriction);
350 group.setFriendlyURL(friendlyURL);
351 group.setSite(site);
352 group.setActive(active);
353
354 if ((serviceContext != null) && (classNameId == groupClassNameId) &&
355 !user.isDefaultUser()) {
356
357 group.setExpandoBridgeAttributes(serviceContext);
358 }
359
360 groupPersistence.update(group);
361
362
363
364 layoutSetLocalService.addLayoutSet(groupId, true);
365
366 layoutSetLocalService.addLayoutSet(groupId, false);
367
368 if ((classNameId == groupClassNameId) && !user.isDefaultUser()) {
369
370
371
372 resourceLocalService.addResources(
373 group.getCompanyId(), 0, 0, Group.class.getName(),
374 group.getGroupId(), false, false, false);
375
376
377
378 Role role = roleLocalService.getRole(
379 group.getCompanyId(), RoleConstants.SITE_OWNER);
380
381 userGroupRoleLocalService.addUserGroupRoles(
382 userId, groupId, new long[] {role.getRoleId()});
383
384
385
386 userLocalService.addGroupUsers(
387 group.getGroupId(), new long[] {userId});
388
389
390
391 if (serviceContext != null) {
392 updateAsset(
393 userId, group, serviceContext.getAssetCategoryIds(),
394 serviceContext.getAssetTagNames());
395 }
396 }
397 else if (className.equals(Organization.class.getName()) &&
398 !user.isDefaultUser()) {
399
400
401
402 resourceLocalService.addResources(
403 group.getCompanyId(), 0, 0, Group.class.getName(),
404 group.getGroupId(), false, false, false);
405 }
406
407 return group;
408 }
409
410
438 @Override
439 public Group addGroup(
440 long userId, long parentGroupId, String className, long classPK,
441 String name, String description, int type, String friendlyURL,
442 boolean site, boolean active, ServiceContext serviceContext)
443 throws PortalException, SystemException {
444
445 return addGroup(
446 userId, parentGroupId, className, classPK,
447 GroupConstants.DEFAULT_LIVE_GROUP_ID, name, description, type, true,
448 GroupConstants.DEFAULT_MEMBERSHIP_RESTRICTION, friendlyURL, site,
449 active, serviceContext);
450 }
451
452
481 @Override
482 public Group addGroup(
483 long userId, String className, long classPK, long liveGroupId,
484 String name, String description, int type, String friendlyURL,
485 boolean site, boolean active, ServiceContext serviceContext)
486 throws PortalException, SystemException {
487
488 return addGroup(
489 userId, GroupConstants.DEFAULT_PARENT_GROUP_ID, className, classPK,
490 liveGroupId, name, description, type, true,
491 GroupConstants.DEFAULT_MEMBERSHIP_RESTRICTION, friendlyURL, site,
492 active, serviceContext);
493 }
494
495
522 @Override
523 public Group addGroup(
524 long userId, String className, long classPK, String name,
525 String description, int type, String friendlyURL, boolean site,
526 boolean active, ServiceContext serviceContext)
527 throws PortalException, SystemException {
528
529 return addGroup(
530 userId, GroupConstants.DEFAULT_PARENT_GROUP_ID, className, classPK,
531 GroupConstants.DEFAULT_LIVE_GROUP_ID, name, description, type, true,
532 GroupConstants.DEFAULT_MEMBERSHIP_RESTRICTION, friendlyURL, site,
533 active, serviceContext);
534 }
535
536
543 @Override
544 public void addRoleGroups(long roleId, long[] groupIds)
545 throws SystemException {
546
547 rolePersistence.addGroups(roleId, groupIds);
548
549 PermissionCacheUtil.clearCache();
550 }
551
552
559 @Override
560 public void addUserGroups(long userId, long[] groupIds)
561 throws SystemException {
562
563 userPersistence.addGroups(userId, groupIds);
564
565 PermissionCacheUtil.clearCache();
566 }
567
568
579 @Override
580 @Transactional(propagation = Propagation.SUPPORTS, readOnly = true)
581 public void checkCompanyGroup(long companyId)
582 throws PortalException, SystemException {
583
584 long classNameId = PortalUtil.getClassNameId(Company.class);
585
586 int count = groupPersistence.countByC_C_C(
587 companyId, classNameId, companyId);
588
589 if (count == 0) {
590 long defaultUserId = userLocalService.getDefaultUserId(companyId);
591
592 groupLocalService.addGroup(
593 defaultUserId, GroupConstants.DEFAULT_PARENT_GROUP_ID,
594 Company.class.getName(), companyId,
595 GroupConstants.DEFAULT_LIVE_GROUP_ID, GroupConstants.GLOBAL,
596 null, 0, true, GroupConstants.DEFAULT_MEMBERSHIP_RESTRICTION,
597 GroupConstants.GLOBAL_FRIENDLY_URL, true, true, null);
598 }
599 }
600
601
610 @Override
611 @Transactional(propagation = Propagation.SUPPORTS, readOnly = true)
612 public void checkSystemGroups(long companyId)
613 throws PortalException, SystemException {
614
615 String companyIdHexString = StringUtil.toHexString(companyId);
616
617 for (Group group : groupFinder.findBySystem(companyId)) {
618 _systemGroupsMap.put(
619 companyIdHexString.concat(group.getName()), group);
620 }
621
622 long defaultUserId = userLocalService.getDefaultUserId(companyId);
623
624 String[] systemGroups = PortalUtil.getSystemGroups();
625
626 for (String name : systemGroups) {
627 String groupCacheKey = companyIdHexString.concat(name);
628
629 Group group = _systemGroupsMap.get(groupCacheKey);
630
631 if (group == null) {
632 group = groupPersistence.fetchByC_N(companyId, name);
633 }
634
635 if (group == null) {
636 String className = null;
637 long classPK = 0;
638 int type = GroupConstants.TYPE_SITE_OPEN;
639 String friendlyURL = null;
640 boolean site = true;
641
642 if (name.equals(GroupConstants.CONTROL_PANEL)) {
643 type = GroupConstants.TYPE_SITE_PRIVATE;
644 friendlyURL = GroupConstants.CONTROL_PANEL_FRIENDLY_URL;
645 site = false;
646 }
647 else if (name.equals(GroupConstants.GUEST)) {
648 friendlyURL = "/guest";
649 }
650 else if (name.equals(GroupConstants.USER_PERSONAL_SITE)) {
651 className = UserPersonalSite.class.getName();
652 classPK = defaultUserId;
653 type = GroupConstants.TYPE_SITE_PRIVATE;
654 friendlyURL =
655 GroupConstants.USER_PERSONAL_SITE_FRIENDLY_URL;
656 site = false;
657 }
658
659 group = groupLocalService.addGroup(
660 defaultUserId, GroupConstants.DEFAULT_PARENT_GROUP_ID,
661 className, classPK, GroupConstants.DEFAULT_LIVE_GROUP_ID,
662 name, null, type, true,
663 GroupConstants.DEFAULT_MEMBERSHIP_RESTRICTION, friendlyURL,
664 site, true, null);
665
666 if (name.equals(GroupConstants.USER_PERSONAL_SITE)) {
667 initUserPersonalSitePermissions(group);
668 }
669 }
670
671 if (group.isControlPanel()) {
672 LayoutSet layoutSet = layoutSetLocalService.getLayoutSet(
673 group.getGroupId(), true);
674
675 if (layoutSet.getPageCount() == 0) {
676 addControlPanelLayouts(group);
677 }
678 }
679
680 if (group.getName().equals(GroupConstants.GUEST)) {
681 LayoutSet layoutSet = layoutSetLocalService.getLayoutSet(
682 group.getGroupId(), false);
683
684 if (layoutSet.getPageCount() == 0) {
685 addDefaultGuestPublicLayouts(group);
686 }
687 }
688
689 _systemGroupsMap.put(groupCacheKey, group);
690 }
691 }
692
693
710 @Override
711 public Group deleteGroup(Group group)
712 throws PortalException, SystemException {
713
714 boolean deleteInProcess = GroupThreadLocal.isDeleteInProcess();
715
716 try {
717 GroupThreadLocal.setDeleteInProcess(true);
718
719 if (((group.isCompany() && !group.isCompanyStagingGroup()) ||
720 PortalUtil.isSystemGroup(group.getName())) &&
721 !CompanyThreadLocal.isDeleteInProcess()) {
722
723 throw new RequiredGroupException(
724 String.valueOf(group.getGroupId()),
725 RequiredGroupException.SYSTEM_GROUP);
726 }
727
728 if (groupPersistence.countByC_P_S(
729 group.getCompanyId(), group.getGroupId(), true) > 0) {
730
731 throw new RequiredGroupException(
732 String.valueOf(group.getGroupId()),
733 RequiredGroupException.PARENT_GROUP);
734 }
735
736 List<BackgroundTask> backgroundTasks =
737 backgroundTaskLocalService.getBackgroundTasks(
738 group.getGroupId(),
739 BackgroundTaskConstants.STATUS_IN_PROGRESS);
740
741 if (!backgroundTasks.isEmpty()) {
742 throw new PendingBackgroundTaskException(
743 "Unable to delete group with pending background tasks");
744 }
745
746
747
748 backgroundTaskLocalService.deleteGroupBackgroundTasks(
749 group.getGroupId());
750
751
752
753 layoutSetBranchLocalService.deleteLayoutSetBranches(
754 group.getGroupId(), true, true);
755
756 layoutSetBranchLocalService.deleteLayoutSetBranches(
757 group.getGroupId(), false, true);
758
759
760
761 ServiceContext serviceContext = new ServiceContext();
762
763 try {
764 layoutSetLocalService.deleteLayoutSet(
765 group.getGroupId(), true, serviceContext);
766 }
767 catch (NoSuchLayoutSetException nslse) {
768 }
769
770 try {
771 layoutSetLocalService.deleteLayoutSet(
772 group.getGroupId(), false, serviceContext);
773 }
774 catch (NoSuchLayoutSetException nslse) {
775 }
776
777
778
779 userGroupRoleLocalService.deleteUserGroupRolesByGroupId(
780 group.getGroupId());
781
782
783
784 userGroupGroupRoleLocalService.deleteUserGroupGroupRolesByGroupId(
785 group.getGroupId());
786
787
788
789 membershipRequestLocalService.deleteMembershipRequests(
790 group.getGroupId());
791
792
793
794 portletPreferencesLocalService.deletePortletPreferences(
795 group.getGroupId(), PortletKeys.PREFS_OWNER_TYPE_GROUP,
796 PortletKeys.PREFS_PLID_SHARED);
797
798
799
800 repositoryLocalService.deleteRepositories(group.getGroupId());
801
802
803
804 subscriptionLocalService.deleteSubscriptions(
805 group.getCompanyId(), BlogsEntry.class.getName(),
806 group.getGroupId());
807 subscriptionLocalService.deleteSubscriptions(
808 group.getCompanyId(), JournalArticle.class.getName(),
809 group.getGroupId());
810
811
812
813 teamLocalService.deleteTeams(group.getGroupId());
814
815
816
817 unscheduleStaging(group);
818
819 if (group.hasStagingGroup()) {
820 try {
821 StagingUtil.disableStaging(group, serviceContext);
822 }
823 catch (Exception e) {
824 _log.error(
825 "Unable to disable staging for group " +
826 group.getGroupId());
827 }
828 }
829
830
831
832 ThemeLoader themeLoader =
833 ThemeLoaderFactory.getDefaultThemeLoader();
834
835 if (themeLoader != null) {
836 String themePath =
837 themeLoader.getFileStorage() + StringPool.SLASH +
838 group.getGroupId();
839
840 FileUtil.deltree(themePath + "-private");
841 FileUtil.deltree(themePath + "-public");
842 }
843
844
845
846 deletePortletData(group);
847
848
849
850 if (group.isRegularSite()) {
851 assetEntryLocalService.deleteEntry(
852 Group.class.getName(), group.getGroupId());
853 }
854
855 assetTagLocalService.deleteGroupTags(group.getGroupId());
856
857 assetVocabularyLocalService.deleteVocabularies(group.getGroupId());
858
859
860
861 expandoRowLocalService.deleteRows(group.getGroupId());
862
863
864
865 shoppingCartLocalService.deleteGroupCarts(group.getGroupId());
866 shoppingCategoryLocalService.deleteCategories(group.getGroupId());
867 shoppingCouponLocalService.deleteCoupons(group.getGroupId());
868 shoppingOrderLocalService.deleteOrders(group.getGroupId());
869
870
871
872 socialActivityLocalService.deleteActivities(group.getGroupId());
873 socialActivitySettingLocalService.deleteActivitySettings(
874 group.getGroupId());
875
876
877
878 scFrameworkVersionLocalService.deleteFrameworkVersions(
879 group.getGroupId());
880 scProductEntryLocalService.deleteProductEntries(group.getGroupId());
881
882
883
884 List<ResourcePermission> resourcePermissions =
885 resourcePermissionPersistence.findByC_LikeP(
886 group.getCompanyId(), String.valueOf(group.getGroupId()));
887
888 for (ResourcePermission resourcePermission : resourcePermissions) {
889 resourcePermissionLocalService.deleteResourcePermission(
890 resourcePermission);
891 }
892
893 if (!group.isStagingGroup() &&
894 (group.isOrganization() || group.isRegularSite())) {
895
896 resourceLocalService.deleteResource(
897 group.getCompanyId(), Group.class.getName(),
898 ResourceConstants.SCOPE_INDIVIDUAL, group.getGroupId());
899 }
900
901
902
903 List<WorkflowHandler> scopeableWorkflowHandlers =
904 WorkflowHandlerRegistryUtil.getScopeableWorkflowHandlers();
905
906 for (WorkflowHandler scopeableWorkflowHandler :
907 scopeableWorkflowHandlers) {
908
909 if (!scopeableWorkflowHandler.isVisible()) {
910 continue;
911 }
912
913 WorkflowDefinitionLink workflowDefinitionLink =
914 workflowDefinitionLinkLocalService.
915 fetchWorkflowDefinitionLink(
916 group.getCompanyId(), group.getGroupId(),
917 scopeableWorkflowHandler.getClassName(), 0, 0,
918 true);
919
920 if (workflowDefinitionLink == null) {
921 continue;
922 }
923
924 workflowDefinitionLinkLocalService.deleteWorkflowDefinitionLink(
925 workflowDefinitionLink);
926 }
927
928
929
930 if (!group.isStagingGroup() && group.isOrganization() &&
931 group.isSite()) {
932
933 group.setSite(false);
934
935 groupPersistence.update(group);
936 }
937 else {
938 groupPersistence.remove(group);
939 }
940
941
942
943 PermissionCacheUtil.clearCache();
944
945 return group;
946 }
947 finally {
948 GroupThreadLocal.setDeleteInProcess(deleteInProcess);
949 }
950 }
951
952
969 @Override
970 public Group deleteGroup(long groupId)
971 throws PortalException, SystemException {
972
973 Group group = groupPersistence.findByPrimaryKey(groupId);
974
975 return deleteGroup(group);
976 }
977
978 @Override
979 public synchronized void disableStaging(long groupId)
980 throws PortalException, SystemException {
981
982 Group group = groupPersistence.findByPrimaryKey(groupId);
983
984 int stagingGroupCount = group.getRemoteStagingGroupCount();
985
986 if (stagingGroupCount > 0) {
987 stagingGroupCount = stagingGroupCount - 1;
988
989 group.setRemoteStagingGroupCount(stagingGroupCount);
990
991 if (stagingGroupCount == 0) {
992 UnicodeProperties typeSettingsProperties =
993 group.getTypeSettingsProperties();
994
995 List<String> keys = new ArrayList<String>();
996
997 for (String key : typeSettingsProperties.keySet()) {
998 if (key.startsWith(StagingConstants.STAGED_PORTLET)) {
999 keys.add(key);
1000 }
1001 }
1002
1003 for (String key : keys) {
1004 typeSettingsProperties.remove(key);
1005 }
1006
1007 group.setTypeSettingsProperties(typeSettingsProperties);
1008 }
1009
1010 groupPersistence.update(group);
1011 }
1012 }
1013
1014 @Override
1015 public synchronized void enableStaging(long groupId)
1016 throws PortalException, SystemException {
1017
1018 Group group = groupPersistence.findByPrimaryKey(groupId);
1019
1020 int stagingGroupCount = group.getRemoteStagingGroupCount() + 1;
1021
1022 group.setRemoteStagingGroupCount(stagingGroupCount);
1023
1024 groupPersistence.update(group);
1025 }
1026
1027
1036 @Override
1037 public Group fetchFriendlyURLGroup(long companyId, String friendlyURL)
1038 throws SystemException {
1039
1040 if (Validator.isNull(friendlyURL)) {
1041 return null;
1042 }
1043
1044 friendlyURL = getFriendlyURL(friendlyURL);
1045
1046 return groupPersistence.fetchByC_F(companyId, friendlyURL);
1047 }
1048
1049
1059 @Override
1060 @Skip
1061 public Group fetchGroup(long companyId, String name)
1062 throws SystemException {
1063
1064 Group group = _systemGroupsMap.get(
1065 StringUtil.toHexString(companyId).concat(name));
1066
1067 if (group != null) {
1068 return group;
1069 }
1070
1071 return groupLocalService.loadFetchGroup(companyId, name);
1072 }
1073
1074
1082 @Override
1083 public Group getCompanyGroup(long companyId)
1084 throws PortalException, SystemException {
1085
1086 long classNameId = PortalUtil.getClassNameId(Company.class);
1087
1088 return groupPersistence.findByC_C_C(companyId, classNameId, companyId);
1089 }
1090
1091
1111 @Override
1112 public List<Group> getCompanyGroups(long companyId, int start, int end)
1113 throws SystemException {
1114
1115 return groupPersistence.findByCompanyId(companyId, start, end);
1116 }
1117
1118
1125 @Override
1126 public int getCompanyGroupsCount(long companyId) throws SystemException {
1127 return groupPersistence.countByCompanyId(companyId);
1128 }
1129
1130
1140 @Override
1141 public Group getFriendlyURLGroup(long companyId, String friendlyURL)
1142 throws PortalException, SystemException {
1143
1144 if (Validator.isNull(friendlyURL)) {
1145 throw new NoSuchGroupException();
1146 }
1147
1148 friendlyURL = getFriendlyURL(friendlyURL);
1149
1150 return groupPersistence.findByC_F(companyId, friendlyURL);
1151 }
1152
1153
1162 @Override
1163 @ThreadLocalCachable
1164 public Group getGroup(long groupId)
1165 throws PortalException, SystemException {
1166
1167 return groupPersistence.findByPrimaryKey(groupId);
1168 }
1169
1170
1179 @Override
1180 @Skip
1181 public Group getGroup(long companyId, String name)
1182 throws PortalException, SystemException {
1183
1184 Group group = _systemGroupsMap.get(
1185 StringUtil.toHexString(companyId).concat(name));
1186
1187 if (group != null) {
1188 return group;
1189 }
1190
1191 return groupLocalService.loadGetGroup(companyId, name);
1192 }
1193
1194 @Override
1195 public String getGroupDescriptiveName(Group group, Locale locale)
1196 throws PortalException, SystemException {
1197
1198 String name = group.getName();
1199
1200 if (group.isCompany() && !group.isCompanyStagingGroup()) {
1201 name = LanguageUtil.get(locale, "global");
1202 }
1203 else if (group.isControlPanel()) {
1204 name = LanguageUtil.get(locale, "control-panel");
1205 }
1206 else if (group.isLayout()) {
1207 Layout layout = layoutLocalService.getLayout(group.getClassPK());
1208
1209 name = layout.getName(locale);
1210 }
1211 else if (group.isLayoutPrototype()) {
1212 LayoutPrototype layoutPrototype =
1213 layoutPrototypeLocalService.getLayoutPrototype(
1214 group.getClassPK());
1215
1216 name = layoutPrototype.getName(locale);
1217 }
1218 else if (group.isLayoutSetPrototype()) {
1219 LayoutSetPrototype layoutSetPrototype =
1220 layoutSetPrototypePersistence.findByPrimaryKey(
1221 group.getClassPK());
1222
1223 name = layoutSetPrototype.getName(locale);
1224 }
1225 else if (group.isOrganization()) {
1226 long organizationId = group.getOrganizationId();
1227
1228 Organization organization =
1229 organizationPersistence.findByPrimaryKey(organizationId);
1230
1231 name = organization.getName();
1232
1233 group = organization.getGroup();
1234 }
1235 else if (group.isUser()) {
1236 long userId = group.getClassPK();
1237
1238 User user = userPersistence.findByPrimaryKey(userId);
1239
1240 name = user.getFullName();
1241 }
1242 else if (group.isUserGroup()) {
1243 long userGroupId = group.getClassPK();
1244
1245 UserGroup userGroup = userGroupPersistence.findByPrimaryKey(
1246 userGroupId);
1247
1248 name = userGroup.getName();
1249 }
1250 else if (group.isUserPersonalSite()) {
1251 name = LanguageUtil.get(locale, "user-personal-site");
1252 }
1253 else if (name.equals(GroupConstants.GUEST)) {
1254 Company company = companyPersistence.findByPrimaryKey(
1255 group.getCompanyId());
1256
1257 Account account = company.getAccount();
1258
1259 name = account.getName();
1260 }
1261
1262 if (group.isStaged() && !group.isStagedRemotely() &&
1263 group.isStagingGroup()) {
1264
1265 Group liveGroup = group.getLiveGroup();
1266
1267 name = liveGroup.getDescriptiveName(locale);
1268 }
1269
1270 return name;
1271 }
1272
1273 @Override
1274 public String getGroupDescriptiveName(long groupId, Locale locale)
1275 throws PortalException, SystemException {
1276
1277 Group group = groupPersistence.findByPrimaryKey(groupId);
1278
1279 return getGroupDescriptiveName(group, locale);
1280 }
1281
1282
1292 @Override
1293 public List<Group> getGroups(
1294 long companyId, long parentGroupId, boolean site)
1295 throws SystemException {
1296
1297 if (parentGroupId == GroupConstants.ANY_PARENT_GROUP_ID) {
1298 return groupPersistence.findByC_S(companyId, site);
1299 }
1300
1301 return groupPersistence.findByC_P_S(companyId, parentGroupId, site);
1302 }
1303
1304
1315 @Override
1316 public List<Group> getGroups(
1317 long companyId, String className, long parentGroupId)
1318 throws SystemException {
1319
1320 long classNameId = PortalUtil.getClassNameId(className);
1321
1322 return groupPersistence.findByC_C_P(
1323 companyId, classNameId, parentGroupId);
1324 }
1325
1326
1338 @Override
1339 public List<Group> getGroups(
1340 long companyId, String className, long parentGroupId, int start,
1341 int end)
1342 throws SystemException {
1343
1344 long classNameId = PortalUtil.getClassNameId(className);
1345
1346 return groupPersistence.findByC_C_P(
1347 companyId, classNameId, parentGroupId, start, end);
1348 }
1349
1350
1358 @Override
1359 public List<Group> getGroups(long[] groupIds)
1360 throws PortalException, SystemException {
1361
1362 List<Group> groups = new ArrayList<Group>(groupIds.length);
1363
1364 for (long groupId : groupIds) {
1365 Group group = getGroup(groupId);
1366
1367 groups.add(group);
1368 }
1369
1370 return groups;
1371 }
1372
1373
1383 @Override
1384 public int getGroupsCount(long companyId, long parentGroupId, boolean site)
1385 throws SystemException {
1386
1387 if (parentGroupId == GroupConstants.ANY_PARENT_GROUP_ID) {
1388 return groupPersistence.countByC_S(companyId, site);
1389 }
1390
1391 return groupPersistence.countByC_P_S(companyId, parentGroupId, site);
1392 }
1393
1394
1404 @Override
1405 public int getGroupsCount(
1406 long companyId, String className, long parentGroupId)
1407 throws SystemException {
1408
1409 long classNameId = PortalUtil.getClassNameId(className);
1410
1411 return groupPersistence.countByC_C_P(
1412 companyId, classNameId, parentGroupId);
1413 }
1414
1415
1424 @Override
1425 public Group getLayoutGroup(long companyId, long plid)
1426 throws PortalException, SystemException {
1427
1428 long classNameId = PortalUtil.getClassNameId(Layout.class);
1429
1430 return groupPersistence.findByC_C_C(companyId, classNameId, plid);
1431 }
1432
1433
1442 @Override
1443 public Group getLayoutPrototypeGroup(long companyId, long layoutPrototypeId)
1444 throws PortalException, SystemException {
1445
1446 long classNameId = PortalUtil.getClassNameId(LayoutPrototype.class);
1447
1448 return groupPersistence.findByC_C_C(
1449 companyId, classNameId, layoutPrototypeId);
1450 }
1451
1452
1461 @Override
1462 public Group getLayoutSetPrototypeGroup(
1463 long companyId, long layoutSetPrototypeId)
1464 throws PortalException, SystemException {
1465
1466 long classNameId = PortalUtil.getClassNameId(LayoutSetPrototype.class);
1467
1468 return groupPersistence.findByC_C_C(
1469 companyId, classNameId, layoutSetPrototypeId);
1470 }
1471
1472
1495 @Override
1496 public List<Group> getLayoutsGroups(
1497 long companyId, long parentGroupId, boolean site, int start,
1498 int end)
1499 throws SystemException {
1500
1501 return groupFinder.findByLayouts(
1502 companyId, parentGroupId, site, start, end);
1503 }
1504
1505
1515 @Override
1516 public int getLayoutsGroupsCount(
1517 long companyId, long parentGroupId, boolean site)
1518 throws SystemException {
1519
1520 return groupFinder.countByLayouts(companyId, parentGroupId, site);
1521 }
1522
1523
1529 @Override
1530 public List<Group> getLiveGroups() throws SystemException {
1531 return groupFinder.findByLiveGroups();
1532 }
1533
1534
1557 @Override
1558 public List<Group> getNoLayoutsGroups(
1559 String className, boolean privateLayout, int start, int end)
1560 throws SystemException {
1561
1562 long classNameId = PortalUtil.getClassNameId(className);
1563
1564 return groupFinder.findByNoLayouts(
1565 classNameId, privateLayout, start, end);
1566 }
1567
1568
1576 @Override
1577 public List<Group> getNullFriendlyURLGroups() throws SystemException {
1578 return groupFinder.findByNullFriendlyURL();
1579 }
1580
1581
1590 @Override
1591 public Group getOrganizationGroup(long companyId, long organizationId)
1592 throws PortalException, SystemException {
1593
1594 long classNameId = PortalUtil.getClassNameId(Organization.class);
1595
1596 return groupPersistence.findByC_C_C(
1597 companyId, classNameId, organizationId);
1598 }
1599
1600
1606 @Override
1607 public List<Group> getOrganizationsGroups(
1608 List<Organization> organizations) {
1609
1610 List<Group> organizationGroups = new ArrayList<Group>();
1611
1612 for (int i = 0; i < organizations.size(); i++) {
1613 Organization organization = organizations.get(i);
1614
1615 Group group = organization.getGroup();
1616
1617 organizationGroups.add(group);
1618 }
1619
1620 return organizationGroups;
1621 }
1622
1623
1630 @Override
1631 public List<Group> getOrganizationsRelatedGroups(
1632 List<Organization> organizations)
1633 throws SystemException {
1634
1635 List<Group> organizationGroups = new ArrayList<Group>();
1636
1637 for (int i = 0; i < organizations.size(); i++) {
1638 Organization organization = organizations.get(i);
1639
1640 List<Group> groups = organizationPersistence.getGroups(
1641 organization.getOrganizationId());
1642
1643 organizationGroups.addAll(groups);
1644 }
1645
1646 return organizationGroups;
1647 }
1648
1649
1660 @Override
1661 public List<Group> getParentGroups(long groupId)
1662 throws PortalException, SystemException {
1663
1664 if (groupId == GroupConstants.DEFAULT_PARENT_GROUP_ID) {
1665 return new ArrayList<Group>();
1666 }
1667
1668 Group group = groupPersistence.findByPrimaryKey(groupId);
1669
1670 return group.getAncestors();
1671 }
1672
1673
1681 @Override
1682 public Group getStagingGroup(long liveGroupId)
1683 throws PortalException, SystemException {
1684
1685 return groupPersistence.findByLiveGroupId(liveGroupId);
1686 }
1687
1688
1697 @Override
1698 public Group getUserGroup(long companyId, long userId)
1699 throws PortalException, SystemException {
1700
1701 long classNameId = PortalUtil.getClassNameId(User.class);
1702
1703 return groupPersistence.findByC_C_C(companyId, classNameId, userId);
1704 }
1705
1706
1716 @Override
1717 public Group getUserGroupGroup(long companyId, long userGroupId)
1718 throws PortalException, SystemException {
1719
1720 long classNameId = PortalUtil.getClassNameId(UserGroup.class);
1721
1722 return groupPersistence.findByC_C_C(
1723 companyId, classNameId, userGroupId);
1724 }
1725
1726
1738 @Override
1739 public List<Group> getUserGroups(long userId, boolean inherit)
1740 throws PortalException, SystemException {
1741
1742 return getUserGroups(
1743 userId, inherit, QueryUtil.ALL_POS, QueryUtil.ALL_POS);
1744 }
1745
1746
1773 @Override
1774 public List<Group> getUserGroups(
1775 long userId, boolean inherit, int start, int end)
1776 throws PortalException, SystemException {
1777
1778 if (inherit) {
1779 User user = userPersistence.findByPrimaryKey(userId);
1780
1781 LinkedHashMap<String, Object> groupParams =
1782 new LinkedHashMap<String, Object>();
1783
1784 groupParams.put("usersGroups", new Long(userId));
1785
1786 return search(
1787 user.getCompanyId(), null, null, groupParams, start, end);
1788 }
1789 else {
1790 return userPersistence.getGroups(userId, start, end);
1791 }
1792 }
1793
1794
1803 @Override
1804 public List<Group> getUserGroupsGroups(List<UserGroup> userGroups)
1805 throws PortalException, SystemException {
1806
1807 List<Group> userGroupGroups = new ArrayList<Group>();
1808
1809 for (int i = 0; i < userGroups.size(); i++) {
1810 UserGroup userGroup = userGroups.get(i);
1811
1812 Group group = userGroup.getGroup();
1813
1814 userGroupGroups.add(group);
1815 }
1816
1817 return userGroupGroups;
1818 }
1819
1820
1827 @Override
1828 public List<Group> getUserGroupsRelatedGroups(List<UserGroup> userGroups)
1829 throws SystemException {
1830
1831 List<Group> userGroupGroups = new ArrayList<Group>();
1832
1833 for (int i = 0; i < userGroups.size(); i++) {
1834 UserGroup userGroup = userGroups.get(i);
1835
1836 List<Group> groups = userGroupPersistence.getGroups(
1837 userGroup.getUserGroupId());
1838
1839 userGroupGroups.addAll(groups);
1840 }
1841
1842 return userGroupGroups;
1843 }
1844
1845
1871 @Override
1872 public List<Group> getUserOrganizationsGroups(
1873 long userId, int start, int end)
1874 throws PortalException, SystemException {
1875
1876 List<Group> userOrgsGroups = new UniqueList<Group>();
1877
1878 List<Organization> userOrgs =
1879 organizationLocalService.getUserOrganizations(userId, start, end);
1880
1881 for (Organization organization : userOrgs) {
1882 userOrgsGroups.add(0, organization.getGroup());
1883
1884 if (!PropsValues.ORGANIZATIONS_MEMBERSHIP_STRICT) {
1885 for (Organization ancestorOrganization :
1886 organization.getAncestors()) {
1887
1888 userOrgsGroups.add(0, ancestorOrganization.getGroup());
1889 }
1890 }
1891 }
1892
1893 return userOrgsGroups;
1894 }
1895
1896 @Override
1897 public Group getUserPersonalSiteGroup(long companyId)
1898 throws PortalException, SystemException {
1899
1900 long classNameId = PortalUtil.getClassNameId(UserPersonalSite.class);
1901 long defaultUserId = userLocalService.getDefaultUserId(companyId);
1902
1903 return groupPersistence.findByC_C_C(
1904 companyId, classNameId, defaultUserId);
1905 }
1906
1907 @Override
1908 public List<Group> getUserSitesGroups(long userId)
1909 throws PortalException, SystemException {
1910
1911 User user = userPersistence.findByPrimaryKey(userId);
1912
1913 LinkedHashMap<String, Object> groupParams =
1914 new LinkedHashMap<String, Object>();
1915
1916 groupParams.put("inherit", Boolean.TRUE);
1917 groupParams.put("site", Boolean.TRUE);
1918 groupParams.put("usersGroups", userId);
1919
1920 return groupFinder.findByCompanyId(
1921 user.getCompanyId(), groupParams, QueryUtil.ALL_POS,
1922 QueryUtil.ALL_POS, new GroupNameComparator(true));
1923 }
1924
1925 @Override
1926 public List<Group> getUserSitesGroups(
1927 long userId, boolean includeAdministrative)
1928 throws PortalException, SystemException {
1929
1930 if (!includeAdministrative) {
1931 return getUserSitesGroups(userId);
1932 }
1933
1934 Set<Group> sites = new HashSet<Group>();
1935
1936 List<UserGroupRole> userGroupRoles =
1937 userGroupRoleLocalService.getUserGroupRoles(userId);
1938
1939 for (UserGroupRole userGroupRole : userGroupRoles) {
1940 Role role = userGroupRole.getRole();
1941
1942 String roleName = role.getName();
1943
1944 if (roleName.equals(RoleConstants.SITE_ADMINISTRATOR) ||
1945 roleName.equals(RoleConstants.SITE_OWNER)) {
1946
1947 Group group = userGroupRole.getGroup();
1948
1949 sites.add(group);
1950 }
1951 }
1952
1953 sites.addAll(getUserSitesGroups(userId));
1954
1955 return new ArrayList<Group>(sites);
1956 }
1957
1958
1966 @Override
1967 public boolean hasStagingGroup(long liveGroupId) throws SystemException {
1968 if (groupPersistence.fetchByLiveGroupId(liveGroupId) != null) {
1969 return true;
1970 }
1971 else {
1972 return false;
1973 }
1974 }
1975
1976
1987 @Override
1988 public boolean hasUserGroup(long userId, long groupId)
1989 throws SystemException {
1990
1991 return hasUserGroup(userId, groupId, true);
1992 }
1993
1994
2007 @Override
2008 public boolean hasUserGroup(long userId, long groupId, boolean inherit)
2009 throws SystemException {
2010
2011 if (groupFinder.countByG_U(groupId, userId, inherit) > 0) {
2012 return true;
2013 }
2014 else {
2015 return false;
2016 }
2017 }
2018
2019
2029 @Override
2030 public Group loadFetchGroup(long companyId, String name)
2031 throws SystemException {
2032
2033 return groupPersistence.fetchByC_N(companyId, name);
2034 }
2035
2036
2045 @Override
2046 public Group loadGetGroup(long companyId, String name)
2047 throws PortalException, SystemException {
2048
2049 return groupPersistence.findByC_N(companyId, name);
2050 }
2051
2052
2066 @Override
2067 public void rebuildTree(long companyId)
2068 throws PortalException, SystemException {
2069
2070 List<Group> groups = groupPersistence.findByCompanyId(companyId);
2071
2072 for (Group group : groups) {
2073 group.setTreePath(group.buildTreePath());
2074
2075 groupPersistence.update(group);
2076 }
2077 }
2078
2079
2108 @Override
2109 public List<Group> search(
2110 long companyId, LinkedHashMap<String, Object> params, int start,
2111 int end)
2112 throws SystemException {
2113
2114 return groupFinder.findByCompanyId(
2115 companyId, params, start, end, new GroupNameComparator(true));
2116 }
2117
2118
2150 @Override
2151 public List<Group> search(
2152 long companyId, long parentGroupId, String keywords,
2153 LinkedHashMap<String, Object> params, int start, int end)
2154 throws SystemException {
2155
2156 return search(
2157 companyId, getClassNameIds(), parentGroupId, keywords, params,
2158 start, end, null);
2159 }
2160
2161
2195 @Override
2196 public List<Group> search(
2197 long companyId, long parentGroupId, String keywords,
2198 LinkedHashMap<String, Object> params, int start, int end,
2199 OrderByComparator obc)
2200 throws SystemException {
2201
2202 return search(
2203 companyId, getClassNameIds(), parentGroupId, keywords, params,
2204 start, end, obc);
2205 }
2206
2207
2242 @Override
2243 public List<Group> search(
2244 long companyId, long parentGroupId, String name, String description,
2245 LinkedHashMap<String, Object> params, boolean andOperator,
2246 int start, int end)
2247 throws SystemException {
2248
2249 return search(
2250 companyId, getClassNameIds(), parentGroupId, name, description,
2251 params, andOperator, start, end, null);
2252 }
2253
2254
2291 @Override
2292 public List<Group> search(
2293 long companyId, long parentGroupId, String name, String description,
2294 LinkedHashMap<String, Object> params, boolean andOperator,
2295 int start, int end, OrderByComparator obc)
2296 throws SystemException {
2297
2298 return search(
2299 companyId, getClassNameIds(), parentGroupId, name, description,
2300 params, andOperator, start, end, obc);
2301 }
2302
2303
2338 @Override
2339 public List<Group> search(
2340 long companyId, long[] classNameIds, long parentGroupId,
2341 String keywords, LinkedHashMap<String, Object> params, int start,
2342 int end)
2343 throws SystemException {
2344
2345 return search(
2346 companyId, classNameIds, parentGroupId, keywords, params, start,
2347 end, null);
2348 }
2349
2350
2387 @Override
2388 public List<Group> search(
2389 long companyId, long[] classNameIds, long parentGroupId,
2390 String keywords, LinkedHashMap<String, Object> params, int start,
2391 int end, OrderByComparator obc)
2392 throws SystemException {
2393
2394 String[] keywordsArray = getSearchNames(companyId, keywords);
2395
2396 boolean andOperator = false;
2397
2398 if (Validator.isNull(keywords)) {
2399 andOperator = true;
2400 }
2401
2402 if (isUseComplexSQL(classNameIds)) {
2403 return groupFinder.findByC_C_PG_N_D(
2404 companyId, classNameIds, parentGroupId, keywordsArray,
2405 keywordsArray, params, andOperator, start, end, obc);
2406 }
2407
2408 List<Group> groups = doSearch(
2409 companyId, classNameIds, parentGroupId, keywordsArray,
2410 keywordsArray, params, andOperator);
2411
2412 return sort(groups, start, end, obc);
2413 }
2414
2415
2453 @Override
2454 public List<Group> search(
2455 long companyId, long[] classNameIds, long parentGroupId,
2456 String name, String description,
2457 LinkedHashMap<String, Object> params, boolean andOperator,
2458 int start, int end)
2459 throws SystemException {
2460
2461 return search(
2462 companyId, classNameIds, parentGroupId, name, description, params,
2463 andOperator, start, end, null);
2464 }
2465
2466
2506 @Override
2507 public List<Group> search(
2508 long companyId, long[] classNameIds, long parentGroupId,
2509 String name, String description,
2510 LinkedHashMap<String, Object> params, boolean andOperator,
2511 int start, int end, OrderByComparator obc)
2512 throws SystemException {
2513
2514 String[] names = getSearchNames(companyId, name);
2515 String[] descriptions = CustomSQLUtil.keywords(description);
2516
2517 if (isUseComplexSQL(classNameIds)) {
2518 return groupFinder.findByC_C_PG_N_D(
2519 companyId, classNameIds, parentGroupId, names, descriptions,
2520 params, andOperator, start, end, obc);
2521 }
2522
2523 List<Group> groups = doSearch(
2524 companyId, classNameIds, parentGroupId, names, descriptions, params,
2525 andOperator);
2526
2527 return sort(groups, start, end, obc);
2528 }
2529
2530
2563 @Override
2564 public List<Group> search(
2565 long companyId, long[] classNameIds, String keywords,
2566 LinkedHashMap<String, Object> params, int start, int end)
2567 throws SystemException {
2568
2569 return search(
2570 companyId, classNameIds, GroupConstants.ANY_PARENT_GROUP_ID,
2571 keywords, params, start, end, null);
2572 }
2573
2574
2609 @Override
2610 public List<Group> search(
2611 long companyId, long[] classNameIds, String keywords,
2612 LinkedHashMap<String, Object> params, int start, int end,
2613 OrderByComparator obc)
2614 throws SystemException {
2615
2616 return search(
2617 companyId, classNameIds, GroupConstants.ANY_PARENT_GROUP_ID,
2618 keywords, params, start, end, obc);
2619 }
2620
2621
2658 @Override
2659 public List<Group> search(
2660 long companyId, long[] classNameIds, String name,
2661 String description, LinkedHashMap<String, Object> params,
2662 boolean andOperator, int start, int end)
2663 throws SystemException {
2664
2665 return search(
2666 companyId, classNameIds, GroupConstants.ANY_PARENT_GROUP_ID, name,
2667 description, params, andOperator, start, end, null);
2668 }
2669
2670
2709 @Override
2710 public List<Group> search(
2711 long companyId, long[] classNameIds, String name,
2712 String description, LinkedHashMap<String, Object> params,
2713 boolean andOperator, int start, int end, OrderByComparator obc)
2714 throws SystemException {
2715
2716 return search(
2717 companyId, classNameIds, GroupConstants.ANY_PARENT_GROUP_ID, name,
2718 description, params, andOperator, start, end, obc);
2719 }
2720
2721
2751 @Override
2752 @ThreadLocalCachable
2753 public List<Group> search(
2754 long companyId, String keywords,
2755 LinkedHashMap<String, Object> params, int start, int end)
2756 throws SystemException {
2757
2758 return search(
2759 companyId, getClassNameIds(), GroupConstants.ANY_PARENT_GROUP_ID,
2760 keywords, params, start, end, null);
2761 }
2762
2763
2795 @Override
2796 public List<Group> search(
2797 long companyId, String keywords,
2798 LinkedHashMap<String, Object> params, int start, int end,
2799 OrderByComparator obc)
2800 throws SystemException {
2801
2802 return search(
2803 companyId, getClassNameIds(), GroupConstants.ANY_PARENT_GROUP_ID,
2804 keywords, params, start, end, obc);
2805 }
2806
2807
2841 @Override
2842 public List<Group> search(
2843 long companyId, String name, String description,
2844 LinkedHashMap<String, Object> params, boolean andOperator,
2845 int start, int end)
2846 throws SystemException {
2847
2848 return search(
2849 companyId, getClassNameIds(), GroupConstants.ANY_PARENT_GROUP_ID,
2850 name, description, params, andOperator, start, end, null);
2851 }
2852
2853
2889 @Override
2890 public List<Group> search(
2891 long companyId, String name, String description,
2892 LinkedHashMap<String, Object> params, boolean andOperator,
2893 int start, int end, OrderByComparator obc)
2894 throws SystemException {
2895
2896 return search(
2897 companyId, getClassNameIds(), GroupConstants.ANY_PARENT_GROUP_ID,
2898 name, description, params, andOperator, start, end, obc);
2899 }
2900
2901
2919 @Override
2920 @ThreadLocalCachable
2921 public int searchCount(
2922 long companyId, long parentGroupId, String keywords,
2923 LinkedHashMap<String, Object> params)
2924 throws SystemException {
2925
2926 return searchCount(
2927 companyId, getClassNameIds(), parentGroupId, keywords, params);
2928 }
2929
2930
2952 @Override
2953 @ThreadLocalCachable
2954 public int searchCount(
2955 long companyId, long parentGroupId, String name, String description,
2956 LinkedHashMap<String, Object> params, boolean andOperator)
2957 throws SystemException {
2958
2959 return searchCount(
2960 companyId, getClassNameIds(), parentGroupId, name, description,
2961 params, andOperator);
2962 }
2963
2964
2985 @Override
2986 @ThreadLocalCachable
2987 public int searchCount(
2988 long companyId, long[] classNameIds, long parentGroupId,
2989 String keywords, LinkedHashMap<String, Object> params)
2990 throws SystemException {
2991
2992 String[] keywordsArray = getSearchNames(companyId, keywords);
2993
2994 boolean andOperator = false;
2995
2996 if (Validator.isNull(keywords)) {
2997 andOperator = true;
2998 }
2999
3000 if (isUseComplexSQL(classNameIds)) {
3001 return groupFinder.countByC_C_PG_N_D(
3002 companyId, classNameIds, parentGroupId, keywordsArray,
3003 keywordsArray, params, andOperator);
3004 }
3005
3006 List<Group> groups = doSearch(
3007 companyId, classNameIds, parentGroupId, keywordsArray,
3008 keywordsArray, params, andOperator);
3009
3010 return groups.size();
3011 }
3012
3013
3037 @Override
3038 @ThreadLocalCachable
3039 public int searchCount(
3040 long companyId, long[] classNameIds, long parentGroupId,
3041 String name, String description,
3042 LinkedHashMap<String, Object> params, boolean andOperator)
3043 throws SystemException {
3044
3045 String[] names = getSearchNames(companyId, name);
3046 String[] descriptions = CustomSQLUtil.keywords(description);
3047
3048 if (isUseComplexSQL(classNameIds)) {
3049 return groupFinder.countByC_C_PG_N_D(
3050 companyId, classNameIds, parentGroupId, names, descriptions,
3051 params, andOperator);
3052 }
3053
3054 List<Group> groups = doSearch(
3055 companyId, classNameIds, parentGroupId, names, descriptions, params,
3056 andOperator);
3057
3058 return groups.size();
3059 }
3060
3061
3080 @Override
3081 @ThreadLocalCachable
3082 public int searchCount(
3083 long companyId, long[] classNameIds, String keywords,
3084 LinkedHashMap<String, Object> params)
3085 throws SystemException {
3086
3087 return searchCount(
3088 companyId, classNameIds, GroupConstants.ANY_PARENT_GROUP_ID,
3089 keywords, params);
3090 }
3091
3092
3114 @Override
3115 @ThreadLocalCachable
3116 public int searchCount(
3117 long companyId, long[] classNameIds, String name,
3118 String description, LinkedHashMap<String, Object> params,
3119 boolean andOperator)
3120 throws SystemException {
3121
3122 return searchCount(
3123 companyId, classNameIds, GroupConstants.ANY_PARENT_GROUP_ID, name,
3124 description, params, andOperator);
3125 }
3126
3127
3144 @Override
3145 @ThreadLocalCachable
3146 public int searchCount(
3147 long companyId, String keywords,
3148 LinkedHashMap<String, Object> params)
3149 throws SystemException {
3150
3151 return searchCount(
3152 companyId, getClassNameIds(), GroupConstants.ANY_PARENT_GROUP_ID,
3153 keywords, params);
3154 }
3155
3156
3177 @Override
3178 @ThreadLocalCachable
3179 public int searchCount(
3180 long companyId, String name, String description,
3181 LinkedHashMap<String, Object> params, boolean andOperator)
3182 throws SystemException {
3183
3184 return searchCount(
3185 companyId, getClassNameIds(), GroupConstants.ANY_PARENT_GROUP_ID,
3186 name, description, params, andOperator);
3187 }
3188
3189
3197 @Override
3198 public void setRoleGroups(long roleId, long[] groupIds)
3199 throws SystemException {
3200
3201 rolePersistence.setGroups(roleId, groupIds);
3202
3203 PermissionCacheUtil.clearCache();
3204 }
3205
3206
3213 @Override
3214 public void unsetRoleGroups(long roleId, long[] groupIds)
3215 throws SystemException {
3216
3217 rolePersistence.removeGroups(roleId, groupIds);
3218
3219 PermissionCacheUtil.clearCache();
3220 }
3221
3222
3229 @Override
3230 public void unsetUserGroups(long userId, long[] groupIds)
3231 throws SystemException {
3232
3233 userGroupRoleLocalService.deleteUserGroupRoles(userId, groupIds);
3234
3235 userPersistence.removeGroups(userId, groupIds);
3236
3237 PermissionCacheUtil.clearCache();
3238 }
3239
3240
3251 @Override
3252 public void updateAsset(
3253 long userId, Group group, long[] assetCategoryIds,
3254 String[] assetTagNames)
3255 throws PortalException, SystemException {
3256
3257 User user = userPersistence.findByPrimaryKey(userId);
3258
3259 Company company = companyPersistence.findByPrimaryKey(
3260 user.getCompanyId());
3261
3262 Group companyGroup = company.getGroup();
3263
3264 assetEntryLocalService.updateEntry(
3265 userId, companyGroup.getGroupId(), null, null,
3266 Group.class.getName(), group.getGroupId(), null, 0,
3267 assetCategoryIds, assetTagNames, false, null, null, null, null,
3268 group.getDescriptiveName(), group.getDescription(), null, null,
3269 null, 0, 0, null, false);
3270 }
3271
3272
3284 @Override
3285 public Group updateFriendlyURL(long groupId, String friendlyURL)
3286 throws PortalException, SystemException {
3287
3288 Group group = groupPersistence.findByPrimaryKey(groupId);
3289
3290 if (group.isUser()) {
3291 User user = userPersistence.findByPrimaryKey(group.getClassPK());
3292
3293 friendlyURL = StringPool.SLASH + user.getScreenName();
3294
3295 if (group.getFriendlyURL().equals(friendlyURL)) {
3296 return group;
3297 }
3298 }
3299
3300 friendlyURL = getFriendlyURL(
3301 group.getCompanyId(), groupId, group.getClassNameId(),
3302 group.getClassPK(), StringPool.BLANK, friendlyURL);
3303
3304 validateFriendlyURL(
3305 group.getCompanyId(), group.getGroupId(), group.getClassNameId(),
3306 group.getClassPK(), friendlyURL);
3307
3308 group.setFriendlyURL(friendlyURL);
3309
3310 groupPersistence.update(group);
3311
3312 return group;
3313 }
3314
3315
3337 @Override
3338 public Group updateGroup(
3339 long groupId, long parentGroupId, String name, String description,
3340 int type, boolean manualMembership, int membershipRestriction,
3341 String friendlyURL, boolean active, ServiceContext serviceContext)
3342 throws PortalException, SystemException {
3343
3344 Group group = groupPersistence.findByPrimaryKey(groupId);
3345
3346 String className = group.getClassName();
3347 long classNameId = group.getClassNameId();
3348 long classPK = group.getClassPK();
3349 friendlyURL = getFriendlyURL(
3350 group.getCompanyId(), groupId, classNameId, classPK,
3351 StringPool.BLANK, friendlyURL);
3352
3353 if ((classNameId <= 0) || className.equals(Group.class.getName())) {
3354 validateName(
3355 group.getGroupId(), group.getCompanyId(), name, group.isSite());
3356 }
3357 else if (className.equals(Organization.class.getName())) {
3358 Organization organization =
3359 organizationPersistence.findByPrimaryKey(classPK);
3360
3361 name = getOrgGroupName(organization.getName());
3362 }
3363 else if (!GroupConstants.USER_PERSONAL_SITE.equals(name)) {
3364 name = String.valueOf(classPK);
3365 }
3366
3367 if (PortalUtil.isSystemGroup(group.getName()) &&
3368 !name.equals(group.getName())) {
3369
3370 throw new RequiredGroupException(
3371 String.valueOf(group.getGroupId()),
3372 RequiredGroupException.SYSTEM_GROUP);
3373 }
3374
3375 validateFriendlyURL(
3376 group.getCompanyId(), group.getGroupId(), group.getClassNameId(),
3377 group.getClassPK(), friendlyURL);
3378
3379 validateParentGroup(group.getGroupId(), parentGroupId);
3380
3381 group.setParentGroupId(parentGroupId);
3382 group.setTreePath(group.buildTreePath());
3383 group.setName(name);
3384 group.setDescription(description);
3385 group.setType(type);
3386 group.setManualMembership(manualMembership);
3387 group.setMembershipRestriction(membershipRestriction);
3388 group.setFriendlyURL(friendlyURL);
3389 group.setActive(active);
3390
3391 if ((serviceContext != null) && group.isSite()) {
3392 group.setExpandoBridgeAttributes(serviceContext);
3393 }
3394
3395 groupPersistence.update(group);
3396
3397
3398
3399 if ((serviceContext == null) || !group.isSite()) {
3400 return group;
3401 }
3402
3403 User user = null;
3404
3405 user = userPersistence.fetchByPrimaryKey(group.getCreatorUserId());
3406
3407 if (user == null) {
3408 user = userPersistence.fetchByPrimaryKey(
3409 serviceContext.getUserId());
3410 }
3411
3412 if (user == null) {
3413 user = userLocalService.getDefaultUser(group.getCompanyId());
3414 }
3415
3416 updateAsset(
3417 user.getUserId(), group, serviceContext.getAssetCategoryIds(),
3418 serviceContext.getAssetTagNames());
3419
3420 return group;
3421 }
3422
3423
3434 @Override
3435 public Group updateGroup(long groupId, String typeSettings)
3436 throws PortalException, SystemException {
3437
3438 Group group = groupPersistence.findByPrimaryKey(groupId);
3439
3440 UnicodeProperties oldTypeSettingsProperties =
3441 group.getTypeSettingsProperties();
3442
3443 UnicodeProperties typeSettingsProperties = new UnicodeProperties(true);
3444
3445 typeSettingsProperties.fastLoad(typeSettings);
3446
3447 String newLanguageIds = typeSettingsProperties.getProperty(
3448 PropsKeys.LOCALES);
3449
3450 if (newLanguageIds != null) {
3451 String oldLanguageIds = oldTypeSettingsProperties.getProperty(
3452 PropsKeys.LOCALES, StringPool.BLANK);
3453
3454 String defaultLanguageId = typeSettingsProperties.getProperty(
3455 "languageId", LocaleUtil.toLanguageId(LocaleUtil.getDefault()));
3456
3457 if (!Validator.equals(oldLanguageIds, newLanguageIds)) {
3458 validateLanguageIds(defaultLanguageId, newLanguageIds);
3459
3460 LanguageUtil.resetAvailableGroupLocales(groupId);
3461 }
3462 }
3463
3464 group.setTypeSettings(typeSettings);
3465
3466 groupPersistence.update(group);
3467
3468 return group;
3469 }
3470
3471
3481 @Override
3482 public Group updateSite(long groupId, boolean site)
3483 throws PortalException, SystemException {
3484
3485 Group group = groupPersistence.findByPrimaryKey(groupId);
3486
3487 if (!group.isOrganization()) {
3488 return group;
3489 }
3490
3491 group.setSite(site);
3492
3493 groupPersistence.update(group);
3494
3495 return group;
3496 }
3497
3498 protected void addControlPanelLayouts(Group group)
3499 throws PortalException, SystemException {
3500
3501 long defaultUserId = userLocalService.getDefaultUserId(
3502 group.getCompanyId());
3503
3504 String friendlyURL = getFriendlyURL(
3505 PropsValues.CONTROL_PANEL_LAYOUT_FRIENDLY_URL);
3506
3507 ServiceContext serviceContext = new ServiceContext();
3508
3509 layoutLocalService.addLayout(
3510 defaultUserId, group.getGroupId(), true,
3511 LayoutConstants.DEFAULT_PARENT_LAYOUT_ID,
3512 PropsValues.CONTROL_PANEL_LAYOUT_NAME, StringPool.BLANK,
3513 StringPool.BLANK, LayoutConstants.TYPE_CONTROL_PANEL, false,
3514 friendlyURL, serviceContext);
3515 }
3516
3517 protected void addDefaultGuestPublicLayoutByProperties(Group group)
3518 throws PortalException, SystemException {
3519
3520 List<Portlet> portlets = portletLocalService.getPortlets(
3521 group.getCompanyId());
3522
3523 if (portlets.isEmpty()) {
3524
3525
3526
3527 return;
3528 }
3529
3530 long defaultUserId = userLocalService.getDefaultUserId(
3531 group.getCompanyId());
3532 String friendlyURL = getFriendlyURL(
3533 PropsValues.DEFAULT_GUEST_PUBLIC_LAYOUT_FRIENDLY_URL);
3534
3535 ServiceContext serviceContext = new ServiceContext();
3536
3537 Layout layout = layoutLocalService.addLayout(
3538 defaultUserId, group.getGroupId(), false,
3539 LayoutConstants.DEFAULT_PARENT_LAYOUT_ID,
3540 PropsValues.DEFAULT_GUEST_PUBLIC_LAYOUT_NAME, StringPool.BLANK,
3541 StringPool.BLANK, LayoutConstants.TYPE_PORTLET, false, friendlyURL,
3542 serviceContext);
3543
3544 LayoutTypePortlet layoutTypePortlet =
3545 (LayoutTypePortlet)layout.getLayoutType();
3546
3547 layoutTypePortlet.setLayoutTemplateId(
3548 0, PropsValues.DEFAULT_GUEST_PUBLIC_LAYOUT_TEMPLATE_ID, false);
3549
3550 LayoutTemplate layoutTemplate = layoutTypePortlet.getLayoutTemplate();
3551
3552 for (String columnId : layoutTemplate.getColumns()) {
3553 String keyPrefix = PropsKeys.DEFAULT_GUEST_PUBLIC_LAYOUT_PREFIX;
3554
3555 String portletIds = PropsUtil.get(keyPrefix.concat(columnId));
3556
3557 layoutTypePortlet.addPortletIds(
3558 0, StringUtil.split(portletIds), columnId, false);
3559 }
3560
3561 layoutLocalService.updateLayout(
3562 layout.getGroupId(), layout.isPrivateLayout(), layout.getLayoutId(),
3563 layout.getTypeSettings());
3564
3565 boolean updateLayoutSet = false;
3566
3567 LayoutSet layoutSet = layout.getLayoutSet();
3568
3569 if (Validator.isNotNull(
3570 PropsValues.DEFAULT_GUEST_PUBLIC_LAYOUT_REGULAR_THEME_ID)) {
3571
3572 layoutSet.setThemeId(
3573 PropsValues.DEFAULT_GUEST_PUBLIC_LAYOUT_REGULAR_THEME_ID);
3574
3575 updateLayoutSet = true;
3576 }
3577
3578 if (Validator.isNotNull(
3579 PropsValues.
3580 DEFAULT_GUEST_PUBLIC_LAYOUT_REGULAR_COLOR_SCHEME_ID)) {
3581
3582 layoutSet.setColorSchemeId(
3583 PropsValues.
3584 DEFAULT_GUEST_PUBLIC_LAYOUT_REGULAR_COLOR_SCHEME_ID);
3585
3586 updateLayoutSet = true;
3587 }
3588
3589 if (Validator.isNotNull(
3590 PropsValues.DEFAULT_GUEST_PUBLIC_LAYOUT_WAP_THEME_ID)) {
3591
3592 layoutSet.setWapThemeId(
3593 PropsValues.DEFAULT_GUEST_PUBLIC_LAYOUT_WAP_THEME_ID);
3594
3595 updateLayoutSet = true;
3596 }
3597
3598 if (Validator.isNotNull(
3599 PropsValues.DEFAULT_GUEST_PUBLIC_LAYOUT_WAP_COLOR_SCHEME_ID)) {
3600
3601 layoutSet.setWapColorSchemeId(
3602 PropsValues.DEFAULT_GUEST_PUBLIC_LAYOUT_WAP_COLOR_SCHEME_ID);
3603
3604 updateLayoutSet = true;
3605 }
3606
3607 if (updateLayoutSet) {
3608 layoutSetLocalService.updateLayoutSet(layoutSet);
3609 }
3610 }
3611
3612 protected void addDefaultGuestPublicLayouts(Group group)
3613 throws PortalException, SystemException {
3614
3615 if (publicLARFile != null) {
3616 addDefaultGuestPublicLayoutsByLAR(group, publicLARFile);
3617 }
3618 else {
3619 addDefaultGuestPublicLayoutByProperties(group);
3620 }
3621 }
3622
3623 protected void addDefaultGuestPublicLayoutsByLAR(Group group, File larFile)
3624 throws PortalException, SystemException {
3625
3626 long defaultUserId = userLocalService.getDefaultUserId(
3627 group.getCompanyId());
3628
3629 Map<String, String[]> parameterMap = new HashMap<String, String[]>();
3630
3631 parameterMap.put(
3632 PortletDataHandlerKeys.CATEGORIES,
3633 new String[] {Boolean.TRUE.toString()});
3634 parameterMap.put(
3635 PortletDataHandlerKeys.PERMISSIONS,
3636 new String[] {Boolean.TRUE.toString()});
3637 parameterMap.put(
3638 PortletDataHandlerKeys.PORTLET_CONFIGURATION,
3639 new String[] {Boolean.TRUE.toString()});
3640 parameterMap.put(
3641 PortletDataHandlerKeys.PORTLET_DATA,
3642 new String[] {Boolean.TRUE.toString()});
3643 parameterMap.put(
3644 PortletDataHandlerKeys.PORTLET_DATA_CONTROL_DEFAULT,
3645 new String[] {Boolean.TRUE.toString()});
3646
3647 layoutLocalService.importLayouts(
3648 defaultUserId, group.getGroupId(), false, parameterMap, larFile);
3649 }
3650
3651 protected void deletePortletData(Group group)
3652 throws PortalException, SystemException {
3653
3654 List<Portlet> portlets = portletLocalService.getPortlets(
3655 group.getCompanyId());
3656
3657 for (Portlet portlet : portlets) {
3658 if (!portlet.isActive()) {
3659 continue;
3660 }
3661
3662 PortletDataHandler portletDataHandler =
3663 portlet.getPortletDataHandlerInstance();
3664
3665 if ((portletDataHandler == null) ||
3666 portletDataHandler.isDataPortalLevel()) {
3667
3668 continue;
3669 }
3670
3671 PortletDataContext portletDataContext =
3672 PortletDataContextFactoryUtil.createExportPortletDataContext(
3673 group.getCompanyId(), group.getGroupId(),
3674 (Map<String, String[]>)null, (Date)null, (Date)null,
3675 (ZipWriter)null);
3676
3677
3678
3679
3680
3681
3682
3683
3684 portletDataHandler.deleteData(
3685 portletDataContext, portlet.getPortletId(), null);
3686
3693 }
3694 }
3695
3696 protected List<Group> doSearch(
3697 long companyId, long[] classNameIds, long parentGroupId,
3698 String[] names, String[] descriptions,
3699 LinkedHashMap<String, Object> params, boolean andOperator)
3700 throws SystemException {
3701
3702 boolean parentGroupIdEquals = true;
3703
3704 if (parentGroupId == GroupConstants.ANY_PARENT_GROUP_ID) {
3705 parentGroupIdEquals = false;
3706 }
3707
3708 params = new LinkedHashMap<String, Object>(params);
3709
3710 Boolean active = (Boolean)params.remove("active");
3711 List<Long> excludedGroupIds = (List<Long>)params.remove(
3712 "excludedGroupIds");
3713 List<Group> groupsTree = (List<Group>)params.remove("groupsTree");
3714 Boolean manualMembership = (Boolean)params.remove("manualMembership");
3715 Integer membershipRestriction = (Integer)params.remove(
3716 "membershipRestriction");
3717 Boolean site = (Boolean)params.remove("site");
3718 List<Integer> types = (List<Integer>)params.remove("types");
3719
3720 List<Group> groups = new ArrayList<Group>();
3721
3722 for (long classNameId : classNameIds) {
3723 groups.addAll(groupPersistence.findByC_C(companyId, classNameId));
3724 }
3725
3726 Iterator<Group> iterator = groups.iterator();
3727
3728 while (iterator.hasNext()) {
3729 Group group = iterator.next();
3730
3731
3732
3733 long liveGroupId = group.getLiveGroupId();
3734
3735 if (liveGroupId != 0) {
3736 iterator.remove();
3737
3738 continue;
3739 }
3740
3741
3742
3743 long groupParentGroupId = group.getParentGroupId();
3744
3745 if ((parentGroupIdEquals &&
3746 (groupParentGroupId != parentGroupId)) ||
3747 (!parentGroupIdEquals &&
3748 (groupParentGroupId == parentGroupId))) {
3749
3750 iterator.remove();
3751
3752 continue;
3753 }
3754
3755
3756
3757 String name = group.getName();
3758
3759 if (name.equals(GroupConstants.CONTROL_PANEL)) {
3760 iterator.remove();
3761
3762 continue;
3763 }
3764
3765 boolean containsName = matches(name, names);
3766 boolean containsDescription = matches(
3767 group.getDescription(), descriptions);
3768
3769 if ((andOperator && (!containsName || !containsDescription)) ||
3770 (!andOperator && (!containsName && !containsDescription))) {
3771
3772 iterator.remove();
3773
3774 continue;
3775 }
3776
3777
3778
3779 if (active != null) {
3780 if (active != group.isActive()) {
3781 iterator.remove();
3782
3783 continue;
3784 }
3785 }
3786
3787
3788
3789 if ((excludedGroupIds != null) &&
3790 excludedGroupIds.contains(group.getGroupId())) {
3791
3792 iterator.remove();
3793
3794 continue;
3795 }
3796
3797
3798
3799 if (groupsTree != null) {
3800 String treePath = group.getTreePath();
3801
3802 boolean matched = false;
3803
3804 for (Group groupTree : groupsTree) {
3805 String groupTreePath = StringUtil.quote(
3806 String.valueOf(groupTree.getGroupId()),
3807 StringPool.SLASH);
3808
3809 if (treePath.contains(groupTreePath)) {
3810 matched = true;
3811
3812 break;
3813 }
3814 }
3815
3816 if (!matched) {
3817 iterator.remove();
3818
3819 continue;
3820 }
3821 }
3822
3823
3824
3825 if ((manualMembership != null) &&
3826 (manualMembership != group.isManualMembership())) {
3827
3828 iterator.remove();
3829
3830 continue;
3831 }
3832
3833
3834
3835 if ((membershipRestriction != null) &&
3836 (membershipRestriction != group.getMembershipRestriction())) {
3837
3838 iterator.remove();
3839
3840 continue;
3841 }
3842
3843
3844
3845 if (site != null) {
3846 if (site != group.isSite()) {
3847 iterator.remove();
3848
3849 continue;
3850 }
3851 }
3852
3853
3854
3855 int type = group.getType();
3856
3857 if (type == 4) {
3858 iterator.remove();
3859
3860 continue;
3861 }
3862
3863 if ((types != null) && !types.contains(type)) {
3864 iterator.remove();
3865
3866 continue;
3867 }
3868 }
3869
3870
3871
3872 List<?> rolePermissions = (List<?>)params.remove("rolePermissions");
3873
3874 if (rolePermissions != null) {
3875 String resourceName = (String)rolePermissions.get(0);
3876 Integer resourceScope = (Integer)rolePermissions.get(1);
3877 String resourceActionId = (String)rolePermissions.get(2);
3878 Long resourceRoleId = (Long)rolePermissions.get(3);
3879
3880 ResourceAction resourceAction =
3881 resourceActionLocalService.fetchResourceAction(
3882 resourceName, resourceActionId);
3883
3884 if (resourceAction != null) {
3885 long bitwiseValue = resourceAction.getBitwiseValue();
3886
3887 if (resourceBlockLocalService.isSupported(resourceName)) {
3888 iterator = groups.iterator();
3889
3890 while (iterator.hasNext()) {
3891 Group group = iterator.next();
3892
3893 ResourceTypePermission resourceTypePermission =
3894 resourceTypePermissionPersistence.fetchByC_G_N_R(
3895 companyId, group.getGroupId(), resourceName,
3896 resourceRoleId);
3897
3898 if ((resourceTypePermission == null) ||
3899 ((resourceTypePermission.getActionIds() &
3900 bitwiseValue) == 0)) {
3901
3902 iterator.remove();
3903 }
3904 }
3905 }
3906 else {
3907 iterator = groups.iterator();
3908
3909 while (iterator.hasNext()) {
3910 Group group = iterator.next();
3911
3912 ResourcePermission resourcePermission =
3913 resourcePermissionPersistence.fetchByC_N_S_P_R(
3914 companyId, resourceName, resourceScope,
3915 String.valueOf(group.getGroupId()),
3916 resourceRoleId);
3917
3918 if ((resourcePermission == null) ||
3919 ((resourcePermission.getActionIds() &
3920 bitwiseValue) == 0)) {
3921
3922 iterator.remove();
3923 }
3924 }
3925 }
3926 }
3927 }
3928
3929
3930
3931 Long userId = (Long)params.remove("usersGroups");
3932
3933 if (userId == null) {
3934 return groups;
3935 }
3936
3937 Set<Group> resultGroups = new HashSet<Group>(groups);
3938
3939 Long roleId = (Long)params.remove("groupsRoles");
3940
3941 if (roleId != null) {
3942 resultGroups.retainAll(rolePersistence.getGroups(roleId));
3943 }
3944
3945
3946
3947 resultGroups.retainAll(userPersistence.getGroups(userId));
3948
3949 boolean inherit = GetterUtil.getBoolean(params.remove("inherit"), true);
3950
3951 if (inherit) {
3952
3953
3954
3955 List<Organization> organizations = userPersistence.getOrganizations(
3956 userId);
3957
3958 for (Organization organization : organizations) {
3959 long organizationId = organization.getOrganizationId();
3960
3961 for (Group group : groups) {
3962 if (organizationId == group.getClassPK()) {
3963 resultGroups.add(group);
3964 }
3965 }
3966 }
3967
3968
3969
3970 for (Organization organization : organizations) {
3971 List<Group> tempGroups = new ArrayList<Group>(groups);
3972
3973 tempGroups.retainAll(
3974 organizationPersistence.getGroups(
3975 organization.getOrganizationId()));
3976
3977 if (!tempGroups.isEmpty()) {
3978 resultGroups.addAll(tempGroups);
3979 }
3980 }
3981
3982
3983
3984 List<UserGroup> userGroups = userPersistence.getUserGroups(userId);
3985
3986 for (UserGroup userGroup : userGroups) {
3987 List<Group> tempGroups = new ArrayList<Group>(groups);
3988
3989 tempGroups.retainAll(
3990 userGroupPersistence.getGroups(userGroup.getUserGroupId()));
3991
3992 if (!tempGroups.isEmpty()) {
3993 resultGroups.addAll(tempGroups);
3994 }
3995 }
3996 }
3997
3998 if (_log.isDebugEnabled() && !params.isEmpty()) {
3999 _log.debug("Unprocessed parameters " + MapUtil.toString(params));
4000 }
4001
4002 return new ArrayList<Group>(resultGroups);
4003 }
4004
4005 protected long[] getClassNameIds() {
4006 if (_classNameIds == null) {
4007 _classNameIds = new long[] {
4008 classNameLocalService.getClassNameId(Group.class),
4009 classNameLocalService.getClassNameId(Organization.class)
4010 };
4011 }
4012
4013 return _classNameIds;
4014 }
4015
4016 protected String getFriendlyURL(
4017 long companyId, long groupId, long classNameId, long classPK,
4018 String friendlyName, String friendlyURL)
4019 throws PortalException, SystemException {
4020
4021 friendlyURL = getFriendlyURL(friendlyURL);
4022
4023 if (Validator.isNotNull(friendlyURL)) {
4024 return friendlyURL;
4025 }
4026
4027 friendlyURL = StringPool.SLASH + getFriendlyURL(friendlyName);
4028
4029 String originalFriendlyURL = friendlyURL;
4030
4031 for (int i = 1;; i++) {
4032 try {
4033 validateFriendlyURL(
4034 companyId, groupId, classNameId, classPK, friendlyURL);
4035
4036 break;
4037 }
4038 catch (GroupFriendlyURLException gfurle) {
4039 int type = gfurle.getType();
4040
4041 if (type == GroupFriendlyURLException.DUPLICATE) {
4042 friendlyURL = originalFriendlyURL + i;
4043 }
4044 else {
4045 friendlyURL = StringPool.SLASH + classPK;
4046
4047 break;
4048 }
4049 }
4050 }
4051
4052 return friendlyURL;
4053 }
4054
4055 protected String getFriendlyURL(String friendlyURL) {
4056 return FriendlyURLNormalizerUtil.normalize(friendlyURL);
4057 }
4058
4059 protected String getOrgGroupName(String name) {
4060 return name + ORGANIZATION_NAME_SUFFIX;
4061 }
4062
4063 protected String[] getSearchNames(long companyId, String name)
4064 throws SystemException {
4065
4066 if (Validator.isNull(name)) {
4067 return new String[] {null};
4068 }
4069
4070 Company company = companyPersistence.fetchByPrimaryKey(companyId);
4071
4072 if (company == null) {
4073 return CustomSQLUtil.keywords(name);
4074 }
4075
4076 Account account = accountPersistence.fetchByPrimaryKey(
4077 company.getAccountId());
4078
4079 if (account == null) {
4080 return CustomSQLUtil.keywords(name);
4081 }
4082
4083 String companyName = account.getName();
4084
4085 if (StringUtil.wildcardMatches(
4086 companyName, name, CharPool.UNDERLINE, CharPool.PERCENT,
4087 CharPool.BACK_SLASH, false)) {
4088
4089 String[] searchNames = CustomSQLUtil.keywords(name);
4090
4091 String guestName = StringUtil.quote(
4092 StringUtil.toLowerCase(GroupConstants.GUEST),
4093 StringPool.PERCENT);
4094
4095 return ArrayUtil.append(searchNames, guestName);
4096 }
4097
4098 return CustomSQLUtil.keywords(name);
4099 }
4100
4101 protected void initImportLARFile() {
4102 String publicLARFileName = PropsValues.DEFAULT_GUEST_PUBLIC_LAYOUTS_LAR;
4103
4104 if (_log.isDebugEnabled()) {
4105 _log.debug("Reading public LAR file " + publicLARFileName);
4106 }
4107
4108 if (Validator.isNotNull(publicLARFileName)) {
4109 publicLARFile = new File(publicLARFileName);
4110
4111 if (!publicLARFile.exists()) {
4112 _log.error(
4113 "Public LAR file " + publicLARFile + " does not exist");
4114
4115 publicLARFile = null;
4116 }
4117 else {
4118 if (_log.isDebugEnabled()) {
4119 _log.debug("Using public LAR file " + publicLARFileName);
4120 }
4121 }
4122 }
4123 }
4124
4125 protected void initUserPersonalSitePermissions(Group group)
4126 throws PortalException, SystemException {
4127
4128
4129
4130 Role role = roleLocalService.getRole(
4131 group.getCompanyId(), RoleConstants.USER);
4132
4133 List<Portlet> portlets = portletLocalService.getPortlets(
4134 group.getCompanyId(), false, false);
4135
4136 for (Portlet portlet : portlets) {
4137 setRolePermissions(
4138 group, role, portlet.getPortletId(),
4139 new String[] {ActionKeys.VIEW});
4140 }
4141
4142 setRolePermissions(
4143 group, role, Layout.class.getName(),
4144 new String[] {ActionKeys.VIEW});
4145
4146 setRolePermissions(
4147 group, role, "com.liferay.portlet.blogs",
4148 new String[] {
4149 ActionKeys.ADD_ENTRY, ActionKeys.PERMISSIONS,
4150 ActionKeys.SUBSCRIBE});
4151
4152
4153
4154 role = roleLocalService.getRole(
4155 group.getCompanyId(), RoleConstants.POWER_USER);
4156
4157 for (Portlet portlet : portlets) {
4158 List<String> actions =
4159 ResourceActionsUtil.getPortletResourceActions(
4160 portlet.getPortletId());
4161
4162 String controlPanelEntryCategory = GetterUtil.getString(
4163 portlet.getControlPanelEntryCategory());
4164
4165 if (actions.contains(ActionKeys.ACCESS_IN_CONTROL_PANEL) &&
4166 controlPanelEntryCategory.startsWith(
4167 PortletCategoryKeys.SITE_ADMINISTRATION)) {
4168
4169 setRolePermissions(
4170 group, role, portlet.getPortletId(),
4171 new String[] {ActionKeys.ACCESS_IN_CONTROL_PANEL});
4172 }
4173 }
4174
4175 setRolePermissions(
4176 group, role, Group.class.getName(),
4177 new String[] {
4178 ActionKeys.MANAGE_LAYOUTS, ActionKeys.VIEW_SITE_ADMINISTRATION
4179 });
4180
4181 setRolePermissions(group, role, "com.liferay.portlet.asset");
4182 setRolePermissions(group, role, "com.liferay.portlet.blogs");
4183 setRolePermissions(group, role, "com.liferay.portlet.bookmarks");
4184 setRolePermissions(group, role, "com.liferay.portlet.documentlibrary");
4185 setRolePermissions(group, role, "com.liferay.portlet.imagegallery");
4186 setRolePermissions(group, role, "com.liferay.portlet.messageboards");
4187 setRolePermissions(group, role, "com.liferay.portlet.polls");
4188 setRolePermissions(group, role, "com.liferay.portlet.wiki");
4189 }
4190
4191 protected boolean isParentGroup(long parentGroupId, long groupId)
4192 throws PortalException, SystemException {
4193
4194
4195
4196 if (groupId == GroupConstants.DEFAULT_PARENT_GROUP_ID) {
4197 return false;
4198 }
4199
4200 Group group = groupPersistence.findByPrimaryKey(groupId);
4201
4202 String treePath = group.getTreePath();
4203
4204 if (treePath.contains(
4205 StringPool.SLASH + parentGroupId + StringPool.SLASH)) {
4206
4207 return true;
4208 }
4209 else {
4210 return false;
4211 }
4212 }
4213
4214 protected boolean isStaging(ServiceContext serviceContext) {
4215 if (serviceContext != null) {
4216 return ParamUtil.getBoolean(serviceContext, "staging");
4217 }
4218
4219 return false;
4220 }
4221
4222 protected boolean isUseComplexSQL(long[] classNameIds) {
4223 if (ArrayUtil.isEmpty(classNameIds)) {
4224 return true;
4225 }
4226
4227 if (_complexSQLClassNameIds == null) {
4228 String[] complexSQLClassNames =
4229 PropsValues.GROUPS_COMPLEX_SQL_CLASS_NAMES;
4230
4231 long[] complexSQLClassNameIds =
4232 new long[complexSQLClassNames.length];
4233
4234 for (int i = 0; i < complexSQLClassNames.length; i++) {
4235 String complexSQLClassName = complexSQLClassNames[i];
4236
4237 complexSQLClassNameIds[i] = PortalUtil.getClassNameId(
4238 complexSQLClassName);
4239 }
4240
4241 _complexSQLClassNameIds = complexSQLClassNameIds;
4242 }
4243
4244 for (long classNameId : classNameIds) {
4245 if (ArrayUtil.contains(_complexSQLClassNameIds, classNameId)) {
4246 return true;
4247 }
4248 }
4249
4250 return false;
4251 }
4252
4253 protected boolean matches(String s, String[] keywords) {
4254 if ((keywords == null) ||
4255 ((keywords.length == 1) && (keywords[0] == null))) {
4256
4257 return true;
4258 }
4259
4260 for (String keyword : keywords) {
4261 if (StringUtil.wildcardMatches(
4262 s, keyword, CharPool.UNDERLINE, CharPool.PERCENT,
4263 CharPool.BACK_SLASH, false)) {
4264
4265 return true;
4266 }
4267 }
4268
4269 return false;
4270 }
4271
4272 protected void setCompanyPermissions(
4273 Role role, String name, String[] actionIds)
4274 throws PortalException, SystemException {
4275
4276 if (resourceBlockLocalService.isSupported(name)) {
4277 resourceBlockLocalService.setCompanyScopePermissions(
4278 role.getCompanyId(), name, role.getRoleId(),
4279 Arrays.asList(actionIds));
4280 }
4281 else {
4282 resourcePermissionLocalService.setResourcePermissions(
4283 role.getCompanyId(), name, ResourceConstants.SCOPE_COMPANY,
4284 String.valueOf(role.getCompanyId()), role.getRoleId(),
4285 actionIds);
4286 }
4287 }
4288
4289 protected void setRolePermissions(Group group, Role role, String name)
4290 throws PortalException, SystemException {
4291
4292 List<String> actions = ResourceActionsUtil.getModelResourceActions(
4293 name);
4294
4295 setRolePermissions(
4296 group, role, name, actions.toArray(new String[actions.size()]));
4297 }
4298
4299 protected void setRolePermissions(
4300 Group group, Role role, String name, String[] actionIds)
4301 throws PortalException, SystemException {
4302
4303 if (resourceBlockLocalService.isSupported(name)) {
4304 resourceBlockLocalService.setGroupScopePermissions(
4305 role.getCompanyId(), group.getGroupId(), name, role.getRoleId(),
4306 Arrays.asList(actionIds));
4307 }
4308 else {
4309 resourcePermissionLocalService.setResourcePermissions(
4310 group.getCompanyId(), name, ResourceConstants.SCOPE_GROUP,
4311 String.valueOf(group.getGroupId()), role.getRoleId(),
4312 actionIds);
4313 }
4314 }
4315
4316 protected List<Group> sort(
4317 List<Group> groups, int start, int end, OrderByComparator obc) {
4318
4319 if (obc == null) {
4320 obc = new GroupNameComparator(true);
4321 }
4322
4323 Collections.sort(groups, obc);
4324
4325 return Collections.unmodifiableList(
4326 ListUtil.subList(groups, start, end));
4327 }
4328
4329 protected void unscheduleStaging(Group group) {
4330 try {
4331
4332
4333
4334 String groupName = StagingUtil.getSchedulerGroupName(
4335 DestinationNames.LAYOUTS_REMOTE_PUBLISHER, group.getGroupId());
4336
4337 SchedulerEngineHelperUtil.delete(groupName, StorageType.PERSISTED);
4338
4339 long liveGroupId = 0;
4340 long stagingGroupId = 0;
4341
4342 if (group.isStagingGroup()) {
4343 liveGroupId = group.getLiveGroupId();
4344
4345 stagingGroupId = group.getGroupId();
4346 }
4347 else if (group.hasStagingGroup()) {
4348 liveGroupId = group.getGroupId();
4349
4350 stagingGroupId = group.getStagingGroup().getGroupId();
4351 }
4352
4353 if ((liveGroupId != 0) && (stagingGroupId != 0)) {
4354
4355
4356
4357 groupName = StagingUtil.getSchedulerGroupName(
4358 DestinationNames.LAYOUTS_LOCAL_PUBLISHER, liveGroupId);
4359
4360 SchedulerEngineHelperUtil.delete(
4361 groupName, StorageType.PERSISTED);
4362
4363
4364
4365 groupName = StagingUtil.getSchedulerGroupName(
4366 DestinationNames.LAYOUTS_LOCAL_PUBLISHER, stagingGroupId);
4367
4368 SchedulerEngineHelperUtil.delete(
4369 groupName, StorageType.PERSISTED);
4370 }
4371 }
4372 catch (Exception e) {
4373 _log.error(
4374 "Unable to unschedule events for group: " + group.getGroupId());
4375 }
4376 }
4377
4378 protected void validateFriendlyURL(
4379 long companyId, long groupId, long classNameId, long classPK,
4380 String friendlyURL)
4381 throws PortalException, SystemException {
4382
4383 Company company = companyPersistence.findByPrimaryKey(companyId);
4384
4385 if (company.isSystem()) {
4386 return;
4387 }
4388
4389 if (Validator.isNull(friendlyURL)) {
4390 return;
4391 }
4392
4393 int exceptionType = LayoutImpl.validateFriendlyURL(friendlyURL);
4394
4395 if (exceptionType != -1) {
4396 throw new GroupFriendlyURLException(exceptionType);
4397 }
4398
4399 Group group = groupPersistence.fetchByC_F(companyId, friendlyURL);
4400
4401 if ((group != null) && (group.getGroupId() != groupId)) {
4402 throw new GroupFriendlyURLException(
4403 GroupFriendlyURLException.DUPLICATE);
4404 }
4405
4406 String groupIdFriendlyURL = friendlyURL.substring(1);
4407
4408 if (Validator.isNumber(groupIdFriendlyURL)) {
4409 long groupClassNameId = PortalUtil.getClassNameId(Group.class);
4410
4411 if (((classNameId != groupClassNameId) &&
4412 !groupIdFriendlyURL.equals(String.valueOf(classPK)) &&
4413 !PropsValues.USERS_SCREEN_NAME_ALLOW_NUMERIC) ||
4414 ((classNameId == groupClassNameId) &&
4415 !groupIdFriendlyURL.equals(String.valueOf(groupId)))) {
4416
4417 GroupFriendlyURLException gfurle =
4418 new GroupFriendlyURLException(
4419 GroupFriendlyURLException.POSSIBLE_DUPLICATE);
4420
4421 gfurle.setKeywordConflict(groupIdFriendlyURL);
4422
4423 throw gfurle;
4424 }
4425 }
4426
4427 String screenName = friendlyURL.substring(1);
4428
4429 User user = userPersistence.fetchByC_SN(companyId, screenName);
4430
4431 if (user != null) {
4432 long userClassNameId = PortalUtil.getClassNameId(User.class);
4433
4434 if ((classNameId == userClassNameId) &&
4435 (classPK == user.getUserId())) {
4436 }
4437 else {
4438 throw new GroupFriendlyURLException(
4439 GroupFriendlyURLException.DUPLICATE);
4440 }
4441 }
4442
4443 if (StringUtil.count(friendlyURL, StringPool.SLASH) > 1) {
4444 throw new GroupFriendlyURLException(
4445 GroupFriendlyURLException.TOO_DEEP);
4446 }
4447 }
4448
4449 protected void validateLanguageIds(
4450 String defaultLanguageId, String languageIds)
4451 throws PortalException {
4452
4453 Locale[] availableLocales = LanguageUtil.getAvailableLocales();
4454
4455 String[] availableLanguageIds = LocaleUtil.toLanguageIds(
4456 availableLocales);
4457
4458 String[] languageIdsArray = StringUtil.split(languageIds);
4459
4460 for (String languageId : languageIdsArray) {
4461 if (!ArrayUtil.contains(availableLanguageIds, languageId)) {
4462 LocaleException le = new LocaleException(
4463 LocaleException.TYPE_DISPLAY_SETTINGS);
4464
4465 le.setSourceAvailableLocales(availableLocales);
4466 le.setTargetAvailableLocales(
4467 LocaleUtil.fromLanguageIds(languageIdsArray));
4468
4469 throw le;
4470 }
4471 }
4472
4473 if (!ArrayUtil.contains(languageIdsArray, defaultLanguageId)) {
4474 LocaleException le = new LocaleException(
4475 LocaleException.TYPE_DEFAULT);
4476
4477 le.setSourceAvailableLocales(availableLocales);
4478 le.setTargetAvailableLocales(
4479 LocaleUtil.fromLanguageIds(languageIdsArray));
4480
4481 throw le;
4482 }
4483 }
4484
4485 protected void validateName(
4486 long groupId, long companyId, String name, boolean site)
4487 throws PortalException, SystemException {
4488
4489 if (Validator.isNull(name) || Validator.isNumber(name) ||
4490 name.contains(StringPool.STAR) ||
4491 name.contains(ORGANIZATION_NAME_SUFFIX)) {
4492
4493 throw new GroupNameException();
4494 }
4495
4496 try {
4497 Group group = groupFinder.findByC_N(companyId, name);
4498
4499 if ((groupId <= 0) || (group.getGroupId() != groupId)) {
4500 throw new DuplicateGroupException();
4501 }
4502 }
4503 catch (NoSuchGroupException nsge) {
4504 }
4505
4506 if (site) {
4507 Company company = companyLocalService.getCompany(companyId);
4508
4509 if (name.equals(company.getName())) {
4510 throw new DuplicateGroupException();
4511 }
4512 }
4513 }
4514
4515 protected void validateParentGroup(long groupId, long parentGroupId)
4516 throws PortalException, SystemException {
4517
4518 if (parentGroupId == GroupConstants.DEFAULT_PARENT_GROUP_ID) {
4519 return;
4520 }
4521
4522 if (groupId == parentGroupId) {
4523 throw new GroupParentException(
4524 GroupParentException.SELF_DESCENDANT);
4525 }
4526
4527 Group group = groupPersistence.fetchByPrimaryKey(groupId);
4528
4529 if (group == null) {
4530 return;
4531 }
4532
4533 if ((groupId > 0) &&
4534 (parentGroupId != GroupConstants.DEFAULT_PARENT_GROUP_ID)) {
4535
4536
4537
4538 if (isParentGroup(groupId, parentGroupId)) {
4539 throw new GroupParentException(
4540 GroupParentException.CHILD_DESCENDANT);
4541 }
4542 }
4543
4544 Group parentGroup = groupPersistence.findByPrimaryKey(parentGroupId);
4545
4546 if (group.isStagingGroup()) {
4547 Group stagingGroup = parentGroup.getStagingGroup();
4548
4549 if (groupId == stagingGroup.getGroupId()) {
4550 throw new GroupParentException(
4551 GroupParentException.STAGING_DESCENDANT);
4552 }
4553 }
4554 }
4555
4556 protected File publicLARFile;
4557
4558 private static Log _log = LogFactoryUtil.getLog(
4559 GroupLocalServiceImpl.class);
4560
4561 private volatile long[] _classNameIds;
4562 private volatile long[] _complexSQLClassNameIds;
4563 private Map<String, Group> _systemGroupsMap = new HashMap<String, Group>();
4564
4565 }