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