1   /**
2    * Copyright (c) 2000-2010 Liferay, Inc. All rights reserved.
3    *
4    * This library is free software; you can redistribute it and/or modify it under
5    * the terms of the GNU Lesser General Public License as published by the Free
6    * Software Foundation; either version 2.1 of the License, or (at your option)
7    * any later version.
8    *
9    * This library is distributed in the hope that it will be useful, but WITHOUT
10   * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
11   * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
12   * details.
13   */
14  
15  package com.liferay.portlet.communities.action;
16  
17  import com.liferay.portal.ImageTypeException;
18  import com.liferay.portal.LayoutFriendlyURLException;
19  import com.liferay.portal.LayoutHiddenException;
20  import com.liferay.portal.LayoutNameException;
21  import com.liferay.portal.LayoutParentLayoutIdException;
22  import com.liferay.portal.LayoutSetVirtualHostException;
23  import com.liferay.portal.LayoutTypeException;
24  import com.liferay.portal.NoSuchGroupException;
25  import com.liferay.portal.NoSuchLayoutException;
26  import com.liferay.portal.RemoteExportException;
27  import com.liferay.portal.RequiredLayoutException;
28  import com.liferay.portal.events.EventsProcessorUtil;
29  import com.liferay.portal.kernel.servlet.SessionErrors;
30  import com.liferay.portal.kernel.upload.UploadPortletRequest;
31  import com.liferay.portal.kernel.util.Constants;
32  import com.liferay.portal.kernel.util.FileUtil;
33  import com.liferay.portal.kernel.util.HttpUtil;
34  import com.liferay.portal.kernel.util.LocalizationUtil;
35  import com.liferay.portal.kernel.util.ParamUtil;
36  import com.liferay.portal.kernel.util.PropertiesParamUtil;
37  import com.liferay.portal.kernel.util.PropsKeys;
38  import com.liferay.portal.kernel.util.StringBundler;
39  import com.liferay.portal.kernel.util.StringPool;
40  import com.liferay.portal.kernel.util.StringUtil;
41  import com.liferay.portal.kernel.util.UnicodeProperties;
42  import com.liferay.portal.kernel.util.Validator;
43  import com.liferay.portal.model.ColorScheme;
44  import com.liferay.portal.model.Group;
45  import com.liferay.portal.model.Layout;
46  import com.liferay.portal.model.LayoutConstants;
47  import com.liferay.portal.model.LayoutPrototype;
48  import com.liferay.portal.model.User;
49  import com.liferay.portal.security.auth.PrincipalException;
50  import com.liferay.portal.security.permission.ActionKeys;
51  import com.liferay.portal.security.permission.PermissionChecker;
52  import com.liferay.portal.service.GroupLocalServiceUtil;
53  import com.liferay.portal.service.GroupServiceUtil;
54  import com.liferay.portal.service.LayoutLocalServiceUtil;
55  import com.liferay.portal.service.LayoutPrototypeServiceUtil;
56  import com.liferay.portal.service.LayoutServiceUtil;
57  import com.liferay.portal.service.LayoutSetServiceUtil;
58  import com.liferay.portal.service.ServiceContext;
59  import com.liferay.portal.service.ServiceContextFactory;
60  import com.liferay.portal.service.ThemeLocalServiceUtil;
61  import com.liferay.portal.service.UserLocalServiceUtil;
62  import com.liferay.portal.service.permission.GroupPermissionUtil;
63  import com.liferay.portal.service.permission.LayoutPermissionUtil;
64  import com.liferay.portal.service.permission.LayoutPrototypePermissionUtil;
65  import com.liferay.portal.service.permission.LayoutSetPrototypePermissionUtil;
66  import com.liferay.portal.service.permission.OrganizationPermissionUtil;
67  import com.liferay.portal.service.permission.UserPermissionUtil;
68  import com.liferay.portal.struts.PortletAction;
69  import com.liferay.portal.theme.ThemeDisplay;
70  import com.liferay.portal.util.LayoutSettings;
71  import com.liferay.portal.util.PortalUtil;
72  import com.liferay.portal.util.PropsValues;
73  import com.liferay.portal.util.WebKeys;
74  import com.liferay.portlet.communities.util.CommunitiesUtil;
75  import com.liferay.portlet.communities.util.StagingUtil;
76  import com.liferay.portlet.tasks.NoSuchProposalException;
77  import com.liferay.util.servlet.UploadException;
78  
79  import java.io.File;
80  
81  import java.util.Locale;
82  import java.util.Map;
83  
84  import javax.portlet.ActionRequest;
85  import javax.portlet.ActionResponse;
86  import javax.portlet.PortletConfig;
87  import javax.portlet.PortletRequest;
88  import javax.portlet.PortletRequestDispatcher;
89  import javax.portlet.RenderRequest;
90  import javax.portlet.RenderResponse;
91  import javax.portlet.ResourceRequest;
92  import javax.portlet.ResourceResponse;
93  
94  import javax.servlet.http.HttpServletResponse;
95  
96  import org.apache.struts.action.ActionForm;
97  import org.apache.struts.action.ActionForward;
98  import org.apache.struts.action.ActionMapping;
99  
100 /**
101  * <a href="EditPagesAction.java.html"><b><i>View Source</i></b></a>
102  *
103  * @author Brian Wing Shun Chan
104  */
105 public class EditPagesAction extends PortletAction {
106 
107     public void processAction(
108             ActionMapping mapping, ActionForm form, PortletConfig portletConfig,
109             ActionRequest actionRequest, ActionResponse actionResponse)
110         throws Exception {
111 
112         try {
113             checkPermissions(actionRequest);
114         }
115         catch (PrincipalException pe) {
116             return;
117         }
118 
119         String cmd = ParamUtil.getString(actionRequest, Constants.CMD);
120 
121         try {
122             Layout layout = null;
123             String oldFriendlyURL = StringPool.BLANK;
124 
125             if (cmd.equals(Constants.ADD) || cmd.equals(Constants.UPDATE)) {
126                 Object[] returnValue = updateLayout(
127                     actionRequest, actionResponse);
128 
129                 layout = (Layout)returnValue[0];
130                 oldFriendlyURL = (String)returnValue[1];
131             }
132             else if (cmd.equals(Constants.DELETE)) {
133                 CommunitiesUtil.deleteLayout(actionRequest, actionResponse);
134             }
135             else if (cmd.equals("copy_from_live")) {
136                 StagingUtil.copyFromLive(actionRequest);
137             }
138             else if (cmd.equals("display_order")) {
139                 updateDisplayOrder(actionRequest);
140             }
141             else if (cmd.equals("logo")) {
142                 updateLogo(actionRequest);
143             }
144             else if (cmd.equals("look_and_feel")) {
145                 updateLookAndFeel(actionRequest);
146             }
147             else if (cmd.equals("merge_pages")) {
148                 updateMergePages(actionRequest);
149             }
150             else if (cmd.equals("monitoring")) {
151                 updateMonitoring(actionRequest);
152             }
153             else if (cmd.equals("publish_to_live")) {
154                 StagingUtil.publishToLive(actionRequest);
155             }
156             else if (cmd.equals("publish_to_remote")) {
157                 StagingUtil.publishToRemote(actionRequest);
158             }
159             else if (cmd.equals("schedule_copy_from_live")) {
160                 StagingUtil.scheduleCopyFromLive(actionRequest);
161             }
162             else if (cmd.equals("schedule_publish_to_live")) {
163                 StagingUtil.schedulePublishToLive(actionRequest);
164             }
165             else if (cmd.equals("schedule_publish_to_remote")) {
166                 StagingUtil.schedulePublishToRemote(actionRequest);
167             }
168             else if (cmd.equals("staging")) {
169                 StagingUtil.updateStaging(actionRequest);
170             }
171             else if (cmd.equals("unschedule_copy_from_live")) {
172                 StagingUtil.unscheduleCopyFromLive(actionRequest);
173             }
174             else if (cmd.equals("unschedule_publish_to_live")) {
175                 StagingUtil.unschedulePublishToLive(actionRequest);
176             }
177             else if (cmd.equals("unschedule_publish_to_remote")) {
178                 StagingUtil.unschedulePublishToRemote(actionRequest);
179             }
180             else if (cmd.equals("virtual_host")) {
181                 updateVirtualHost(actionRequest);
182             }
183             else if (cmd.equals("workflow")) {
184                 updateWorkflow(actionRequest);
185             }
186 
187             String redirect = ParamUtil.getString(
188                 actionRequest, "pagesRedirect");
189 
190             if ((layout != null) && Validator.isNotNull(oldFriendlyURL)) {
191                 ThemeDisplay themeDisplay =
192                     (ThemeDisplay)actionRequest.getAttribute(
193                         WebKeys.THEME_DISPLAY);
194 
195                 if (layout.getPlid() == themeDisplay.getPlid()) {
196                     Group group = layout.getGroup();
197 
198                     String oldPath = group.getFriendlyURL() + oldFriendlyURL;
199                     String newPath =
200                         group.getFriendlyURL() + layout.getFriendlyURL();
201 
202                     redirect = StringUtil.replace(redirect, oldPath, newPath);
203 
204                     redirect = StringUtil.replace(
205                         redirect, HttpUtil.encodeURL(oldPath),
206                         HttpUtil.encodeURL(newPath));
207                 }
208             }
209 
210             sendRedirect(actionRequest, actionResponse, redirect);
211         }
212         catch (Exception e) {
213             if (e instanceof NoSuchLayoutException ||
214                 e instanceof NoSuchProposalException ||
215                 e instanceof PrincipalException) {
216 
217                 SessionErrors.add(actionRequest, e.getClass().getName());
218 
219                 setForward(actionRequest, "portlet.communities.error");
220             }
221             else if (e instanceof RemoteExportException) {
222                 SessionErrors.add(actionRequest, e.getClass().getName(), e);
223 
224                 String redirect = ParamUtil.getString(
225                     actionRequest, "pagesRedirect");
226 
227                 sendRedirect(actionRequest, actionResponse, redirect);
228             }
229             else if (e instanceof ImageTypeException ||
230                      e instanceof LayoutFriendlyURLException ||
231                      e instanceof LayoutHiddenException ||
232                      e instanceof LayoutNameException ||
233                      e instanceof LayoutParentLayoutIdException ||
234                      e instanceof LayoutSetVirtualHostException ||
235                      e instanceof LayoutTypeException ||
236                      e instanceof RequiredLayoutException ||
237                      e instanceof UploadException) {
238 
239                 if (e instanceof LayoutFriendlyURLException) {
240                     SessionErrors.add(
241                         actionRequest,
242                         LayoutFriendlyURLException.class.getName(), e);
243                 }
244                 else {
245                     SessionErrors.add(actionRequest, e.getClass().getName(), e);
246                 }
247             }
248             else {
249                 throw e;
250             }
251         }
252     }
253 
254     public ActionForward render(
255             ActionMapping mapping, ActionForm form, PortletConfig portletConfig,
256             RenderRequest renderRequest, RenderResponse renderResponse)
257         throws Exception {
258 
259         try {
260             checkPermissions(renderRequest);
261         }
262         catch (PrincipalException pe) {
263             SessionErrors.add(
264                 renderRequest, PrincipalException.class.getName());
265 
266             return mapping.findForward("portlet.communities.error");
267         }
268 
269         try {
270             ActionUtil.getGroup(renderRequest);
271         }
272         catch (Exception e) {
273             if (e instanceof NoSuchGroupException ||
274                 e instanceof PrincipalException) {
275 
276                 SessionErrors.add(renderRequest, e.getClass().getName());
277 
278                 return mapping.findForward("portlet.communities.error");
279             }
280             else {
281                 throw e;
282             }
283         }
284 
285         return mapping.findForward(
286             getForward(renderRequest, "portlet.communities.edit_pages"));
287     }
288 
289     public void serveResource(
290             ActionMapping mapping, ActionForm form, PortletConfig portletConfig,
291             ResourceRequest resourceRequest, ResourceResponse resourceResponse)
292         throws Exception {
293 
294         PortletRequestDispatcher portletRequestDispatcher =
295             portletConfig.getPortletContext().getRequestDispatcher(
296                 "/html/portlet/communities/scheduled_publishing_events.jsp");
297 
298         portletRequestDispatcher.include(resourceRequest, resourceResponse);
299     }
300 
301     protected void checkPermissions(PortletRequest portletRequest)
302         throws Exception {
303 
304         // LEP-850
305 
306         ThemeDisplay themeDisplay = (ThemeDisplay)portletRequest.getAttribute(
307             WebKeys.THEME_DISPLAY);
308 
309         PermissionChecker permissionChecker =
310             themeDisplay.getPermissionChecker();
311 
312         long groupId = ParamUtil.getLong(portletRequest, "groupId");
313 
314         Group group = GroupLocalServiceUtil.getGroup(groupId);
315 
316         Layout layout = themeDisplay.getLayout();
317 
318         boolean hasUpdateLayoutPermission = false;
319 
320         if (layout != null) {
321             hasUpdateLayoutPermission = LayoutPermissionUtil.contains(
322                 permissionChecker, layout.getGroupId(),
323                 layout.isPrivateLayout(), layout.getLayoutId(),
324                 ActionKeys.UPDATE);
325         }
326 
327         if (group.isCommunity()) {
328             String cmd = ParamUtil.getString(portletRequest, Constants.CMD);
329 
330             boolean publishToLive =
331                 GroupPermissionUtil.contains(
332                     permissionChecker, group.getGroupId(),
333                     ActionKeys.PUBLISH_STAGING) &&
334                 cmd.equals("publish_to_live");
335 
336             if (!GroupPermissionUtil.contains(
337                     permissionChecker, group.getGroupId(),
338                     ActionKeys.APPROVE_PROPOSAL) &&
339                 !GroupPermissionUtil.contains(
340                     permissionChecker, group.getGroupId(),
341                     ActionKeys.MANAGE_LAYOUTS) &&
342                 !hasUpdateLayoutPermission && !publishToLive) {
343 
344                 throw new PrincipalException();
345             }
346         }
347         else if (group.isCompany()) {
348             if (!permissionChecker.isCompanyAdmin()) {
349                 throw new PrincipalException();
350             }
351         }
352         else if (group.isLayoutPrototype()) {
353             LayoutPrototypePermissionUtil.check(
354                 permissionChecker, group.getClassPK(), ActionKeys.UPDATE);
355         }
356         else if (group.isLayoutSetPrototype()) {
357             LayoutSetPrototypePermissionUtil.check(
358                 permissionChecker, group.getClassPK(), ActionKeys.UPDATE);
359         }
360         else if (group.isOrganization()) {
361             long organizationId = group.getClassPK();
362 
363             String cmd = ParamUtil.getString(portletRequest, Constants.CMD);
364 
365             boolean publishToLive =
366                 OrganizationPermissionUtil.contains(
367                     permissionChecker, organizationId,
368                     ActionKeys.PUBLISH_STAGING) &&
369                 cmd.equals("publish_to_live");
370 
371             if (!OrganizationPermissionUtil.contains(
372                     permissionChecker, organizationId,
373                     ActionKeys.APPROVE_PROPOSAL) &&
374                 !OrganizationPermissionUtil.contains(
375                     permissionChecker, organizationId,
376                     ActionKeys.MANAGE_LAYOUTS) &&
377                 !hasUpdateLayoutPermission && !publishToLive) {
378 
379                 throw new PrincipalException();
380             }
381         }
382         else if (group.isUser()) {
383             long groupUserId = group.getClassPK();
384 
385             User groupUser = UserLocalServiceUtil.getUserById(groupUserId);
386 
387             long[] organizationIds = groupUser.getOrganizationIds();
388 
389             UserPermissionUtil.check(
390                 permissionChecker, groupUserId, organizationIds,
391                 ActionKeys.UPDATE);
392 
393             if (!PropsValues.LAYOUT_USER_PRIVATE_LAYOUTS_MODIFIABLE &&
394                  !PropsValues.LAYOUT_USER_PUBLIC_LAYOUTS_MODIFIABLE) {
395 
396                 throw new PrincipalException();
397             }
398         }
399     }
400 
401     protected UnicodeProperties getTypeSettingsProperties(
402         ActionRequest actionRequest) {
403 
404         return PropertiesParamUtil.getProperties(
405             actionRequest, "TypeSettingsProperties--");
406     }
407 
408     protected void updateDisplayOrder(ActionRequest actionRequest)
409         throws Exception {
410 
411         long groupId = ParamUtil.getLong(actionRequest, "groupId");
412         boolean privateLayout = ParamUtil.getBoolean(
413             actionRequest, "privateLayout");
414         long parentLayoutId = ParamUtil.getLong(
415             actionRequest, "parentLayoutId");
416         long[] layoutIds = StringUtil.split(
417             ParamUtil.getString(actionRequest, "layoutIds"), 0L);
418 
419         LayoutServiceUtil.setLayouts(
420             groupId, privateLayout, parentLayoutId, layoutIds);
421     }
422 
423     protected Object[] updateLayout(
424             ActionRequest actionRequest, ActionResponse actionResponse)
425         throws Exception {
426 
427         UploadPortletRequest uploadRequest = PortalUtil.getUploadPortletRequest(
428             actionRequest);
429 
430         String cmd = ParamUtil.getString(uploadRequest, Constants.CMD);
431 
432         long groupId = ParamUtil.getLong(actionRequest, "groupId");
433         boolean privateLayout = ParamUtil.getBoolean(
434             actionRequest, "privateLayout");
435         long layoutId = ParamUtil.getLong(actionRequest, "layoutId");
436         long parentLayoutId = ParamUtil.getLong(
437             uploadRequest, "parentLayoutId");
438         String description = ParamUtil.getString(uploadRequest, "description");
439         String type = ParamUtil.getString(uploadRequest, "type");
440         boolean hidden = ParamUtil.getBoolean(uploadRequest, "hidden");
441         String friendlyURL = ParamUtil.getString(uploadRequest, "friendlyURL");
442         boolean iconImage = ParamUtil.getBoolean(uploadRequest, "iconImage");
443         byte[] iconBytes = FileUtil.getBytes(
444             uploadRequest.getFile("iconFileName"));
445         long layoutPrototypeId = ParamUtil.getLong(
446             uploadRequest, "layoutPrototypeId");
447 
448         boolean inheritFromParentLayoutId = ParamUtil.getBoolean(
449             uploadRequest, "inheritFromParentLayoutId");
450 
451         long copyLayoutId = ParamUtil.getLong(uploadRequest, "copyLayoutId");
452 
453         Map<Locale, String> localeNamesMap =
454             LocalizationUtil.getLocalizationMap(actionRequest, "name");
455         Map<Locale, String> localeTitlesMap =
456             LocalizationUtil.getLocalizationMap(actionRequest, "title");
457 
458         ServiceContext serviceContext = ServiceContextFactory.getInstance(
459             Layout.class.getName(), actionRequest);
460 
461         Layout layout = null;
462         String oldFriendlyURL = StringPool.BLANK;
463 
464         if (cmd.equals(Constants.ADD)) {
465 
466             // Add layout
467 
468             if (inheritFromParentLayoutId && (parentLayoutId > 0)) {
469                 Layout parentLayout = LayoutLocalServiceUtil.getLayout(
470                     groupId, privateLayout, parentLayoutId);
471 
472                 layout = LayoutServiceUtil.addLayout(
473                     groupId, privateLayout, parentLayoutId, localeNamesMap,
474                     localeTitlesMap, description, parentLayout.getType(),
475                     parentLayout.isHidden(), friendlyURL,
476                     serviceContext);
477 
478                 LayoutServiceUtil.updateLayout(
479                     layout.getGroupId(), layout.isPrivateLayout(),
480                     layout.getLayoutId(), parentLayout.getTypeSettings());
481 
482                 if (parentLayout.isTypePortlet()) {
483                     ActionUtil.copyPreferences(
484                         actionRequest, layout, parentLayout);
485                 }
486             }
487             else if (layoutPrototypeId > 0) {
488                 LayoutPrototype layoutPrototype =
489                     LayoutPrototypeServiceUtil.getLayoutPrototype(
490                         layoutPrototypeId);
491 
492                 Layout layoutPrototypeLayout = layoutPrototype.getLayout();
493 
494                 layout = LayoutServiceUtil.addLayout(
495                     groupId, privateLayout, parentLayoutId, localeNamesMap,
496                     localeTitlesMap, description, LayoutConstants.TYPE_PORTLET,
497                     false, friendlyURL, serviceContext);
498 
499                 LayoutServiceUtil.updateLayout(
500                     layout.getGroupId(), layout.isPrivateLayout(),
501                     layout.getLayoutId(),
502                     layoutPrototypeLayout.getTypeSettings());
503 
504                 ActionUtil.copyPreferences(
505                     actionRequest, layout, layoutPrototypeLayout);
506             }
507             else {
508                 LayoutServiceUtil.addLayout(
509                     groupId, privateLayout, parentLayoutId, localeNamesMap,
510                     localeTitlesMap, description, type, hidden, friendlyURL,
511                     serviceContext);
512             }
513         }
514         else {
515 
516             // Update layout
517 
518             layout = LayoutLocalServiceUtil.getLayout(
519                 groupId, privateLayout, layoutId);
520 
521             oldFriendlyURL = layout.getFriendlyURL();
522 
523             layout = LayoutServiceUtil.updateLayout(
524                 groupId, privateLayout, layoutId, layout.getParentLayoutId(),
525                 localeNamesMap, localeTitlesMap, description, type, hidden,
526                 friendlyURL, Boolean.valueOf(iconImage), iconBytes,
527                 serviceContext);
528 
529             if (oldFriendlyURL.equals(layout.getFriendlyURL())) {
530                 oldFriendlyURL = StringPool.BLANK;
531             }
532 
533             UnicodeProperties formTypeSettingsProperties =
534                 getTypeSettingsProperties(actionRequest);
535 
536             if (type.equals(LayoutConstants.TYPE_PORTLET)) {
537                 if ((copyLayoutId > 0) &&
538                     (copyLayoutId != layout.getLayoutId())) {
539 
540                     try {
541                         Layout copyLayout = LayoutLocalServiceUtil.getLayout(
542                             groupId, privateLayout, copyLayoutId);
543 
544                         if (copyLayout.isTypePortlet()) {
545                             LayoutServiceUtil.updateLayout(
546                                 groupId, privateLayout, layoutId,
547                                 copyLayout.getTypeSettings());
548 
549                             ActionUtil.copyPreferences(
550                                 actionRequest, layout, copyLayout);
551                         }
552                     }
553                     catch (NoSuchLayoutException nsle) {
554                     }
555                 }
556                 else {
557                     UnicodeProperties layoutTypeSettingsProperties =
558                         layout.getTypeSettingsProperties();
559 
560                     for (String property: formTypeSettingsProperties.keySet()) {
561                         layoutTypeSettingsProperties.setProperty(
562                             property,
563                             formTypeSettingsProperties.getProperty(property));
564                     }
565 
566                     LayoutServiceUtil.updateLayout(
567                         groupId, privateLayout, layoutId,
568                         layout.getTypeSettings());
569                 }
570             }
571             else {
572                 layout.setTypeSettingsProperties(formTypeSettingsProperties);
573 
574                 LayoutServiceUtil.updateLayout(
575                     groupId, privateLayout, layoutId, layout.getTypeSettings());
576             }
577 
578             HttpServletResponse response = PortalUtil.getHttpServletResponse(
579                 actionResponse);
580 
581             LayoutSettings layoutSettings = LayoutSettings.getInstance(layout);
582 
583             EventsProcessorUtil.process(
584                 PropsKeys.LAYOUT_CONFIGURATION_ACTION_UPDATE,
585                 layoutSettings.getConfigurationActionUpdate(), uploadRequest,
586                 response);
587         }
588 
589         return new Object[] {layout, oldFriendlyURL};
590     }
591 
592     protected void updateLogo(ActionRequest actionRequest) throws Exception {
593         UploadPortletRequest uploadRequest = PortalUtil.getUploadPortletRequest(
594             actionRequest);
595 
596         long liveGroupId = ParamUtil.getLong(actionRequest, "liveGroupId");
597         long stagingGroupId = ParamUtil.getLong(
598             actionRequest, "stagingGroupId");
599 
600         boolean privateLayout = ParamUtil.getBoolean(
601             actionRequest, "privateLayout");
602         boolean logo = ParamUtil.getBoolean(actionRequest, "logo");
603 
604         File file = uploadRequest.getFile("logoFileName");
605         byte[] bytes = FileUtil.getBytes(file);
606 
607         if (logo && ((bytes == null) || (bytes.length == 0))) {
608             throw new UploadException();
609         }
610 
611         LayoutSetServiceUtil.updateLogo(liveGroupId, privateLayout, logo, file);
612 
613         if (stagingGroupId > 0) {
614             LayoutSetServiceUtil.updateLogo(
615                 stagingGroupId, privateLayout, logo, file);
616         }
617     }
618 
619     protected void updateLookAndFeel(ActionRequest actionRequest)
620         throws Exception {
621 
622         ThemeDisplay themeDisplay = (ThemeDisplay)actionRequest.getAttribute(
623             WebKeys.THEME_DISPLAY);
624 
625         long companyId = themeDisplay.getCompanyId();
626 
627         long liveGroupId = ParamUtil.getLong(actionRequest, "liveGroupId");
628         long stagingGroupId = ParamUtil.getLong(
629             actionRequest, "stagingGroupId");
630 
631         boolean privateLayout = ParamUtil.getBoolean(
632             actionRequest, "privateLayout");
633         long layoutId = ParamUtil.getLong(actionRequest, "layoutId");
634         String themeId = ParamUtil.getString(actionRequest, "themeId");
635         String colorSchemeId = ParamUtil.getString(
636             actionRequest, "colorSchemeId");
637         String css = ParamUtil.getString(actionRequest, "css");
638         boolean wapTheme = ParamUtil.getBoolean(actionRequest, "wapTheme");
639 
640         if (stagingGroupId > 0) {
641             updateLookAndFeel(
642                 companyId, stagingGroupId, privateLayout, layoutId, themeId,
643                 colorSchemeId, css, wapTheme);
644         }
645         else {
646             updateLookAndFeel(
647                 companyId, liveGroupId, privateLayout, layoutId, themeId,
648                 colorSchemeId, css, wapTheme);
649         }
650     }
651 
652     protected void updateLookAndFeel(
653             long companyId, long groupId, boolean privateLayout, long layoutId,
654             String themeId, String colorSchemeId, String css, boolean wapTheme)
655         throws Exception {
656 
657         if (Validator.isNotNull(themeId) && Validator.isNull(colorSchemeId)) {
658             ColorScheme colorScheme = ThemeLocalServiceUtil.getColorScheme(
659                 companyId, themeId, colorSchemeId, wapTheme);
660 
661             colorSchemeId = colorScheme.getColorSchemeId();
662         }
663 
664         if (layoutId <= 0) {
665             LayoutSetServiceUtil.updateLookAndFeel(
666                 groupId, privateLayout, themeId, colorSchemeId, css, wapTheme);
667         }
668         else {
669             LayoutServiceUtil.updateLookAndFeel(
670                 groupId, privateLayout, layoutId, themeId, colorSchemeId, css,
671                 wapTheme);
672         }
673     }
674 
675     protected void updateMergePages(ActionRequest actionRequest)
676         throws Exception {
677 
678         long liveGroupId = ParamUtil.getLong(actionRequest, "liveGroupId");
679 
680         boolean mergeGuestPublicPages = ParamUtil.getBoolean(
681             actionRequest, "mergeGuestPublicPages");
682 
683         Group liveGroup = GroupLocalServiceUtil.getGroup(liveGroupId);
684 
685         UnicodeProperties props = liveGroup.getTypeSettingsProperties();
686 
687         props.setProperty(
688             "mergeGuestPublicPages", String.valueOf(mergeGuestPublicPages));
689 
690         GroupServiceUtil.updateGroup(liveGroupId, liveGroup.getTypeSettings());
691     }
692 
693     protected void updateMonitoring(ActionRequest actionRequest)
694         throws Exception {
695 
696         long liveGroupId = ParamUtil.getLong(actionRequest, "liveGroupId");
697 
698         String googleAnalyticsId = ParamUtil.getString(
699             actionRequest, "googleAnalyticsId");
700 
701         Group liveGroup = GroupLocalServiceUtil.getGroup(liveGroupId);
702 
703         UnicodeProperties props = liveGroup.getTypeSettingsProperties();
704 
705         props.setProperty("googleAnalyticsId", googleAnalyticsId);
706 
707         GroupServiceUtil.updateGroup(liveGroupId, liveGroup.getTypeSettings());
708     }
709 
710     protected void updateVirtualHost(ActionRequest actionRequest)
711         throws Exception {
712 
713         long liveGroupId = ParamUtil.getLong(actionRequest, "liveGroupId");
714 
715         String publicVirtualHost = ParamUtil.getString(
716             actionRequest, "publicVirtualHost");
717         String privateVirtualHost = ParamUtil.getString(
718             actionRequest, "privateVirtualHost");
719         String friendlyURL = ParamUtil.getString(actionRequest, "friendlyURL");
720 
721         LayoutSetServiceUtil.updateVirtualHost(
722             liveGroupId, false, publicVirtualHost);
723 
724         LayoutSetServiceUtil.updateVirtualHost(
725             liveGroupId, true, privateVirtualHost);
726 
727         GroupServiceUtil.updateFriendlyURL(liveGroupId, friendlyURL);
728 
729         Group liveGroup = GroupServiceUtil.getGroup(liveGroupId);
730 
731         if (liveGroup.hasStagingGroup()) {
732             Group stagingGroup = liveGroup.getStagingGroup();
733 
734             publicVirtualHost = ParamUtil.getString(
735                 actionRequest, "stagingPublicVirtualHost");
736             privateVirtualHost = ParamUtil.getString(
737                 actionRequest, "stagingPrivateVirtualHost");
738             friendlyURL = ParamUtil.getString(
739                 actionRequest, "stagingFriendlyURL");
740 
741             LayoutSetServiceUtil.updateVirtualHost(
742                 stagingGroup.getGroupId(), false, publicVirtualHost);
743 
744             LayoutSetServiceUtil.updateVirtualHost(
745                 stagingGroup.getGroupId(), true, privateVirtualHost);
746 
747             GroupServiceUtil.updateFriendlyURL(
748                 stagingGroup.getGroupId(), friendlyURL);
749         }
750     }
751 
752     protected void updateWorkflow(ActionRequest actionRequest)
753         throws Exception {
754 
755         long liveGroupId = ParamUtil.getLong(actionRequest, "liveGroupId");
756 
757         boolean workflowEnabled = ParamUtil.getBoolean(
758             actionRequest, "workflowEnabled");
759         int workflowStages = ParamUtil.getInteger(
760             actionRequest, "workflowStages");
761 
762         String workflowRoleNames;
763 
764         if (workflowStages == 0) {
765             workflowRoleNames = StringPool.BLANK;
766         }
767         else {
768             StringBundler sb = new StringBundler(workflowStages * 2 - 1);
769 
770             for (int i = 1; i <= workflowStages; i++) {
771                 String workflowRoleName = ParamUtil.getString(
772                     actionRequest, "workflowRoleName_" + i);
773 
774                 sb.append(workflowRoleName);
775 
776                 if ((i + 1) <= workflowStages) {
777                     sb.append(",");
778                 }
779             }
780 
781             workflowRoleNames = sb.toString();
782         }
783 
784         GroupServiceUtil.updateWorkflow(
785             liveGroupId, workflowEnabled, workflowStages, workflowRoleNames);
786     }
787 
788 }