001    /**
002     * Copyright (c) 2000-2012 Liferay, Inc. All rights reserved.
003     *
004     * This library is free software; you can redistribute it and/or modify it under
005     * the terms of the GNU Lesser General Public License as published by the Free
006     * Software Foundation; either version 2.1 of the License, or (at your option)
007     * any later version.
008     *
009     * This library is distributed in the hope that it will be useful, but WITHOUT
010     * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
011     * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
012     * details.
013     */
014    
015    package com.liferay.portal.service.impl;
016    
017    import com.liferay.portal.DuplicateUserGroupException;
018    import com.liferay.portal.NoSuchUserGroupException;
019    import com.liferay.portal.RequiredUserGroupException;
020    import com.liferay.portal.UserGroupNameException;
021    import com.liferay.portal.kernel.exception.PortalException;
022    import com.liferay.portal.kernel.exception.SystemException;
023    import com.liferay.portal.kernel.lar.PortletDataHandlerKeys;
024    import com.liferay.portal.kernel.lar.UserIdStrategy;
025    import com.liferay.portal.kernel.search.Hits;
026    import com.liferay.portal.kernel.search.Indexer;
027    import com.liferay.portal.kernel.search.IndexerRegistryUtil;
028    import com.liferay.portal.kernel.search.QueryConfig;
029    import com.liferay.portal.kernel.search.SearchContext;
030    import com.liferay.portal.kernel.search.Sort;
031    import com.liferay.portal.kernel.util.CharPool;
032    import com.liferay.portal.kernel.util.OrderByComparator;
033    import com.liferay.portal.kernel.util.Validator;
034    import com.liferay.portal.kernel.workflow.WorkflowConstants;
035    import com.liferay.portal.model.Group;
036    import com.liferay.portal.model.GroupConstants;
037    import com.liferay.portal.model.ResourceConstants;
038    import com.liferay.portal.model.Team;
039    import com.liferay.portal.model.User;
040    import com.liferay.portal.model.UserGroup;
041    import com.liferay.portal.model.UserGroupConstants;
042    import com.liferay.portal.security.ldap.LDAPUserGroupTransactionThreadLocal;
043    import com.liferay.portal.security.permission.PermissionCacheUtil;
044    import com.liferay.portal.service.ServiceContext;
045    import com.liferay.portal.service.base.UserGroupLocalServiceBaseImpl;
046    import com.liferay.portal.util.PropsValues;
047    
048    import java.io.File;
049    import java.io.Serializable;
050    
051    import java.util.ArrayList;
052    import java.util.HashMap;
053    import java.util.LinkedHashMap;
054    import java.util.List;
055    import java.util.Map;
056    
057    /**
058     * The implementation of the user group local service.
059     *
060     * @author Charles May
061     */
062    public class UserGroupLocalServiceImpl extends UserGroupLocalServiceBaseImpl {
063    
064            /**
065             * Adds the user groups to the group.
066             *
067             * @param  groupId the primary key of the group
068             * @param  userGroupIds the primary keys of the user groups
069             * @throws SystemException if a system exception occurred
070             */
071            public void addGroupUserGroups(long groupId, long[] userGroupIds)
072                    throws SystemException {
073    
074                    groupPersistence.addUserGroups(groupId, userGroupIds);
075    
076                    PermissionCacheUtil.clearCache();
077            }
078    
079            /**
080             * Adds the user groups to the team.
081             *
082             * @param  teamId the primary key of the team
083             * @param  userGroupIds the primary keys of the user groups
084             * @throws SystemException if a system exception occurred
085             */
086            public void addTeamUserGroups(long teamId, long[] userGroupIds)
087                    throws SystemException {
088    
089                    teamPersistence.addUserGroups(teamId, userGroupIds);
090    
091                    PermissionCacheUtil.clearCache();
092            }
093    
094            /**
095             * Adds a user group.
096             *
097             * <p>
098             * This method handles the creation and bookkeeping of the user group,
099             * including its resources, metadata, and internal data structures. It is
100             * not necessary to make subsequent calls to setup default groups and
101             * resources for the user group.
102             * </p>
103             *
104             * @param      userId the primary key of the user
105             * @param      companyId the primary key of the user group's company
106             * @param      name the user group's name
107             * @param      description the user group's description
108             * @return     the user group
109             * @throws     PortalException if the user group's information was invalid
110             * @throws     SystemException if a system exception occurred
111             * @deprecated {@link #addUserGroup(long, long, String, String,
112             *             ServiceContext)}
113             */
114            public UserGroup addUserGroup(
115                            long userId, long companyId, String name, String description)
116                    throws PortalException, SystemException {
117    
118                    return addUserGroup(userId, companyId, name, description, null);
119            }
120    
121            /**
122             * Adds a user group.
123             *
124             * <p>
125             * This method handles the creation and bookkeeping of the user group,
126             * including its resources, metadata, and internal data structures. It is
127             * not necessary to make subsequent calls to setup default groups and
128             * resources for the user group.
129             * </p>
130             *
131             * @param  userId the primary key of the user
132             * @param  companyId the primary key of the user group's company
133             * @param  name the user group's name
134             * @param  description the user group's description
135             * @param  serviceContext the user group's service context (optionally
136             *         <code>null</code>). Can set expando bridge attributes for the
137             *         user group.
138             * @return the user group
139             * @throws PortalException if the user group's information was invalid
140             * @throws SystemException if a system exception occurred
141             */
142            public UserGroup addUserGroup(
143                            long userId, long companyId, String name, String description,
144                            ServiceContext serviceContext)
145                    throws PortalException, SystemException {
146    
147                    // User group
148    
149                    validate(0, companyId, name);
150    
151                    long userGroupId = counterLocalService.increment();
152    
153                    UserGroup userGroup = userGroupPersistence.create(userGroupId);
154    
155                    userGroup.setCompanyId(companyId);
156                    userGroup.setParentUserGroupId(
157                            UserGroupConstants.DEFAULT_PARENT_USER_GROUP_ID);
158                    userGroup.setName(name);
159                    userGroup.setDescription(description);
160                    userGroup.setAddedByLDAPImport(
161                            LDAPUserGroupTransactionThreadLocal.isOriginatesFromLDAP());
162                    userGroup.setExpandoBridgeAttributes(serviceContext);
163    
164                    userGroupPersistence.update(userGroup);
165    
166                    // Group
167    
168                    groupLocalService.addGroup(
169                            userId, GroupConstants.DEFAULT_PARENT_GROUP_ID,
170                            UserGroup.class.getName(), userGroup.getUserGroupId(),
171                            GroupConstants.DEFAULT_LIVE_GROUP_ID, String.valueOf(userGroupId),
172                            null, 0, null, false, true, null);
173    
174                    // Resources
175    
176                    resourceLocalService.addResources(
177                            companyId, 0, userId, UserGroup.class.getName(),
178                            userGroup.getUserGroupId(), false, false, false);
179    
180                    // Indexer
181    
182                    Indexer indexer = IndexerRegistryUtil.nullSafeGetIndexer(
183                            UserGroup.class);
184    
185                    indexer.reindex(userGroup);
186    
187                    return userGroup;
188            }
189    
190            /**
191             * Clears all associations between the user and its user groups and clears
192             * the permissions cache.
193             *
194             * <p>
195             * This method is called from {@link #deleteUserGroup(UserGroup)}.
196             * </p>
197             *
198             * @param  userId the primary key of the user
199             * @throws SystemException if a system exception occurred
200             */
201            public void clearUserUserGroups(long userId) throws SystemException {
202                    userPersistence.clearUserGroups(userId);
203    
204                    PermissionCacheUtil.clearCache();
205            }
206    
207            /**
208             * Copies the user group's layouts to the users who are not already members
209             * of the user group.
210             *
211             * @param      userGroupId the primary key of the user group
212             * @param      userIds the primary keys of the users
213             * @throws     PortalException if any one of the users could not be found or
214             *             if a portal exception occurred
215             * @throws     SystemException if a system exception occurred
216             * @deprecated
217             */
218            public void copyUserGroupLayouts(long userGroupId, long userIds[])
219                    throws PortalException, SystemException {
220    
221                    Map<String, String[]> parameterMap = getLayoutTemplatesParameters();
222    
223                    File[] files = exportLayouts(userGroupId, parameterMap);
224    
225                    try {
226                            for (long userId : userIds) {
227                                    if (!userGroupPersistence.containsUser(userGroupId, userId)) {
228                                            importLayouts(userId, parameterMap, files[0], files[1]);
229                                    }
230                            }
231                    }
232                    finally {
233                            if (files[0] != null) {
234                                    files[0].delete();
235                            }
236    
237                            if (files[1] != null) {
238                                    files[1].delete();
239                            }
240                    }
241            }
242    
243            /**
244             * Copies the user groups' layouts to the user.
245             *
246             * @param      userGroupIds the primary keys of the user groups
247             * @param      userId the primary key of the user
248             * @throws     PortalException if a user with the primary key could not be
249             *             found or if a portal exception occurred
250             * @throws     SystemException if a system exception occurred
251             * @deprecated
252             */
253            public void copyUserGroupLayouts(long userGroupIds[], long userId)
254                    throws PortalException, SystemException {
255    
256                    for (long userGroupId : userGroupIds) {
257                            if (!userGroupPersistence.containsUser(userGroupId, userId)) {
258                                    copyUserGroupLayouts(userGroupId, userId);
259                            }
260                    }
261            }
262    
263            /**
264             * Copies the user group's layout to the user.
265             *
266             * @param      userGroupId the primary key of the user group
267             * @param      userId the primary key of the user
268             * @throws     PortalException if a user with the primary key could not be
269             *             found or if a portal exception occurred
270             * @throws     SystemException if a system exception occurred
271             * @deprecated
272             */
273            public void copyUserGroupLayouts(long userGroupId, long userId)
274                    throws PortalException, SystemException {
275    
276                    Map<String, String[]> parameterMap = getLayoutTemplatesParameters();
277    
278                    File[] files = exportLayouts(userGroupId, parameterMap);
279    
280                    try {
281                            importLayouts(userId, parameterMap, files[0], files[1]);
282                    }
283                    finally {
284                            if (files[0] != null) {
285                                    files[0].delete();
286                            }
287    
288                            if (files[1] != null) {
289                                    files[1].delete();
290                            }
291                    }
292            }
293    
294            /**
295             * Deletes the user group.
296             *
297             * @param  userGroupId the primary key of the user group
298             * @return the deleted user group
299             * @throws PortalException if a user group with the primary key could not be
300             *         found or if the user group had a workflow in approved status
301             * @throws SystemException if a system exception occurred
302             */
303            @Override
304            public UserGroup deleteUserGroup(long userGroupId)
305                    throws PortalException, SystemException {
306    
307                    UserGroup userGroup = userGroupPersistence.findByPrimaryKey(
308                            userGroupId);
309    
310                    return deleteUserGroup(userGroup);
311            }
312    
313            /**
314             * Deletes the user group.
315             *
316             * @param  userGroup the user group
317             * @return the deleted user group
318             * @throws PortalException if the organization had a workflow in approved
319             *         status
320             * @throws SystemException if a system exception occurred
321             */
322            @Override
323            public UserGroup deleteUserGroup(UserGroup userGroup)
324                    throws PortalException, SystemException {
325    
326                    int count = userLocalService.getUserGroupUsersCount(
327                            userGroup.getUserGroupId(), WorkflowConstants.STATUS_APPROVED);
328    
329                    if (count > 0) {
330                            throw new RequiredUserGroupException();
331                    }
332    
333                    // Expando
334    
335                    expandoValueLocalService.deleteValues(
336                            UserGroup.class.getName(), userGroup.getUserGroupId());
337    
338                    // Users
339    
340                    clearUserUserGroups(userGroup.getUserGroupId());
341    
342                    // Group
343    
344                    Group group = userGroup.getGroup();
345    
346                    groupLocalService.deleteGroup(group);
347    
348                    // User group roles
349    
350                    userGroupGroupRoleLocalService.deleteUserGroupGroupRolesByUserGroupId(
351                            userGroup.getUserGroupId());
352    
353                    // Resources
354    
355                    resourceLocalService.deleteResource(
356                            userGroup.getCompanyId(), UserGroup.class.getName(),
357                            ResourceConstants.SCOPE_INDIVIDUAL, userGroup.getUserGroupId());
358    
359                    // User group
360    
361                    userGroupPersistence.remove(userGroup);
362    
363                    // Permission cache
364    
365                    PermissionCacheUtil.clearCache();
366    
367                    return userGroup;
368            }
369    
370            /**
371             * Returns the user group with the name.
372             *
373             * @param  companyId the primary key of the user group's company
374             * @param  name the user group's name
375             * @return Returns the user group with the name
376             * @throws PortalException if a user group with the name could not be found
377             * @throws SystemException if a system exception occurred
378             */
379            public UserGroup getUserGroup(long companyId, String name)
380                    throws PortalException, SystemException {
381    
382                    return userGroupPersistence.findByC_N(companyId, name);
383            }
384    
385            /**
386             * Returns all the user groups belonging to the company.
387             *
388             * @param  companyId the primary key of the user groups' company
389             * @return the user groups belonging to the company
390             * @throws SystemException if a system exception occurred
391             */
392            public List<UserGroup> getUserGroups(long companyId)
393                    throws SystemException {
394    
395                    return userGroupPersistence.findByCompanyId(companyId);
396            }
397    
398            /**
399             * Returns all the user groups with the primary keys.
400             *
401             * @param  userGroupIds the primary keys of the user groups
402             * @return the user groups with the primary keys
403             * @throws PortalException if any one of the user groups could not be found
404             * @throws SystemException if a system exception occurred
405             */
406            public List<UserGroup> getUserGroups(long[] userGroupIds)
407                    throws PortalException, SystemException {
408    
409                    List<UserGroup> userGroups = new ArrayList<UserGroup>(
410                            userGroupIds.length);
411    
412                    for (long userGroupId : userGroupIds) {
413                            UserGroup userGroup = getUserGroup(userGroupId);
414    
415                            userGroups.add(userGroup);
416                    }
417    
418                    return userGroups;
419            }
420    
421            /**
422             * Returns all the user groups to which the user belongs.
423             *
424             * @param  userId the primary key of the user
425             * @return the user groups to which the user belongs
426             * @throws SystemException if a system exception occurred
427             */
428            public List<UserGroup> getUserUserGroups(long userId)
429                    throws SystemException {
430    
431                    return userPersistence.getUserGroups(userId);
432            }
433    
434            /**
435             * Returns <code>true</code> if the user group is associated with the group.
436             *
437             * @param  groupId the primary key of the group
438             * @param  userGroupId the primary key of the user group
439             * @return <code>true</code> if the user group belongs to the group;
440             *         <code>false</code> otherwise
441             * @throws SystemException if a system exception occurred
442             */
443            public boolean hasGroupUserGroup(long groupId, long userGroupId)
444                    throws SystemException {
445    
446                    return groupPersistence.containsUserGroup(groupId, userGroupId);
447            }
448    
449            /**
450             * Returns <code>true</code> if the user group belongs to the team.
451             *
452             * @param  teamId the primary key of the team
453             * @param  userGroupId the primary key of the user group
454             * @return <code>true</code> if the user group belongs to the team;
455             *         <code>false</code> otherwise
456             * @throws SystemException if a system exception occurred
457             */
458            public boolean hasTeamUserGroup(long teamId, long userGroupId)
459                    throws SystemException {
460    
461                    return teamPersistence.containsUserGroup(teamId, userGroupId);
462            }
463    
464            /**
465             * Returns an ordered range of all the user groups that match the keywords.
466             *
467             * <p>
468             * Useful when paginating results. Returns a maximum of <code>end -
469             * start</code> instances. <code>start</code> and <code>end</code> are not
470             * primary keys, they are indexes in the result set. Thus, <code>0</code>
471             * refers to the first result in the set. Setting both <code>start</code>
472             * and <code>end</code> to {@link
473             * com.liferay.portal.kernel.dao.orm.QueryUtil#ALL_POS} will return the full
474             * result set.
475             * </p>
476             *
477             * @param  companyId the primary key of the user group's company
478             * @param  keywords the keywords (space separated), which may occur in the
479             *         user group's name or description (optionally <code>null</code>)
480             * @param  params the finder params (optionally <code>null</code>). For more
481             *         information see {@link
482             *         com.liferay.portal.service.persistence.UserGroupFinder}
483             * @param  start the lower bound of the range of user groups to return
484             * @param  end the upper bound of the range of user groups to return (not
485             *         inclusive)
486             * @param  obc the comparator to order the user groups (optionally
487             *         <code>null</code>)
488             * @return the matching user groups ordered by comparator <code>obc</code>
489             * @throws SystemException if a system exception occurred
490             * @see    com.liferay.portal.service.persistence.UserGroupFinder
491             */
492            public List<UserGroup> search(
493                            long companyId, String keywords,
494                            LinkedHashMap<String, Object> params, int start, int end,
495                            OrderByComparator obc)
496                    throws SystemException {
497    
498                    return userGroupFinder.findByKeywords(
499                            companyId, keywords, params, start, end, obc);
500            }
501    
502            /**
503             * Returns an ordered range of all the user groups that match the keywords,
504             * using the indexer. It is preferable to use this method instead of the
505             * non-indexed version whenever possible for performance reasons.
506             *
507             * <p>
508             * Useful when paginating results. Returns a maximum of <code>end -
509             * start</code> instances. <code>start</code> and <code>end</code> are not
510             * primary keys, they are indexes in the result set. Thus, <code>0</code>
511             * refers to the first result in the set. Setting both <code>start</code>
512             * and <code>end</code> to {@link
513             * com.liferay.portal.kernel.dao.orm.QueryUtil#ALL_POS} will return the full
514             * result set.
515             * </p>
516             *
517             * @param  companyId the primary key of the user group's company
518             * @param  keywords the keywords (space separated), which may occur in the
519             *         user group's name or description (optionally <code>null</code>)
520             * @param  params the finder params (optionally <code>null</code>). For more
521             *         information see {@link
522             *         com.liferay.portlet.usergroupsadmin.util.UserGroupIndexer}
523             * @param  start the lower bound of the range of user groups to return
524             * @param  end the upper bound of the range of user groups to return (not
525             *         inclusive)
526             * @param  sort the field and direction by which to sort (optionally
527             *         <code>null</code>)
528             * @return the matching user groups ordered by sort
529             * @throws SystemException if a system exception occurred
530             * @see    com.liferay.portlet.usergroupsadmin.util.UserGroupIndexer
531             */
532            public Hits search(
533                            long companyId, String keywords,
534                            LinkedHashMap<String, Object> params, int start, int end, Sort sort)
535                    throws SystemException {
536    
537                    String name = null;
538                    String description = null;
539                    boolean andOperator = false;
540    
541                    if (Validator.isNotNull(keywords)) {
542                            name = keywords;
543                            description = keywords;
544                    }
545                    else {
546                            andOperator = true;
547                    }
548    
549                    if (params != null) {
550                            params.put("keywords", keywords);
551                    }
552    
553                    return search(
554                            companyId, name, description, params, andOperator, start, end,
555                            sort);
556            }
557    
558            /**
559             * Returns an ordered range of all the user groups that match the name and
560             * description. It is preferable to use this method instead of the
561             * non-indexed version whenever possible for performance reasons.
562             *
563             * <p>
564             * Useful when paginating results. Returns a maximum of <code>end -
565             * start</code> instances. <code>start</code> and <code>end</code> are not
566             * primary keys, they are indexes in the result set. Thus, <code>0</code>
567             * refers to the first result in the set. Setting both <code>start</code>
568             * and <code>end</code> to {@link
569             * com.liferay.portal.kernel.dao.orm.QueryUtil#ALL_POS} will return the full
570             * result set.
571             * </p>
572             *
573             * @param  companyId the primary key of the user group's company
574             * @param  name the user group's name (optionally <code>null</code>)
575             * @param  description the user group's description (optionally
576             *         <code>null</code>)
577             * @param  params the finder params (optionally <code>null</code>). For more
578             *         information see {@link
579             *         com.liferay.portlet.usergroupsadmin.util.UserGroupIndexer}
580             * @param  andSearch whether every field must match its keywords or just one
581             *         field
582             * @param  start the lower bound of the range of user groups to return
583             * @param  end the upper bound of the range of user groups to return (not
584             *         inclusive)
585             * @param  sort the field and direction by which to sort (optionally
586             *         <code>null</code>)
587             * @return the matching user groups ordered by sort
588             * @throws SystemException if a system exception occurred
589             * @see    com.liferay.portal.service.persistence.UserGroupFinder
590             */
591            public Hits search(
592                            long companyId, String name, String description,
593                            LinkedHashMap<String, Object> params, boolean andSearch, int start,
594                            int end, Sort sort)
595                    throws SystemException {
596    
597                    try {
598                            SearchContext searchContext = new SearchContext();
599    
600                            searchContext.setAndSearch(andSearch);
601    
602                            Map<String, Serializable> attributes =
603                                    new HashMap<String, Serializable>();
604    
605                            attributes.put("description", description);
606                            attributes.put("name", name);
607    
608                            searchContext.setAttributes(attributes);
609    
610                            searchContext.setCompanyId(companyId);
611                            searchContext.setEnd(end);
612    
613                            if (params != null) {
614                                    String keywords = (String)params.remove("keywords");
615    
616                                    if (Validator.isNotNull(keywords)) {
617                                            searchContext.setKeywords(keywords);
618                                    }
619                            }
620    
621                            QueryConfig queryConfig = new QueryConfig();
622    
623                            queryConfig.setHighlightEnabled(false);
624                            queryConfig.setScoreEnabled(false);
625    
626                            searchContext.setQueryConfig(queryConfig);
627    
628                            if (sort != null) {
629                                    searchContext.setSorts(new Sort[] {sort});
630                            }
631    
632                            searchContext.setStart(start);
633    
634                            Indexer indexer = IndexerRegistryUtil.nullSafeGetIndexer(
635                                    UserGroup.class);
636    
637                            return indexer.search(searchContext);
638                    }
639                    catch (Exception e) {
640                            throw new SystemException(e);
641                    }
642            }
643    
644            /**
645             * Returns an ordered range of all the user groups that match the name and
646             * description.
647             *
648             * <p>
649             * Useful when paginating results. Returns a maximum of <code>end -
650             * start</code> instances. <code>start</code> and <code>end</code> are not
651             * primary keys, they are indexes in the result set. Thus, <code>0</code>
652             * refers to the first result in the set. Setting both <code>start</code>
653             * and <code>end</code> to {@link
654             * com.liferay.portal.kernel.dao.orm.QueryUtil#ALL_POS} will return the full
655             * result set.
656             * </p>
657             *
658             * @param  companyId the primary key of the user group's company
659             * @param  name the user group's name (optionally <code>null</code>)
660             * @param  description the user group's description (optionally
661             *         <code>null</code>)
662             * @param  params the finder params (optionally <code>null</code>). For more
663             *         information see {@link
664             *         com.liferay.portal.service.persistence.UserGroupFinder}
665             * @param  start the lower bound of the range of user groups to return
666             * @param  end the upper bound of the range of user groups to return (not
667             *         inclusive)
668             * @param  obc the comparator to order the user groups (optionally
669             *         <code>null</code>)
670             * @return the matching user groups ordered by comparator <code>obc</code>
671             * @throws SystemException if a system exception occurred
672             * @see    com.liferay.portal.service.persistence.UserGroupFinder
673             */
674            public List<UserGroup> search(
675                            long companyId, String name, String description,
676                            LinkedHashMap<String, Object> params, int start, int end,
677                            OrderByComparator obc)
678                    throws SystemException {
679    
680                    return userGroupFinder.findByC_N_D(
681                            companyId, name, description, params, false, start, end, obc);
682            }
683    
684            /**
685             * Returns the number of user groups that match the keywords
686             *
687             * @param  companyId the primary key of the user group's company
688             * @param  keywords the keywords (space separated), which may occur in the
689             *         user group's name or description (optionally <code>null</code>)
690             * @param  params the finder params (optionally <code>null</code>). For more
691             *         information see {@link
692             *         com.liferay.portal.service.persistence.UserGroupFinder}
693             * @return the number of matching user groups
694             * @throws SystemException if a system exception occurred
695             * @see    com.liferay.portal.service.persistence.UserGroupFinder
696             */
697            public int searchCount(
698                            long companyId, String keywords,
699                            LinkedHashMap<String, Object> params)
700                    throws SystemException {
701    
702                    return userGroupFinder.countByKeywords(companyId, keywords, params);
703            }
704    
705            /**
706             * Returns the number of user groups that match the name and description.
707             *
708             * @param  companyId the primary key of the user group's company
709             * @param  name the user group's name (optionally <code>null</code>)
710             * @param  description the user group's description (optionally
711             *         <code>null</code>)
712             * @param  params the finder params (optionally <code>null</code>). For more
713             *         information see {@link
714             *         com.liferay.portal.service.persistence.UserGroupFinder}
715             * @return the number of matching user groups
716             * @throws SystemException if a system exception occurred
717             * @see    com.liferay.portal.service.persistence.UserGroupFinder
718             */
719            public int searchCount(
720                            long companyId, String name, String description,
721                            LinkedHashMap<String, Object> params)
722                    throws SystemException {
723    
724                    return userGroupFinder.countByC_N_D(
725                            companyId, name, description, params, false);
726            }
727    
728            /**
729             * Sets the user groups associated with the user copying the user group
730             * layouts and removing and adding user group associations for the user as
731             * necessary.
732             *
733             * @param  userId the primary key of the user
734             * @param  userGroupIds the primary keys of the user groups
735             * @throws PortalException if a portal exception occurred
736             * @throws SystemException if a system exception occurred
737             */
738            public void setUserUserGroups(long userId, long[] userGroupIds)
739                    throws PortalException, SystemException {
740    
741                    copyUserGroupLayouts(userGroupIds, userId);
742    
743                    userPersistence.setUserGroups(userId, userGroupIds);
744    
745                    Indexer indexer = IndexerRegistryUtil.nullSafeGetIndexer(User.class);
746    
747                    indexer.reindex(userId);
748    
749                    PermissionCacheUtil.clearCache();
750            }
751    
752            /**
753             * Removes the user groups from the group.
754             *
755             * @param  groupId the primary key of the group
756             * @param  userGroupIds the primary keys of the user groups
757             * @throws SystemException if a system exception occurred
758             */
759            public void unsetGroupUserGroups(long groupId, long[] userGroupIds)
760                    throws SystemException {
761    
762                    List<Team> teams = teamPersistence.findByGroupId(groupId);
763    
764                    for (Team team : teams) {
765                            teamPersistence.removeUserGroups(team.getTeamId(), userGroupIds);
766                    }
767    
768                    userGroupGroupRoleLocalService.deleteUserGroupGroupRoles(
769                            userGroupIds, groupId);
770    
771                    groupPersistence.removeUserGroups(groupId, userGroupIds);
772    
773                    PermissionCacheUtil.clearCache();
774            }
775    
776            /**
777             * Removes the user groups from the team.
778             *
779             * @param  teamId the primary key of the team
780             * @param  userGroupIds the primary keys of the user groups
781             * @throws SystemException if a system exception occurred
782             */
783            public void unsetTeamUserGroups(long teamId, long[] userGroupIds)
784                    throws SystemException {
785    
786                    teamPersistence.removeUserGroups(teamId, userGroupIds);
787    
788                    PermissionCacheUtil.clearCache();
789            }
790    
791            /**
792             * Updates the user group.
793             *
794             * @param      companyId the primary key of the user group's company
795             * @param      userGroupId the primary key of the user group
796             * @param      name the user group's name
797             * @param      description the user group's description
798             * @return     the user group
799             * @throws     PortalException if a user group with the primary key could
800             *             not be found or if the new information was invalid
801             * @throws     SystemException if a system exception occurred
802             * @deprecated {@link #updateUserGroup(long, long, String, String,
803             *             ServiceContext)}
804             */
805            public UserGroup updateUserGroup(
806                            long companyId, long userGroupId, String name, String description)
807                    throws PortalException, SystemException {
808    
809                    return updateUserGroup(companyId, userGroupId, name, description, null);
810            }
811    
812            /**
813             * Updates the user group.
814             *
815             * @param  companyId the primary key of the user group's company
816             * @param  userGroupId the primary key of the user group
817             * @param  name the user group's name
818             * @param  description the user group's description
819             * @param  serviceContext the user group's service context (optionally
820             *         <code>null</code>). Can set expando bridge attributes for the
821             *         user group.
822             * @return the user group
823             * @throws PortalException if a user group with the primary key could not be
824             *         found or if the new information was invalid
825             * @throws SystemException if a system exception occurred
826             */
827            public UserGroup updateUserGroup(
828                            long companyId, long userGroupId, String name, String description,
829                            ServiceContext serviceContext)
830                    throws PortalException, SystemException {
831    
832                    // User group
833    
834                    validate(userGroupId, companyId, name);
835    
836                    UserGroup userGroup = userGroupPersistence.findByPrimaryKey(
837                            userGroupId);
838    
839                    userGroup.setName(name);
840                    userGroup.setDescription(description);
841                    userGroup.setExpandoBridgeAttributes(serviceContext);
842    
843                    userGroupPersistence.update(userGroup);
844    
845                    // Indexer
846    
847                    Indexer indexer = IndexerRegistryUtil.nullSafeGetIndexer(
848                            UserGroup.class);
849    
850                    indexer.reindex(userGroup);
851    
852                    return userGroup;
853            }
854    
855            protected File[] exportLayouts(
856                            long userGroupId, Map<String, String[]> parameterMap)
857                    throws PortalException, SystemException {
858    
859                    File[] files = new File[2];
860    
861                    UserGroup userGroup = userGroupPersistence.findByPrimaryKey(
862                            userGroupId);
863    
864                    Group group = userGroup.getGroup();
865    
866                    if (userGroup.hasPrivateLayouts()) {
867                            files[0] = layoutLocalService.exportLayoutsAsFile(
868                                    group.getGroupId(), true, null, parameterMap, null, null);
869                    }
870    
871                    if (userGroup.hasPublicLayouts()) {
872                            files[1] = layoutLocalService.exportLayoutsAsFile(
873                                    group.getGroupId(), false, null, parameterMap, null, null);
874                    }
875    
876                    return files;
877            }
878    
879            protected Map<String, String[]> getLayoutTemplatesParameters() {
880                    Map<String, String[]> parameterMap =
881                            new LinkedHashMap<String, String[]>();
882    
883                    parameterMap.put(
884                            PortletDataHandlerKeys.CATEGORIES,
885                            new String[] {Boolean.TRUE.toString()});
886                    parameterMap.put(
887                            PortletDataHandlerKeys.DATA_STRATEGY,
888                            new String[] {PortletDataHandlerKeys.DATA_STRATEGY_MIRROR});
889                    parameterMap.put(
890                            PortletDataHandlerKeys.DELETE_MISSING_LAYOUTS,
891                            new String[] {Boolean.FALSE.toString()});
892                    parameterMap.put(
893                            PortletDataHandlerKeys.DELETE_PORTLET_DATA,
894                            new String[] {Boolean.FALSE.toString()});
895                    parameterMap.put(
896                            PortletDataHandlerKeys.LAYOUT_SET_SETTINGS,
897                            new String[] {Boolean.FALSE.toString()});
898                    parameterMap.put(
899                            PortletDataHandlerKeys.LAYOUTS_IMPORT_MODE,
900                            new String[] {PortletDataHandlerKeys.
901                                    LAYOUTS_IMPORT_MODE_CREATED_FROM_PROTOTYPE});
902                    parameterMap.put(
903                            PortletDataHandlerKeys.LOGO,
904                            new String[] {Boolean.FALSE.toString()});
905                    parameterMap.put(
906                            PortletDataHandlerKeys.PERMISSIONS,
907                            new String[] {Boolean.TRUE.toString()});
908                    parameterMap.put(
909                            PortletDataHandlerKeys.PORTLET_DATA,
910                            new String[] {Boolean.TRUE.toString()});
911                    parameterMap.put(
912                            PortletDataHandlerKeys.PORTLET_DATA_ALL,
913                            new String[] {Boolean.TRUE.toString()});
914                    parameterMap.put(
915                            PortletDataHandlerKeys.PORTLET_SETUP,
916                            new String[] {Boolean.TRUE.toString()});
917                    parameterMap.put(
918                            PortletDataHandlerKeys.PORTLET_USER_PREFERENCES,
919                            new String[] {Boolean.TRUE.toString()});
920                    parameterMap.put(
921                            PortletDataHandlerKeys.PORTLETS_MERGE_MODE,
922                            new String[] {PortletDataHandlerKeys.
923                                    PORTLETS_MERGE_MODE_ADD_TO_BOTTOM});
924                    parameterMap.put(
925                            PortletDataHandlerKeys.THEME,
926                            new String[] {Boolean.FALSE.toString()});
927                    parameterMap.put(
928                            PortletDataHandlerKeys.THEME_REFERENCE,
929                            new String[] {Boolean.TRUE.toString()});
930                    parameterMap.put(
931                            PortletDataHandlerKeys.UPDATE_LAST_PUBLISH_DATE,
932                            new String[] {Boolean.FALSE.toString()});
933                    parameterMap.put(
934                            PortletDataHandlerKeys.USER_ID_STRATEGY,
935                            new String[] {UserIdStrategy.CURRENT_USER_ID});
936    
937                    return parameterMap;
938            }
939    
940            protected void importLayouts(
941                            long userId, Map<String, String[]> parameterMap,
942                            File privateLayoutsFile, File publicLayoutsFile)
943                    throws PortalException, SystemException {
944    
945                    User user = userPersistence.findByPrimaryKey(userId);
946    
947                    long groupId = user.getGroup().getGroupId();
948    
949                    if (privateLayoutsFile != null) {
950                            layoutLocalService.importLayouts(
951                                    userId, groupId, true, parameterMap, privateLayoutsFile);
952                    }
953    
954                    if (publicLayoutsFile != null) {
955                            layoutLocalService.importLayouts(
956                                    userId, groupId, false, parameterMap, publicLayoutsFile);
957                    }
958            }
959    
960            protected void validate(long userGroupId, long companyId, String name)
961                    throws PortalException, SystemException {
962    
963                    if (Validator.isNull(name) ||
964                            (name.indexOf(CharPool.COMMA) != -1) ||
965                            (name.indexOf(CharPool.STAR) != -1)) {
966    
967                            throw new UserGroupNameException();
968                    }
969    
970                    if (Validator.isNumber(name) &&
971                            !PropsValues.USER_GROUPS_NAME_ALLOW_NUMERIC) {
972    
973                            throw new UserGroupNameException();
974                    }
975    
976                    try {
977                            UserGroup userGroup = userGroupFinder.findByC_N(companyId, name);
978    
979                            if (userGroup.getUserGroupId() != userGroupId) {
980                                    throw new DuplicateUserGroupException();
981                            }
982                    }
983                    catch (NoSuchUserGroupException nsuge) {
984                    }
985            }
986    
987    }