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