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