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