1   /**
2    * Copyright (c) 2000-2008 Liferay, Inc. All rights reserved.
3    *
4    * Permission is hereby granted, free of charge, to any person obtaining a copy
5    * of this software and associated documentation files (the "Software"), to deal
6    * in the Software without restriction, including without limitation the rights
7    * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8    * copies of the Software, and to permit persons to whom the Software is
9    * furnished to do so, subject to the following conditions:
10   *
11   * The above copyright notice and this permission notice shall be included in
12   * all copies or substantial portions of the Software.
13   *
14   * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15   * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16   * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17   * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18   * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19   * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20   * SOFTWARE.
21   */
22  
23  package com.liferay.portlet.communities.action;
24  
25  import com.germinus.easyconf.Filter;
26  
27  import com.liferay.portal.LayoutFriendlyURLException;
28  import com.liferay.portal.LayoutHiddenException;
29  import com.liferay.portal.LayoutNameException;
30  import com.liferay.portal.LayoutParentLayoutIdException;
31  import com.liferay.portal.LayoutSetVirtualHostException;
32  import com.liferay.portal.LayoutTypeException;
33  import com.liferay.portal.NoSuchGroupException;
34  import com.liferay.portal.NoSuchLayoutException;
35  import com.liferay.portal.PortalException;
36  import com.liferay.portal.RequiredLayoutException;
37  import com.liferay.portal.SystemException;
38  import com.liferay.portal.events.EventsProcessor;
39  import com.liferay.portal.kernel.language.LanguageUtil;
40  import com.liferay.portal.kernel.lar.PortletDataHandlerKeys;
41  import com.liferay.portal.kernel.lar.UserIdStrategy;
42  import com.liferay.portal.kernel.security.permission.ActionKeys;
43  import com.liferay.portal.kernel.security.permission.PermissionChecker;
44  import com.liferay.portal.kernel.util.Constants;
45  import com.liferay.portal.kernel.util.LocaleUtil;
46  import com.liferay.portal.kernel.util.ParamUtil;
47  import com.liferay.portal.kernel.util.StringUtil;
48  import com.liferay.portal.kernel.util.Validator;
49  import com.liferay.portal.model.ColorScheme;
50  import com.liferay.portal.model.Group;
51  import com.liferay.portal.model.Layout;
52  import com.liferay.portal.model.LayoutTypePortlet;
53  import com.liferay.portal.model.PortletPreferencesIds;
54  import com.liferay.portal.model.User;
55  import com.liferay.portal.model.impl.GroupImpl;
56  import com.liferay.portal.model.impl.LayoutImpl;
57  import com.liferay.portal.security.auth.PrincipalException;
58  import com.liferay.portal.service.GroupLocalServiceUtil;
59  import com.liferay.portal.service.GroupServiceUtil;
60  import com.liferay.portal.service.LayoutLocalServiceUtil;
61  import com.liferay.portal.service.LayoutServiceUtil;
62  import com.liferay.portal.service.LayoutSetServiceUtil;
63  import com.liferay.portal.service.PortletPreferencesLocalServiceUtil;
64  import com.liferay.portal.service.UserLocalServiceUtil;
65  import com.liferay.portal.service.impl.ThemeLocalUtil;
66  import com.liferay.portal.service.permission.GroupPermissionUtil;
67  import com.liferay.portal.service.permission.LayoutPermissionUtil;
68  import com.liferay.portal.service.permission.OrganizationPermissionUtil;
69  import com.liferay.portal.service.permission.UserPermissionUtil;
70  import com.liferay.portal.struts.PortletAction;
71  import com.liferay.portal.theme.ThemeDisplay;
72  import com.liferay.portal.util.PortalUtil;
73  import com.liferay.portal.util.PortletKeys;
74  import com.liferay.portal.util.PropsUtil;
75  import com.liferay.portal.util.PropsValues;
76  import com.liferay.portal.util.WebKeys;
77  import com.liferay.portlet.ActionRequestImpl;
78  import com.liferay.portlet.ActionResponseImpl;
79  import com.liferay.portlet.PortletPreferencesFactoryUtil;
80  import com.liferay.portlet.communities.form.PageForm;
81  import com.liferay.util.FileUtil;
82  import com.liferay.util.servlet.SessionErrors;
83  import com.liferay.util.servlet.UploadException;
84  import com.liferay.util.servlet.UploadPortletRequest;
85  
86  import java.io.ByteArrayInputStream;
87  import java.io.File;
88  
89  import java.util.ArrayList;
90  import java.util.HashMap;
91  import java.util.Iterator;
92  import java.util.LinkedHashMap;
93  import java.util.List;
94  import java.util.Locale;
95  import java.util.Map.Entry;
96  import java.util.Map;
97  import java.util.Properties;
98  
99  import javax.portlet.ActionRequest;
100 import javax.portlet.ActionResponse;
101 import javax.portlet.PortletConfig;
102 import javax.portlet.PortletPreferences;
103 import javax.portlet.PortletRequest;
104 import javax.portlet.RenderRequest;
105 import javax.portlet.RenderResponse;
106 
107 import javax.servlet.http.HttpServletRequest;
108 import javax.servlet.http.HttpServletResponse;
109 
110 import org.apache.commons.logging.Log;
111 import org.apache.commons.logging.LogFactory;
112 import org.apache.struts.action.ActionForm;
113 import org.apache.struts.action.ActionForward;
114 import org.apache.struts.action.ActionMapping;
115 
116 /**
117  * <a href="EditPagesAction.java.html"><b><i>View Source</i></b></a>
118  *
119  * @author Brian Wing Shun Chan
120  *
121  */
122 public class EditPagesAction extends PortletAction {
123 
124     public void processAction(
125             ActionMapping mapping, ActionForm form, PortletConfig config,
126             ActionRequest req, ActionResponse res)
127         throws Exception {
128 
129         try {
130             checkPermissions(req);
131         }
132         catch (PrincipalException pe) {
133             return;
134         }
135 
136         PageForm pageForm = (PageForm)form;
137 
138         String cmd = ParamUtil.getString(req, Constants.CMD);
139 
140         try {
141             if (cmd.equals(Constants.ADD) || cmd.equals(Constants.UPDATE)) {
142                 updateLayout(pageForm, req, res);
143             }
144             else if (cmd.equals(Constants.DELETE)) {
145                 deleteLayout(req, res);
146             }
147             else if (cmd.equals("copy_from_live")) {
148                 copyFromLive(req);
149             }
150             else if (cmd.equals("display_order")) {
151                 updateDisplayOrder(req);
152             }
153             else if (cmd.equals("logo")) {
154                 updateLogo(req);
155             }
156             else if (cmd.equals("look_and_feel")) {
157                 updateLookAndFeel(req);
158             }
159             else if (cmd.equals("merge_pages")) {
160                 updateMergePages(req);
161             }
162             else if (cmd.equals("monitoring")) {
163                 updateMonitoring(req);
164             }
165             else if (cmd.equals("publish_to_live")) {
166                 publishToLive(req);
167             }
168             else if (cmd.equals("update_staging_state")) {
169                 updateStagingState(req);
170             }
171             else if (cmd.equals("virtual_host")) {
172                 updateVirtualHost(req);
173             }
174 
175             String redirect = ParamUtil.getString(req, "pagesRedirect");
176 
177             sendRedirect(req, res, redirect);
178         }
179         catch (Exception e) {
180             if (e instanceof NoSuchLayoutException ||
181                 e instanceof PrincipalException) {
182 
183                 SessionErrors.add(req, e.getClass().getName());
184 
185                 setForward(req, "portlet.communities.error");
186             }
187             else if (e instanceof LayoutFriendlyURLException ||
188                      e instanceof LayoutHiddenException ||
189                      e instanceof LayoutNameException ||
190                      e instanceof LayoutParentLayoutIdException ||
191                      e instanceof LayoutSetVirtualHostException ||
192                      e instanceof LayoutTypeException ||
193                      e instanceof RequiredLayoutException ||
194                      e instanceof UploadException) {
195 
196                 if (e instanceof LayoutFriendlyURLException) {
197                     SessionErrors.add(
198                         req, LayoutFriendlyURLException.class.getName(), e);
199                 }
200                 else {
201                     SessionErrors.add(req, e.getClass().getName(), e);
202                 }
203             }
204             else {
205                 throw e;
206             }
207         }
208     }
209 
210     public ActionForward render(
211             ActionMapping mapping, ActionForm form, PortletConfig config,
212             RenderRequest req, RenderResponse res)
213         throws Exception {
214 
215         try {
216             checkPermissions(req);
217         }
218         catch (PrincipalException pe) {
219             SessionErrors.add(req, PrincipalException.class.getName());
220 
221             return mapping.findForward("portlet.communities.error");
222         }
223 
224         try {
225             ActionUtil.getGroup(req);
226         }
227         catch (Exception e) {
228             if (e instanceof NoSuchGroupException ||
229                 e instanceof PrincipalException) {
230 
231                 SessionErrors.add(req, e.getClass().getName());
232 
233                 return mapping.findForward("portlet.communities.error");
234             }
235             else {
236                 throw e;
237             }
238         }
239 
240         return mapping.findForward(
241             getForward(req, "portlet.communities.edit_pages"));
242     }
243 
244     protected void checkPermissions(PortletRequest req) throws Exception {
245 
246         // LEP-850
247 
248         ThemeDisplay themeDisplay =
249             (ThemeDisplay)req.getAttribute(WebKeys.THEME_DISPLAY);
250 
251         PermissionChecker permissionChecker =
252             themeDisplay.getPermissionChecker();
253 
254         long groupId = ParamUtil.getLong(req, "groupId");
255 
256         Group group = GroupLocalServiceUtil.getGroup(groupId);
257 
258         if (group.isCommunity()) {
259             GroupPermissionUtil.check(
260                 permissionChecker, group.getGroupId(),
261                 ActionKeys.MANAGE_LAYOUTS);
262         }
263         else if (group.isOrganization()) {
264             long organizationId = group.getClassPK();
265 
266             OrganizationPermissionUtil.check(
267                 permissionChecker, organizationId, ActionKeys.MANAGE_LAYOUTS);
268         }
269         else if (group.isUser()) {
270             long groupUserId = group.getClassPK();
271 
272             User groupUser = UserLocalServiceUtil.getUserById(groupUserId);
273 
274             long[] organizationIds = groupUser.getOrganizationIds();
275 
276             UserPermissionUtil.check(
277                 permissionChecker, groupUserId, organizationIds,
278                 ActionKeys.UPDATE);
279 
280             if (!groupUser.isLayoutsRequired()) {
281                 throw new PrincipalException();
282             }
283         }
284     }
285 
286     protected void copyFromLive(ActionRequest req) throws Exception {
287         String tabs2 = ParamUtil.getString(req, "tabs2");
288 
289         long stagingGroupId = ParamUtil.getLong(req, "stagingGroupId");
290 
291         Group stagingGroup = GroupLocalServiceUtil.getGroup(stagingGroupId);
292 
293         boolean privateLayout = true;
294 
295         if (tabs2.equals("public")) {
296             privateLayout = false;
297         }
298 
299         if (_log.isDebugEnabled()) {
300             _log.debug(
301                 "Copying live to staging for group " +
302                     stagingGroup.getLiveGroupId());
303         }
304 
305         String scope = ParamUtil.getString(req, "scope");
306 
307         if (scope.equals("all-pages")) {
308             copyLayouts(
309                 stagingGroup.getLiveGroupId(), stagingGroup.getGroupId(),
310                 privateLayout);
311         }
312         else if (scope.equals("selected-pages")) {
313             Map layoutIdMap = new LinkedHashMap();
314 
315             long[] rowIds = ParamUtil.getLongValues(req, "rowIds");
316 
317             for (int i = 0; i < rowIds.length; i++) {
318                 long selPlid = rowIds[i];
319                 boolean includeChildren = ParamUtil.getBoolean(
320                     req, "includeChildren_" + selPlid);
321 
322                 layoutIdMap.put(
323                     new Long(selPlid), new Boolean(includeChildren));
324             }
325 
326             publishLayouts(
327                 layoutIdMap, stagingGroup.getLiveGroupId(),
328                 stagingGroup.getGroupId(), privateLayout);
329         }
330     }
331 
332     protected void copyLayouts(
333             long sourceGroupId, long targetGroupId, boolean privateLayout)
334         throws Exception {
335 
336         Map parameterMap = getStagingParameters();
337 
338         byte[] data = LayoutServiceUtil.exportLayouts(
339             sourceGroupId, privateLayout, parameterMap);
340 
341         ByteArrayInputStream bais = new ByteArrayInputStream(data);
342 
343         LayoutServiceUtil.importLayouts(
344             targetGroupId, privateLayout, parameterMap, bais);
345     }
346 
347     protected void copyPreferences(
348             ActionRequest req, Layout layout, Layout copyLayout)
349         throws Exception {
350 
351         long companyId = layout.getCompanyId();
352 
353         LayoutTypePortlet copyLayoutTypePortlet =
354             (LayoutTypePortlet)copyLayout.getLayoutType();
355 
356         List copyPortletIds = copyLayoutTypePortlet.getPortletIds();
357 
358         for (int i = 0; i < copyPortletIds.size(); i++) {
359             String copyPortletId = (String)copyPortletIds.get(i);
360 
361             HttpServletRequest httpReq = PortalUtil.getHttpServletRequest(req);
362 
363             // Copy preference
364 
365             PortletPreferencesIds portletPreferencesIds =
366                 PortletPreferencesFactoryUtil.getPortletPreferencesIds(
367                     httpReq, layout, copyPortletId);
368 
369             PortletPreferencesLocalServiceUtil.getPreferences(
370                 portletPreferencesIds);
371 
372             PortletPreferencesIds copyPortletPreferencesIds =
373                 PortletPreferencesFactoryUtil.getPortletPreferencesIds(
374                     httpReq, copyLayout, copyPortletId);
375 
376             PortletPreferences copyPrefs =
377                 PortletPreferencesLocalServiceUtil.getPreferences(
378                     copyPortletPreferencesIds);
379 
380             PortletPreferencesLocalServiceUtil.updatePreferences(
381                 portletPreferencesIds.getOwnerId(),
382                 portletPreferencesIds.getOwnerType(),
383                 portletPreferencesIds.getPlid(),
384                 portletPreferencesIds.getPortletId(), copyPrefs);
385 
386             // Copy portlet setup
387 
388             PortletPreferencesLocalServiceUtil.getPreferences(
389                 companyId, PortletKeys.PREFS_OWNER_ID_DEFAULT,
390                 PortletKeys.PREFS_OWNER_TYPE_LAYOUT, layout.getPlid(),
391                 copyPortletId);
392 
393             copyPrefs =
394                 PortletPreferencesLocalServiceUtil.getPreferences(
395                     companyId, PortletKeys.PREFS_OWNER_ID_DEFAULT,
396                     PortletKeys.PREFS_OWNER_TYPE_LAYOUT, copyLayout.getPlid(),
397                     copyPortletId);
398 
399             PortletPreferencesLocalServiceUtil.updatePreferences(
400                 PortletKeys.PREFS_OWNER_ID_DEFAULT,
401                 PortletKeys.PREFS_OWNER_TYPE_LAYOUT, layout.getPlid(),
402                 copyPortletId, copyPrefs);
403         }
404     }
405 
406     protected void deleteLayout(ActionRequest req, ActionResponse res)
407         throws Exception {
408 
409         ThemeDisplay themeDisplay =
410             (ThemeDisplay)req.getAttribute(WebKeys.THEME_DISPLAY);
411 
412         PermissionChecker permissionChecker =
413             themeDisplay.getPermissionChecker();
414 
415         long groupId = ParamUtil.getLong(req, "groupId");
416         boolean privateLayout = ParamUtil.getBoolean(req, "privateLayout");
417         long layoutId = ParamUtil.getLong(req, "layoutId");
418 
419         if (LayoutPermissionUtil.contains(
420                 permissionChecker, groupId, privateLayout, layoutId,
421                 ActionKeys.DELETE)) {
422 
423             Layout layout = LayoutLocalServiceUtil.getLayout(
424                 groupId, privateLayout, layoutId);
425 
426             String[] eventClasses = StringUtil.split(
427                 PropsUtil.getComponentProperties().getString(
428                     PropsUtil.LAYOUT_CONFIGURATION_ACTION_DELETE,
429                     Filter.by(layout.getType())));
430 
431             HttpServletRequest httpReq = (HttpServletRequest)
432                 ((ActionRequestImpl)req).getHttpServletRequest();
433             HttpServletResponse httpRes = (HttpServletResponse)
434                 ((ActionResponseImpl)res).getHttpServletResponse();
435 
436             EventsProcessor.process(eventClasses, httpReq, httpRes);
437         }
438 
439         LayoutServiceUtil.deleteLayout(groupId, privateLayout, layoutId);
440     }
441 
442     protected List getMissingParents(Layout layout, long liveGroupId)
443         throws PortalException, SystemException {
444 
445         List missingParents = new ArrayList();
446 
447         long parentLayoutId = layout.getParentLayoutId();
448 
449         while (parentLayoutId > 0) {
450             try {
451                 LayoutLocalServiceUtil.getLayout(
452                     liveGroupId, layout.isPrivateLayout(), parentLayoutId);
453 
454                 // If one parent is found all others are assumed to exist
455 
456                 break;
457             }
458             catch (NoSuchLayoutException nsle) {
459                 Layout parent = LayoutLocalServiceUtil.getLayout(
460                     layout.getGroupId(), layout.isPrivateLayout(),
461                     parentLayoutId);
462 
463                 missingParents.add(parent);
464 
465                 parentLayoutId = parent.getParentLayoutId();
466             }
467         }
468 
469         return missingParents;
470     }
471 
472     protected Map getStagingParameters() {
473         Map parameterMap = new HashMap();
474 
475         parameterMap.put(
476             PortletDataHandlerKeys.PERMISSIONS, Boolean.TRUE.toString());
477         parameterMap.put(
478             PortletDataHandlerKeys.USER_PERMISSIONS, Boolean.FALSE.toString());
479         parameterMap.put(
480             PortletDataHandlerKeys.PORTLET_DATA, Boolean.TRUE.toString());
481         parameterMap.put(
482             PortletDataHandlerKeys.PORTLET_DATA_ALL, Boolean.TRUE.toString());
483         parameterMap.put(
484             PortletDataHandlerKeys.PORTLET_SETUP, Boolean.TRUE.toString());
485         parameterMap.put(
486             PortletDataHandlerKeys.PORTLET_USER_PREFERENCES,
487             Boolean.TRUE.toString());
488         parameterMap.put(
489             PortletDataHandlerKeys.THEME, Boolean.FALSE.toString());
490         parameterMap.put(
491             PortletDataHandlerKeys.DELETE_MISSING_LAYOUTS,
492             Boolean.TRUE.toString());
493         parameterMap.put(
494             PortletDataHandlerKeys.DELETE_PORTLET_DATA,
495             Boolean.FALSE.toString());
496         parameterMap.put(
497             PortletDataHandlerKeys.DATA_STRATEGY,
498             PortletDataHandlerKeys.DATA_STRATEGY_MIRROR);
499         parameterMap.put(
500             PortletDataHandlerKeys.USER_ID_STRATEGY,
501             UserIdStrategy.CURRENT_USER_ID);
502 
503         return parameterMap;
504     }
505 
506     protected void publishLayout(
507             long plid, long liveGroupId, boolean includeChildren)
508         throws Exception {
509 
510         Map parameterMap = getStagingParameters();
511 
512         parameterMap.put(
513             PortletDataHandlerKeys.DELETE_MISSING_LAYOUTS,
514             Boolean.FALSE.toString());
515 
516         Layout layout = LayoutLocalServiceUtil.getLayout(plid);
517 
518         List layouts = new ArrayList();
519 
520         layouts.add(layout);
521 
522         layouts.addAll(getMissingParents(layout, liveGroupId));
523 
524         if (includeChildren) {
525             layouts.addAll(layout.getAllChildren());
526         }
527 
528         Iterator itr = layouts.iterator();
529 
530         long[] layoutIds = new long[layouts.size()];
531 
532         for (int i = 0; itr.hasNext(); i++) {
533             Layout curLayout = (Layout)itr.next();
534 
535             layoutIds[i] = curLayout.getLayoutId();
536         }
537 
538         byte[] data = LayoutServiceUtil.exportLayouts(
539             layout.getGroupId(), layout.isPrivateLayout(), layoutIds,
540             parameterMap);
541 
542         ByteArrayInputStream bais = new ByteArrayInputStream(data);
543 
544         LayoutServiceUtil.importLayouts(
545             liveGroupId, layout.isPrivateLayout(), parameterMap, bais);
546     }
547 
548     protected void publishLayouts(
549             Map layoutIdMap, long stagingGroupId, long liveGroupId,
550             boolean privateLayout)
551         throws Exception {
552 
553         Map parameterMap = getStagingParameters();
554 
555         parameterMap.put(
556             PortletDataHandlerKeys.DELETE_MISSING_LAYOUTS,
557             Boolean.FALSE.toString());
558 
559         List layouts = new ArrayList();
560 
561         Iterator itr1 = layoutIdMap.entrySet().iterator();
562 
563         while (itr1.hasNext()) {
564             Entry entry = (Entry)itr1.next();
565 
566             long plid = ((Long)entry.getKey()).longValue();
567             boolean includeChildren =
568                 ((Boolean)entry.getValue()).booleanValue();
569 
570             Layout layout = LayoutLocalServiceUtil.getLayout(plid);
571 
572             if (!layouts.contains(layout)) {
573                 layouts.add(layout);
574             }
575 
576             Iterator itr2 = getMissingParents(layout, liveGroupId).iterator();
577 
578             while (itr2.hasNext()) {
579                 Layout parentLayout = (Layout)itr2.next();
580 
581                 if (!layouts.contains(parentLayout)) {
582                     layouts.add(parentLayout);
583                 }
584             }
585 
586             if (includeChildren) {
587                 itr2 = layout.getAllChildren().iterator();
588 
589                 while (itr2.hasNext()) {
590                     Layout childLayout = (Layout)itr2.next();
591 
592                     if (!layouts.contains(childLayout)) {
593                         layouts.add(childLayout);
594                     }
595                 }
596             }
597         }
598 
599         itr1 = layouts.iterator();
600 
601         long[] layoutIds = new long[layouts.size()];
602 
603         for (int i = 0; itr1.hasNext(); i++) {
604             Layout curLayout = (Layout)itr1.next();
605 
606             layoutIds[i] = curLayout.getLayoutId();
607         }
608 
609         byte[] data = LayoutServiceUtil.exportLayouts(
610             stagingGroupId, privateLayout, layoutIds, parameterMap);
611 
612         ByteArrayInputStream bais = new ByteArrayInputStream(data);
613 
614         LayoutServiceUtil.importLayouts(
615             liveGroupId, privateLayout, parameterMap, bais);
616     }
617 
618     protected void publishToLive(ActionRequest req) throws Exception {
619         String tabs2 = ParamUtil.getString(req, "tabs2");
620 
621         long stagingGroupId = ParamUtil.getLong(req, "stagingGroupId");
622 
623         Group stagingGroup = GroupLocalServiceUtil.getGroup(stagingGroupId);
624 
625         boolean privateLayout = true;
626 
627         if (tabs2.equals("public")) {
628             privateLayout = false;
629         }
630 
631         if (_log.isDebugEnabled()) {
632             _log.debug(
633                 "Copying staging to live for group " +
634                     stagingGroup.getLiveGroupId());
635         }
636 
637         String scope = ParamUtil.getString(req, "scope");
638 
639         if (scope.equals("all-pages")) {
640             copyLayouts(
641                 stagingGroup.getGroupId(), stagingGroup.getLiveGroupId(),
642                 privateLayout);
643         }
644         else if (scope.equals("selected-pages")) {
645             Map layoutIdMap = new LinkedHashMap();
646 
647             long[] rowIds = ParamUtil.getLongValues(req, "rowIds");
648 
649             for (int i = 0; i < rowIds.length; i++) {
650                 long selPlid = rowIds[i];
651                 boolean includeChildren = ParamUtil.getBoolean(
652                     req, "includeChildren_" + selPlid);
653 
654                 layoutIdMap.put(
655                     new Long(selPlid), new Boolean(includeChildren));
656             }
657 
658             publishLayouts(
659                 layoutIdMap, stagingGroup.getGroupId(),
660                 stagingGroup.getLiveGroupId(), privateLayout);
661         }
662     }
663 
664     protected void updateDisplayOrder(ActionRequest req) throws Exception {
665         long groupId = ParamUtil.getLong(req, "groupId");
666         boolean privateLayout = ParamUtil.getBoolean(req, "privateLayout");
667         long parentLayoutId = ParamUtil.getLong(req, "parentLayoutId");
668         long[] layoutIds = StringUtil.split(
669             ParamUtil.getString(req, "layoutIds"), 0L);
670 
671         LayoutServiceUtil.setLayouts(
672             groupId, privateLayout, parentLayoutId, layoutIds);
673     }
674 
675     protected void updateLayout(
676             PageForm pageForm, ActionRequest req, ActionResponse res)
677         throws Exception {
678 
679         UploadPortletRequest uploadReq =
680             PortalUtil.getUploadPortletRequest(req);
681 
682         String cmd = ParamUtil.getString(uploadReq, Constants.CMD);
683 
684         long groupId = ParamUtil.getLong(req, "groupId");
685         boolean privateLayout = ParamUtil.getBoolean(req, "privateLayout");
686         long layoutId = ParamUtil.getLong(req, "layoutId");
687         long parentLayoutId = ParamUtil.getLong(uploadReq, "parentLayoutId");
688         String description = ParamUtil.getString(uploadReq, "description");
689         String type = ParamUtil.getString(uploadReq, "type");
690         boolean hidden = ParamUtil.getBoolean(uploadReq, "hidden");
691         String friendlyURL = ParamUtil.getString(uploadReq, "friendlyURL");
692         boolean iconImage = ParamUtil.getBoolean(uploadReq, "iconImage");
693         byte[] iconBytes = FileUtil.getBytes(
694             uploadReq.getFile("iconFileName"));
695 
696         boolean inheritFromParentLayoutId = ParamUtil.getBoolean(
697             uploadReq, "inheritFromParentLayoutId");
698 
699         long copyLayoutId = ParamUtil.getLong(uploadReq, "copyLayoutId");
700 
701         Locale[] locales = LanguageUtil.getAvailableLocales();
702 
703         Map localeNamesMap = new HashMap();
704         Map localeTitlesMap = new HashMap();
705 
706         for (int i = 0; i < locales.length; i++) {
707             String languageId = LocaleUtil.toLanguageId(locales[i]);
708 
709             localeNamesMap.put(
710                 locales[i],
711                 ParamUtil.getString(uploadReq, "name_" + languageId));
712             localeTitlesMap.put(
713                 locales[i],
714                 ParamUtil.getString(uploadReq, "title_" + languageId));
715         }
716 
717         if (cmd.equals(Constants.ADD)) {
718 
719             // Add layout
720 
721             if (inheritFromParentLayoutId && (parentLayoutId > 0)) {
722                 Layout parentLayout = LayoutLocalServiceUtil.getLayout(
723                     groupId, privateLayout, parentLayoutId);
724 
725                 Layout layout = LayoutServiceUtil.addLayout(
726                     groupId, privateLayout, parentLayoutId, localeNamesMap,
727                     localeTitlesMap, description, parentLayout.getType(),
728                     parentLayout.isHidden(), friendlyURL);
729 
730                 LayoutServiceUtil.updateLayout(
731                     layout.getGroupId(), layout.isPrivateLayout(),
732                     layout.getLayoutId(), parentLayout.getTypeSettings());
733             }
734             else {
735                 Layout layout = LayoutServiceUtil.addLayout(
736                     groupId, privateLayout, parentLayoutId, localeNamesMap,
737                     localeTitlesMap, description, type, hidden, friendlyURL);
738 
739                 if (type.equals(LayoutImpl.TYPE_PORTLET)) {
740                     LayoutTypePortlet layoutTypePortlet =
741                         (LayoutTypePortlet)layout.getLayoutType();
742 
743                     layoutTypePortlet.setLayoutTemplateId(
744                         0, PropsValues.LAYOUT_DEFAULT_TEMPLATE_ID, false);
745 
746                     LayoutServiceUtil.updateLayout(
747                         layout.getGroupId(), layout.isPrivateLayout(),
748                         layout.getLayoutId(), layout.getTypeSettings());
749                 }
750             }
751         }
752         else {
753 
754             // Update layout
755 
756             Layout layout = LayoutLocalServiceUtil.getLayout(
757                 groupId, privateLayout, layoutId);
758 
759             layout = LayoutServiceUtil.updateLayout(
760                 groupId, privateLayout, layoutId, layout.getParentLayoutId(),
761                 localeNamesMap, localeTitlesMap, description, type, hidden,
762                 friendlyURL, Boolean.valueOf(iconImage), iconBytes);
763 
764             if (type.equals(LayoutImpl.TYPE_PORTLET)) {
765                 if ((copyLayoutId > 0) &&
766                     (copyLayoutId != layout.getLayoutId())) {
767 
768                     try {
769                         Layout copyLayout = LayoutLocalServiceUtil.getLayout(
770                             groupId, privateLayout, copyLayoutId);
771 
772                         if (copyLayout.getType().equals(
773                                 LayoutImpl.TYPE_PORTLET)) {
774 
775                             LayoutServiceUtil.updateLayout(
776                                 groupId, privateLayout, layoutId,
777                                 copyLayout.getTypeSettings());
778 
779                             copyPreferences(req, layout, copyLayout);
780                         }
781                     }
782                     catch (NoSuchLayoutException nsle) {
783                     }
784                 }
785                 else {
786                     Properties formProperties =
787                         pageForm.getTypeSettingsProperties();
788 
789                     Properties layoutProperties =
790                         layout.getTypeSettingsProperties();
791 
792                     layoutProperties.setProperty(
793                         "meta-robots",
794                         formProperties.getProperty("meta-robots"));
795                     layoutProperties.setProperty(
796                         "meta-description",
797                         formProperties.getProperty("meta-description"));
798                     layoutProperties.setProperty(
799                         "meta-keywords",
800                         formProperties.getProperty("meta-keywords"));
801 
802                     layoutProperties.setProperty(
803                         "javascript-1",
804                         formProperties.getProperty("javascript-1"));
805                     layoutProperties.setProperty(
806                         "javascript-2",
807                         formProperties.getProperty("javascript-2"));
808                     layoutProperties.setProperty(
809                         "javascript-3",
810                         formProperties.getProperty("javascript-3"));
811                     layoutProperties.setProperty(
812                         "sitemap-include",
813                         formProperties.getProperty("sitemap-include"));
814                     layoutProperties.setProperty(
815                         "sitemap-priority",
816                         formProperties.getProperty("sitemap-priority"));
817                     layoutProperties.setProperty(
818                         "sitemap-changefreq",
819                         formProperties.getProperty("sitemap-changefreq"));
820 
821                     LayoutServiceUtil.updateLayout(
822                         groupId, privateLayout, layoutId,
823                         layout.getTypeSettings());
824                 }
825             }
826             else {
827                 layout.setTypeSettingsProperties(
828                     pageForm.getTypeSettingsProperties());
829 
830                 LayoutServiceUtil.updateLayout(
831                     groupId, privateLayout, layoutId, layout.getTypeSettings());
832             }
833 
834             HttpServletResponse httpRes = (HttpServletResponse)
835                 ((ActionResponseImpl)res).getHttpServletResponse();
836 
837             String[] eventClasses = StringUtil.split(
838                 PropsUtil.getComponentProperties().getString(
839                     PropsUtil.LAYOUT_CONFIGURATION_ACTION_UPDATE,
840                     Filter.by(type)));
841 
842             EventsProcessor.process(eventClasses, uploadReq, httpRes);
843         }
844     }
845 
846     protected void updateLogo(ActionRequest req) throws Exception {
847         UploadPortletRequest uploadReq =
848             PortalUtil.getUploadPortletRequest(req);
849 
850         long groupId = ParamUtil.getLong(req, "groupId");
851         boolean privateLayout = ParamUtil.getBoolean(req, "privateLayout");
852         boolean logo = ParamUtil.getBoolean(req, "logo");
853 
854         File file = uploadReq.getFile("logoFileName");
855         byte[] bytes = FileUtil.getBytes(file);
856 
857         if (logo && ((bytes == null) || (bytes.length == 0))) {
858             throw new UploadException();
859         }
860 
861         LayoutSetServiceUtil.updateLogo(groupId, privateLayout, logo, file);
862     }
863 
864     protected void updateLookAndFeel(ActionRequest req) throws Exception {
865         long companyId = PortalUtil.getCompanyId(req);
866 
867         long groupId = ParamUtil.getLong(req, "groupId");
868         boolean privateLayout = ParamUtil.getBoolean(req, "privateLayout");
869         long layoutId = ParamUtil.getLong(req, "layoutId");
870         String themeId = ParamUtil.getString(req, "themeId");
871         String colorSchemeId = ParamUtil.getString(req, "colorSchemeId");
872         String css = ParamUtil.getString(req, "css");
873         boolean wapTheme = ParamUtil.getBoolean(req, "wapTheme");
874 
875         if (Validator.isNotNull(themeId) && Validator.isNull(colorSchemeId)) {
876             ColorScheme colorScheme = ThemeLocalUtil.getColorScheme(
877                 companyId, themeId, colorSchemeId, wapTheme);
878 
879             colorSchemeId = colorScheme.getColorSchemeId();
880         }
881 
882         if (layoutId <= 0) {
883 
884             // Update layout set
885 
886             LayoutSetServiceUtil.updateLookAndFeel(
887                 groupId, privateLayout, themeId, colorSchemeId, css, wapTheme);
888         }
889         else {
890 
891             // Update layout
892 
893             LayoutServiceUtil.updateLookAndFeel(
894                 groupId, privateLayout, layoutId, themeId, colorSchemeId, css,
895                 wapTheme);
896         }
897     }
898 
899     protected void updateMergePages(ActionRequest req) throws Exception {
900         long groupId = ParamUtil.getLong(req, "groupId");
901 
902         Group group = GroupLocalServiceUtil.getGroup(groupId);
903 
904         boolean mergeGuestPublicPages = ParamUtil.getBoolean(
905             req, "mergeGuestPublicPages");
906 
907         Properties props = group.getTypeSettingsProperties();
908 
909         props.setProperty(
910             "mergeGuestPublicPages", String.valueOf(mergeGuestPublicPages));
911 
912         GroupServiceUtil.updateGroup(groupId, group.getTypeSettings());
913     }
914 
915     protected void updateMonitoring(ActionRequest req) throws Exception {
916         long groupId = ParamUtil.getLong(req, "groupId");
917 
918         Group group = GroupLocalServiceUtil.getGroup(groupId);
919 
920         String googleAnalyticsId = ParamUtil.getString(
921             req, "googleAnalyticsId");
922 
923         Properties props = group.getTypeSettingsProperties();
924 
925         props.setProperty("googleAnalyticsId", googleAnalyticsId);
926 
927         GroupServiceUtil.updateGroup(groupId, group.getTypeSettings());
928     }
929 
930     protected void updateStagingState(ActionRequest req) throws Exception {
931         long liveGroupId = ParamUtil.getLong(req, "liveGroupId");
932         long stagingGroupId = ParamUtil.getLong(req, "stagingGroupId");
933         boolean activateStaging = ParamUtil.getBoolean(req, "activateStaging");
934 
935         if ((stagingGroupId > 0) && !activateStaging) {
936             GroupServiceUtil.deleteGroup(stagingGroupId);
937         }
938         else if ((stagingGroupId == 0) && activateStaging) {
939             Group group = GroupServiceUtil.getGroup(liveGroupId);
940 
941             Group stagingGroup = GroupServiceUtil.addGroup(
942                 group.getGroupId(), group.getName() + " (Staging)",
943                 group.getDescription(), GroupImpl.TYPE_COMMUNITY_PRIVATE, null,
944                 group.isActive());
945 
946             if (group.hasPrivateLayouts()) {
947                 copyLayouts(
948                     group.getGroupId(), stagingGroup.getGroupId(), true);
949             }
950 
951             if (group.hasPublicLayouts()) {
952                 copyLayouts(
953                     group.getGroupId(), stagingGroup.getGroupId(), false);
954             }
955         }
956     }
957 
958     protected void updateVirtualHost(ActionRequest req) throws Exception {
959 
960         // Public virtual host
961 
962         long groupId = ParamUtil.getLong(req, "groupId");
963 
964         String publicVirtualHost = ParamUtil.getString(
965             req, "publicVirtualHost");
966 
967         LayoutSetServiceUtil.updateVirtualHost(
968             groupId, false, publicVirtualHost);
969 
970         // Private virtual host
971 
972         String privateVirtualHost = ParamUtil.getString(
973             req, "privateVirtualHost");
974 
975         LayoutSetServiceUtil.updateVirtualHost(
976             groupId, true, privateVirtualHost);
977 
978         // Friendly URL
979 
980         String friendlyURL = ParamUtil.getString(req, "friendlyURL");
981 
982         Group group = GroupLocalServiceUtil.getGroup(groupId);
983 
984         GroupServiceUtil.updateGroup(
985             groupId, group.getName(), group.getDescription(), group.getType(),
986             friendlyURL, group.isActive());
987     }
988 
989     private static Log _log = LogFactory.getLog(EditPagesAction.class);
990 
991 }