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.util;
24  
25  import com.liferay.portal.NoSuchGroupException;
26  import com.liferay.portal.NoSuchLayoutException;
27  import com.liferay.portal.PortalException;
28  import com.liferay.portal.RemoteExportException;
29  import com.liferay.portal.SystemException;
30  import com.liferay.portal.kernel.cal.DayAndPosition;
31  import com.liferay.portal.kernel.cal.Duration;
32  import com.liferay.portal.kernel.cal.Recurrence;
33  import com.liferay.portal.kernel.cal.RecurrenceSerializer;
34  import com.liferay.portal.kernel.lar.PortletDataHandlerKeys;
35  import com.liferay.portal.kernel.lar.UserIdStrategy;
36  import com.liferay.portal.kernel.messaging.DestinationNames;
37  import com.liferay.portal.kernel.util.CalendarFactoryUtil;
38  import com.liferay.portal.kernel.util.Http;
39  import com.liferay.portal.kernel.util.LocaleUtil;
40  import com.liferay.portal.kernel.util.ParamUtil;
41  import com.liferay.portal.kernel.util.StringPool;
42  import com.liferay.portal.kernel.util.Time;
43  import com.liferay.portal.kernel.util.TimeZoneUtil;
44  import com.liferay.portal.kernel.util.Validator;
45  import com.liferay.portal.model.Group;
46  import com.liferay.portal.model.Layout;
47  import com.liferay.portal.model.Portlet;
48  import com.liferay.portal.model.User;
49  import com.liferay.portal.model.impl.GroupImpl;
50  import com.liferay.portal.security.auth.HttpPrincipal;
51  import com.liferay.portal.security.auth.PrincipalException;
52  import com.liferay.portal.security.permission.ActionKeys;
53  import com.liferay.portal.security.permission.PermissionChecker;
54  import com.liferay.portal.security.permission.PermissionThreadLocal;
55  import com.liferay.portal.service.GroupLocalServiceUtil;
56  import com.liferay.portal.service.GroupServiceUtil;
57  import com.liferay.portal.service.LayoutLocalServiceUtil;
58  import com.liferay.portal.service.LayoutServiceUtil;
59  import com.liferay.portal.service.UserLocalServiceUtil;
60  import com.liferay.portal.service.http.GroupServiceHttp;
61  import com.liferay.portal.service.http.LayoutServiceHttp;
62  import com.liferay.portal.service.permission.GroupPermissionUtil;
63  import com.liferay.portal.theme.ThemeDisplay;
64  import com.liferay.portal.util.WebKeys;
65  
66  import java.io.ByteArrayInputStream;
67  
68  import java.util.ArrayList;
69  import java.util.Calendar;
70  import java.util.Date;
71  import java.util.Iterator;
72  import java.util.LinkedHashMap;
73  import java.util.List;
74  import java.util.Locale;
75  import java.util.Map.Entry;
76  import java.util.Map;
77  import java.util.TimeZone;
78  
79  import javax.portlet.ActionRequest;
80  
81  import org.apache.commons.logging.Log;
82  import org.apache.commons.logging.LogFactory;
83  
84  /**
85   * <a href="StagingUtil.java.html"><b><i>View Source</i></b></a>
86   *
87   * @author Raymond Augé
88   * @author Bruno Farache
89   *
90   */
91  public class StagingUtil {
92  
93      public static void copyFromLive(ActionRequest actionRequest)
94          throws Exception {
95  
96          long stagingGroupId = ParamUtil.getLong(
97              actionRequest, "stagingGroupId");
98  
99          Group stagingGroup = GroupLocalServiceUtil.getGroup(stagingGroupId);
100 
101         long liveGroupId = stagingGroup.getLiveGroupId();
102 
103         Map<String, String[]> parameterMap = getStagingParameters();
104 
105         _publishLayouts(
106             actionRequest, liveGroupId, stagingGroupId, parameterMap, false);
107     }
108 
109     public static void copyFromLive(
110             ActionRequest actionRequest, Portlet portlet)
111         throws Exception {
112 
113         long plid = ParamUtil.getLong(actionRequest, "plid");
114 
115         Layout targetLayout = LayoutLocalServiceUtil.getLayout(plid);
116 
117         Group stagingGroup = targetLayout.getGroup();
118         Group liveGroup = stagingGroup.getLiveGroup();
119 
120         Layout sourceLayout = LayoutLocalServiceUtil.getLayout(
121             liveGroup.getGroupId(), targetLayout.isPrivateLayout(),
122             targetLayout.getLayoutId());
123 
124         copyPortlet(
125             actionRequest, sourceLayout.getPlid(), targetLayout.getPlid(),
126             portlet.getPortletId());
127     }
128 
129     public static void copyPortlet(
130             ActionRequest actionRequest, long sourcePlid, long targetPlid,
131             String portletId)
132         throws Exception {
133 
134         Map<String, String[]> parameterMap = getStagingParameters(
135             actionRequest);
136 
137         byte[] bytes = LayoutLocalServiceUtil.exportPortletInfo(
138             sourcePlid, portletId, parameterMap, null, null);
139 
140         ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
141 
142         LayoutServiceUtil.importPortletInfo(
143             targetPlid, portletId, parameterMap, bais);
144     }
145 
146     public static void copyRemoteLayouts(
147             long sourceGroupId, boolean privateLayout,
148             Map<Long, Boolean> layoutIdMap,
149             Map<String, String[]> exportParameterMap, String remoteAddress,
150             int remotePort, boolean secureConnection, long remoteGroupId,
151             boolean remotePrivateLayout,
152             Map<String, String[]> importParameterMap, Date startDate,
153             Date endDate)
154         throws Exception {
155 
156         PermissionChecker permissionChecker =
157             PermissionThreadLocal.getPermissionChecker();
158 
159         User user = UserLocalServiceUtil.getUser(permissionChecker.getUserId());
160 
161         StringBuilder sb = new StringBuilder();
162 
163         if (secureConnection) {
164             sb.append(Http.HTTPS_WITH_SLASH);
165         }
166         else {
167             sb.append(Http.HTTP_WITH_SLASH);
168         }
169 
170         sb.append(remoteAddress);
171         sb.append(StringPool.COLON);
172         sb.append(remotePort);
173 
174         String url = sb.toString();
175 
176         HttpPrincipal httpPrincipal = new HttpPrincipal(
177             url, user.getEmailAddress(), user.getPassword(),
178             user.getPasswordEncrypted());
179 
180         // Ping remote host and verify that the group exists
181 
182         try {
183             GroupServiceHttp.getGroup(httpPrincipal, remoteGroupId);
184         }
185         catch (NoSuchGroupException nsge) {
186             RemoteExportException ree = new RemoteExportException(
187                 RemoteExportException.NO_GROUP);
188 
189             ree.setGroupId(remoteGroupId);
190 
191             throw ree;
192         }
193         catch (SystemException se) {
194             RemoteExportException ree = new RemoteExportException(
195                 RemoteExportException.BAD_CONNECTION);
196 
197             ree.setURL(url);
198 
199             throw ree;
200         }
201 
202         byte[] bytes = null;
203 
204         if (layoutIdMap == null) {
205             bytes = LayoutServiceUtil.exportLayouts(
206                 sourceGroupId, privateLayout, exportParameterMap, startDate,
207                 endDate);
208         }
209         else {
210             List<Layout> layouts = new ArrayList<Layout>();
211 
212             Iterator<Map.Entry<Long, Boolean>> itr1 =
213                 layoutIdMap.entrySet().iterator();
214 
215             while (itr1.hasNext()) {
216                 Entry<Long, Boolean> entry = itr1.next();
217 
218                 long plid = entry.getKey();
219                 boolean includeChildren = entry.getValue();
220 
221                 Layout layout = LayoutLocalServiceUtil.getLayout(plid);
222 
223                 if (!layouts.contains(layout)) {
224                     layouts.add(layout);
225                 }
226 
227                 Iterator<Layout> itr2 = getMissingParents(
228                     layout, sourceGroupId).iterator();
229 
230                 while (itr2.hasNext()) {
231                     Layout parentLayout = itr2.next();
232 
233                     if (!layouts.contains(parentLayout)) {
234                         layouts.add(parentLayout);
235                     }
236                 }
237 
238                 if (includeChildren) {
239                     itr2 = layout.getAllChildren().iterator();
240 
241                     while (itr2.hasNext()) {
242                         Layout childLayout = itr2.next();
243 
244                         if (!layouts.contains(childLayout)) {
245                             layouts.add(childLayout);
246                         }
247                     }
248                 }
249             }
250 
251             long[] layoutIds = new long[layouts.size()];
252 
253             for (int i = 0; i < layouts.size(); i++) {
254                 Layout curLayout = layouts.get(i);
255 
256                 layoutIds[i] = curLayout.getLayoutId();
257             }
258 
259             if (layoutIds.length <= 0) {
260                 throw new RemoteExportException(
261                     RemoteExportException.NO_LAYOUTS);
262             }
263 
264             bytes = LayoutServiceUtil.exportLayouts(
265                 sourceGroupId, privateLayout, layoutIds, exportParameterMap,
266                 startDate, endDate);
267         }
268 
269         LayoutServiceHttp.importLayouts(
270             httpPrincipal, remoteGroupId, remotePrivateLayout,
271             importParameterMap, bytes);
272     }
273 
274     public static List<Layout> getMissingParents(
275             Layout layout, long liveGroupId)
276         throws PortalException, SystemException {
277 
278         List<Layout> missingParents = new ArrayList<Layout>();
279 
280         long parentLayoutId = layout.getParentLayoutId();
281 
282         while (parentLayoutId > 0) {
283             try {
284                 LayoutLocalServiceUtil.getLayout(
285                     liveGroupId, layout.isPrivateLayout(), parentLayoutId);
286 
287                 // If one parent is found all others are assumed to exist
288 
289                 break;
290             }
291             catch (NoSuchLayoutException nsle) {
292                 Layout parent = LayoutLocalServiceUtil.getLayout(
293                     layout.getGroupId(), layout.isPrivateLayout(),
294                     parentLayoutId);
295 
296                 missingParents.add(parent);
297 
298                 parentLayoutId = parent.getParentLayoutId();
299             }
300         }
301 
302         return missingParents;
303     }
304 
305     public static String getSchedulerGroupName(
306         String destinationName, long groupId) {
307 
308         StringBuilder sb = new StringBuilder();
309 
310         sb.append(destinationName);
311         sb.append(StringPool.SLASH);
312         sb.append(groupId);
313 
314         return sb.toString();
315     }
316 
317     public static Map<String, String[]> getStagingParameters() {
318         Map<String, String[]> parameterMap =
319             new LinkedHashMap<String, String[]>();
320 
321         parameterMap.put(
322             PortletDataHandlerKeys.PERMISSIONS,
323             new String[] {Boolean.TRUE.toString()});
324         parameterMap.put(
325             PortletDataHandlerKeys.USER_PERMISSIONS,
326             new String[] {Boolean.FALSE.toString()});
327         parameterMap.put(
328             PortletDataHandlerKeys.PORTLET_DATA,
329             new String[] {Boolean.TRUE.toString()});
330         parameterMap.put(
331             PortletDataHandlerKeys.PORTLET_DATA_ALL,
332             new String[] {Boolean.TRUE.toString()});
333         parameterMap.put(
334             PortletDataHandlerKeys.PORTLET_SETUP,
335             new String[] {Boolean.TRUE.toString()});
336         parameterMap.put(
337             PortletDataHandlerKeys.PORTLET_USER_PREFERENCES,
338             new String[] {Boolean.TRUE.toString()});
339         parameterMap.put(
340             PortletDataHandlerKeys.THEME,
341             new String[] {Boolean.FALSE.toString()});
342         parameterMap.put(
343             PortletDataHandlerKeys.DELETE_MISSING_LAYOUTS,
344             new String[] {Boolean.TRUE.toString()});
345         parameterMap.put(
346             PortletDataHandlerKeys.DELETE_PORTLET_DATA,
347             new String[] {Boolean.FALSE.toString()});
348         parameterMap.put(
349             PortletDataHandlerKeys.DATA_STRATEGY,
350             new String[] {PortletDataHandlerKeys.DATA_STRATEGY_MIRROR});
351         parameterMap.put(
352             PortletDataHandlerKeys.USER_ID_STRATEGY,
353             new String[] {UserIdStrategy.CURRENT_USER_ID});
354 
355         return parameterMap;
356     }
357 
358     public static Map<String, String[]> getStagingParameters(
359         ActionRequest actionRequest) {
360 
361         Map<String, String[]> parameterMap =
362             new LinkedHashMap<String, String[]>(
363                 actionRequest.getParameterMap());
364 
365         if (!parameterMap.containsKey(
366                 PortletDataHandlerKeys.PORTLET_DATA)) {
367 
368             parameterMap.put(
369                 PortletDataHandlerKeys.PORTLET_DATA,
370                 new String[] {Boolean.FALSE.toString()});
371         }
372 
373         if (!parameterMap.containsKey(
374                 PortletDataHandlerKeys.PORTLET_DATA_ALL)) {
375 
376             parameterMap.put(
377                 PortletDataHandlerKeys.PORTLET_DATA_ALL,
378                 new String[] {Boolean.FALSE.toString()});
379         }
380 
381         if (!parameterMap.containsKey(PortletDataHandlerKeys.PORTLET_SETUP)) {
382             parameterMap.put(
383                 PortletDataHandlerKeys.PORTLET_SETUP,
384                 new String[] {Boolean.TRUE.toString()});
385         }
386 
387         if (!parameterMap.containsKey(
388                 PortletDataHandlerKeys.PORTLET_USER_PREFERENCES)) {
389 
390             parameterMap.put(
391                 PortletDataHandlerKeys.PORTLET_USER_PREFERENCES,
392                 new String[] {Boolean.TRUE.toString()});
393         }
394 
395         if (!parameterMap.containsKey(PortletDataHandlerKeys.THEME)) {
396             parameterMap.put(
397                 PortletDataHandlerKeys.THEME,
398                 new String[] {Boolean.FALSE.toString()});
399         }
400 
401         if (!parameterMap.containsKey(
402                 PortletDataHandlerKeys.DELETE_MISSING_LAYOUTS)) {
403 
404             parameterMap.put(
405                 PortletDataHandlerKeys.DELETE_MISSING_LAYOUTS,
406                 new String[] {Boolean.TRUE.toString()});
407         }
408 
409         if (!parameterMap.containsKey(
410                 PortletDataHandlerKeys.DELETE_PORTLET_DATA)) {
411 
412             parameterMap.put(
413                 PortletDataHandlerKeys.DELETE_PORTLET_DATA,
414                 new String[] {Boolean.FALSE.toString()});
415         }
416 
417         if (!parameterMap.containsKey(PortletDataHandlerKeys.DATA_STRATEGY)) {
418             parameterMap.put(
419                 PortletDataHandlerKeys.DATA_STRATEGY,
420                 new String[] {PortletDataHandlerKeys.DATA_STRATEGY_MIRROR});
421         }
422 
423         if (!parameterMap.containsKey(
424                 PortletDataHandlerKeys.USER_ID_STRATEGY)) {
425 
426             parameterMap.put(
427                 PortletDataHandlerKeys.USER_ID_STRATEGY,
428                 new String[] {UserIdStrategy.CURRENT_USER_ID});
429         }
430 
431         return parameterMap;
432     }
433 
434     public static void publishLayout(
435             long plid, long liveGroupId, boolean includeChildren)
436         throws Exception {
437 
438         Map<String, String[]> parameterMap = getStagingParameters();
439 
440         parameterMap.put(
441             PortletDataHandlerKeys.DELETE_MISSING_LAYOUTS,
442             new String[] {Boolean.FALSE.toString()});
443 
444         Layout layout = LayoutLocalServiceUtil.getLayout(plid);
445 
446         List<Layout> layouts = new ArrayList<Layout>();
447 
448         layouts.add(layout);
449 
450         layouts.addAll(getMissingParents(layout, liveGroupId));
451 
452         if (includeChildren) {
453             layouts.addAll(layout.getAllChildren());
454         }
455 
456         Iterator<Layout> itr = layouts.iterator();
457 
458         long[] layoutIds = new long[layouts.size()];
459 
460         for (int i = 0; itr.hasNext(); i++) {
461             Layout curLayout = itr.next();
462 
463             layoutIds[i] = curLayout.getLayoutId();
464         }
465 
466         byte[] bytes = LayoutServiceUtil.exportLayouts(
467             layout.getGroupId(), layout.isPrivateLayout(), layoutIds,
468             parameterMap, null, null);
469 
470         ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
471 
472         LayoutServiceUtil.importLayouts(
473             liveGroupId, layout.isPrivateLayout(), parameterMap, bais);
474     }
475 
476     public static void publishLayouts(
477             long sourceGroupId, long targetGroupId, boolean privateLayout,
478             Map<String, String[]> parameterMap, Date startDate, Date endDate)
479         throws Exception {
480 
481         byte[] bytes = LayoutServiceUtil.exportLayouts(
482             sourceGroupId, privateLayout, parameterMap, startDate, endDate);
483 
484         ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
485 
486         LayoutServiceUtil.importLayouts(
487             targetGroupId, privateLayout, parameterMap, bais);
488     }
489 
490     public static void publishLayouts(
491             long sourceGroupId, long targetGroupId, boolean privateLayout,
492             Map<Long, Boolean> layoutIdMap, Map<String, String[]> parameterMap,
493             Date startDate, Date endDate)
494         throws Exception {
495 
496         parameterMap.put(
497             PortletDataHandlerKeys.DELETE_MISSING_LAYOUTS,
498             new String[] {Boolean.FALSE.toString()});
499 
500         List<Layout> layouts = new ArrayList<Layout>();
501 
502         Iterator<Map.Entry<Long, Boolean>> itr1 =
503             layoutIdMap.entrySet().iterator();
504 
505         while (itr1.hasNext()) {
506             Entry<Long, Boolean> entry = itr1.next();
507 
508             long plid = entry.getKey();
509             boolean includeChildren = entry.getValue();
510 
511             Layout layout = LayoutLocalServiceUtil.getLayout(plid);
512 
513             if (!layouts.contains(layout)) {
514                 layouts.add(layout);
515             }
516 
517             Iterator<Layout> itr2 = getMissingParents(
518                 layout, targetGroupId).iterator();
519 
520             while (itr2.hasNext()) {
521                 Layout parentLayout = itr2.next();
522 
523                 if (!layouts.contains(parentLayout)) {
524                     layouts.add(parentLayout);
525                 }
526             }
527 
528             if (includeChildren) {
529                 itr2 = layout.getAllChildren().iterator();
530 
531                 while (itr2.hasNext()) {
532                     Layout childLayout = itr2.next();
533 
534                     if (!layouts.contains(childLayout)) {
535                         layouts.add(childLayout);
536                     }
537                 }
538             }
539         }
540 
541         long[] layoutIds = new long[layouts.size()];
542 
543         for (int i = 0; i < layouts.size(); i++) {
544             Layout curLayout = layouts.get(i);
545 
546             layoutIds[i] = curLayout.getLayoutId();
547         }
548 
549         byte[] bytes = LayoutServiceUtil.exportLayouts(
550             sourceGroupId, privateLayout, layoutIds, parameterMap, startDate,
551             endDate);
552 
553         ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
554 
555         LayoutServiceUtil.importLayouts(
556             targetGroupId, privateLayout, parameterMap, bais);
557     }
558 
559     public static void publishToLive(ActionRequest actionRequest)
560         throws Exception {
561 
562         long stagingGroupId = ParamUtil.getLong(
563             actionRequest, "stagingGroupId");
564 
565         Group stagingGroup = GroupLocalServiceUtil.getGroup(stagingGroupId);
566 
567         long liveGroupId = stagingGroup.getLiveGroupId();
568 
569         Map<String, String[]> parameterMap = getStagingParameters(
570             actionRequest);
571 
572         _publishLayouts(
573             actionRequest, stagingGroupId, liveGroupId, parameterMap, false);
574     }
575 
576     public static void publishToLive(
577             ActionRequest actionRequest, Portlet portlet)
578         throws Exception {
579 
580         long plid = ParamUtil.getLong(actionRequest, "plid");
581 
582         Layout sourceLayout = LayoutLocalServiceUtil.getLayout(plid);
583 
584         Group stagingGroup = sourceLayout.getGroup();
585         Group liveGroup = stagingGroup.getLiveGroup();
586 
587         Layout targetLayout = LayoutLocalServiceUtil.getLayout(
588             liveGroup.getGroupId(), sourceLayout.isPrivateLayout(),
589             sourceLayout.getLayoutId());
590 
591         copyPortlet(
592             actionRequest, sourceLayout.getPlid(), targetLayout.getPlid(),
593             portlet.getPortletId());
594     }
595 
596     public static void publishToRemote(ActionRequest actionRequest)
597         throws Exception {
598 
599         _publishToRemote(actionRequest, false);
600     }
601 
602     public static void scheduleCopyFromLive(ActionRequest actionRequest)
603         throws Exception {
604 
605         long stagingGroupId = ParamUtil.getLong(
606             actionRequest, "stagingGroupId");
607 
608         Group stagingGroup = GroupLocalServiceUtil.getGroup(stagingGroupId);
609 
610         long liveGroupId = stagingGroup.getLiveGroupId();
611 
612         Map<String, String[]> parameterMap = getStagingParameters();
613 
614         _publishLayouts(
615             actionRequest, liveGroupId, stagingGroupId, parameterMap, true);
616     }
617 
618     public static void schedulePublishToLive(ActionRequest actionRequest)
619         throws Exception {
620 
621         long stagingGroupId = ParamUtil.getLong(
622             actionRequest, "stagingGroupId");
623 
624         Group stagingGroup = GroupLocalServiceUtil.getGroup(stagingGroupId);
625 
626         long liveGroupId = stagingGroup.getLiveGroupId();
627 
628         Map<String, String[]> parameterMap = getStagingParameters(
629             actionRequest);
630 
631         _publishLayouts(
632             actionRequest, stagingGroupId, liveGroupId, parameterMap, true);
633     }
634 
635     public static void schedulePublishToRemote(ActionRequest actionRequest)
636         throws Exception {
637 
638         _publishToRemote(actionRequest, true);
639     }
640 
641     public static void unscheduleCopyFromLive(ActionRequest actionRequest)
642         throws Exception {
643 
644         long stagingGroupId = ParamUtil.getLong(
645             actionRequest, "stagingGroupId");
646 
647         String jobName = ParamUtil.getString(actionRequest, "jobName");
648         String groupName = getSchedulerGroupName(
649             DestinationNames.LAYOUTS_LOCAL_PUBLISHER, stagingGroupId);
650 
651         LayoutServiceUtil.unschedulePublishToLive(
652             stagingGroupId, jobName, groupName);
653     }
654 
655     public static void unschedulePublishToLive(ActionRequest actionRequest)
656         throws Exception {
657 
658         long stagingGroupId = ParamUtil.getLong(
659             actionRequest, "stagingGroupId");
660 
661         Group stagingGroup = GroupLocalServiceUtil.getGroup(stagingGroupId);
662 
663         long liveGroupId = stagingGroup.getLiveGroupId();
664 
665         String jobName = ParamUtil.getString(actionRequest, "jobName");
666         String groupName = getSchedulerGroupName(
667             DestinationNames.LAYOUTS_LOCAL_PUBLISHER, liveGroupId);
668 
669         LayoutServiceUtil.unschedulePublishToLive(
670             liveGroupId, jobName, groupName);
671     }
672 
673     public static void unschedulePublishToRemote(ActionRequest actionRequest)
674         throws Exception {
675 
676         long stagingGroupId = ParamUtil.getLong(
677             actionRequest, "stagingGroupId");
678 
679         Group stagingGroup = GroupLocalServiceUtil.getGroup(stagingGroupId);
680 
681         long liveGroupId = stagingGroup.getLiveGroupId();
682 
683         String jobName = ParamUtil.getString(actionRequest, "jobName");
684         String groupName = getSchedulerGroupName(
685             DestinationNames.LAYOUTS_REMOTE_PUBLISHER, liveGroupId);
686 
687         LayoutServiceUtil.unschedulePublishToRemote(
688             liveGroupId, jobName, groupName);
689     }
690 
691     public static void updateStaging(ActionRequest actionRequest)
692         throws Exception {
693 
694         ThemeDisplay themeDisplay = (ThemeDisplay)actionRequest.getAttribute(
695             WebKeys.THEME_DISPLAY);
696 
697         PermissionChecker permissionChecker =
698             themeDisplay.getPermissionChecker();
699 
700         long liveGroupId = ParamUtil.getLong(actionRequest, "liveGroupId");
701 
702         if (!GroupPermissionUtil.contains(
703                 permissionChecker, liveGroupId, ActionKeys.MANAGE_STAGING)) {
704 
705             throw new PrincipalException();
706         }
707 
708         long stagingGroupId = ParamUtil.getLong(
709             actionRequest, "stagingGroupId");
710 
711         boolean stagingEnabled = ParamUtil.getBoolean(
712             actionRequest, "stagingEnabled");
713 
714         if ((stagingGroupId > 0) && !stagingEnabled) {
715             GroupServiceUtil.deleteGroup(stagingGroupId);
716 
717             GroupServiceUtil.updateWorkflow(liveGroupId, false, 0, null);
718         }
719         else if ((stagingGroupId == 0) && stagingEnabled) {
720             Group liveGroup = GroupServiceUtil.getGroup(liveGroupId);
721 
722             Group stagingGroup = GroupServiceUtil.addGroup(
723                 liveGroup.getGroupId(), liveGroup.getName() + " (Staging)",
724                 liveGroup.getDescription(), GroupImpl.TYPE_COMMUNITY_PRIVATE,
725                 null, liveGroup.isActive());
726 
727             if (liveGroup.hasPrivateLayouts()) {
728                 Map<String, String[]> parameterMap = getStagingParameters();
729 
730                 publishLayouts(
731                     liveGroup.getGroupId(), stagingGroup.getGroupId(), true,
732                     parameterMap, null, null);
733             }
734 
735             if (liveGroup.hasPublicLayouts()) {
736                 Map<String, String[]> parameterMap = getStagingParameters();
737 
738                 publishLayouts(
739                     liveGroup.getGroupId(), stagingGroup.getGroupId(), false,
740                     parameterMap, null, null);
741             }
742         }
743     }
744 
745     private static void _addWeeklyDayPos(
746         ActionRequest actionRequest, List<DayAndPosition> list, int day) {
747 
748         if (ParamUtil.getBoolean(actionRequest, "weeklyDayPos" + day)) {
749             list.add(new DayAndPosition(day, 0));
750         }
751     }
752 
753     private static String _getCronText(
754             ActionRequest actionRequest, Calendar startDate,
755             boolean timeZoneSensitive, int recurrenceType)
756         throws Exception {
757 
758         Calendar startCal = null;
759 
760         if (timeZoneSensitive) {
761             startCal = CalendarFactoryUtil.getCalendar();
762 
763             startCal.setTime(startDate.getTime());
764         }
765         else {
766             startCal = (Calendar)startDate.clone();
767         }
768 
769         Recurrence recurrence = new Recurrence(
770             startCal, new Duration(1, 0, 0, 0), recurrenceType);
771 
772         recurrence.setWeekStart(Calendar.SUNDAY);
773 
774         if (recurrenceType == Recurrence.DAILY) {
775             int dailyType = ParamUtil.getInteger(actionRequest, "dailyType");
776 
777             if (dailyType == 0) {
778                 int dailyInterval = ParamUtil.getInteger(
779                     actionRequest, "dailyInterval", 1);
780 
781                 recurrence.setInterval(dailyInterval);
782             }
783             else {
784                 DayAndPosition[] dayPos = {
785                     new DayAndPosition(Calendar.MONDAY, 0),
786                     new DayAndPosition(Calendar.TUESDAY, 0),
787                     new DayAndPosition(Calendar.WEDNESDAY, 0),
788                     new DayAndPosition(Calendar.THURSDAY, 0),
789                     new DayAndPosition(Calendar.FRIDAY, 0)};
790 
791                 recurrence.setByDay(dayPos);
792             }
793         }
794         else if (recurrenceType == Recurrence.WEEKLY) {
795             int weeklyInterval = ParamUtil.getInteger(
796                 actionRequest, "weeklyInterval", 1);
797 
798             recurrence.setInterval(weeklyInterval);
799 
800             List<DayAndPosition> dayPos = new ArrayList<DayAndPosition>();
801 
802             _addWeeklyDayPos(actionRequest, dayPos, Calendar.SUNDAY);
803             _addWeeklyDayPos(actionRequest, dayPos, Calendar.MONDAY);
804             _addWeeklyDayPos(actionRequest, dayPos, Calendar.TUESDAY);
805             _addWeeklyDayPos(actionRequest, dayPos, Calendar.WEDNESDAY);
806             _addWeeklyDayPos(actionRequest, dayPos, Calendar.THURSDAY);
807             _addWeeklyDayPos(actionRequest, dayPos, Calendar.FRIDAY);
808             _addWeeklyDayPos(actionRequest, dayPos, Calendar.SATURDAY);
809 
810             if (dayPos.size() == 0) {
811                 dayPos.add(new DayAndPosition(Calendar.MONDAY, 0));
812             }
813 
814             recurrence.setByDay(dayPos.toArray(new DayAndPosition[0]));
815         }
816         else if (recurrenceType == Recurrence.MONTHLY) {
817             int monthlyType = ParamUtil.getInteger(
818                 actionRequest, "monthlyType");
819 
820             if (monthlyType == 0) {
821                 int monthlyDay = ParamUtil.getInteger(
822                     actionRequest, "monthlyDay0", 1);
823 
824                 recurrence.setByMonthDay(new int[] {monthlyDay});
825 
826                 int monthlyInterval = ParamUtil.getInteger(
827                     actionRequest, "monthlyInterval0", 1);
828 
829                 recurrence.setInterval(monthlyInterval);
830             }
831             else {
832                 int monthlyPos = ParamUtil.getInteger(
833                     actionRequest, "monthlyPos");
834                 int monthlyDay = ParamUtil.getInteger(
835                     actionRequest, "monthlyDay1");
836 
837                 DayAndPosition[] dayPos = {
838                     new DayAndPosition(monthlyDay, monthlyPos)};
839 
840                 recurrence.setByDay(dayPos);
841 
842                 int monthlyInterval = ParamUtil.getInteger(
843                     actionRequest, "monthlyInterval1", 1);
844 
845                 recurrence.setInterval(monthlyInterval);
846             }
847         }
848         else if (recurrenceType == Recurrence.YEARLY) {
849             int yearlyType = ParamUtil.getInteger(actionRequest, "yearlyType");
850 
851             if (yearlyType == 0) {
852                 int yearlyMonth = ParamUtil.getInteger(
853                     actionRequest, "yearlyMonth0");
854                 int yearlyDay = ParamUtil.getInteger(
855                     actionRequest, "yearlyDay0", 1);
856 
857                 recurrence.setByMonth(new int[] {yearlyMonth});
858                 recurrence.setByMonthDay(new int[] {yearlyDay});
859 
860                 int yearlyInterval = ParamUtil.getInteger(
861                     actionRequest, "yearlyInterval0", 1);
862 
863                 recurrence.setInterval(yearlyInterval);
864             }
865             else {
866                 int yearlyPos = ParamUtil.getInteger(
867                     actionRequest, "yearlyPos");
868                 int yearlyDay = ParamUtil.getInteger(
869                     actionRequest, "yearlyDay1");
870                 int yearlyMonth = ParamUtil.getInteger(
871                     actionRequest, "yearlyMonth1");
872 
873                 DayAndPosition[] dayPos = {
874                     new DayAndPosition(yearlyDay, yearlyPos)};
875 
876                 recurrence.setByDay(dayPos);
877 
878                 recurrence.setByMonth(new int[] {yearlyMonth});
879 
880                 int yearlyInterval = ParamUtil.getInteger(
881                     actionRequest, "yearlyInterval1", 1);
882 
883                 recurrence.setInterval(yearlyInterval);
884             }
885         }
886 
887         return RecurrenceSerializer.toCronText(recurrence);
888     }
889 
890     private static Calendar _getDate(
891             ActionRequest actionRequest, String paramPrefix,
892             boolean timeZoneSensitive)
893         throws Exception {
894 
895         int dateMonth = ParamUtil.getInteger(
896             actionRequest, paramPrefix + "Month");
897         int dateDay = ParamUtil.getInteger(actionRequest, paramPrefix + "Day");
898         int dateYear = ParamUtil.getInteger(
899             actionRequest, paramPrefix + "Year");
900         int dateHour = ParamUtil.getInteger(
901             actionRequest, paramPrefix + "Hour");
902         int dateMinute = ParamUtil.getInteger(
903             actionRequest, paramPrefix + "Minute");
904         int dateAmPm = ParamUtil.getInteger(
905             actionRequest, paramPrefix + "AmPm");
906 
907         if (dateAmPm == Calendar.PM) {
908             dateHour += 12;
909         }
910 
911         Locale locale = null;
912         TimeZone timeZone = null;
913 
914         if (timeZoneSensitive) {
915             ThemeDisplay themeDisplay =
916                 (ThemeDisplay)actionRequest.getAttribute(WebKeys.THEME_DISPLAY);
917 
918             locale = themeDisplay.getLocale();
919             timeZone = themeDisplay.getTimeZone();
920         }
921         else {
922             locale = LocaleUtil.getDefault();
923             timeZone = TimeZoneUtil.getDefault();
924         }
925 
926         Calendar cal = CalendarFactoryUtil.getCalendar(timeZone, locale);
927 
928         cal.set(Calendar.MONTH, dateMonth);
929         cal.set(Calendar.DATE, dateDay);
930         cal.set(Calendar.YEAR, dateYear);
931         cal.set(Calendar.HOUR_OF_DAY, dateHour);
932         cal.set(Calendar.MINUTE, dateMinute);
933         cal.set(Calendar.SECOND, 0);
934         cal.set(Calendar.MILLISECOND, 0);
935 
936         return cal;
937     }
938 
939     private static void _publishLayouts(
940             ActionRequest actionRequest, long sourceGroupId, long targetGroupId,
941             Map<String, String[]> parameterMap, boolean schedule)
942         throws Exception {
943 
944         String tabs1 = ParamUtil.getString(actionRequest, "tabs1");
945 
946         boolean privateLayout = true;
947 
948         if (tabs1.equals("public-pages")) {
949             privateLayout = false;
950         }
951 
952         String scope = ParamUtil.getString(actionRequest, "scope");
953 
954         Map<Long, Boolean> layoutIdMap = new LinkedHashMap<Long, Boolean>();
955 
956         if (scope.equals("selected-pages")) {
957             long[] rowIds = ParamUtil.getLongValues(actionRequest, "rowIds");
958 
959             for (long selPlid : rowIds) {
960                 boolean includeChildren = ParamUtil.getBoolean(
961                     actionRequest, "includeChildren_" + selPlid);
962 
963                 layoutIdMap.put(selPlid, includeChildren);
964             }
965         }
966 
967         String range = ParamUtil.getString(actionRequest, "range");
968 
969         Date startDate = null;
970         Date endDate = null;
971 
972         if (range.equals("dateRange")) {
973             startDate = _getDate(actionRequest, "startDate", true).getTime();
974 
975             endDate = _getDate(actionRequest, "endDate", true).getTime();
976         }
977         else if (range.equals("last")) {
978             int rangeLast = ParamUtil.getInteger(actionRequest, "last");
979 
980             Date now = new Date();
981 
982             startDate = new Date(now.getTime() - (rangeLast * Time.HOUR));
983 
984             endDate = now;
985         }
986 
987         if (schedule) {
988             String groupName = getSchedulerGroupName(
989                 DestinationNames.LAYOUTS_LOCAL_PUBLISHER, targetGroupId);
990 
991             int recurrenceType = ParamUtil.getInteger(
992                 actionRequest, "recurrenceType");
993 
994             Calendar startCal = _getDate(
995                 actionRequest, "schedulerStartDate", false);
996 
997             String cronText = _getCronText(
998                 actionRequest, startCal, false, recurrenceType);
999 
1000            Date schedulerEndDate = null;
1001
1002            int endDateType = ParamUtil.getInteger(
1003                actionRequest, "endDateType");
1004
1005            if (endDateType == 1) {
1006                Calendar endCal = _getDate(
1007                    actionRequest, "schedulerEndDate", false);
1008
1009                schedulerEndDate = endCal.getTime();
1010            }
1011
1012            String description = ParamUtil.getString(
1013                actionRequest, "description");
1014
1015            LayoutServiceUtil.schedulePublishToLive(
1016                sourceGroupId, targetGroupId, privateLayout, layoutIdMap,
1017                parameterMap, scope, startDate, endDate, groupName, cronText,
1018                startCal.getTime(), schedulerEndDate, description);
1019        }
1020        else {
1021            if (scope.equals("all-pages")) {
1022                publishLayouts(
1023                    sourceGroupId, targetGroupId, privateLayout, parameterMap,
1024                    startDate, endDate);
1025            }
1026            else {
1027                publishLayouts(
1028                    sourceGroupId, targetGroupId, privateLayout, layoutIdMap,
1029                    parameterMap, startDate, endDate);
1030            }
1031        }
1032    }
1033
1034    private static void _publishToRemote(
1035            ActionRequest actionRequest, boolean schedule)
1036        throws Exception {
1037
1038        String tabs1 = ParamUtil.getString(actionRequest, "tabs1");
1039
1040        long groupId = ParamUtil.getLong(actionRequest, "groupId");
1041
1042        boolean privateLayout = true;
1043
1044        if (tabs1.equals("public-pages")) {
1045            privateLayout = false;
1046        }
1047
1048        String scope = ParamUtil.getString(actionRequest, "scope");
1049
1050        if (Validator.isNull(scope)) {
1051            scope = "all-pages";
1052        }
1053
1054        Map<Long, Boolean> layoutIdMap = null;
1055        Map<String, String[]> parameterMap = actionRequest.getParameterMap();
1056
1057        if (scope.equals("selected-pages")) {
1058            layoutIdMap = new LinkedHashMap<Long, Boolean>();
1059
1060            long[] rowIds = ParamUtil.getLongValues(actionRequest, "rowIds");
1061
1062            for (long selPlid : rowIds) {
1063                boolean includeChildren = ParamUtil.getBoolean(
1064                    actionRequest, "includeChildren_" + selPlid);
1065
1066                layoutIdMap.put(selPlid, includeChildren);
1067            }
1068        }
1069
1070        String remoteAddress = ParamUtil.getString(
1071            actionRequest, "remoteAddress");
1072        int remotePort = ParamUtil.getInteger(actionRequest, "remotePort");
1073        boolean secureConnection = ParamUtil.getBoolean(
1074            actionRequest, "secureConnection");
1075
1076        long remoteGroupId = ParamUtil.getLong(actionRequest, "remoteGroupId");
1077        boolean remotePrivateLayout = ParamUtil.getBoolean(
1078            actionRequest, "remotePrivateLayout");
1079
1080        String range = ParamUtil.getString(actionRequest, "range");
1081
1082        Date startDate = null;
1083        Date endDate = null;
1084
1085        if (range.equals("dateRange")) {
1086            startDate = _getDate(actionRequest, "startDate", true).getTime();
1087
1088            endDate = _getDate(actionRequest, "endDate", true).getTime();
1089        }
1090        else if (range.equals("last")) {
1091            int rangeLast = ParamUtil.getInteger(actionRequest, "last");
1092
1093            Date now = new Date();
1094
1095            startDate = new Date(now.getTime() - (rangeLast * Time.HOUR));
1096
1097            endDate = now;
1098        }
1099
1100        if (schedule) {
1101            String groupName = getSchedulerGroupName(
1102                DestinationNames.LAYOUTS_REMOTE_PUBLISHER, groupId);
1103
1104            int recurrenceType = ParamUtil.getInteger(
1105                actionRequest, "recurrenceType");
1106
1107            Calendar startCal = _getDate(
1108                actionRequest, "schedulerStartDate", false);
1109
1110            String cronText = _getCronText(
1111                actionRequest, startCal, false, recurrenceType);
1112
1113            Date schedulerEndDate = null;
1114
1115            int endDateType = ParamUtil.getInteger(
1116                actionRequest, "endDateType");
1117
1118            if (endDateType == 1) {
1119                Calendar endCal = _getDate(
1120                    actionRequest, "schedulerEndDate", false);
1121
1122                schedulerEndDate = endCal.getTime();
1123            }
1124
1125            String description = ParamUtil.getString(
1126                actionRequest, "description");
1127
1128            LayoutServiceUtil.schedulePublishToRemote(
1129                groupId, privateLayout, layoutIdMap,
1130                getStagingParameters(actionRequest), remoteAddress, remotePort,
1131                secureConnection, remoteGroupId, remotePrivateLayout, startDate,
1132                endDate, groupName, cronText, startCal.getTime(),
1133                schedulerEndDate, description);
1134        }
1135        else {
1136            copyRemoteLayouts(
1137                groupId, privateLayout, layoutIdMap, parameterMap,
1138                remoteAddress, remotePort, secureConnection, remoteGroupId,
1139                remotePrivateLayout, getStagingParameters(actionRequest),
1140                startDate, endDate);
1141        }
1142    }
1143
1144    private static Log _log = LogFactory.getLog(StagingUtil.class);
1145
1146}