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