001    /**
002     * Copyright (c) 2000-2013 Liferay, Inc. All rights reserved.
003     *
004     * This library is free software; you can redistribute it and/or modify it under
005     * the terms of the GNU Lesser General Public License as published by the Free
006     * Software Foundation; either version 2.1 of the License, or (at your option)
007     * any later version.
008     *
009     * This library is distributed in the hope that it will be useful, but WITHOUT
010     * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
011     * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
012     * details.
013     */
014    
015    package com.liferay.portlet.layoutsadmin.action;
016    
017    import com.liferay.portal.DuplicateLockException;
018    import com.liferay.portal.ImageTypeException;
019    import com.liferay.portal.LayoutFriendlyURLException;
020    import com.liferay.portal.LayoutNameException;
021    import com.liferay.portal.LayoutParentLayoutIdException;
022    import com.liferay.portal.LayoutPrototypeException;
023    import com.liferay.portal.LayoutSetVirtualHostException;
024    import com.liferay.portal.LayoutTypeException;
025    import com.liferay.portal.NoSuchGroupException;
026    import com.liferay.portal.NoSuchLayoutException;
027    import com.liferay.portal.RemoteExportException;
028    import com.liferay.portal.RemoteOptionsException;
029    import com.liferay.portal.RequiredLayoutException;
030    import com.liferay.portal.events.EventsProcessorUtil;
031    import com.liferay.portal.kernel.exception.PortalException;
032    import com.liferay.portal.kernel.exception.SystemException;
033    import com.liferay.portal.kernel.log.Log;
034    import com.liferay.portal.kernel.log.LogFactoryUtil;
035    import com.liferay.portal.kernel.servlet.SessionErrors;
036    import com.liferay.portal.kernel.staging.StagingUtil;
037    import com.liferay.portal.kernel.upload.UploadException;
038    import com.liferay.portal.kernel.upload.UploadPortletRequest;
039    import com.liferay.portal.kernel.util.Constants;
040    import com.liferay.portal.kernel.util.FileUtil;
041    import com.liferay.portal.kernel.util.HttpUtil;
042    import com.liferay.portal.kernel.util.LocalizationUtil;
043    import com.liferay.portal.kernel.util.ParamUtil;
044    import com.liferay.portal.kernel.util.PropertiesParamUtil;
045    import com.liferay.portal.kernel.util.PropsKeys;
046    import com.liferay.portal.kernel.util.StringPool;
047    import com.liferay.portal.kernel.util.StringUtil;
048    import com.liferay.portal.kernel.util.ThemeFactoryUtil;
049    import com.liferay.portal.kernel.util.UnicodeProperties;
050    import com.liferay.portal.kernel.util.Validator;
051    import com.liferay.portal.kernel.workflow.WorkflowConstants;
052    import com.liferay.portal.model.ColorScheme;
053    import com.liferay.portal.model.Group;
054    import com.liferay.portal.model.Layout;
055    import com.liferay.portal.model.LayoutConstants;
056    import com.liferay.portal.model.LayoutPrototype;
057    import com.liferay.portal.model.LayoutRevision;
058    import com.liferay.portal.model.LayoutSet;
059    import com.liferay.portal.model.LayoutSetBranch;
060    import com.liferay.portal.model.LayoutTypePortlet;
061    import com.liferay.portal.model.Theme;
062    import com.liferay.portal.model.ThemeSetting;
063    import com.liferay.portal.model.User;
064    import com.liferay.portal.model.impl.ThemeSettingImpl;
065    import com.liferay.portal.security.auth.PrincipalException;
066    import com.liferay.portal.security.permission.ActionKeys;
067    import com.liferay.portal.security.permission.PermissionChecker;
068    import com.liferay.portal.service.LayoutLocalServiceUtil;
069    import com.liferay.portal.service.LayoutPrototypeLocalServiceUtil;
070    import com.liferay.portal.service.LayoutPrototypeServiceUtil;
071    import com.liferay.portal.service.LayoutRevisionLocalServiceUtil;
072    import com.liferay.portal.service.LayoutServiceUtil;
073    import com.liferay.portal.service.LayoutSetBranchLocalServiceUtil;
074    import com.liferay.portal.service.LayoutSetLocalServiceUtil;
075    import com.liferay.portal.service.PortletLocalServiceUtil;
076    import com.liferay.portal.service.ServiceContext;
077    import com.liferay.portal.service.ServiceContextFactory;
078    import com.liferay.portal.service.ThemeLocalServiceUtil;
079    import com.liferay.portal.service.UserLocalServiceUtil;
080    import com.liferay.portal.service.permission.GroupPermissionUtil;
081    import com.liferay.portal.service.permission.LayoutPermissionUtil;
082    import com.liferay.portal.service.permission.LayoutPrototypePermissionUtil;
083    import com.liferay.portal.service.permission.LayoutSetPrototypePermissionUtil;
084    import com.liferay.portal.service.permission.UserPermissionUtil;
085    import com.liferay.portal.struts.PortletAction;
086    import com.liferay.portal.theme.ThemeDisplay;
087    import com.liferay.portal.util.LayoutSettings;
088    import com.liferay.portal.util.PortalUtil;
089    import com.liferay.portal.util.PropsValues;
090    import com.liferay.portal.util.WebKeys;
091    import com.liferay.portlet.mobiledevicerules.model.MDRAction;
092    import com.liferay.portlet.mobiledevicerules.model.MDRRuleGroupInstance;
093    import com.liferay.portlet.mobiledevicerules.service.MDRActionLocalServiceUtil;
094    import com.liferay.portlet.mobiledevicerules.service.MDRActionServiceUtil;
095    import com.liferay.portlet.mobiledevicerules.service.MDRRuleGroupInstanceLocalServiceUtil;
096    import com.liferay.portlet.mobiledevicerules.service.MDRRuleGroupInstanceServiceUtil;
097    import com.liferay.portlet.sites.action.ActionUtil;
098    import com.liferay.portlet.sites.util.SitesUtil;
099    
100    import java.io.IOException;
101    import java.io.InputStream;
102    
103    import java.util.Iterator;
104    import java.util.List;
105    import java.util.Locale;
106    import java.util.Map;
107    import java.util.Set;
108    
109    import javax.portlet.ActionRequest;
110    import javax.portlet.ActionResponse;
111    import javax.portlet.PortletConfig;
112    import javax.portlet.PortletContext;
113    import javax.portlet.PortletRequest;
114    import javax.portlet.PortletRequestDispatcher;
115    import javax.portlet.RenderRequest;
116    import javax.portlet.RenderResponse;
117    import javax.portlet.ResourceRequest;
118    import javax.portlet.ResourceResponse;
119    
120    import javax.servlet.http.HttpServletRequest;
121    import javax.servlet.http.HttpServletResponse;
122    
123    import org.apache.struts.action.ActionForm;
124    import org.apache.struts.action.ActionForward;
125    import org.apache.struts.action.ActionMapping;
126    
127    /**
128     * @author Brian Wing Shun Chan
129     * @author Julio Camarero
130     */
131    public class EditLayoutsAction extends PortletAction {
132    
133            @Override
134            public void processAction(
135                            ActionMapping mapping, ActionForm form, PortletConfig portletConfig,
136                            ActionRequest actionRequest, ActionResponse actionResponse)
137                    throws Exception {
138    
139                    try {
140                            checkPermissions(actionRequest);
141                    }
142                    catch (PrincipalException pe) {
143                            return;
144                    }
145    
146                    ThemeDisplay themeDisplay = (ThemeDisplay)actionRequest.getAttribute(
147                            WebKeys.THEME_DISPLAY);
148    
149                    String cmd = ParamUtil.getString(actionRequest, Constants.CMD);
150    
151                    String redirect = ParamUtil.getString(actionRequest, "redirect");
152                    String closeRedirect = ParamUtil.getString(
153                            actionRequest, "closeRedirect");
154    
155                    try {
156                            Layout layout = null;
157                            String oldFriendlyURL = StringPool.BLANK;
158    
159                            if (cmd.equals(Constants.ADD) || cmd.equals(Constants.UPDATE)) {
160                                    Object[] returnValue = updateLayout(
161                                            actionRequest, actionResponse);
162    
163                                    layout = (Layout)returnValue[0];
164                                    oldFriendlyURL = (String)returnValue[1];
165    
166                                    redirect = updateCloseRedirect(
167                                            redirect, null, layout, oldFriendlyURL);
168                                    closeRedirect = updateCloseRedirect(
169                                            closeRedirect, null, layout, oldFriendlyURL);
170                            }
171                            else if (cmd.equals(Constants.DELETE)) {
172                                    long plid = ParamUtil.getLong(actionRequest, "plid");
173    
174                                    if (plid <= 0) {
175                                            long groupId = ParamUtil.getLong(actionRequest, "groupId");
176                                            boolean privateLayout = ParamUtil.getBoolean(
177                                                    actionRequest, "privateLayout");
178                                            long layoutId = ParamUtil.getLong(
179                                                    actionRequest, "layoutId");
180    
181                                            layout = LayoutLocalServiceUtil.getLayout(
182                                                    groupId, privateLayout, layoutId);
183    
184                                            plid = layout.getPlid();
185                                    }
186    
187                                    Object[] returnValue = SitesUtil.deleteLayout(
188                                            actionRequest, actionResponse);
189    
190                                    Group group = (Group)returnValue[0];
191                                    oldFriendlyURL = (String)returnValue[1];
192                                    long newRefererPlid = (Long)returnValue[2];
193    
194                                    redirect = updateCloseRedirect(
195                                            redirect, group, null, oldFriendlyURL);
196    
197                                    long refererPlid = themeDisplay.getRefererPlid();
198    
199                                    if (plid == refererPlid) {
200                                            redirect = HttpUtil.setParameter(
201                                                    redirect, "refererPlid", newRefererPlid);
202                                    }
203    
204                                    closeRedirect = updateCloseRedirect(
205                                            closeRedirect, group, null, oldFriendlyURL);
206                            }
207                            else if (cmd.equals("copy_from_live")) {
208                                    StagingUtil.copyFromLive(actionRequest);
209                            }
210                            else if (cmd.equals("display_order")) {
211                                    updateDisplayOrder(actionRequest);
212                            }
213                            else if (cmd.equals("delete_layout_revision")) {
214                                    deleteLayoutRevision(actionRequest);
215                            }
216                            else if (cmd.equals("enable")) {
217                                    enableLayout(actionRequest);
218                            }
219                            else if (cmd.equals("publish_to_live")) {
220                                    StagingUtil.publishToLive(actionRequest);
221                            }
222                            else if (cmd.equals("publish_to_remote")) {
223                                    StagingUtil.publishToRemote(actionRequest);
224                            }
225                            else if (cmd.equals("reset_customized_view")) {
226                                    LayoutTypePortlet layoutTypePortlet =
227                                            themeDisplay.getLayoutTypePortlet();
228    
229                                    if ((layoutTypePortlet != null) &&
230                                            layoutTypePortlet.isCustomizable() &&
231                                            layoutTypePortlet.isCustomizedView()) {
232    
233                                            layoutTypePortlet.resetUserPreferences();
234                                    }
235                            }
236                            else if (cmd.equals("reset_merge_fail_count_and_merge")) {
237                                    resetMergeFailCountAndMerge(actionRequest);
238                            }
239                            else if (cmd.equals("reset_prototype")) {
240                                    SitesUtil.resetPrototype(themeDisplay.getLayout());
241                            }
242                            else if (cmd.equals("schedule_copy_from_live")) {
243                                    StagingUtil.scheduleCopyFromLive(actionRequest);
244                            }
245                            else if (cmd.equals("schedule_publish_to_live")) {
246                                    StagingUtil.schedulePublishToLive(actionRequest);
247                            }
248                            else if (cmd.equals("schedule_publish_to_remote")) {
249                                    StagingUtil.schedulePublishToRemote(actionRequest);
250                            }
251                            else if (cmd.equals("select_layout_set_branch")) {
252                                    selectLayoutSetBranch(actionRequest);
253                            }
254                            else if (cmd.equals("select_layout_branch")) {
255                                    selectLayoutBranch(actionRequest);
256                            }
257                            else if (cmd.equals("unschedule_copy_from_live")) {
258                                    StagingUtil.unscheduleCopyFromLive(actionRequest);
259                            }
260                            else if (cmd.equals("unschedule_publish_to_live")) {
261                                    StagingUtil.unschedulePublishToLive(actionRequest);
262                            }
263                            else if (cmd.equals("unschedule_publish_to_remote")) {
264                                    StagingUtil.unschedulePublishToRemote(actionRequest);
265                            }
266                            else if (cmd.equals("update_layout_revision")) {
267                                    updateLayoutRevision(actionRequest, themeDisplay);
268                            }
269    
270                            sendRedirect(
271                                    portletConfig, actionRequest, actionResponse, redirect,
272                                    closeRedirect);
273                    }
274                    catch (Exception e) {
275                            if (e instanceof NoSuchLayoutException ||
276                                    e instanceof PrincipalException) {
277    
278                                    SessionErrors.add(actionRequest, e.getClass());
279    
280                                    setForward(actionRequest, "portlet.layouts_admin.error");
281                            }
282                            else if (e instanceof ImageTypeException ||
283                                             e instanceof LayoutFriendlyURLException ||
284                                             e instanceof LayoutNameException ||
285                                             e instanceof LayoutParentLayoutIdException ||
286                                             e instanceof LayoutSetVirtualHostException ||
287                                             e instanceof LayoutTypeException ||
288                                             e instanceof RequiredLayoutException ||
289                                             e instanceof UploadException) {
290    
291                                    if (e instanceof LayoutFriendlyURLException) {
292                                            SessionErrors.add(
293                                                    actionRequest,
294                                                    LayoutFriendlyURLException.class.getName(), e);
295                                    }
296                                    else {
297                                            SessionErrors.add(actionRequest, e.getClass(), e);
298                                    }
299    
300                                    sendRedirect(
301                                            portletConfig, actionRequest, actionResponse, redirect,
302                                            closeRedirect);
303                            }
304                            else if (e instanceof DuplicateLockException ||
305                                             e instanceof LayoutPrototypeException ||
306                                             e instanceof RemoteExportException ||
307                                             e instanceof RemoteOptionsException ||
308                                             e instanceof SystemException) {
309    
310                                    SessionErrors.add(actionRequest, e.getClass(), e);
311    
312                                    redirect = ParamUtil.getString(actionRequest, "pagesRedirect");
313    
314                                    sendRedirect(
315                                            portletConfig, actionRequest, actionResponse, redirect,
316                                            closeRedirect);
317                            }
318                            else {
319                                    throw e;
320                            }
321                    }
322            }
323    
324            @Override
325            public ActionForward render(
326                            ActionMapping mapping, ActionForm form, PortletConfig portletConfig,
327                            RenderRequest renderRequest, RenderResponse renderResponse)
328                    throws Exception {
329    
330                    try {
331                            checkPermissions(renderRequest);
332                    }
333                    catch (PrincipalException pe) {
334                            SessionErrors.add(
335                                    renderRequest, PrincipalException.class.getName());
336    
337                            return mapping.findForward("portlet.layouts_admin.error");
338                    }
339    
340                    try {
341                            getGroup(renderRequest);
342                    }
343                    catch (Exception e) {
344                            if (e instanceof NoSuchGroupException ||
345                                    e instanceof PrincipalException) {
346    
347                                    SessionErrors.add(renderRequest, e.getClass());
348    
349                                    return mapping.findForward("portlet.layouts_admin.error");
350                            }
351                            else {
352                                    throw e;
353                            }
354                    }
355    
356                    return mapping.findForward(
357                            getForward(renderRequest, "portlet.layouts_admin.edit_layouts"));
358            }
359    
360            @Override
361            public void serveResource(
362                            ActionMapping mapping, ActionForm form, PortletConfig portletConfig,
363                            ResourceRequest resourceRequest, ResourceResponse resourceResponse)
364                    throws Exception {
365    
366                    String cmd = ParamUtil.getString(resourceRequest, Constants.CMD);
367    
368                    PortletContext portletContext = portletConfig.getPortletContext();
369    
370                    PortletRequestDispatcher portletRequestDispatcher = null;
371    
372                    if (cmd.equals(ActionKeys.PUBLISH_STAGING)) {
373                            portletRequestDispatcher = portletContext.getRequestDispatcher(
374                                    "/html/portlet/layouts_admin/scheduled_publishing_events.jsp");
375                    }
376                    else if (cmd.equals(ActionKeys.VIEW_TREE)) {
377                            getGroup(resourceRequest);
378    
379                            portletRequestDispatcher = portletContext.getRequestDispatcher(
380                                    "/html/portlet/layouts_admin/tree_js.jsp");
381                    }
382                    else {
383                            getGroup(resourceRequest);
384    
385                            portletRequestDispatcher = portletContext.getRequestDispatcher(
386                                    "/html/portlet/layouts_admin/view_resources.jsp");
387                    }
388    
389                    portletRequestDispatcher.include(resourceRequest, resourceResponse);
390            }
391    
392            protected void checkPermission(
393                            PermissionChecker permissionChecker, Group group, Layout layout,
394                            long selPlid)
395                    throws PortalException, SystemException {
396    
397                    if (selPlid > 0) {
398                            LayoutPermissionUtil.check(
399                                    permissionChecker, layout, ActionKeys.VIEW);
400                    }
401                    else {
402                            GroupPermissionUtil.check(
403                                    permissionChecker, group, ActionKeys.VIEW);
404                    }
405            }
406    
407            protected void checkPermissions(PortletRequest portletRequest)
408                    throws Exception {
409    
410                    Group group = getGroup(portletRequest);
411    
412                    if (group == null) {
413                            throw new PrincipalException();
414                    }
415    
416                    ThemeDisplay themeDisplay = (ThemeDisplay)portletRequest.getAttribute(
417                            WebKeys.THEME_DISPLAY);
418    
419                    PermissionChecker permissionChecker =
420                            themeDisplay.getPermissionChecker();
421    
422                    Layout layout = themeDisplay.getLayout();
423    
424                    String cmd = ParamUtil.getString(portletRequest, Constants.CMD);
425    
426                    long selPlid = ParamUtil.getLong(portletRequest, "selPlid");
427    
428                    if (selPlid > 0) {
429                            layout = LayoutLocalServiceUtil.getLayout(selPlid);
430                    }
431    
432                    if (cmd.equals(Constants.ADD)) {
433                            long parentPlid = ParamUtil.getLong(portletRequest, "parentPlid");
434    
435                            if (parentPlid == LayoutConstants.DEFAULT_PARENT_LAYOUT_ID) {
436                                    if (!GroupPermissionUtil.contains(
437                                                    permissionChecker, group.getGroupId(),
438                                                    ActionKeys.ADD_LAYOUT)) {
439    
440                                            throw new PrincipalException();
441                                    }
442                            }
443                            else {
444                                    layout = LayoutLocalServiceUtil.getLayout(parentPlid);
445    
446                                    if (!LayoutPermissionUtil.contains(
447                                                    permissionChecker, layout, ActionKeys.ADD_LAYOUT)) {
448    
449                                            throw new PrincipalException();
450                                    }
451                            }
452                    }
453                    else if (cmd.equals(Constants.DELETE)) {
454                            if (!LayoutPermissionUtil.contains(
455                                            permissionChecker, layout, ActionKeys.DELETE)) {
456    
457                                    throw new PrincipalException();
458                            }
459                    }
460                    else if (cmd.equals(Constants.UPDATE)) {
461                            if (group.isCompany()) {
462                                    if (!permissionChecker.isCompanyAdmin()) {
463                                            throw new PrincipalException();
464                                    }
465                            }
466                            else if (group.isLayoutPrototype()) {
467                                    LayoutPrototypePermissionUtil.check(
468                                            permissionChecker, group.getClassPK(), ActionKeys.UPDATE);
469                            }
470                            else if (group.isLayoutSetPrototype()) {
471                                    LayoutSetPrototypePermissionUtil.check(
472                                            permissionChecker, group.getClassPK(), ActionKeys.UPDATE);
473                            }
474                            else if (group.isUser()) {
475                                    long groupUserId = group.getClassPK();
476    
477                                    User groupUser = UserLocalServiceUtil.getUserById(groupUserId);
478    
479                                    long[] organizationIds = groupUser.getOrganizationIds();
480    
481                                    UserPermissionUtil.check(
482                                            permissionChecker, groupUserId, organizationIds,
483                                            ActionKeys.UPDATE);
484                            }
485                            else {
486                                    checkPermission(permissionChecker, group, layout, selPlid);
487                            }
488                    }
489                    else if (cmd.equals("publish_to_live")) {
490                            boolean hasUpdateLayoutPermission = false;
491    
492                            if (layout != null) {
493                                    hasUpdateLayoutPermission = LayoutPermissionUtil.contains(
494                                            permissionChecker, layout, ActionKeys.UPDATE);
495                            }
496    
497                            if (group.isCompany() || group.isSite()) {
498                                    boolean publishToLive = GroupPermissionUtil.contains(
499                                            permissionChecker, group.getGroupId(),
500                                            ActionKeys.PUBLISH_STAGING);
501    
502                                    if (!hasUpdateLayoutPermission && !publishToLive) {
503                                            throw new PrincipalException();
504                                    }
505                            }
506                            else {
507                                    checkPermission(permissionChecker, group, layout, selPlid);
508                            }
509                    }
510                    else if (cmd.equals("reset_customized_view")) {
511                            if (!LayoutPermissionUtil.contains(
512                                            permissionChecker, layout, ActionKeys.CUSTOMIZE)) {
513    
514                                    throw new PrincipalException();
515                            }
516                    }
517                    else {
518                            checkPermission(permissionChecker, group, layout, selPlid);
519                    }
520            }
521    
522            protected void deleteLayoutRevision(ActionRequest actionRequest)
523                    throws Exception {
524    
525                    HttpServletRequest request = PortalUtil.getHttpServletRequest(
526                            actionRequest);
527    
528                    long layoutRevisionId = ParamUtil.getLong(
529                            actionRequest, "layoutRevisionId");
530    
531                    LayoutRevision layoutRevision =
532                            LayoutRevisionLocalServiceUtil.getLayoutRevision(layoutRevisionId);
533    
534                    LayoutRevisionLocalServiceUtil.deleteLayoutRevision(layoutRevision);
535    
536                    boolean updateRecentLayoutRevisionId = ParamUtil.getBoolean(
537                            actionRequest, "updateRecentLayoutRevisionId");
538    
539                    if (updateRecentLayoutRevisionId) {
540                            StagingUtil.setRecentLayoutRevisionId(
541                                    request, layoutRevision.getLayoutSetBranchId(),
542                                    layoutRevision.getPlid(),
543                                    layoutRevision.getParentLayoutRevisionId());
544                    }
545            }
546    
547            protected void deleteThemeSettingsProperties(
548                    UnicodeProperties typeSettingsProperties, String device) {
549    
550                    String keyPrefix = ThemeSettingImpl.namespaceProperty(device);
551    
552                    Set<String> keys = typeSettingsProperties.keySet();
553    
554                    Iterator<String> itr = keys.iterator();
555    
556                    while (itr.hasNext()) {
557                            String key = itr.next();
558    
559                            if (key.startsWith(keyPrefix)) {
560                                    itr.remove();
561                            }
562                    }
563            }
564    
565            protected void enableLayout(ActionRequest actionRequest) throws Exception {
566                    long incompleteLayoutRevisionId = ParamUtil.getLong(
567                            actionRequest, "incompleteLayoutRevisionId");
568    
569                    LayoutRevision incompleteLayoutRevision =
570                            LayoutRevisionLocalServiceUtil.getLayoutRevision(
571                                    incompleteLayoutRevisionId);
572    
573                    long layoutBranchId = ParamUtil.getLong(
574                            actionRequest, "layoutBranchId",
575                            incompleteLayoutRevision.getLayoutBranchId());
576    
577                    ServiceContext serviceContext = ServiceContextFactory.getInstance(
578                            actionRequest);
579    
580                    serviceContext.setWorkflowAction(WorkflowConstants.ACTION_SAVE_DRAFT);
581    
582                    LayoutRevisionLocalServiceUtil.updateLayoutRevision(
583                            serviceContext.getUserId(),
584                            incompleteLayoutRevision.getLayoutRevisionId(), layoutBranchId,
585                            incompleteLayoutRevision.getName(),
586                            incompleteLayoutRevision.getTitle(),
587                            incompleteLayoutRevision.getDescription(),
588                            incompleteLayoutRevision.getKeywords(),
589                            incompleteLayoutRevision.getRobots(),
590                            incompleteLayoutRevision.getTypeSettings(),
591                            incompleteLayoutRevision.getIconImage(),
592                            incompleteLayoutRevision.getIconImageId(),
593                            incompleteLayoutRevision.getThemeId(),
594                            incompleteLayoutRevision.getColorSchemeId(),
595                            incompleteLayoutRevision.getWapThemeId(),
596                            incompleteLayoutRevision.getWapColorSchemeId(),
597                            incompleteLayoutRevision.getCss(), serviceContext);
598            }
599    
600            protected String getColorSchemeId(
601                            long companyId, String themeId, String colorSchemeId,
602                            boolean wapTheme)
603                    throws Exception {
604    
605                    Theme theme = ThemeLocalServiceUtil.getTheme(
606                            companyId, themeId, wapTheme);
607    
608                    if (!theme.hasColorSchemes()) {
609                            colorSchemeId = StringPool.BLANK;
610                    }
611    
612                    if (Validator.isNull(colorSchemeId)) {
613                            ColorScheme colorScheme = ThemeLocalServiceUtil.getColorScheme(
614                                    companyId, themeId, colorSchemeId, wapTheme);
615    
616                            colorSchemeId = colorScheme.getColorSchemeId();
617                    }
618    
619                    return colorSchemeId;
620            }
621    
622            protected Group getGroup(PortletRequest portletRequest) throws Exception {
623                    return ActionUtil.getGroup(portletRequest);
624            }
625    
626            protected byte[] getIconBytes(
627                    UploadPortletRequest uploadPortletRequest, String iconFileName) {
628    
629                    InputStream inputStream = null;
630    
631                    try {
632                            inputStream = uploadPortletRequest.getFileAsStream(iconFileName);
633    
634                            if (inputStream != null) {
635                                    return FileUtil.getBytes(inputStream);
636                            }
637                    }
638                    catch (IOException ioe) {
639                            if (_log.isWarnEnabled()) {
640                                    _log.warn("Unable to retrieve icon", ioe);
641                            }
642                    }
643    
644                    return new byte[0];
645            }
646    
647            protected void inheritMobileRuleGroups(
648                            Layout layout, ServiceContext serviceContext)
649                    throws PortalException, SystemException {
650    
651                    List<MDRRuleGroupInstance> parentMDRRuleGroupInstances =
652                            MDRRuleGroupInstanceLocalServiceUtil.getRuleGroupInstances(
653                                    Layout.class.getName(), layout.getParentPlid());
654    
655                    for (MDRRuleGroupInstance parentMDRRuleGroupInstance :
656                                    parentMDRRuleGroupInstances) {
657    
658                            MDRRuleGroupInstance mdrRuleGroupInstance =
659                                    MDRRuleGroupInstanceServiceUtil.addRuleGroupInstance(
660                                            layout.getGroupId(), Layout.class.getName(),
661                                            layout.getPlid(),
662                                            parentMDRRuleGroupInstance.getRuleGroupId(),
663                                            parentMDRRuleGroupInstance.getPriority(), serviceContext);
664    
665                            List<MDRAction> parentMDRActions =
666                                    MDRActionLocalServiceUtil.getActions(
667                                            parentMDRRuleGroupInstance.getRuleGroupInstanceId());
668    
669                            for (MDRAction mdrAction : parentMDRActions) {
670                                    MDRActionServiceUtil.addAction(
671                                            mdrRuleGroupInstance.getRuleGroupInstanceId(),
672                                            mdrAction.getNameMap(), mdrAction.getDescriptionMap(),
673                                            mdrAction.getType(), mdrAction.getTypeSettings(),
674                                            serviceContext);
675                            }
676                    }
677            }
678    
679            @Override
680            protected boolean isCheckMethodOnProcessAction() {
681                    return _CHECK_METHOD_ON_PROCESS_ACTION;
682            }
683    
684            protected void resetMergeFailCountAndMerge(ActionRequest actionRequest)
685                    throws Exception {
686    
687                    long layoutPrototypeId = ParamUtil.getLong(
688                            actionRequest, "layoutPrototypeId");
689    
690                    LayoutPrototype layoutPrototype =
691                            LayoutPrototypeLocalServiceUtil.getLayoutPrototype(
692                                    layoutPrototypeId);
693    
694                    SitesUtil.setMergeFailCount(layoutPrototype, 0);
695    
696                    long selPlid = ParamUtil.getLong(actionRequest, "selPlid");
697    
698                    Layout selLayout = LayoutLocalServiceUtil.getLayout(selPlid);
699    
700                    SitesUtil.resetPrototype(selLayout);
701    
702                    SitesUtil.mergeLayoutPrototypeLayout(selLayout.getGroup(), selLayout);
703    
704                    layoutPrototype = LayoutPrototypeServiceUtil.getLayoutPrototype(
705                            layoutPrototypeId);
706    
707                    int mergeFailCountAfterMerge = SitesUtil.getMergeFailCount(
708                            layoutPrototype);
709    
710                    if (mergeFailCountAfterMerge > 0) {
711                            SessionErrors.add(actionRequest, "resetMergeFailCountAndMerge");
712                    }
713            }
714    
715            protected void selectLayoutBranch(ActionRequest actionRequest)
716                    throws Exception {
717    
718                    HttpServletRequest request = PortalUtil.getHttpServletRequest(
719                            actionRequest);
720    
721                    ThemeDisplay themeDisplay = (ThemeDisplay)actionRequest.getAttribute(
722                            WebKeys.THEME_DISPLAY);
723    
724                    long layoutSetBranchId = ParamUtil.getLong(
725                            actionRequest, "layoutSetBranchId");
726    
727                    long layoutBranchId = ParamUtil.getLong(
728                            actionRequest, "layoutBranchId");
729    
730                    StagingUtil.setRecentLayoutBranchId(
731                            request, layoutSetBranchId, themeDisplay.getPlid(), layoutBranchId);
732            }
733    
734            protected void selectLayoutSetBranch(ActionRequest actionRequest)
735                    throws Exception {
736    
737                    HttpServletRequest request = PortalUtil.getHttpServletRequest(
738                            actionRequest);
739    
740                    long groupId = ParamUtil.getLong(actionRequest, "groupId");
741                    boolean privateLayout = ParamUtil.getBoolean(
742                            actionRequest, "privateLayout");
743    
744                    LayoutSet layoutSet = LayoutSetLocalServiceUtil.getLayoutSet(
745                            groupId, privateLayout);
746    
747                    long layoutSetBranchId = ParamUtil.getLong(
748                            actionRequest, "layoutSetBranchId");
749    
750                    // Ensure layout set branch exists
751    
752                    LayoutSetBranch layoutSetBranch =
753                            LayoutSetBranchLocalServiceUtil.getLayoutSetBranch(
754                                    layoutSetBranchId);
755    
756                    StagingUtil.setRecentLayoutSetBranchId(
757                            request, layoutSet.getLayoutSetId(),
758                            layoutSetBranch.getLayoutSetBranchId());
759            }
760    
761            protected void setThemeSettingProperties(
762                            ActionRequest actionRequest,
763                            UnicodeProperties typeSettingsProperties, String themeId,
764                            Map<String, ThemeSetting> themeSettings, String device,
765                            String deviceThemeId)
766                    throws PortalException, SystemException {
767    
768                    long groupId = ParamUtil.getLong(actionRequest, "groupId");
769                    boolean privateLayout = ParamUtil.getBoolean(
770                            actionRequest, "privateLayout");
771                    long layoutId = ParamUtil.getLong(actionRequest, "layoutId");
772    
773                    Layout layout = LayoutLocalServiceUtil.getLayout(
774                            groupId, privateLayout, layoutId);
775    
776                    LayoutSet layoutSet = layout.getLayoutSet();
777    
778                    for (String key : themeSettings.keySet()) {
779                            ThemeSetting themeSetting = themeSettings.get(key);
780    
781                            String value = null;
782    
783                            if (!themeId.equals(deviceThemeId)) {
784                                    value = themeSetting.getValue();
785                            }
786                            else {
787                                    String property =
788                                            device + "ThemeSettingsProperties--" + key +
789                                                    StringPool.DOUBLE_DASH;
790    
791                                    value = ParamUtil.getString(actionRequest, property);
792                            }
793    
794                            if (!Validator.equals(
795                                            value, layoutSet.getThemeSetting(key, device))) {
796    
797                                    typeSettingsProperties.setProperty(
798                                            ThemeSettingImpl.namespaceProperty(device, key), value);
799                            }
800                    }
801            }
802    
803            protected String updateCloseRedirect(
804                    String closeRedirect, Group group, Layout layout,
805                    String oldLayoutFriendlyURL) {
806    
807                    if (Validator.isNull(closeRedirect) ||
808                            Validator.isNull(oldLayoutFriendlyURL)) {
809    
810                            return closeRedirect;
811                    }
812    
813                    if (layout != null) {
814                            String oldPath = oldLayoutFriendlyURL;
815                            String newPath = layout.getFriendlyURL();
816    
817                            return PortalUtil.updateRedirect(closeRedirect, oldPath, newPath);
818                    }
819                    else if (group != null) {
820                            String oldPath = group.getFriendlyURL() + oldLayoutFriendlyURL;
821                            String newPath = group.getFriendlyURL();
822    
823                            return PortalUtil.updateRedirect(closeRedirect, oldPath, newPath);
824                    }
825    
826                    return closeRedirect;
827            }
828    
829            protected void updateDisplayOrder(ActionRequest actionRequest)
830                    throws Exception {
831    
832                    long groupId = ParamUtil.getLong(actionRequest, "groupId");
833                    boolean privateLayout = ParamUtil.getBoolean(
834                            actionRequest, "privateLayout");
835                    long parentLayoutId = ParamUtil.getLong(
836                            actionRequest, "parentLayoutId");
837                    long[] layoutIds = StringUtil.split(
838                            ParamUtil.getString(actionRequest, "layoutIds"), 0L);
839    
840                    ServiceContext serviceContext = ServiceContextFactory.getInstance(
841                            actionRequest);
842    
843                    LayoutServiceUtil.setLayouts(
844                            groupId, privateLayout, parentLayoutId, layoutIds, serviceContext);
845            }
846    
847            protected Object[] updateLayout(
848                            ActionRequest actionRequest, ActionResponse actionResponse)
849                    throws Exception {
850    
851                    UploadPortletRequest uploadPortletRequest =
852                            PortalUtil.getUploadPortletRequest(actionRequest);
853    
854                    ThemeDisplay themeDisplay = (ThemeDisplay)actionRequest.getAttribute(
855                            WebKeys.THEME_DISPLAY);
856    
857                    String cmd = ParamUtil.getString(uploadPortletRequest, Constants.CMD);
858    
859                    long groupId = ParamUtil.getLong(actionRequest, "groupId");
860                    long liveGroupId = ParamUtil.getLong(actionRequest, "liveGroupId");
861                    long stagingGroupId = ParamUtil.getLong(
862                            actionRequest, "stagingGroupId");
863                    boolean privateLayout = ParamUtil.getBoolean(
864                            actionRequest, "privateLayout");
865                    long layoutId = ParamUtil.getLong(actionRequest, "layoutId");
866                    long parentLayoutId = ParamUtil.getLong(
867                            uploadPortletRequest, "parentLayoutId");
868                    Map<Locale, String> nameMap = LocalizationUtil.getLocalizationMap(
869                            actionRequest, "name");
870                    Map<Locale, String> titleMap = LocalizationUtil.getLocalizationMap(
871                            actionRequest, "title");
872                    Map<Locale, String> descriptionMap =
873                            LocalizationUtil.getLocalizationMap(actionRequest, "description");
874                    Map<Locale, String> keywordsMap = LocalizationUtil.getLocalizationMap(
875                            actionRequest, "keywords");
876                    Map<Locale, String> robotsMap = LocalizationUtil.getLocalizationMap(
877                            actionRequest, "robots");
878                    String type = ParamUtil.getString(uploadPortletRequest, "type");
879                    boolean hidden = ParamUtil.getBoolean(uploadPortletRequest, "hidden");
880                    String friendlyURL = ParamUtil.getString(
881                            uploadPortletRequest, "friendlyURL");
882                    boolean iconImage = ParamUtil.getBoolean(
883                            uploadPortletRequest, "iconImage");
884                    byte[] iconBytes = getIconBytes(uploadPortletRequest, "iconFileName");
885                    long layoutPrototypeId = ParamUtil.getLong(
886                            uploadPortletRequest, "layoutPrototypeId");
887    
888                    ServiceContext serviceContext = ServiceContextFactory.getInstance(
889                            Layout.class.getName(), actionRequest);
890    
891                    Layout layout = null;
892                    UnicodeProperties layoutTypeSettingsProperties = null;
893                    String oldFriendlyURL = StringPool.BLANK;
894    
895                    if (cmd.equals(Constants.ADD)) {
896    
897                            // Add layout
898    
899                            boolean inheritFromParentLayoutId = ParamUtil.getBoolean(
900                                    uploadPortletRequest, "inheritFromParentLayoutId");
901    
902                            if (inheritFromParentLayoutId && (parentLayoutId > 0)) {
903                                    Layout parentLayout = LayoutLocalServiceUtil.getLayout(
904                                            groupId, privateLayout, parentLayoutId);
905    
906                                    layout = LayoutServiceUtil.addLayout(
907                                            groupId, privateLayout, parentLayoutId, nameMap, titleMap,
908                                            parentLayout.getDescriptionMap(),
909                                            parentLayout.getKeywordsMap(), parentLayout.getRobotsMap(),
910                                            parentLayout.getType(), hidden, friendlyURL,
911                                            serviceContext);
912    
913                                    LayoutServiceUtil.updateLayout(
914                                            layout.getGroupId(), layout.isPrivateLayout(),
915                                            layout.getLayoutId(), parentLayout.getTypeSettings());
916    
917                                    inheritMobileRuleGroups(layout, serviceContext);
918    
919                                    if (parentLayout.isTypePortlet()) {
920                                            ActionUtil.copyPreferences(
921                                                    actionRequest, layout, parentLayout);
922    
923                                            SitesUtil.copyLookAndFeel(layout, parentLayout);
924                                    }
925                            }
926                            else if (layoutPrototypeId > 0) {
927                                    LayoutPrototype layoutPrototype =
928                                            LayoutPrototypeServiceUtil.getLayoutPrototype(
929                                                    layoutPrototypeId);
930    
931                                    String layoutPrototypeLinkEnabled= ParamUtil.getString(
932                                            uploadPortletRequest, "layoutPrototypeLinkEnabled");
933    
934                                    if (Validator.isNotNull(layoutPrototypeLinkEnabled)) {
935                                            serviceContext.setAttribute(
936                                                    "layoutPrototypeLinkEnabled",
937                                                    layoutPrototypeLinkEnabled);
938                                    }
939    
940                                    serviceContext.setAttribute(
941                                            "layoutPrototypeUuid", layoutPrototype.getUuid());
942    
943                                    layout = LayoutServiceUtil.addLayout(
944                                            groupId, privateLayout, parentLayoutId, nameMap, titleMap,
945                                            descriptionMap, keywordsMap, robotsMap,
946                                            LayoutConstants.TYPE_PORTLET, hidden, friendlyURL,
947                                            serviceContext);
948                            }
949                            else {
950                                    layout = LayoutServiceUtil.addLayout(
951                                            groupId, privateLayout, parentLayoutId, nameMap, titleMap,
952                                            descriptionMap, keywordsMap, robotsMap, type, hidden,
953                                            friendlyURL, serviceContext);
954                            }
955    
956                            layoutTypeSettingsProperties = layout.getTypeSettingsProperties();
957                    }
958                    else {
959    
960                            // Update layout
961    
962                            layout = LayoutLocalServiceUtil.getLayout(
963                                    groupId, privateLayout, layoutId);
964    
965                            oldFriendlyURL = layout.getFriendlyURL();
966    
967                            layout = LayoutServiceUtil.updateLayout(
968                                    groupId, privateLayout, layoutId, layout.getParentLayoutId(),
969                                    nameMap, titleMap, descriptionMap, keywordsMap, robotsMap, type,
970                                    hidden, friendlyURL, Boolean.valueOf(iconImage), iconBytes,
971                                    serviceContext);
972    
973                            layoutTypeSettingsProperties = layout.getTypeSettingsProperties();
974    
975                            if (oldFriendlyURL.equals(layout.getFriendlyURL())) {
976                                    oldFriendlyURL = StringPool.BLANK;
977                            }
978    
979                            UnicodeProperties formTypeSettingsProperties =
980                                    PropertiesParamUtil.getProperties(
981                                            actionRequest, "TypeSettingsProperties--");
982    
983                            if (type.equals(LayoutConstants.TYPE_PORTLET)) {
984                                    LayoutTypePortlet layoutTypePortlet =
985                                            (LayoutTypePortlet)layout.getLayoutType();
986    
987                                    String layoutTemplateId = ParamUtil.getString(
988                                            uploadPortletRequest, "layoutTemplateId",
989                                            PropsValues.DEFAULT_LAYOUT_TEMPLATE_ID);
990    
991                                    layoutTypePortlet.setLayoutTemplateId(
992                                            themeDisplay.getUserId(), layoutTemplateId);
993    
994                                    long copyLayoutId = ParamUtil.getLong(
995                                            uploadPortletRequest, "copyLayoutId");
996    
997                                    if ((copyLayoutId > 0) &&
998                                            (copyLayoutId != layout.getLayoutId())) {
999    
1000                                            try {
1001                                                    Layout copyLayout = LayoutLocalServiceUtil.getLayout(
1002                                                            groupId, privateLayout, copyLayoutId);
1003    
1004                                                    if (copyLayout.isTypePortlet()) {
1005                                                            layoutTypeSettingsProperties =
1006                                                                    copyLayout.getTypeSettingsProperties();
1007    
1008                                                            ActionUtil.copyPreferences(
1009                                                                    actionRequest, layout, copyLayout);
1010    
1011                                                            SitesUtil.copyLookAndFeel(layout, copyLayout);
1012                                                    }
1013                                            }
1014                                            catch (NoSuchLayoutException nsle) {
1015                                            }
1016                                    }
1017                                    else {
1018                                            layoutTypeSettingsProperties.putAll(
1019                                                    formTypeSettingsProperties);
1020    
1021                                            LayoutServiceUtil.updateLayout(
1022                                                    groupId, privateLayout, layoutId,
1023                                                    layout.getTypeSettings());
1024                                    }
1025                            }
1026                            else {
1027                                    layout.setTypeSettingsProperties(formTypeSettingsProperties);
1028    
1029                                    layoutTypeSettingsProperties.putAll(
1030                                            layout.getTypeSettingsProperties());
1031    
1032                                    LayoutServiceUtil.updateLayout(
1033                                            groupId, privateLayout, layoutId, layout.getTypeSettings());
1034                            }
1035    
1036                            String[] removeEmbeddedPortletIds = ParamUtil.getParameterValues(
1037                                    actionRequest, "removeEmbeddedPortletIds");
1038    
1039                            if (removeEmbeddedPortletIds.length > 0) {
1040                                    PortletLocalServiceUtil.deletePortlets(
1041                                            themeDisplay.getCompanyId(), removeEmbeddedPortletIds,
1042                                            layout.getPlid());
1043                            }
1044    
1045                            LayoutSettings layoutSettings = LayoutSettings.getInstance(layout);
1046    
1047                            HttpServletResponse response = PortalUtil.getHttpServletResponse(
1048                                    actionResponse);
1049    
1050                            EventsProcessorUtil.process(
1051                                    PropsKeys.LAYOUT_CONFIGURATION_ACTION_UPDATE,
1052                                    layoutSettings.getConfigurationActionUpdate(),
1053                                    uploadPortletRequest, response);
1054                    }
1055    
1056                    updateLookAndFeel(
1057                            actionRequest, themeDisplay.getCompanyId(), liveGroupId,
1058                            stagingGroupId, privateLayout, layout.getLayoutId(),
1059                            layoutTypeSettingsProperties, layout.getThemeId());
1060    
1061                    return new Object[] {layout, oldFriendlyURL};
1062            }
1063    
1064            protected void updateLayoutRevision(
1065                            ActionRequest actionRequest, ThemeDisplay themeDisplay)
1066                    throws Exception {
1067    
1068                    long layoutRevisionId = ParamUtil.getLong(
1069                            actionRequest, "layoutRevisionId");
1070    
1071                    LayoutRevision layoutRevision =
1072                            LayoutRevisionLocalServiceUtil.getLayoutRevision(layoutRevisionId);
1073    
1074                    ServiceContext serviceContext = ServiceContextFactory.getInstance(
1075                            actionRequest);
1076    
1077                    LayoutRevision enableLayoutRevision =
1078                            LayoutRevisionLocalServiceUtil.updateLayoutRevision(
1079                                    serviceContext.getUserId(), layoutRevisionId,
1080                                    layoutRevision.getLayoutBranchId(), layoutRevision.getName(),
1081                                    layoutRevision.getTitle(), layoutRevision.getDescription(),
1082                                    layoutRevision.getKeywords(), layoutRevision.getRobots(),
1083                                    layoutRevision.getTypeSettings(), layoutRevision.getIconImage(),
1084                                    layoutRevision.getIconImageId(), layoutRevision.getThemeId(),
1085                                    layoutRevision.getColorSchemeId(),
1086                                    layoutRevision.getWapThemeId(),
1087                                    layoutRevision.getWapColorSchemeId(), layoutRevision.getCss(),
1088                                    serviceContext);
1089    
1090                    if (layoutRevision.getStatus() == WorkflowConstants.STATUS_INCOMPLETE) {
1091                            LayoutRevision lastLayoutRevision =
1092                                    LayoutRevisionLocalServiceUtil.fetchLastLayoutRevision(
1093                                            enableLayoutRevision.getPlid(), true);
1094    
1095                            if (lastLayoutRevision != null) {
1096                                    LayoutRevision newLayoutRevision =
1097                                            LayoutRevisionLocalServiceUtil.addLayoutRevision(
1098                                                    serviceContext.getUserId(),
1099                                                    layoutRevision.getLayoutSetBranchId(),
1100                                                    layoutRevision.getLayoutBranchId(),
1101                                                    enableLayoutRevision.getLayoutRevisionId(), false,
1102                                                    layoutRevision.getPlid(),
1103                                                    lastLayoutRevision.getLayoutRevisionId(),
1104                                                    lastLayoutRevision.isPrivateLayout(),
1105                                                    lastLayoutRevision.getName(),
1106                                                    lastLayoutRevision.getTitle(),
1107                                                    lastLayoutRevision.getDescription(),
1108                                                    lastLayoutRevision.getKeywords(),
1109                                                    lastLayoutRevision.getRobots(),
1110                                                    lastLayoutRevision.getTypeSettings(),
1111                                                    lastLayoutRevision.isIconImage(),
1112                                                    lastLayoutRevision.getIconImageId(),
1113                                                    lastLayoutRevision.getThemeId(),
1114                                                    lastLayoutRevision.getColorSchemeId(),
1115                                                    lastLayoutRevision.getWapThemeId(),
1116                                                    lastLayoutRevision.getWapColorSchemeId(),
1117                                                    lastLayoutRevision.getCss(), serviceContext);
1118    
1119                                    StagingUtil.setRecentLayoutRevisionId(
1120                                            themeDisplay.getUser(),
1121                                            newLayoutRevision.getLayoutSetBranchId(),
1122                                            newLayoutRevision.getPlid(),
1123                                            newLayoutRevision.getLayoutRevisionId());
1124                            }
1125                    }
1126            }
1127    
1128            protected void updateLookAndFeel(
1129                            ActionRequest actionRequest, long companyId, long liveGroupId,
1130                            long stagingGroupId, boolean privateLayout, long layoutId,
1131                            UnicodeProperties typeSettingsProperties, String themeId)
1132                    throws Exception {
1133    
1134                    String[] devices = StringUtil.split(
1135                            ParamUtil.getString(actionRequest, "devices"));
1136    
1137                    for (String device : devices) {
1138                            String deviceThemeId = ParamUtil.getString(
1139                                    actionRequest, device + "ThemeId");
1140                            String deviceColorSchemeId = ParamUtil.getString(
1141                                    actionRequest, device + "ColorSchemeId");
1142                            String deviceCss = ParamUtil.getString(
1143                                    actionRequest, device + "Css");
1144                            boolean deviceWapTheme = device.equals("wap");
1145    
1146                            boolean deviceInheritLookAndFeel = ParamUtil.getBoolean(
1147                                    actionRequest, device + "InheritLookAndFeel");
1148    
1149                            if (deviceInheritLookAndFeel) {
1150                                    deviceThemeId = ThemeFactoryUtil.getDefaultRegularThemeId(
1151                                            companyId);
1152                                    deviceColorSchemeId = StringPool.BLANK;
1153    
1154                                    deleteThemeSettingsProperties(typeSettingsProperties, device);
1155                            }
1156                            else if (Validator.isNotNull(deviceThemeId)) {
1157                                    deviceColorSchemeId = getColorSchemeId(
1158                                            companyId, deviceThemeId, deviceColorSchemeId,
1159                                            deviceWapTheme);
1160    
1161                                    updateThemeSettingsProperties(
1162                                            actionRequest, companyId, typeSettingsProperties, themeId,
1163                                            device, deviceThemeId, deviceWapTheme);
1164                            }
1165    
1166                            long groupId = liveGroupId;
1167    
1168                            if (stagingGroupId > 0) {
1169                                    groupId = stagingGroupId;
1170                            }
1171    
1172                            LayoutServiceUtil.updateLayout(
1173                                    groupId, privateLayout, layoutId,
1174                                    typeSettingsProperties.toString());
1175    
1176                            LayoutServiceUtil.updateLookAndFeel(
1177                                    groupId, privateLayout, layoutId, deviceThemeId,
1178                                    deviceColorSchemeId, deviceCss, deviceWapTheme);
1179                    }
1180            }
1181    
1182            protected UnicodeProperties updateThemeSettingsProperties(
1183                            ActionRequest actionRequest, long companyId,
1184                            UnicodeProperties typeSettingsProperties, String themeId,
1185                            String device, String deviceThemeId, boolean wapTheme)
1186                    throws Exception {
1187    
1188                    Theme theme = ThemeLocalServiceUtil.getTheme(
1189                            companyId, deviceThemeId, wapTheme);
1190    
1191                    deleteThemeSettingsProperties(typeSettingsProperties, device);
1192    
1193                    Map<String, ThemeSetting> themeSettings =
1194                            theme.getConfigurableSettings();
1195    
1196                    if (themeSettings.isEmpty()) {
1197                            return typeSettingsProperties;
1198                    }
1199    
1200                    setThemeSettingProperties(
1201                            actionRequest, typeSettingsProperties, themeId, themeSettings,
1202                            device, deviceThemeId);
1203    
1204                    return typeSettingsProperties;
1205            }
1206    
1207            private static final boolean _CHECK_METHOD_ON_PROCESS_ACTION = false;
1208    
1209            private static Log _log = LogFactoryUtil.getLog(EditLayoutsAction.class);
1210    
1211    }