001    /**
002     * Copyright (c) 2000-present 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.portlet.sites.action;
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.LayoutSetVirtualHostException;
022    import com.liferay.portal.LocaleException;
023    import com.liferay.portal.NoSuchGroupException;
024    import com.liferay.portal.NoSuchLayoutException;
025    import com.liferay.portal.PendingBackgroundTaskException;
026    import com.liferay.portal.RemoteExportException;
027    import com.liferay.portal.RemoteOptionsException;
028    import com.liferay.portal.RequiredGroupException;
029    import com.liferay.portal.kernel.dao.orm.QueryUtil;
030    import com.liferay.portal.kernel.exception.PortalException;
031    import com.liferay.portal.kernel.exception.SystemException;
032    import com.liferay.portal.kernel.log.Log;
033    import com.liferay.portal.kernel.log.LogFactoryUtil;
034    import com.liferay.portal.kernel.servlet.MultiSessionMessages;
035    import com.liferay.portal.kernel.servlet.SessionErrors;
036    import com.liferay.portal.kernel.staging.StagingUtil;
037    import com.liferay.portal.kernel.transaction.Propagation;
038    import com.liferay.portal.kernel.util.ArrayUtil;
039    import com.liferay.portal.kernel.util.Constants;
040    import com.liferay.portal.kernel.util.GetterUtil;
041    import com.liferay.portal.kernel.util.HttpUtil;
042    import com.liferay.portal.kernel.util.ListUtil;
043    import com.liferay.portal.kernel.util.ParamUtil;
044    import com.liferay.portal.kernel.util.PrefsPropsUtil;
045    import com.liferay.portal.kernel.util.PropertiesParamUtil;
046    import com.liferay.portal.kernel.util.PropsKeys;
047    import com.liferay.portal.kernel.util.StringPool;
048    import com.liferay.portal.kernel.util.StringUtil;
049    import com.liferay.portal.kernel.util.UnicodeProperties;
050    import com.liferay.portal.kernel.util.Validator;
051    import com.liferay.portal.liveusers.LiveUsers;
052    import com.liferay.portal.model.Group;
053    import com.liferay.portal.model.GroupConstants;
054    import com.liferay.portal.model.Layout;
055    import com.liferay.portal.model.LayoutConstants;
056    import com.liferay.portal.model.LayoutSet;
057    import com.liferay.portal.model.LayoutSetPrototype;
058    import com.liferay.portal.model.MembershipRequest;
059    import com.liferay.portal.model.MembershipRequestConstants;
060    import com.liferay.portal.model.Role;
061    import com.liferay.portal.model.Team;
062    import com.liferay.portal.security.auth.AuthException;
063    import com.liferay.portal.security.auth.PrincipalException;
064    import com.liferay.portal.security.auth.RemoteAuthException;
065    import com.liferay.portal.service.GroupLocalServiceUtil;
066    import com.liferay.portal.service.GroupServiceUtil;
067    import com.liferay.portal.service.LayoutLocalServiceUtil;
068    import com.liferay.portal.service.LayoutSetLocalServiceUtil;
069    import com.liferay.portal.service.LayoutSetPrototypeServiceUtil;
070    import com.liferay.portal.service.LayoutSetServiceUtil;
071    import com.liferay.portal.service.MembershipRequestLocalServiceUtil;
072    import com.liferay.portal.service.MembershipRequestServiceUtil;
073    import com.liferay.portal.service.RoleLocalServiceUtil;
074    import com.liferay.portal.service.ServiceContext;
075    import com.liferay.portal.service.ServiceContextFactory;
076    import com.liferay.portal.service.ServiceContextThreadLocal;
077    import com.liferay.portal.service.TeamLocalServiceUtil;
078    import com.liferay.portal.spring.transaction.TransactionAttributeBuilder;
079    import com.liferay.portal.spring.transaction.TransactionalCallableUtil;
080    import com.liferay.portal.struts.PortletAction;
081    import com.liferay.portal.theme.ThemeDisplay;
082    import com.liferay.portal.util.PortalUtil;
083    import com.liferay.portal.util.PortletKeys;
084    import com.liferay.portal.util.WebKeys;
085    import com.liferay.portlet.asset.AssetCategoryException;
086    import com.liferay.portlet.asset.AssetTagException;
087    import com.liferay.portlet.sites.util.Sites;
088    import com.liferay.portlet.sites.util.SitesUtil;
089    
090    import java.util.ArrayList;
091    import java.util.List;
092    import java.util.concurrent.Callable;
093    
094    import javax.portlet.ActionRequest;
095    import javax.portlet.ActionResponse;
096    import javax.portlet.PortletConfig;
097    import javax.portlet.PortletRequest;
098    import javax.portlet.PortletURL;
099    import javax.portlet.RenderRequest;
100    import javax.portlet.RenderResponse;
101    
102    import org.apache.struts.action.ActionForm;
103    import org.apache.struts.action.ActionForward;
104    import org.apache.struts.action.ActionMapping;
105    
106    import org.springframework.transaction.interceptor.TransactionAttribute;
107    
108    /**
109     * @author Brian Wing Shun Chan
110     * @author Zsolt Berentey
111     * @author Josef Sustacek
112     */
113    public class EditGroupAction extends PortletAction {
114    
115            @Override
116            public void processAction(
117                            ActionMapping actionMapping, ActionForm actionForm,
118                            PortletConfig portletConfig, ActionRequest actionRequest,
119                            ActionResponse actionResponse)
120                    throws Exception {
121    
122                    ThemeDisplay themeDisplay = (ThemeDisplay)actionRequest.getAttribute(
123                            WebKeys.THEME_DISPLAY);
124    
125                    String cmd = ParamUtil.getString(actionRequest, Constants.CMD);
126    
127                    String redirect = ParamUtil.getString(actionRequest, "redirect");
128                    String closeRedirect = ParamUtil.getString(
129                            actionRequest, "closeRedirect");
130    
131                    Group group = getLiveGroup(actionRequest);
132    
133                    try {
134                            if (cmd.equals(Constants.ADD) || cmd.equals(Constants.UPDATE)) {
135                                    String oldFriendlyURL = getGroupFriendlyURL(group);
136                                    String oldStagingFriendlyURL = getStagingGroupFriendlyURL(
137                                            group);
138    
139                                    Callable<Group> groupCallable = new GroupCallable(
140                                            actionRequest);
141    
142                                    group = TransactionalCallableUtil.call(
143                                            _transactionAttribute, groupCallable);
144    
145                                    Layout layout = themeDisplay.getLayout();
146    
147                                    Group layoutGroup = layout.getGroup();
148    
149                                    if (cmd.equals(Constants.ADD) && layoutGroup.isControlPanel()) {
150                                            themeDisplay.setScopeGroupId(group.getGroupId());
151    
152                                            PortletURL siteAdministrationURL =
153                                                    PortalUtil.getSiteAdministrationURL(
154                                                            actionResponse, themeDisplay,
155                                                            PortletKeys.SITE_SETTINGS);
156    
157                                            String controlPanelURL = HttpUtil.setParameter(
158                                                    themeDisplay.getURLControlPanel(), "p_p_id",
159                                                    PortletKeys.SITES_ADMIN);
160    
161                                            controlPanelURL = HttpUtil.setParameter(
162                                                    controlPanelURL, "controlPanelCategory",
163                                                    themeDisplay.getControlPanelCategory());
164    
165                                            siteAdministrationURL.setParameter(
166                                                    "redirect", controlPanelURL);
167    
168                                            redirect = siteAdministrationURL.toString();
169    
170                                            hideDefaultSuccessMessage(actionRequest);
171    
172                                            MultiSessionMessages.add(
173                                                    actionRequest,
174                                                    PortletKeys.SITE_SETTINGS + "requestProcessed");
175                                    }
176                                    else {
177                                            long newRefererPlid = getRefererPlid(
178                                                    group, themeDisplay.getScopeGroupId(), redirect);
179    
180                                            redirect = HttpUtil.setParameter(
181                                                    redirect, "doAsGroupId", group.getGroupId());
182                                            redirect = HttpUtil.setParameter(
183                                                    redirect, "refererPlid", newRefererPlid);
184    
185                                            closeRedirect = updateCloseRedirect(
186                                                    closeRedirect, group, themeDisplay, oldFriendlyURL,
187                                                    oldStagingFriendlyURL);
188                                    }
189                            }
190                            else if (cmd.equals(Constants.DEACTIVATE) ||
191                                             cmd.equals(Constants.RESTORE)) {
192    
193                                    updateActive(actionRequest, cmd);
194                            }
195                            else if (cmd.equals(Constants.DELETE)) {
196                                    deleteGroups(actionRequest);
197                            }
198                            else if (cmd.equals("reset_merge_fail_count_and_merge")) {
199                                    resetMergeFailCountAndMerge(actionRequest);
200                            }
201    
202                            sendRedirect(
203                                    portletConfig, actionRequest, actionResponse, redirect,
204                                    closeRedirect);
205                    }
206                    catch (Exception e) {
207                            if (e instanceof NoSuchGroupException ||
208                                    e instanceof PrincipalException) {
209    
210                                    SessionErrors.add(actionRequest, e.getClass());
211    
212                                    setForward(actionRequest, "portlet.sites_admin.error");
213                            }
214                            else if (e instanceof AssetCategoryException ||
215                                             e instanceof AssetTagException ||
216                                             e instanceof AuthException ||
217                                             e instanceof DuplicateGroupException ||
218                                             e instanceof GroupFriendlyURLException ||
219                                             e instanceof GroupNameException ||
220                                             e instanceof GroupParentException ||
221                                             e instanceof LayoutSetVirtualHostException ||
222                                             e instanceof LocaleException ||
223                                             e instanceof PendingBackgroundTaskException ||
224                                             e instanceof RemoteAuthException ||
225                                             e instanceof RemoteExportException ||
226                                             e instanceof RemoteOptionsException ||
227                                             e instanceof RequiredGroupException ||
228                                             e instanceof SystemException) {
229    
230                                    if (e instanceof RemoteAuthException) {
231                                            SessionErrors.add(actionRequest, AuthException.class, e);
232                                    }
233                                    else {
234                                            SessionErrors.add(actionRequest, e.getClass(), e);
235                                    }
236                            }
237                            else {
238                                    throw e;
239                            }
240                    }
241                    catch (Throwable t) {
242                            _log.error(t);
243    
244                            setForward(actionRequest, "portlet.sites_admin.error");
245                    }
246            }
247    
248            @Override
249            public ActionForward render(
250                            ActionMapping actionMapping, ActionForm actionForm,
251                            PortletConfig portletConfig, RenderRequest renderRequest,
252                            RenderResponse renderResponse)
253                    throws Exception {
254    
255                    try {
256                            ActionUtil.getGroup(renderRequest);
257                    }
258                    catch (Exception e) {
259                            if (e instanceof NoSuchGroupException ||
260                                    e instanceof PrincipalException) {
261    
262                                    SessionErrors.add(renderRequest, e.getClass());
263    
264                                    return actionMapping.findForward("portlet.sites_admin.error");
265                            }
266                            else {
267                                    throw e;
268                            }
269                    }
270    
271                    return actionMapping.findForward(
272                            getForward(renderRequest, "portlet.sites_admin.edit_site"));
273            }
274    
275            protected void deleteGroups(ActionRequest actionRequest) throws Exception {
276                    ThemeDisplay themeDisplay = (ThemeDisplay)actionRequest.getAttribute(
277                            WebKeys.THEME_DISPLAY);
278    
279                    long[] deleteGroupIds = null;
280    
281                    long groupId = ParamUtil.getLong(actionRequest, "groupId");
282    
283                    if (groupId > 0) {
284                            deleteGroupIds = new long[] {groupId};
285                    }
286                    else {
287                            deleteGroupIds = StringUtil.split(
288                                    ParamUtil.getString(actionRequest, "deleteGroupIds"), 0L);
289                    }
290    
291                    for (long deleteGroupId : deleteGroupIds) {
292                            GroupServiceUtil.deleteGroup(deleteGroupId);
293    
294                            LiveUsers.deleteGroup(themeDisplay.getCompanyId(), deleteGroupId);
295                    }
296            }
297    
298            protected String getGroupFriendlyURL(Group liveGroup) {
299                    if (liveGroup != null) {
300                            return liveGroup.getFriendlyURL();
301                    }
302    
303                    return null;
304            }
305    
306            protected Group getLiveGroup(PortletRequest portletRequest)
307                    throws PortalException {
308    
309                    long liveGroupId = ParamUtil.getLong(portletRequest, "liveGroupId");
310    
311                    if (liveGroupId > 0) {
312                            return GroupLocalServiceUtil.getGroup(liveGroupId);
313                    }
314    
315                    return null;
316            }
317    
318            protected long getRefererGroupId(ThemeDisplay themeDisplay)
319                    throws Exception {
320    
321                    long refererGroupId = 0;
322    
323                    try {
324                            Layout refererLayout = LayoutLocalServiceUtil.getLayout(
325                                    themeDisplay.getRefererPlid());
326    
327                            refererGroupId = refererLayout.getGroupId();
328                    }
329                    catch (NoSuchLayoutException nsle) {
330                    }
331    
332                    return refererGroupId;
333            }
334    
335            protected long getRefererPlid(
336                    Group liveGroup, long scopeGroupId, String redirect) {
337    
338                    long refererPlid = GetterUtil.getLong(
339                            HttpUtil.getParameter(redirect, "refererPlid", false));
340    
341                    if ((refererPlid > 0) && liveGroup.hasStagingGroup() &&
342                            (scopeGroupId != liveGroup.getGroupId())) {
343    
344                            Layout firstLayout = LayoutLocalServiceUtil.fetchFirstLayout(
345                                    liveGroup.getGroupId(), false,
346                                    LayoutConstants.DEFAULT_PARENT_LAYOUT_ID);
347    
348                            if (firstLayout == null) {
349                                    firstLayout = LayoutLocalServiceUtil.fetchFirstLayout(
350                                            liveGroup.getGroupId(), true,
351                                            LayoutConstants.DEFAULT_PARENT_LAYOUT_ID);
352                            }
353    
354                            if (firstLayout != null) {
355                                    return firstLayout.getPlid();
356                            }
357                    }
358    
359                    return LayoutConstants.DEFAULT_PLID;
360            }
361    
362            protected List<Role> getRoles(PortletRequest portletRequest)
363                    throws Exception {
364    
365                    List<Role> roles = new ArrayList<Role>();
366    
367                    long[] siteRolesRoleIds = StringUtil.split(
368                            ParamUtil.getString(portletRequest, "siteRolesRoleIds"), 0L);
369    
370                    for (long siteRolesRoleId : siteRolesRoleIds) {
371                            if (siteRolesRoleId == 0) {
372                                    continue;
373                            }
374    
375                            Role role = RoleLocalServiceUtil.getRole(siteRolesRoleId);
376    
377                            roles.add(role);
378                    }
379    
380                    return roles;
381            }
382    
383            protected String getStagingGroupFriendlyURL(Group liveGroup) {
384                    if ((liveGroup != null) && liveGroup.hasStagingGroup()) {
385                            Group stagingGroup = liveGroup.getStagingGroup();
386    
387                            return stagingGroup.getFriendlyURL();
388                    }
389    
390                    return null;
391            }
392    
393            protected List<Team> getTeams(PortletRequest portletRequest)
394                    throws Exception {
395    
396                    List<Team> teams = new ArrayList<Team>();
397    
398                    long[] teamsTeamIds = ArrayUtil.unique(
399                            StringUtil.split(
400                                    ParamUtil.getString(portletRequest, "teamsTeamIds"), 0L));
401    
402                    for (long teamsTeamId : teamsTeamIds) {
403                            if (teamsTeamId == 0) {
404                                    continue;
405                            }
406    
407                            Team team = TeamLocalServiceUtil.getTeam(teamsTeamId);
408    
409                            teams.add(team);
410                    }
411    
412                    return teams;
413            }
414    
415            /**
416             * Resets the number of failed merge attempts for the site template, which
417             * is accessed by retrieving the layout set prototype ID. Once the counter
418             * is reset, the modified site template is merged back into its linked site,
419             * which is accessed by retrieving the group ID and private layout set.
420             *
421             * <p>
422             * If the number of failed merge attempts is not equal to zero after the
423             * merge, an error key is submitted to {@link SessionErrors}.
424             * </p>
425             *
426             * @param  actionRequest the portlet request used to retrieve parameters
427             * @throws Exception if an exception occurred
428             */
429            protected void resetMergeFailCountAndMerge(ActionRequest actionRequest)
430                    throws Exception {
431    
432                    long layoutSetPrototypeId = ParamUtil.getLong(
433                            actionRequest, "layoutSetPrototypeId");
434    
435                    LayoutSetPrototype layoutSetPrototype =
436                            LayoutSetPrototypeServiceUtil.getLayoutSetPrototype(
437                                    layoutSetPrototypeId);
438    
439                    SitesUtil.setMergeFailCount(layoutSetPrototype, 0);
440    
441                    long groupId = ParamUtil.getLong(actionRequest, "groupId");
442                    boolean privateLayoutSet = ParamUtil.getBoolean(
443                            actionRequest, "privateLayoutSet");
444    
445                    LayoutSet layoutSet = LayoutSetLocalServiceUtil.getLayoutSet(
446                            groupId, privateLayoutSet);
447    
448                    SitesUtil.resetPrototype(layoutSet);
449    
450                    Group group = GroupLocalServiceUtil.getGroup(groupId);
451    
452                    SitesUtil.mergeLayoutSetPrototypeLayouts(group, layoutSet);
453    
454                    layoutSetPrototype =
455                            LayoutSetPrototypeServiceUtil.getLayoutSetPrototype(
456                                    layoutSetPrototypeId);
457    
458                    if (SitesUtil.getMergeFailCount(layoutSetPrototype) > 0) {
459                            SessionErrors.add(actionRequest, "resetMergeFailCountAndMerge");
460                    }
461            }
462    
463            protected void updateActive(ActionRequest actionRequest, String cmd)
464                    throws Exception {
465    
466                    ThemeDisplay themeDisplay = (ThemeDisplay)actionRequest.getAttribute(
467                            WebKeys.THEME_DISPLAY);
468    
469                    long groupId = ParamUtil.getLong(actionRequest, "groupId");
470    
471                    if ((groupId == themeDisplay.getDoAsGroupId()) ||
472                            (groupId == themeDisplay.getScopeGroupId()) ||
473                            (groupId == getRefererGroupId(themeDisplay))) {
474    
475                            throw new RequiredGroupException(
476                                    String.valueOf(groupId), RequiredGroupException.CURRENT_GROUP);
477                    }
478    
479                    Group group = GroupServiceUtil.getGroup(groupId);
480    
481                    boolean active = false;
482    
483                    if (cmd.equals(Constants.RESTORE)) {
484                            active = true;
485                    }
486    
487                    ServiceContext serviceContext = ServiceContextFactory.getInstance(
488                            Group.class.getName(), actionRequest);
489    
490                    GroupServiceUtil.updateGroup(
491                            groupId, group.getParentGroupId(), group.getName(),
492                            group.getDescription(), group.getType(), group.isManualMembership(),
493                            group.getMembershipRestriction(), group.getFriendlyURL(), active,
494                            serviceContext);
495            }
496    
497            protected String updateCloseRedirect(
498                            String closeRedirect, Group group, ThemeDisplay themeDisplay,
499                            String oldFriendlyURL, String oldStagingFriendlyURL)
500                    throws PortalException {
501    
502                    if (Validator.isNull(closeRedirect) || (group == null)) {
503                            return closeRedirect;
504                    }
505    
506                    String oldPath = null;
507                    String newPath = null;
508    
509                    if (Validator.isNotNull(oldFriendlyURL)) {
510                            oldPath = oldFriendlyURL;
511                            newPath = group.getFriendlyURL();
512    
513                            if (closeRedirect.contains(oldPath)) {
514                                    closeRedirect = PortalUtil.updateRedirect(
515                                            closeRedirect, oldPath, newPath);
516                            }
517                            else {
518                                    closeRedirect = PortalUtil.getGroupFriendlyURL(
519                                            group, false, themeDisplay);
520                            }
521                    }
522    
523                    if (Validator.isNotNull(oldStagingFriendlyURL)) {
524                            Group stagingGroup = group.getStagingGroup();
525    
526                            if (GroupLocalServiceUtil.fetchGroup(
527                                            stagingGroup.getGroupId()) == null) {
528    
529                                    oldPath = oldStagingFriendlyURL;
530                                    newPath = group.getFriendlyURL();
531                            }
532                            else {
533                                    oldPath = oldStagingFriendlyURL;
534                                    newPath = stagingGroup.getFriendlyURL();
535                            }
536    
537                            if (closeRedirect.contains(oldPath)) {
538                                    closeRedirect = PortalUtil.updateRedirect(
539                                            closeRedirect, oldPath, newPath);
540                            }
541                            else {
542                                    closeRedirect = PortalUtil.getGroupFriendlyURL(
543                                            group, false, themeDisplay);
544                            }
545                    }
546    
547                    return closeRedirect;
548            }
549    
550            protected Group updateGroup(ActionRequest actionRequest) throws Exception {
551                    ThemeDisplay themeDisplay = (ThemeDisplay)actionRequest.getAttribute(
552                            WebKeys.THEME_DISPLAY);
553    
554                    long userId = PortalUtil.getUserId(actionRequest);
555    
556                    long liveGroupId = ParamUtil.getLong(actionRequest, "liveGroupId");
557    
558                    long parentGroupId = ParamUtil.getLong(
559                            actionRequest, "parentGroupSearchContainerPrimaryKeys",
560                            GroupConstants.DEFAULT_PARENT_GROUP_ID);
561                    String name = null;
562                    String description = null;
563                    int type = 0;
564                    String friendlyURL = null;
565                    boolean active = false;
566                    boolean manualMembership = true;
567    
568                    int membershipRestriction =
569                            GroupConstants.DEFAULT_MEMBERSHIP_RESTRICTION;
570    
571                    boolean actionRequestMembershipRestriction = ParamUtil.getBoolean(
572                            actionRequest, "membershipRestriction");
573    
574                    if (actionRequestMembershipRestriction &&
575                            (parentGroupId != GroupConstants.DEFAULT_PARENT_GROUP_ID)) {
576    
577                            membershipRestriction =
578                                    GroupConstants.MEMBERSHIP_RESTRICTION_TO_PARENT_SITE_MEMBERS;
579                    }
580    
581                    ServiceContext serviceContext = ServiceContextFactory.getInstance(
582                            Group.class.getName(), actionRequest);
583    
584                    ServiceContextThreadLocal.pushServiceContext(serviceContext);
585    
586                    Group liveGroup = null;
587    
588                    if (liveGroupId <= 0) {
589    
590                            // Add group
591    
592                            name = ParamUtil.getString(actionRequest, "name");
593                            description = ParamUtil.getString(actionRequest, "description");
594                            type = ParamUtil.getInteger(actionRequest, "type");
595                            friendlyURL = ParamUtil.getString(actionRequest, "friendlyURL");
596                            active = ParamUtil.getBoolean(actionRequest, "active");
597                            manualMembership = ParamUtil.getBoolean(
598                                    actionRequest, "manualMembership");
599    
600                            liveGroup = GroupServiceUtil.addGroup(
601                                    parentGroupId, GroupConstants.DEFAULT_LIVE_GROUP_ID, name,
602                                    description, type, manualMembership, membershipRestriction,
603                                    friendlyURL, true, active, serviceContext);
604    
605                            LiveUsers.joinGroup(
606                                    themeDisplay.getCompanyId(), liveGroup.getGroupId(), userId);
607                    }
608                    else {
609    
610                            // Update group
611    
612                            liveGroup = GroupLocalServiceUtil.getGroup(liveGroupId);
613    
614                            name = ParamUtil.getString(
615                                    actionRequest, "name", liveGroup.getName());
616                            description = ParamUtil.getString(
617                                    actionRequest, "description", liveGroup.getDescription());
618                            type = ParamUtil.getInteger(
619                                    actionRequest, "type", liveGroup.getType());
620                            friendlyURL = ParamUtil.getString(
621                                    actionRequest, "friendlyURL", liveGroup.getFriendlyURL());
622                            active = ParamUtil.getBoolean(
623                                    actionRequest, "active", liveGroup.getActive());
624                            manualMembership = ParamUtil.getBoolean(
625                                    actionRequest, "manualMembership",
626                                    liveGroup.isManualMembership());
627    
628                            liveGroup = GroupServiceUtil.updateGroup(
629                                    liveGroupId, parentGroupId, name, description, type,
630                                    manualMembership, membershipRestriction, friendlyURL, active,
631                                    serviceContext);
632    
633                            if (type == GroupConstants.TYPE_SITE_OPEN) {
634                                    List<MembershipRequest> membershipRequests =
635                                            MembershipRequestLocalServiceUtil.search(
636                                                    liveGroupId, MembershipRequestConstants.STATUS_PENDING,
637                                                    QueryUtil.ALL_POS, QueryUtil.ALL_POS);
638    
639                                    for (MembershipRequest membershipRequest : membershipRequests) {
640                                            MembershipRequestServiceUtil.updateStatus(
641                                                    membershipRequest.getMembershipRequestId(),
642                                                    themeDisplay.translate(
643                                                            "your-membership-has-been-approved"),
644                                                    MembershipRequestConstants.STATUS_APPROVED,
645                                                    serviceContext);
646    
647                                            LiveUsers.joinGroup(
648                                                    themeDisplay.getCompanyId(),
649                                                    membershipRequest.getGroupId(),
650                                                    new long[] {membershipRequest.getUserId()});
651                                    }
652                            }
653                    }
654    
655                    // Settings
656    
657                    UnicodeProperties typeSettingsProperties =
658                            liveGroup.getTypeSettingsProperties();
659    
660                    String customJspServletContextName = ParamUtil.getString(
661                            actionRequest, "customJspServletContextName",
662                            typeSettingsProperties.getProperty("customJspServletContextName"));
663    
664                    typeSettingsProperties.setProperty(
665                            "customJspServletContextName", customJspServletContextName);
666    
667                    typeSettingsProperties.setProperty(
668                            "defaultSiteRoleIds",
669                            ListUtil.toString(
670                                    getRoles(actionRequest), Role.ROLE_ID_ACCESSOR,
671                                    StringPool.COMMA));
672                    typeSettingsProperties.setProperty(
673                            "defaultTeamIds",
674                            ListUtil.toString(
675                                    getTeams(actionRequest), Team.TEAM_ID_ACCESSOR,
676                                    StringPool.COMMA));
677    
678                    String[] analyticsTypes = PrefsPropsUtil.getStringArray(
679                            themeDisplay.getCompanyId(), PropsKeys.ADMIN_ANALYTICS_TYPES,
680                            StringPool.NEW_LINE);
681    
682                    for (String analyticsType : analyticsTypes) {
683                            if (StringUtil.equalsIgnoreCase(analyticsType, "google")) {
684                                    String googleAnalyticsId = ParamUtil.getString(
685                                            actionRequest, "googleAnalyticsId",
686                                            typeSettingsProperties.getProperty("googleAnalyticsId"));
687    
688                                    typeSettingsProperties.setProperty(
689                                            "googleAnalyticsId", googleAnalyticsId);
690                            }
691                            else {
692                                    String analyticsScript = ParamUtil.getString(
693                                            actionRequest, Sites.ANALYTICS_PREFIX + analyticsType,
694                                            typeSettingsProperties.getProperty(analyticsType));
695    
696                                    typeSettingsProperties.setProperty(
697                                            Sites.ANALYTICS_PREFIX + analyticsType, analyticsScript);
698                            }
699                    }
700    
701                    String publicRobots = ParamUtil.getString(
702                            actionRequest, "publicRobots",
703                            liveGroup.getTypeSettingsProperty("false-robots.txt"));
704                    String privateRobots = ParamUtil.getString(
705                            actionRequest, "privateRobots",
706                            liveGroup.getTypeSettingsProperty("true-robots.txt"));
707    
708                    typeSettingsProperties.setProperty("false-robots.txt", publicRobots);
709                    typeSettingsProperties.setProperty("true-robots.txt", privateRobots);
710    
711                    boolean trashEnabled = ParamUtil.getBoolean(
712                            actionRequest, "trashEnabled",
713                            GetterUtil.getBoolean(
714                                    typeSettingsProperties.getProperty("trashEnabled"), true));
715    
716                    typeSettingsProperties.setProperty(
717                            "trashEnabled", String.valueOf(trashEnabled));
718    
719                    int trashEntriesMaxAgeCompany = PrefsPropsUtil.getInteger(
720                            themeDisplay.getCompanyId(), PropsKeys.TRASH_ENTRIES_MAX_AGE);
721    
722                    double trashEntriesMaxAgeGroup = ParamUtil.getDouble(
723                            actionRequest, "trashEntriesMaxAge");
724    
725                    if (trashEntriesMaxAgeGroup > 0) {
726                            trashEntriesMaxAgeGroup *= 1440;
727                    }
728                    else {
729                            trashEntriesMaxAgeGroup = GetterUtil.getInteger(
730                                    typeSettingsProperties.getProperty("trashEntriesMaxAge"),
731                                    trashEntriesMaxAgeCompany);
732                    }
733    
734                    if (trashEntriesMaxAgeGroup != trashEntriesMaxAgeCompany) {
735                            typeSettingsProperties.setProperty(
736                                    "trashEntriesMaxAge",
737                                    String.valueOf(GetterUtil.getInteger(trashEntriesMaxAgeGroup)));
738                    }
739                    else {
740                            typeSettingsProperties.remove("trashEntriesMaxAge");
741                    }
742    
743                    int contentSharingWithChildrenEnabled = ParamUtil.getInteger(
744                            actionRequest, "contentSharingWithChildrenEnabled",
745                            GetterUtil.getInteger(
746                                    typeSettingsProperties.getProperty(
747                                            "contentSharingWithChildrenEnabled"),
748                                    Sites.CONTENT_SHARING_WITH_CHILDREN_DEFAULT_VALUE));
749    
750                    typeSettingsProperties.setProperty(
751                            "contentSharingWithChildrenEnabled",
752                            String.valueOf(contentSharingWithChildrenEnabled));
753    
754                    UnicodeProperties formTypeSettingsProperties =
755                            PropertiesParamUtil.getProperties(
756                                    actionRequest, "TypeSettingsProperties--");
757    
758                    typeSettingsProperties.putAll(formTypeSettingsProperties);
759    
760                    // Virtual hosts
761    
762                    LayoutSet publicLayoutSet = liveGroup.getPublicLayoutSet();
763    
764                    String publicVirtualHost = ParamUtil.getString(
765                            actionRequest, "publicVirtualHost",
766                            publicLayoutSet.getVirtualHostname());
767    
768                    LayoutSetServiceUtil.updateVirtualHost(
769                            liveGroup.getGroupId(), false, publicVirtualHost);
770    
771                    LayoutSet privateLayoutSet = liveGroup.getPrivateLayoutSet();
772    
773                    String privateVirtualHost = ParamUtil.getString(
774                            actionRequest, "privateVirtualHost",
775                            privateLayoutSet.getVirtualHostname());
776    
777                    LayoutSetServiceUtil.updateVirtualHost(
778                            liveGroup.getGroupId(), true, privateVirtualHost);
779    
780                    // Staging
781    
782                    if (liveGroup.hasStagingGroup()) {
783                            Group stagingGroup = liveGroup.getStagingGroup();
784    
785                            friendlyURL = ParamUtil.getString(
786                                    actionRequest, "stagingFriendlyURL",
787                                    stagingGroup.getFriendlyURL());
788    
789                            GroupServiceUtil.updateFriendlyURL(
790                                    stagingGroup.getGroupId(), friendlyURL);
791    
792                            LayoutSet stagingPublicLayoutSet =
793                                    stagingGroup.getPublicLayoutSet();
794    
795                            publicVirtualHost = ParamUtil.getString(
796                                    actionRequest, "stagingPublicVirtualHost",
797                                    stagingPublicLayoutSet.getVirtualHostname());
798    
799                            LayoutSetServiceUtil.updateVirtualHost(
800                                    stagingGroup.getGroupId(), false, publicVirtualHost);
801    
802                            LayoutSet stagingPrivateLayoutSet =
803                                    stagingGroup.getPrivateLayoutSet();
804    
805                            privateVirtualHost = ParamUtil.getString(
806                                    actionRequest, "stagingPrivateVirtualHost",
807                                    stagingPrivateLayoutSet.getVirtualHostname());
808    
809                            LayoutSetServiceUtil.updateVirtualHost(
810                                    stagingGroup.getGroupId(), true, privateVirtualHost);
811    
812                            GroupServiceUtil.updateGroup(
813                                    stagingGroup.getGroupId(), typeSettingsProperties.toString());
814                    }
815    
816                    liveGroup = GroupServiceUtil.updateGroup(
817                            liveGroup.getGroupId(), typeSettingsProperties.toString());
818    
819                    // Layout set prototypes
820    
821                    long privateLayoutSetPrototypeId = ParamUtil.getLong(
822                            actionRequest, "privateLayoutSetPrototypeId");
823                    long publicLayoutSetPrototypeId = ParamUtil.getLong(
824                            actionRequest, "publicLayoutSetPrototypeId");
825    
826                    boolean privateLayoutSetPrototypeLinkEnabled = ParamUtil.getBoolean(
827                            actionRequest, "privateLayoutSetPrototypeLinkEnabled",
828                            privateLayoutSet.isLayoutSetPrototypeLinkEnabled());
829                    boolean publicLayoutSetPrototypeLinkEnabled = ParamUtil.getBoolean(
830                            actionRequest, "publicLayoutSetPrototypeLinkEnabled",
831                            publicLayoutSet.isLayoutSetPrototypeLinkEnabled());
832    
833                    if ((privateLayoutSetPrototypeId == 0) &&
834                            (publicLayoutSetPrototypeId == 0) &&
835                            !privateLayoutSetPrototypeLinkEnabled &&
836                            !publicLayoutSetPrototypeLinkEnabled) {
837    
838                            long layoutSetPrototypeId = ParamUtil.getLong(
839                                    actionRequest, "layoutSetPrototypeId");
840                            int layoutSetVisibility = ParamUtil.getInteger(
841                                    actionRequest, "layoutSetVisibility");
842                            boolean layoutSetPrototypeLinkEnabled = ParamUtil.getBoolean(
843                                    actionRequest, "layoutSetPrototypeLinkEnabled",
844                                    (layoutSetPrototypeId > 0));
845    
846                            if (layoutSetVisibility == _LAYOUT_SET_VISIBILITY_PRIVATE) {
847                                    privateLayoutSetPrototypeId = layoutSetPrototypeId;
848    
849                                    privateLayoutSetPrototypeLinkEnabled =
850                                            layoutSetPrototypeLinkEnabled;
851                            }
852                            else {
853                                    publicLayoutSetPrototypeId = layoutSetPrototypeId;
854    
855                                    publicLayoutSetPrototypeLinkEnabled =
856                                            layoutSetPrototypeLinkEnabled;
857                            }
858                    }
859    
860                    if (!liveGroup.isStaged() || liveGroup.isStagedRemotely()) {
861                            SitesUtil.updateLayoutSetPrototypesLinks(
862                                    liveGroup, publicLayoutSetPrototypeId,
863                                    privateLayoutSetPrototypeId,
864                                    publicLayoutSetPrototypeLinkEnabled,
865                                    privateLayoutSetPrototypeLinkEnabled);
866                    }
867                    else {
868                            SitesUtil.updateLayoutSetPrototypesLinks(
869                                    liveGroup.getStagingGroup(), publicLayoutSetPrototypeId,
870                                    privateLayoutSetPrototypeId,
871                                    publicLayoutSetPrototypeLinkEnabled,
872                                    privateLayoutSetPrototypeLinkEnabled);
873                    }
874    
875                    // Staging
876    
877                    if (!privateLayoutSet.isLayoutSetPrototypeLinkActive() &&
878                            !publicLayoutSet.isLayoutSetPrototypeLinkActive()) {
879    
880                            StagingUtil.updateStaging(actionRequest, liveGroup);
881                    }
882    
883                    return liveGroup;
884            }
885    
886            private static final int _LAYOUT_SET_VISIBILITY_PRIVATE = 1;
887    
888            private static Log _log = LogFactoryUtil.getLog(EditGroupAction.class);
889    
890            private TransactionAttribute _transactionAttribute =
891                    TransactionAttributeBuilder.build(
892                            Propagation.REQUIRED, new Class<?>[]{Exception.class});
893    
894            private class GroupCallable implements Callable<Group> {
895    
896                    @Override
897                    public Group call() throws Exception {
898                            return updateGroup(_actionRequest);
899                    }
900    
901                    private GroupCallable(ActionRequest actionRequest) {
902                            _actionRequest = actionRequest;
903                    }
904    
905                    private ActionRequest _actionRequest;
906    
907            }
908    
909    }