001    /**
002     * Copyright (c) 2000-2011 Liferay, Inc. All rights reserved.
003     *
004     * This library is free software; you can redistribute it and/or modify it under
005     * the terms of the GNU Lesser General Public License as published by the Free
006     * Software Foundation; either version 2.1 of the License, or (at your option)
007     * any later version.
008     *
009     * This library is distributed in the hope that it will be useful, but WITHOUT
010     * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
011     * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
012     * details.
013     */
014    
015    package com.liferay.portal.staging;
016    
017    import com.liferay.portal.NoSuchGroupException;
018    import com.liferay.portal.NoSuchLayoutException;
019    import com.liferay.portal.RemoteExportException;
020    import com.liferay.portal.RemoteOptionsException;
021    import com.liferay.portal.kernel.cal.DayAndPosition;
022    import com.liferay.portal.kernel.cal.Duration;
023    import com.liferay.portal.kernel.cal.Recurrence;
024    import com.liferay.portal.kernel.cal.RecurrenceSerializer;
025    import com.liferay.portal.kernel.exception.PortalException;
026    import com.liferay.portal.kernel.exception.SystemException;
027    import com.liferay.portal.kernel.lar.PortletDataHandlerKeys;
028    import com.liferay.portal.kernel.lar.UserIdStrategy;
029    import com.liferay.portal.kernel.messaging.DestinationNames;
030    import com.liferay.portal.kernel.messaging.MessageBusUtil;
031    import com.liferay.portal.kernel.messaging.MessageStatus;
032    import com.liferay.portal.kernel.staging.Staging;
033    import com.liferay.portal.kernel.staging.StagingConstants;
034    import com.liferay.portal.kernel.util.CalendarFactoryUtil;
035    import com.liferay.portal.kernel.util.GetterUtil;
036    import com.liferay.portal.kernel.util.Http;
037    import com.liferay.portal.kernel.util.HttpUtil;
038    import com.liferay.portal.kernel.util.LocaleUtil;
039    import com.liferay.portal.kernel.util.MapUtil;
040    import com.liferay.portal.kernel.util.ParamUtil;
041    import com.liferay.portal.kernel.util.StringBundler;
042    import com.liferay.portal.kernel.util.StringPool;
043    import com.liferay.portal.kernel.util.StringUtil;
044    import com.liferay.portal.kernel.util.Time;
045    import com.liferay.portal.kernel.util.TimeZoneUtil;
046    import com.liferay.portal.kernel.util.UnicodeProperties;
047    import com.liferay.portal.kernel.util.Validator;
048    import com.liferay.portal.lar.LayoutExporter;
049    import com.liferay.portal.model.Group;
050    import com.liferay.portal.model.Layout;
051    import com.liferay.portal.model.LayoutSet;
052    import com.liferay.portal.model.Portlet;
053    import com.liferay.portal.model.User;
054    import com.liferay.portal.security.auth.HttpPrincipal;
055    import com.liferay.portal.security.auth.PrincipalException;
056    import com.liferay.portal.security.permission.ActionKeys;
057    import com.liferay.portal.security.permission.PermissionChecker;
058    import com.liferay.portal.security.permission.PermissionThreadLocal;
059    import com.liferay.portal.service.GroupLocalServiceUtil;
060    import com.liferay.portal.service.GroupServiceUtil;
061    import com.liferay.portal.service.LayoutLocalServiceUtil;
062    import com.liferay.portal.service.LayoutServiceUtil;
063    import com.liferay.portal.service.LayoutSetLocalServiceUtil;
064    import com.liferay.portal.service.ServiceContext;
065    import com.liferay.portal.service.UserLocalServiceUtil;
066    import com.liferay.portal.service.http.GroupServiceHttp;
067    import com.liferay.portal.service.http.LayoutServiceHttp;
068    import com.liferay.portal.service.permission.GroupPermissionUtil;
069    import com.liferay.portal.theme.ThemeDisplay;
070    import com.liferay.portal.util.PropsValues;
071    import com.liferay.portal.util.WebKeys;
072    import com.liferay.portlet.communities.messaging.LayoutsLocalPublisherRequest;
073    import com.liferay.portlet.communities.messaging.LayoutsRemotePublisherRequest;
074    import com.liferay.portlet.tasks.service.TasksProposalLocalServiceUtil;
075    
076    import java.io.File;
077    
078    import java.util.ArrayList;
079    import java.util.Calendar;
080    import java.util.Date;
081    import java.util.Enumeration;
082    import java.util.HashSet;
083    import java.util.Iterator;
084    import java.util.LinkedHashMap;
085    import java.util.List;
086    import java.util.Locale;
087    import java.util.Map.Entry;
088    import java.util.Map;
089    import java.util.Set;
090    import java.util.TimeZone;
091    
092    import javax.portlet.PortletRequest;
093    
094    /**
095     * @author Raymond Augé
096     * @author Bruno Farache
097     * @author Wesley Gong
098     */
099    public class StagingImpl implements Staging {
100    
101            public void copyFromLive(PortletRequest portletRequest) throws Exception {
102                    long stagingGroupId = ParamUtil.getLong(
103                            portletRequest, "stagingGroupId");
104    
105                    Group stagingGroup = GroupLocalServiceUtil.getGroup(stagingGroupId);
106    
107                    long liveGroupId = stagingGroup.getLiveGroupId();
108    
109                    Map<String, String[]> parameterMap = getStagingParameters(
110                            portletRequest);
111    
112                    publishLayouts(
113                            portletRequest, liveGroupId, stagingGroupId, parameterMap, false);
114            }
115    
116            public void copyFromLive(PortletRequest portletRequest, Portlet portlet)
117                    throws Exception {
118    
119                    long plid = ParamUtil.getLong(portletRequest, "plid");
120    
121                    Layout targetLayout = LayoutLocalServiceUtil.getLayout(plid);
122    
123                    Group stagingGroup = targetLayout.getGroup();
124                    Group liveGroup = stagingGroup.getLiveGroup();
125    
126                    Layout sourceLayout = LayoutLocalServiceUtil.getLayout(
127                            liveGroup.getGroupId(), targetLayout.isPrivateLayout(),
128                            targetLayout.getLayoutId());
129    
130                    copyPortlet(
131                            portletRequest, liveGroup.getGroupId(), stagingGroup.getGroupId(),
132                            sourceLayout.getPlid(), targetLayout.getPlid(),
133                            portlet.getPortletId());
134            }
135    
136            public void copyPortlet(
137                            PortletRequest portletRequest, long sourceGroupId,
138                            long targetGroupId, long sourcePlid, long targetPlid,
139                            String portletId)
140                    throws Exception {
141    
142                    Map<String, String[]> parameterMap = getStagingParameters(
143                            portletRequest);
144    
145                    File file = LayoutLocalServiceUtil.exportPortletInfoAsFile(
146                            sourcePlid, sourceGroupId, portletId, parameterMap, null, null);
147    
148                    try {
149                            LayoutServiceUtil.importPortletInfo(
150                                    targetPlid, targetGroupId, portletId, parameterMap, file);
151                    }
152                    finally {
153                            file.delete();
154                    }
155            }
156    
157            public void copyRemoteLayouts(
158                            long sourceGroupId, boolean privateLayout,
159                            Map<Long, Boolean> layoutIdMap,
160                            Map<String, String[]> exportParameterMap, String remoteAddress,
161                            int remotePort, boolean secureConnection, long remoteGroupId,
162                            boolean remotePrivateLayout,
163                            Map<String, String[]> importParameterMap, Date startDate,
164                            Date endDate)
165                    throws Exception {
166    
167                    PermissionChecker permissionChecker =
168                            PermissionThreadLocal.getPermissionChecker();
169    
170                    User user = UserLocalServiceUtil.getUser(permissionChecker.getUserId());
171    
172                    StringBundler sb = new StringBundler(4);
173    
174                    if (secureConnection) {
175                            sb.append(Http.HTTPS_WITH_SLASH);
176                    }
177                    else {
178                            sb.append(Http.HTTP_WITH_SLASH);
179                    }
180    
181                    sb.append(remoteAddress);
182                    sb.append(StringPool.COLON);
183                    sb.append(remotePort);
184    
185                    String url = sb.toString();
186    
187                    HttpPrincipal httpPrincipal = new HttpPrincipal(
188                            url, user.getEmailAddress(), user.getPassword(),
189                            user.getPasswordEncrypted());
190    
191                    // Ping remote host and verify that the group exists
192    
193                    try {
194                            GroupServiceHttp.getGroup(httpPrincipal, remoteGroupId);
195                    }
196                    catch (NoSuchGroupException nsge) {
197                            RemoteExportException ree = new RemoteExportException(
198                                    RemoteExportException.NO_GROUP);
199    
200                            ree.setGroupId(remoteGroupId);
201    
202                            throw ree;
203                    }
204                    catch (SystemException se) {
205                            RemoteExportException ree = new RemoteExportException(
206                                    RemoteExportException.BAD_CONNECTION);
207    
208                            ree.setURL(url);
209    
210                            throw ree;
211                    }
212    
213                    byte[] bytes = null;
214    
215                    if (layoutIdMap == null) {
216                            bytes = LayoutServiceUtil.exportLayouts(
217                                    sourceGroupId, privateLayout, exportParameterMap, startDate,
218                                    endDate);
219                    }
220                    else {
221                            List<Layout> layouts = new ArrayList<Layout>();
222    
223                            Iterator<Map.Entry<Long, Boolean>> itr1 =
224                                    layoutIdMap.entrySet().iterator();
225    
226                            while (itr1.hasNext()) {
227                                    Entry<Long, Boolean> entry = itr1.next();
228    
229                                    long plid = GetterUtil.getLong(String.valueOf(entry.getKey()));
230                                    boolean includeChildren = entry.getValue();
231    
232                                    Layout layout = LayoutLocalServiceUtil.getLayout(plid);
233    
234                                    if (!layouts.contains(layout)) {
235                                            layouts.add(layout);
236                                    }
237    
238                                    Iterator<Layout> itr2 = getMissingParents(
239                                            layout, sourceGroupId).iterator();
240    
241                                    while (itr2.hasNext()) {
242                                            Layout parentLayout = itr2.next();
243    
244                                            if (!layouts.contains(parentLayout)) {
245                                                    layouts.add(parentLayout);
246                                            }
247                                    }
248    
249                                    if (includeChildren) {
250                                            itr2 = layout.getAllChildren().iterator();
251    
252                                            while (itr2.hasNext()) {
253                                                    Layout childLayout = itr2.next();
254    
255                                                    if (!layouts.contains(childLayout)) {
256                                                            layouts.add(childLayout);
257                                                    }
258                                            }
259                                    }
260                            }
261    
262                            long[] layoutIds = new long[layouts.size()];
263    
264                            for (int i = 0; i < layouts.size(); i++) {
265                                    Layout curLayout = layouts.get(i);
266    
267                                    layoutIds[i] = curLayout.getLayoutId();
268                            }
269    
270                            if (layoutIds.length <= 0) {
271                                    throw new RemoteExportException(
272                                            RemoteExportException.NO_LAYOUTS);
273                            }
274    
275                            bytes = LayoutServiceUtil.exportLayouts(
276                                    sourceGroupId, privateLayout, layoutIds, exportParameterMap,
277                                    startDate, endDate);
278                    }
279    
280                    LayoutServiceHttp.importLayouts(
281                            httpPrincipal, remoteGroupId, remotePrivateLayout,
282                            importParameterMap, bytes);
283            }
284    
285            public List<Layout> getMissingParents(
286                            Layout layout, long liveGroupId)
287                    throws PortalException, SystemException {
288    
289                    List<Layout> missingParents = new ArrayList<Layout>();
290    
291                    long parentLayoutId = layout.getParentLayoutId();
292    
293                    while (parentLayoutId > 0) {
294                            try {
295                                    LayoutLocalServiceUtil.getLayout(
296                                            liveGroupId, layout.isPrivateLayout(), parentLayoutId);
297    
298                                    // If one parent is found all others are assumed to exist
299    
300                                    break;
301                            }
302                            catch (NoSuchLayoutException nsle) {
303                                    Layout parent = LayoutLocalServiceUtil.getLayout(
304                                            layout.getGroupId(), layout.isPrivateLayout(),
305                                            parentLayoutId);
306    
307                                    missingParents.add(parent);
308    
309                                    parentLayoutId = parent.getParentLayoutId();
310                            }
311                    }
312    
313                    return missingParents;
314            }
315    
316            public String getSchedulerGroupName(
317                    String destinationName, long groupId) {
318    
319                    return destinationName.concat(StringPool.SLASH).concat(
320                            String.valueOf(groupId));
321            }
322    
323            public Map<String, String[]> getStagingParameters() {
324                    Map<String, String[]> parameterMap =
325                            new LinkedHashMap<String, String[]>();
326    
327                    parameterMap.put(
328                            PortletDataHandlerKeys.CATEGORIES,
329                            new String[] {Boolean.TRUE.toString()});
330                    parameterMap.put(
331                            PortletDataHandlerKeys.DATA_STRATEGY,
332                            new String[] {PortletDataHandlerKeys.DATA_STRATEGY_MIRROR});
333                    parameterMap.put(
334                            PortletDataHandlerKeys.DELETE_MISSING_LAYOUTS,
335                            new String[] {Boolean.TRUE.toString()});
336                    parameterMap.put(
337                            PortletDataHandlerKeys.DELETE_PORTLET_DATA,
338                            new String[] {Boolean.FALSE.toString()});
339                    parameterMap.put(
340                            PortletDataHandlerKeys.IGNORE_LAST_PUBLISH_DATE,
341                            new String[] {Boolean.TRUE.toString()});
342                    parameterMap.put(
343                            PortletDataHandlerKeys.PERMISSIONS,
344                            new String[] {Boolean.TRUE.toString()});
345                    parameterMap.put(
346                            PortletDataHandlerKeys.PORTLET_DATA,
347                            new String[] {Boolean.TRUE.toString()});
348                    parameterMap.put(
349                            PortletDataHandlerKeys.PORTLET_DATA_ALL,
350                            new String[] {Boolean.TRUE.toString()});
351                    parameterMap.put(
352                            PortletDataHandlerKeys.PORTLET_SETUP,
353                            new String[] {Boolean.TRUE.toString()});
354                    parameterMap.put(
355                            PortletDataHandlerKeys.PORTLET_USER_PREFERENCES,
356                            new String[] {Boolean.TRUE.toString()});
357                    parameterMap.put(
358                            PortletDataHandlerKeys.THEME,
359                            new String[] {Boolean.FALSE.toString()});
360                    parameterMap.put(
361                            PortletDataHandlerKeys.USER_ID_STRATEGY,
362                            new String[] {UserIdStrategy.CURRENT_USER_ID});
363                    parameterMap.put(
364                            PortletDataHandlerKeys.USER_PERMISSIONS,
365                            new String[] {Boolean.FALSE.toString()});
366    
367                    return parameterMap;
368            }
369    
370            public Map<String, String[]> getStagingParameters(
371                    PortletRequest portletRequest) {
372    
373                    Map<String, String[]> parameterMap =
374                            new LinkedHashMap<String, String[]>(
375                                    portletRequest.getParameterMap());
376    
377                    if (!parameterMap.containsKey(PortletDataHandlerKeys.DATA_STRATEGY)) {
378                            parameterMap.put(
379                                    PortletDataHandlerKeys.DATA_STRATEGY,
380                                    new String[] {PortletDataHandlerKeys.DATA_STRATEGY_MIRROR});
381                    }
382    
383                    if (!parameterMap.containsKey(
384                                    PortletDataHandlerKeys.DELETE_MISSING_LAYOUTS)) {
385    
386                            parameterMap.put(
387                                    PortletDataHandlerKeys.DELETE_MISSING_LAYOUTS,
388                                    new String[] {Boolean.TRUE.toString()});
389                    }
390    
391                    if (!parameterMap.containsKey(
392                                    PortletDataHandlerKeys.DELETE_PORTLET_DATA)) {
393    
394                            parameterMap.put(
395                                    PortletDataHandlerKeys.DELETE_PORTLET_DATA,
396                                    new String[] {Boolean.FALSE.toString()});
397                    }
398    
399                    if (!parameterMap.containsKey(
400                                    PortletDataHandlerKeys.PORTLET_DATA)) {
401    
402                            parameterMap.put(
403                                    PortletDataHandlerKeys.PORTLET_DATA,
404                                    new String[] {Boolean.FALSE.toString()});
405                    }
406    
407                    if (!parameterMap.containsKey(
408                                    PortletDataHandlerKeys.PORTLET_DATA_ALL)) {
409    
410                            parameterMap.put(
411                                    PortletDataHandlerKeys.PORTLET_DATA_ALL,
412                                    new String[] {Boolean.FALSE.toString()});
413                    }
414    
415                    if (!parameterMap.containsKey(PortletDataHandlerKeys.PORTLET_SETUP)) {
416                            parameterMap.put(
417                                    PortletDataHandlerKeys.PORTLET_SETUP,
418                                    new String[] {Boolean.TRUE.toString()});
419                    }
420    
421                    if (!parameterMap.containsKey(
422                                    PortletDataHandlerKeys.PORTLET_USER_PREFERENCES)) {
423    
424                            parameterMap.put(
425                                    PortletDataHandlerKeys.PORTLET_USER_PREFERENCES,
426                                    new String[] {Boolean.TRUE.toString()});
427                    }
428    
429                    if (!parameterMap.containsKey(PortletDataHandlerKeys.THEME)) {
430                            parameterMap.put(
431                                    PortletDataHandlerKeys.THEME,
432                                    new String[] {Boolean.FALSE.toString()});
433                    }
434    
435                    if (!parameterMap.containsKey(
436                                    PortletDataHandlerKeys.USER_ID_STRATEGY)) {
437    
438                            parameterMap.put(
439                                    PortletDataHandlerKeys.USER_ID_STRATEGY,
440                                    new String[] {UserIdStrategy.CURRENT_USER_ID});
441                    }
442    
443                    return parameterMap;
444            }
445    
446            public void publishLayout(
447                            long plid, long liveGroupId, boolean includeChildren)
448                    throws Exception {
449    
450                    Map<String, String[]> parameterMap = getStagingParameters();
451    
452                    parameterMap.put(
453                            PortletDataHandlerKeys.DELETE_MISSING_LAYOUTS,
454                            new String[] {Boolean.FALSE.toString()});
455    
456                    Layout layout = LayoutLocalServiceUtil.getLayout(plid);
457    
458                    List<Layout> layouts = new ArrayList<Layout>();
459    
460                    layouts.add(layout);
461    
462                    layouts.addAll(getMissingParents(layout, liveGroupId));
463    
464                    if (includeChildren) {
465                            layouts.addAll(layout.getAllChildren());
466                    }
467    
468                    Iterator<Layout> itr = layouts.iterator();
469    
470                    long[] layoutIds = new long[layouts.size()];
471    
472                    for (int i = 0; itr.hasNext(); i++) {
473                            Layout curLayout = itr.next();
474    
475                            layoutIds[i] = curLayout.getLayoutId();
476                    }
477    
478                    publishLayouts(
479                            layout.getGroupId(), liveGroupId, layout.isPrivateLayout(),
480                            layoutIds, parameterMap, null, null);
481            }
482    
483            public void publishLayouts(
484                            long sourceGroupId, long targetGroupId, boolean privateLayout,
485                            long[] layoutIds, Map<String, String[]> parameterMap,
486                            Date startDate, Date endDate)
487                    throws Exception {
488    
489                    File file = LayoutLocalServiceUtil.exportLayoutsAsFile(
490                            sourceGroupId, privateLayout, layoutIds, parameterMap, startDate,
491                            endDate);
492    
493                    try {
494                            LayoutServiceUtil.importLayouts(
495                                    targetGroupId, privateLayout, parameterMap, file);
496                    }
497                    finally {
498                            file.delete();
499                    }
500            }
501    
502            public void publishLayouts(
503                            long sourceGroupId, long targetGroupId, boolean privateLayout,
504                            Map<Long, Boolean> layoutIdMap, Map<String, String[]> parameterMap,
505                            Date startDate, Date endDate)
506                    throws Exception {
507    
508                    parameterMap.put(
509                            PortletDataHandlerKeys.DELETE_MISSING_LAYOUTS,
510                            new String[] {Boolean.FALSE.toString()});
511    
512                    List<Layout> layouts = new ArrayList<Layout>();
513    
514                    Iterator<Map.Entry<Long, Boolean>> itr1 =
515                            layoutIdMap.entrySet().iterator();
516    
517                    while (itr1.hasNext()) {
518                            Entry<Long, Boolean> entry = itr1.next();
519    
520                            long plid = GetterUtil.getLong(String.valueOf(entry.getKey()));
521                            boolean includeChildren = entry.getValue();
522    
523                            Layout layout = LayoutLocalServiceUtil.getLayout(plid);
524    
525                            if (!layouts.contains(layout)) {
526                                    layouts.add(layout);
527                            }
528    
529                            Iterator<Layout> itr2 = getMissingParents(
530                                    layout, targetGroupId).iterator();
531    
532                            while (itr2.hasNext()) {
533                                    Layout parentLayout = itr2.next();
534    
535                                    if (!layouts.contains(parentLayout)) {
536                                            layouts.add(parentLayout);
537                                    }
538                            }
539    
540                            if (includeChildren) {
541                                    itr2 = layout.getAllChildren().iterator();
542    
543                                    while (itr2.hasNext()) {
544                                            Layout childLayout = itr2.next();
545    
546                                            if (!layouts.contains(childLayout)) {
547                                                    layouts.add(childLayout);
548                                            }
549                                    }
550                            }
551                    }
552    
553                    long[] layoutIds = new long[layouts.size()];
554    
555                    for (int i = 0; i < layouts.size(); i++) {
556                            Layout curLayout = layouts.get(i);
557    
558                            layoutIds[i] = curLayout.getLayoutId();
559                    }
560    
561                    publishLayouts(
562                            sourceGroupId, targetGroupId, privateLayout, layoutIds,
563                            parameterMap, startDate, endDate);
564            }
565    
566            public void publishLayouts(
567                            long sourceGroupId, long targetGroupId, boolean privateLayout,
568                            Map<String, String[]> parameterMap, Date startDate, Date endDate)
569                    throws Exception {
570    
571                    publishLayouts(
572                            sourceGroupId, targetGroupId, privateLayout, (long[])null,
573                            parameterMap, startDate, endDate);
574            }
575    
576            public void publishToLive(PortletRequest portletRequest) throws Exception {
577                    long groupId = ParamUtil.getLong(portletRequest, "groupId");
578    
579                    Group liveGroup = GroupLocalServiceUtil.getGroup(groupId);
580    
581                    Map<String, String[]> parameterMap = getStagingParameters(
582                            portletRequest);
583    
584                    if (liveGroup.isStaged()) {
585                            if (liveGroup.isStagedRemotely()) {
586                                    publishToRemote(portletRequest);
587                            }
588                            else {
589                                    Group stagingGroup = liveGroup.getStagingGroup();
590    
591                                    publishLayouts(
592                                            portletRequest, stagingGroup.getGroupId(), groupId,
593                                            parameterMap, false);
594                            }
595                    }
596            }
597    
598            public void publishToLive(PortletRequest portletRequest, Portlet portlet)
599                    throws Exception {
600    
601                    long plid = ParamUtil.getLong(portletRequest, "plid");
602    
603                    Layout sourceLayout = LayoutLocalServiceUtil.getLayout(plid);
604    
605                    Group stagingGroup = sourceLayout.getGroup();
606                    Group liveGroup = stagingGroup.getLiveGroup();
607    
608                    Layout targetLayout = LayoutLocalServiceUtil.getLayout(
609                            liveGroup.getGroupId(), sourceLayout.isPrivateLayout(),
610                            sourceLayout.getLayoutId());
611    
612                    copyPortlet(
613                            portletRequest, stagingGroup.getGroupId(), liveGroup.getGroupId(),
614                            sourceLayout.getPlid(), targetLayout.getPlid(),
615                            portlet.getPortletId());
616            }
617    
618            public void publishToRemote(PortletRequest portletRequest)
619                    throws Exception {
620    
621                    publishToRemote(portletRequest, false);
622            }
623    
624            public void scheduleCopyFromLive(PortletRequest portletRequest)
625                    throws Exception {
626    
627                    long stagingGroupId = ParamUtil.getLong(
628                            portletRequest, "stagingGroupId");
629    
630                    Group stagingGroup = GroupLocalServiceUtil.getGroup(stagingGroupId);
631    
632                    long liveGroupId = stagingGroup.getLiveGroupId();
633    
634                    Map<String, String[]> parameterMap = getStagingParameters(
635                            portletRequest);
636    
637                    publishLayouts(
638                            portletRequest, liveGroupId, stagingGroupId, parameterMap, true);
639            }
640    
641            public void schedulePublishToLive(PortletRequest portletRequest)
642                    throws Exception {
643    
644                    long stagingGroupId = ParamUtil.getLong(
645                            portletRequest, "stagingGroupId");
646    
647                    Group stagingGroup = GroupLocalServiceUtil.getGroup(stagingGroupId);
648    
649                    long liveGroupId = stagingGroup.getLiveGroupId();
650    
651                    Map<String, String[]> parameterMap = getStagingParameters(
652                            portletRequest);
653    
654                    publishLayouts(
655                            portletRequest, stagingGroupId, liveGroupId, parameterMap, true);
656            }
657    
658            public void schedulePublishToRemote(PortletRequest portletRequest)
659                    throws Exception {
660    
661                    publishToRemote(portletRequest, true);
662            }
663    
664            public void unscheduleCopyFromLive(PortletRequest portletRequest)
665                    throws Exception {
666    
667                    long stagingGroupId = ParamUtil.getLong(
668                            portletRequest, "stagingGroupId");
669    
670                    String jobName = ParamUtil.getString(portletRequest, "jobName");
671                    String groupName = getSchedulerGroupName(
672                            DestinationNames.LAYOUTS_LOCAL_PUBLISHER, stagingGroupId);
673    
674                    LayoutServiceUtil.unschedulePublishToLive(
675                            stagingGroupId, jobName, groupName);
676            }
677    
678            public void unschedulePublishToLive(PortletRequest portletRequest)
679                    throws Exception {
680    
681                    long stagingGroupId = ParamUtil.getLong(
682                            portletRequest, "stagingGroupId");
683    
684                    Group stagingGroup = GroupLocalServiceUtil.getGroup(stagingGroupId);
685    
686                    long liveGroupId = stagingGroup.getLiveGroupId();
687    
688                    String jobName = ParamUtil.getString(portletRequest, "jobName");
689                    String groupName = getSchedulerGroupName(
690                            DestinationNames.LAYOUTS_LOCAL_PUBLISHER, liveGroupId);
691    
692                    LayoutServiceUtil.unschedulePublishToLive(
693                            liveGroupId, jobName, groupName);
694            }
695    
696            public void unschedulePublishToRemote(PortletRequest portletRequest)
697                    throws Exception {
698    
699                    long groupId = ParamUtil.getLong(portletRequest, "groupId");
700    
701                    String jobName = ParamUtil.getString(portletRequest, "jobName");
702                    String groupName = getSchedulerGroupName(
703                            DestinationNames.LAYOUTS_REMOTE_PUBLISHER, groupId);
704    
705                    LayoutServiceUtil.unschedulePublishToRemote(
706                            groupId, jobName, groupName);
707            }
708    
709            public void updateStaging(PortletRequest portletRequest) throws Exception {
710                    ThemeDisplay themeDisplay = (ThemeDisplay)portletRequest.getAttribute(
711                            WebKeys.THEME_DISPLAY);
712    
713                    PermissionChecker permissionChecker =
714                            themeDisplay.getPermissionChecker();
715    
716                    long liveGroupId = ParamUtil.getLong(portletRequest, "liveGroupId");
717    
718                    if (!GroupPermissionUtil.contains(
719                                    permissionChecker, liveGroupId, ActionKeys.MANAGE_STAGING)) {
720    
721                            throw new PrincipalException();
722                    }
723    
724                    int stagingType = ParamUtil.getInteger(portletRequest, "stagingType");
725    
726                    if (stagingType == StagingConstants.TYPE_NOT_STAGED) {
727                            disableStaging(portletRequest, liveGroupId);
728                    }
729                    else if (stagingType == StagingConstants.TYPE_LOCAL_STAGING) {
730                            enableLocalStaging(portletRequest, liveGroupId);
731                    }
732                    else if (stagingType == StagingConstants.TYPE_REMOTE_STAGING) {
733                            enableRemoteStaging(portletRequest, liveGroupId);
734                    }
735            }
736    
737            protected void addWeeklyDayPos(
738                    PortletRequest portletRequest, List<DayAndPosition> list, int day) {
739    
740                    if (ParamUtil.getBoolean(portletRequest, "weeklyDayPos" + day)) {
741                            list.add(new DayAndPosition(day, 0));
742                    }
743            }
744    
745            protected void disableStaging(
746                            PortletRequest portletRequest, long liveGroupId)
747                    throws Exception {
748    
749                    Group liveGroup = GroupLocalServiceUtil.getGroup(liveGroupId);
750    
751                    UnicodeProperties typeSettingsProperties =
752                            liveGroup.getTypeSettingsProperties();
753    
754                    typeSettingsProperties.remove("remoteAddress");
755                    typeSettingsProperties.remove("remoteGroupId");
756                    typeSettingsProperties.remove("remotePort");
757                    typeSettingsProperties.remove("secureConnection");
758                    typeSettingsProperties.remove("staged");
759                    typeSettingsProperties.remove("stagedRemotely");
760                    typeSettingsProperties.remove("workflowEnabled");
761                    typeSettingsProperties.remove("workflowRoleNames");
762                    typeSettingsProperties.remove("workflowStages");
763    
764                    Set<String> keys = new HashSet<String>();
765    
766                    for (String key : typeSettingsProperties.keySet()) {
767                            if (key.startsWith(StagingConstants.STAGED_PORTLET)) {
768                                    keys.add(key);
769                            }
770                    }
771    
772                    for (String key : keys) {
773                            typeSettingsProperties.remove(key);
774                    }
775    
776                    if (liveGroup.hasStagingGroup()) {
777                            ThemeDisplay themeDisplay =
778                                    (ThemeDisplay)portletRequest.getAttribute(
779                                            WebKeys.THEME_DISPLAY);
780    
781                            if (themeDisplay.getScopeGroupId() != liveGroup.getGroupId()) {
782                                    String redirect = ParamUtil.getString(
783                                            portletRequest, "pagesRedirect");
784    
785                                    redirect = HttpUtil.removeParameter(redirect, "refererPlid");
786    
787                                    redirect = StringUtil.replace(
788                                            redirect, String.valueOf(themeDisplay.getScopeGroupId()),
789                                            String.valueOf(liveGroup.getGroupId()));
790    
791                                    portletRequest.setAttribute(WebKeys.REDIRECT, redirect);
792                            }
793    
794                            GroupLocalServiceUtil.deleteGroup(
795                                    liveGroup.getStagingGroup().getGroupId());
796    
797                            TasksProposalLocalServiceUtil.deleteProposals(
798                                    liveGroup.getGroupId());
799                    }
800    
801                    GroupLocalServiceUtil.updateGroup(
802                            liveGroup.getGroupId(), typeSettingsProperties.toString());
803            }
804    
805            protected void enableLocalStaging(
806                            PortletRequest portletRequest, long liveGroupId)
807                    throws Exception {
808    
809                    Group liveGroup = GroupServiceUtil.getGroup(liveGroupId);
810    
811                    if (liveGroup.isStagedRemotely()) {
812                            disableStaging(portletRequest, liveGroupId);
813                    }
814    
815                    UnicodeProperties typeSettingsProperties =
816                            liveGroup.getTypeSettingsProperties();
817    
818                    typeSettingsProperties.setProperty(
819                            "staged", Boolean.TRUE.toString());
820                    typeSettingsProperties.setProperty(
821                            "stagedRemotely", String.valueOf(false));
822    
823                    setCommonStagingOptions(
824                            portletRequest, liveGroup, typeSettingsProperties);
825    
826                    if (!liveGroup.hasStagingGroup()) {
827                            ServiceContext serviceContext = new ServiceContext();
828    
829                            serviceContext.setAttribute("staging", String.valueOf(true));
830    
831                            Group stagingGroup = GroupLocalServiceUtil.addGroup(
832                                    liveGroup.getCreatorUserId(), liveGroup.getClassName(),
833                                    liveGroup.getClassPK(), liveGroup.getGroupId(),
834                                    liveGroup.getDescriptiveName(), liveGroup.getDescription(),
835                                    liveGroup.getType(), liveGroup.getFriendlyURL(),
836                                    liveGroup.isActive(), serviceContext);
837    
838                            GroupServiceUtil.updateGroup(
839                                    liveGroup.getGroupId(), typeSettingsProperties.toString());
840    
841                            if (liveGroup.hasPrivateLayouts()) {
842                                    Map<String, String[]> parameterMap = getStagingParameters();
843    
844                                    publishLayouts(
845                                            liveGroup.getGroupId(), stagingGroup.getGroupId(), true,
846                                            parameterMap, null, null);
847                            }
848    
849                            if (liveGroup.hasPublicLayouts()) {
850                                    Map<String, String[]> parameterMap = getStagingParameters();
851    
852                                    publishLayouts(
853                                            liveGroup.getGroupId(), stagingGroup.getGroupId(), false,
854                                            parameterMap, null, null);
855                            }
856                    }
857                    else {
858                            GroupServiceUtil.updateGroup(
859                                    liveGroup.getGroupId(), typeSettingsProperties.toString());
860                    }
861            }
862    
863            protected void enableRemoteStaging(
864                            PortletRequest portletRequest, long liveGroupId)
865                    throws Exception {
866    
867                    Group liveGroup = GroupServiceUtil.getGroup(liveGroupId);
868    
869                    String remoteAddress = ParamUtil.getString(
870                            portletRequest, "remoteAddress");
871                    long remoteGroupId = ParamUtil.getLong(portletRequest, "remoteGroupId");
872                    int remotePort = ParamUtil.getInteger(portletRequest, "remotePort");
873                    boolean secureConnection = ParamUtil.getBoolean(
874                            portletRequest, "secureConnection");
875    
876                    validate(remoteAddress, remoteGroupId, remotePort, secureConnection);
877    
878                    if (liveGroup.hasStagingGroup()) {
879                            disableStaging(portletRequest, liveGroupId);
880                    }
881    
882                    UnicodeProperties typeSettingsProperties =
883                            liveGroup.getTypeSettingsProperties();
884    
885                    typeSettingsProperties.setProperty("remoteAddress", remoteAddress);
886                    typeSettingsProperties.setProperty(
887                            "remoteGroupId", String.valueOf(remoteGroupId));
888                    typeSettingsProperties.setProperty(
889                            "remotePort", String.valueOf(remotePort));
890                    typeSettingsProperties.setProperty(
891                            "secureConnection", String.valueOf(secureConnection));
892                    typeSettingsProperties.setProperty("staged", Boolean.TRUE.toString());
893                    typeSettingsProperties.setProperty(
894                            "stagedRemotely", Boolean.TRUE.toString());
895    
896                    setCommonStagingOptions(
897                            portletRequest, liveGroup, typeSettingsProperties);
898    
899                    GroupServiceUtil.updateGroup(
900                            liveGroup.getGroupId(), typeSettingsProperties.toString());
901            }
902    
903            protected String getCronText(
904                            PortletRequest portletRequest, Calendar startDate,
905                            boolean timeZoneSensitive, int recurrenceType)
906                    throws Exception {
907    
908                    Calendar startCal = null;
909    
910                    if (timeZoneSensitive) {
911                            startCal = CalendarFactoryUtil.getCalendar();
912    
913                            startCal.setTime(startDate.getTime());
914                    }
915                    else {
916                            startCal = (Calendar)startDate.clone();
917                    }
918    
919                    Recurrence recurrence = new Recurrence(
920                            startCal, new Duration(1, 0, 0, 0), recurrenceType);
921    
922                    recurrence.setWeekStart(Calendar.SUNDAY);
923    
924                    if (recurrenceType == Recurrence.DAILY) {
925                            int dailyType = ParamUtil.getInteger(portletRequest, "dailyType");
926    
927                            if (dailyType == 0) {
928                                    int dailyInterval = ParamUtil.getInteger(
929                                            portletRequest, "dailyInterval", 1);
930    
931                                    recurrence.setInterval(dailyInterval);
932                            }
933                            else {
934                                    DayAndPosition[] dayPos = {
935                                            new DayAndPosition(Calendar.MONDAY, 0),
936                                            new DayAndPosition(Calendar.TUESDAY, 0),
937                                            new DayAndPosition(Calendar.WEDNESDAY, 0),
938                                            new DayAndPosition(Calendar.THURSDAY, 0),
939                                            new DayAndPosition(Calendar.FRIDAY, 0)};
940    
941                                    recurrence.setByDay(dayPos);
942                            }
943                    }
944                    else if (recurrenceType == Recurrence.WEEKLY) {
945                            int weeklyInterval = ParamUtil.getInteger(
946                                    portletRequest, "weeklyInterval", 1);
947    
948                            recurrence.setInterval(weeklyInterval);
949    
950                            List<DayAndPosition> dayPos = new ArrayList<DayAndPosition>();
951    
952                            addWeeklyDayPos(portletRequest, dayPos, Calendar.SUNDAY);
953                            addWeeklyDayPos(portletRequest, dayPos, Calendar.MONDAY);
954                            addWeeklyDayPos(portletRequest, dayPos, Calendar.TUESDAY);
955                            addWeeklyDayPos(portletRequest, dayPos, Calendar.WEDNESDAY);
956                            addWeeklyDayPos(portletRequest, dayPos, Calendar.THURSDAY);
957                            addWeeklyDayPos(portletRequest, dayPos, Calendar.FRIDAY);
958                            addWeeklyDayPos(portletRequest, dayPos, Calendar.SATURDAY);
959    
960                            if (dayPos.size() == 0) {
961                                    dayPos.add(new DayAndPosition(Calendar.MONDAY, 0));
962                            }
963    
964                            recurrence.setByDay(dayPos.toArray(new DayAndPosition[0]));
965                    }
966                    else if (recurrenceType == Recurrence.MONTHLY) {
967                            int monthlyType = ParamUtil.getInteger(
968                                    portletRequest, "monthlyType");
969    
970                            if (monthlyType == 0) {
971                                    int monthlyDay = ParamUtil.getInteger(
972                                            portletRequest, "monthlyDay0", 1);
973    
974                                    recurrence.setByMonthDay(new int[] {monthlyDay});
975    
976                                    int monthlyInterval = ParamUtil.getInteger(
977                                            portletRequest, "monthlyInterval0", 1);
978    
979                                    recurrence.setInterval(monthlyInterval);
980                            }
981                            else {
982                                    int monthlyPos = ParamUtil.getInteger(
983                                            portletRequest, "monthlyPos");
984                                    int monthlyDay = ParamUtil.getInteger(
985                                            portletRequest, "monthlyDay1");
986    
987                                    DayAndPosition[] dayPos = {
988                                            new DayAndPosition(monthlyDay, monthlyPos)};
989    
990                                    recurrence.setByDay(dayPos);
991    
992                                    int monthlyInterval = ParamUtil.getInteger(
993                                            portletRequest, "monthlyInterval1", 1);
994    
995                                    recurrence.setInterval(monthlyInterval);
996                            }
997                    }
998                    else if (recurrenceType == Recurrence.YEARLY) {
999                            int yearlyType = ParamUtil.getInteger(portletRequest, "yearlyType");
1000    
1001                            if (yearlyType == 0) {
1002                                    int yearlyMonth = ParamUtil.getInteger(
1003                                            portletRequest, "yearlyMonth0");
1004                                    int yearlyDay = ParamUtil.getInteger(
1005                                            portletRequest, "yearlyDay0", 1);
1006    
1007                                    recurrence.setByMonth(new int[] {yearlyMonth});
1008                                    recurrence.setByMonthDay(new int[] {yearlyDay});
1009    
1010                                    int yearlyInterval = ParamUtil.getInteger(
1011                                            portletRequest, "yearlyInterval0", 1);
1012    
1013                                    recurrence.setInterval(yearlyInterval);
1014                            }
1015                            else {
1016                                    int yearlyPos = ParamUtil.getInteger(
1017                                            portletRequest, "yearlyPos");
1018                                    int yearlyDay = ParamUtil.getInteger(
1019                                            portletRequest, "yearlyDay1");
1020                                    int yearlyMonth = ParamUtil.getInteger(
1021                                            portletRequest, "yearlyMonth1");
1022    
1023                                    DayAndPosition[] dayPos = {
1024                                            new DayAndPosition(yearlyDay, yearlyPos)};
1025    
1026                                    recurrence.setByDay(dayPos);
1027    
1028                                    recurrence.setByMonth(new int[] {yearlyMonth});
1029    
1030                                    int yearlyInterval = ParamUtil.getInteger(
1031                                            portletRequest, "yearlyInterval1", 1);
1032    
1033                                    recurrence.setInterval(yearlyInterval);
1034                            }
1035                    }
1036    
1037                    return RecurrenceSerializer.toCronText(recurrence);
1038            }
1039    
1040            protected Calendar getDate(
1041                            PortletRequest portletRequest, String paramPrefix,
1042                            boolean timeZoneSensitive)
1043                    throws Exception {
1044    
1045                    int dateMonth = ParamUtil.getInteger(
1046                            portletRequest, paramPrefix + "Month");
1047                    int dateDay = ParamUtil.getInteger(portletRequest, paramPrefix + "Day");
1048                    int dateYear = ParamUtil.getInteger(
1049                            portletRequest, paramPrefix + "Year");
1050                    int dateHour = ParamUtil.getInteger(
1051                            portletRequest, paramPrefix + "Hour");
1052                    int dateMinute = ParamUtil.getInteger(
1053                            portletRequest, paramPrefix + "Minute");
1054                    int dateAmPm = ParamUtil.getInteger(
1055                            portletRequest, paramPrefix + "AmPm");
1056    
1057                    if (dateAmPm == Calendar.PM) {
1058                            dateHour += 12;
1059                    }
1060    
1061                    Locale locale = null;
1062                    TimeZone timeZone = null;
1063    
1064                    if (timeZoneSensitive) {
1065                            ThemeDisplay themeDisplay =
1066                                    (ThemeDisplay)portletRequest.getAttribute(
1067                                            WebKeys.THEME_DISPLAY);
1068    
1069                            locale = themeDisplay.getLocale();
1070                            timeZone = themeDisplay.getTimeZone();
1071                    }
1072                    else {
1073                            locale = LocaleUtil.getDefault();
1074                            timeZone = TimeZoneUtil.getDefault();
1075                    }
1076    
1077                    Calendar cal = CalendarFactoryUtil.getCalendar(timeZone, locale);
1078    
1079                    cal.set(Calendar.MONTH, dateMonth);
1080                    cal.set(Calendar.DATE, dateDay);
1081                    cal.set(Calendar.YEAR, dateYear);
1082                    cal.set(Calendar.HOUR_OF_DAY, dateHour);
1083                    cal.set(Calendar.MINUTE, dateMinute);
1084                    cal.set(Calendar.SECOND, 0);
1085                    cal.set(Calendar.MILLISECOND, 0);
1086    
1087                    return cal;
1088            }
1089    
1090            protected String getWorkflowRoleNames(PortletRequest portletRequest) {
1091                    int workflowStages = ParamUtil.getInteger(
1092                            portletRequest, "workflowStages");
1093    
1094                    String workflowRoleNames = null;
1095    
1096                    if (workflowStages == 0) {
1097                            workflowRoleNames = StringPool.BLANK;
1098                    }
1099                    else {
1100                            StringBundler sb = new StringBundler(workflowStages * 2 - 1);
1101    
1102                            for (int i = 1; i <= (workflowStages - 1); i++) {
1103                                    if (i > 1) {
1104                                            sb.append(StringPool.COMMA);
1105                                    }
1106    
1107                                    String workflowRoleName = ParamUtil.getString(
1108                                            portletRequest, "workflowRoleName_" + i);
1109    
1110                                    sb.append(workflowRoleName);
1111                            }
1112    
1113                            String workflowRoleName = ParamUtil.getString(
1114                                    portletRequest, "workflowRoleName_Last");
1115    
1116                            sb.append(",");
1117                            sb.append(workflowRoleName);
1118    
1119                            workflowRoleNames = sb.toString();
1120                    }
1121    
1122                    return workflowRoleNames;
1123            }
1124    
1125            protected void publishLayouts(
1126                            PortletRequest portletRequest, long sourceGroupId,
1127                            long targetGroupId, Map<String, String[]> parameterMap,
1128                            boolean schedule)
1129                    throws Exception {
1130    
1131                    ThemeDisplay themeDisplay =
1132                            (ThemeDisplay)portletRequest.getAttribute(WebKeys.THEME_DISPLAY);
1133    
1134                    String tabs1 = ParamUtil.getString(portletRequest, "tabs1");
1135    
1136                    boolean privateLayout = true;
1137    
1138                    if (tabs1.equals("public-pages")) {
1139                            privateLayout = false;
1140                    }
1141    
1142                    String scope = ParamUtil.getString(portletRequest, "scope");
1143    
1144                    Map<Long, Boolean> layoutIdMap = new LinkedHashMap<Long, Boolean>();
1145    
1146                    if (scope.equals("selected-pages")) {
1147                            long[] rowIds = ParamUtil.getLongValues(portletRequest, "rowIds");
1148    
1149                            for (long selPlid : rowIds) {
1150                                    boolean includeChildren = ParamUtil.getBoolean(
1151                                            portletRequest, "includeChildren_" + selPlid);
1152    
1153                                    layoutIdMap.put(selPlid, includeChildren);
1154                            }
1155                    }
1156    
1157                    String range = ParamUtil.getString(portletRequest, "range");
1158    
1159                    Date startDate = null;
1160                    Date endDate = null;
1161    
1162                    if (range.equals("dateRange")) {
1163                            startDate = getDate(portletRequest, "startDate", true).getTime();
1164    
1165                            endDate = getDate(portletRequest, "endDate", true).getTime();
1166                    }
1167                    else if (range.equals("fromLastPublishDate")) {
1168                            LayoutSet layoutSet = LayoutSetLocalServiceUtil.getLayoutSet(
1169                                    sourceGroupId, privateLayout);
1170    
1171                            UnicodeProperties settingsProperties =
1172                                    layoutSet.getSettingsProperties();
1173    
1174                            long lastPublishDate = GetterUtil.getLong(
1175                                    settingsProperties.getProperty("last-publish-date"));
1176    
1177                            if (lastPublishDate > 0) {
1178                                    Calendar cal = Calendar.getInstance(
1179                                            themeDisplay.getTimeZone(), themeDisplay.getLocale());
1180    
1181                                    endDate = cal.getTime();
1182    
1183                                    cal.setTimeInMillis(lastPublishDate);
1184    
1185                                    startDate = cal.getTime();
1186                            }
1187                    }
1188                    else if (range.equals("last")) {
1189                            int rangeLast = ParamUtil.getInteger(portletRequest, "last");
1190    
1191                            Date now = new Date();
1192    
1193                            startDate = new Date(now.getTime() - (rangeLast * Time.HOUR));
1194    
1195                            endDate = now;
1196                    }
1197    
1198                    if (schedule) {
1199                            String groupName = getSchedulerGroupName(
1200                                    DestinationNames.LAYOUTS_LOCAL_PUBLISHER, targetGroupId);
1201    
1202                            int recurrenceType = ParamUtil.getInteger(
1203                                    portletRequest, "recurrenceType");
1204    
1205                            Calendar startCal = getDate(
1206                                    portletRequest, "schedulerStartDate", true);
1207    
1208                            String cronText = getCronText(
1209                                    portletRequest, startCal, true, recurrenceType);
1210    
1211                            Date schedulerEndDate = null;
1212    
1213                            int endDateType = ParamUtil.getInteger(
1214                                    portletRequest, "endDateType");
1215    
1216                            if (endDateType == 1) {
1217                                    Calendar endCal = getDate(
1218                                            portletRequest, "schedulerEndDate", true);
1219    
1220                                    schedulerEndDate = endCal.getTime();
1221                            }
1222    
1223                            String description = ParamUtil.getString(
1224                                    portletRequest, "description");
1225    
1226                            LayoutServiceUtil.schedulePublishToLive(
1227                                    sourceGroupId, targetGroupId, privateLayout, layoutIdMap,
1228                                    parameterMap, scope, startDate, endDate, groupName, cronText,
1229                                    startCal.getTime(), schedulerEndDate, description);
1230                    }
1231                    else {
1232                            MessageStatus messageStatus = new MessageStatus();
1233    
1234                            messageStatus.startTimer();
1235    
1236                            String command =
1237                                    LayoutsLocalPublisherRequest.COMMAND_SELECTED_PAGES;
1238    
1239                            try {
1240                                    if (scope.equals("all-pages")) {
1241                                            command = LayoutsLocalPublisherRequest.COMMAND_ALL_PAGES;
1242    
1243                                            publishLayouts(
1244                                                    sourceGroupId, targetGroupId, privateLayout,
1245                                                    parameterMap, startDate, endDate);
1246                                    }
1247                                    else {
1248                                            publishLayouts(
1249                                                    sourceGroupId, targetGroupId, privateLayout,
1250                                                    layoutIdMap, parameterMap, startDate, endDate);
1251                                    }
1252                            }
1253                            catch (Exception e) {
1254                                    messageStatus.setException(e);
1255    
1256                                    throw e;
1257                            }
1258                            finally {
1259                                    messageStatus.stopTimer();
1260    
1261                                    LayoutsLocalPublisherRequest publisherRequest =
1262                                            new LayoutsLocalPublisherRequest(
1263                                                    command, themeDisplay.getUserId(), sourceGroupId,
1264                                                    targetGroupId, privateLayout, layoutIdMap, parameterMap,
1265                                                    startDate, endDate);
1266    
1267                                    messageStatus.setPayload(publisherRequest);
1268    
1269                                    MessageBusUtil.sendMessage(
1270                                            DestinationNames.MESSAGE_BUS_MESSAGE_STATUS, messageStatus);
1271                            }
1272                    }
1273            }
1274    
1275            protected void publishToRemote(
1276                            PortletRequest portletRequest, boolean schedule)
1277                    throws Exception {
1278    
1279                    ThemeDisplay themeDisplay =
1280                            (ThemeDisplay)portletRequest.getAttribute(WebKeys.THEME_DISPLAY);
1281    
1282                    String tabs1 = ParamUtil.getString(portletRequest, "tabs1");
1283    
1284                    long groupId = ParamUtil.getLong(portletRequest, "groupId");
1285    
1286                    boolean privateLayout = true;
1287    
1288                    if (tabs1.equals("public-pages")) {
1289                            privateLayout = false;
1290                    }
1291    
1292                    String scope = ParamUtil.getString(portletRequest, "scope");
1293    
1294                    if (Validator.isNull(scope)) {
1295                            scope = "all-pages";
1296                    }
1297    
1298                    Map<Long, Boolean> layoutIdMap = null;
1299                    Map<String, String[]> parameterMap = portletRequest.getParameterMap();
1300    
1301                    if (scope.equals("selected-pages")) {
1302                            layoutIdMap = new LinkedHashMap<Long, Boolean>();
1303    
1304                            long[] rowIds = ParamUtil.getLongValues(portletRequest, "rowIds");
1305    
1306                            for (long selPlid : rowIds) {
1307                                    boolean includeChildren = ParamUtil.getBoolean(
1308                                            portletRequest, "includeChildren_" + selPlid);
1309    
1310                                    layoutIdMap.put(selPlid, includeChildren);
1311                            }
1312                    }
1313    
1314                    Group group = GroupLocalServiceUtil.getGroup(groupId);
1315    
1316                    UnicodeProperties groupTypeSettingsProperties =
1317                            group.getTypeSettingsProperties();
1318    
1319                    String remoteAddress = ParamUtil.getString(
1320                            portletRequest, "remoteAddress",
1321                            groupTypeSettingsProperties.getProperty("remoteAddress"));
1322                    long remoteGroupId = ParamUtil.getLong(
1323                            portletRequest, "remoteGroupId",
1324                            GetterUtil.getLong(
1325                                    groupTypeSettingsProperties.getProperty("remoteGroupId")));
1326                    int remotePort = ParamUtil.getInteger(
1327                            portletRequest, "remotePort",
1328                            GetterUtil.getInteger(
1329                                    groupTypeSettingsProperties.getProperty("remotePort")));
1330                    boolean remotePrivateLayout = ParamUtil.getBoolean(
1331                            portletRequest, "remotePrivateLayout");
1332                    boolean secureConnection = ParamUtil.getBoolean(
1333                            portletRequest, "secureConnection",
1334                            GetterUtil.getBoolean(
1335                                    groupTypeSettingsProperties.getProperty("secureConnection")));
1336    
1337                    validate(remoteAddress, remoteGroupId, remotePort, secureConnection);
1338    
1339                    String range = ParamUtil.getString(portletRequest, "range");
1340    
1341                    Date startDate = null;
1342                    Date endDate = null;
1343    
1344                    if (range.equals("dateRange")) {
1345                            startDate = getDate(portletRequest, "startDate", true).getTime();
1346    
1347                            endDate = getDate(portletRequest, "endDate", true).getTime();
1348                    }
1349                    else if (range.equals("fromLastPublishDate")) {
1350                            LayoutSet layoutSet = LayoutSetLocalServiceUtil.getLayoutSet(
1351                                    groupId, privateLayout);
1352    
1353                            UnicodeProperties layoutTypeSettingsProperties =
1354                                    layoutSet.getSettingsProperties();
1355    
1356                            long lastPublishDate = GetterUtil.getLong(
1357                                    layoutTypeSettingsProperties.getProperty("last-publish-date"));
1358    
1359                            if (lastPublishDate > 0) {
1360                                    Calendar cal = Calendar.getInstance(
1361                                            themeDisplay.getTimeZone(), themeDisplay.getLocale());
1362    
1363                                    endDate = cal.getTime();
1364    
1365                                    cal.setTimeInMillis(lastPublishDate);
1366    
1367                                    startDate = cal.getTime();
1368                            }
1369                    }
1370                    else if (range.equals("last")) {
1371                            int rangeLast = ParamUtil.getInteger(portletRequest, "last");
1372    
1373                            Date now = new Date();
1374    
1375                            startDate = new Date(now.getTime() - (rangeLast * Time.HOUR));
1376    
1377                            endDate = now;
1378                    }
1379    
1380                    if (schedule) {
1381                            String groupName = getSchedulerGroupName(
1382                                    DestinationNames.LAYOUTS_REMOTE_PUBLISHER, groupId);
1383    
1384                            int recurrenceType = ParamUtil.getInteger(
1385                                    portletRequest, "recurrenceType");
1386    
1387                            Calendar startCal = getDate(
1388                                    portletRequest, "schedulerStartDate", true);
1389    
1390                            String cronText = getCronText(
1391                                    portletRequest, startCal, true, recurrenceType);
1392    
1393                            Date schedulerEndDate = null;
1394    
1395                            int endDateType = ParamUtil.getInteger(
1396                                    portletRequest, "endDateType");
1397    
1398                            if (endDateType == 1) {
1399                                    Calendar endCal = getDate(
1400                                            portletRequest, "schedulerEndDate", true);
1401    
1402                                    schedulerEndDate = endCal.getTime();
1403                            }
1404    
1405                            String description = ParamUtil.getString(
1406                                    portletRequest, "description");
1407    
1408                            LayoutServiceUtil.schedulePublishToRemote(
1409                                    groupId, privateLayout, layoutIdMap,
1410                                    getStagingParameters(portletRequest), remoteAddress, remotePort,
1411                                    secureConnection, remoteGroupId, remotePrivateLayout, startDate,
1412                                    endDate, groupName, cronText, startCal.getTime(),
1413                                    schedulerEndDate, description);
1414                    }
1415                    else {
1416                            MessageStatus messageStatus = new MessageStatus();
1417    
1418                            messageStatus.startTimer();
1419    
1420                            try {
1421                                    copyRemoteLayouts(
1422                                            groupId, privateLayout, layoutIdMap, parameterMap,
1423                                            remoteAddress, remotePort, secureConnection, remoteGroupId,
1424                                            remotePrivateLayout, getStagingParameters(portletRequest),
1425                                            startDate, endDate);
1426                            }
1427                            catch (Exception e) {
1428                                    messageStatus.setException(e);
1429    
1430                                    throw e;
1431                            }
1432                            finally {
1433                                    messageStatus.stopTimer();
1434    
1435                                    LayoutsRemotePublisherRequest publisherRequest =
1436                                            new LayoutsRemotePublisherRequest(
1437                                                    themeDisplay.getUserId(), groupId, privateLayout,
1438                                                    layoutIdMap, parameterMap, remoteAddress, remotePort,
1439                                                    secureConnection, remoteGroupId, remotePrivateLayout,
1440                                                    startDate, endDate);
1441    
1442                                    messageStatus.setPayload(publisherRequest);
1443    
1444                                    MessageBusUtil.sendMessage(
1445                                            DestinationNames.MESSAGE_BUS_MESSAGE_STATUS, messageStatus);
1446                            }
1447                    }
1448            }
1449    
1450            protected void setCommonStagingOptions(
1451                            PortletRequest portletRequest, Group liveGroup,
1452                            UnicodeProperties typeSettingsProperties)
1453                    throws Exception {
1454    
1455                    LayoutExporter.updateLastPublishDate(
1456                            liveGroup.getPrivateLayoutSet(), 0);
1457                    LayoutExporter.updateLastPublishDate(
1458                            liveGroup.getPublicLayoutSet(), 0);
1459    
1460                    Enumeration<String> enu = portletRequest.getParameterNames();
1461    
1462                    while (enu.hasMoreElements()) {
1463                            String parameterName = enu.nextElement();
1464    
1465                            boolean staged = MapUtil.getBoolean(
1466                                    portletRequest.getParameterMap(), parameterName);
1467    
1468                            if (parameterName.startsWith(StagingConstants.STAGED_PORTLET) &&
1469                                    !parameterName.endsWith("Checkbox")) {
1470    
1471                                    typeSettingsProperties.setProperty(
1472                                            parameterName, String.valueOf(staged));
1473                            }
1474                    }
1475    
1476                    boolean workflowEnabled = false;
1477    
1478                    int workflowStages = ParamUtil.getInteger(
1479                            portletRequest, "workflowStages");
1480    
1481                    if (workflowStages > 1) {
1482                            workflowEnabled = true;
1483                    }
1484    
1485                    typeSettingsProperties.setProperty(
1486                            "workflowEnabled", String.valueOf(workflowEnabled));
1487    
1488                    if (workflowEnabled) {
1489                            String workflowRoleNames = getWorkflowRoleNames(portletRequest);
1490    
1491                            if (Validator.isNull(workflowRoleNames)) {
1492                                    workflowRoleNames = PropsValues.TASKS_DEFAULT_ROLE_NAMES;
1493                            }
1494    
1495                            typeSettingsProperties.setProperty(
1496                                    "workflowRoleNames", workflowRoleNames);
1497    
1498                            if (workflowStages < PropsValues.TASKS_DEFAULT_STAGES) {
1499                                    workflowStages = PropsValues.TASKS_DEFAULT_STAGES;
1500                            }
1501    
1502                            typeSettingsProperties.setProperty(
1503                                    "workflowStages", String.valueOf(workflowStages));
1504                    }
1505            }
1506    
1507            protected void validate(
1508                            String remoteAddress, long remoteGroupId, int remotePort,
1509                            boolean secureConnection)
1510                    throws Exception {
1511    
1512                    RemoteOptionsException roe = null;
1513    
1514                    if (!Validator.isDomain(remoteAddress) &&
1515                            !Validator.isIPAddress(remoteAddress)) {
1516    
1517                            roe = new RemoteOptionsException(
1518                                    RemoteOptionsException.REMOTE_ADDRESS);
1519    
1520                            roe.setRemoteAddress(remoteAddress);
1521    
1522                            throw roe;
1523                    }
1524    
1525                    if ((remotePort < 1) || (remotePort > 65535)) {
1526                            roe = new RemoteOptionsException(
1527                                    RemoteOptionsException.REMOTE_PORT);
1528    
1529                            roe.setRemotePort(remotePort);
1530    
1531                            throw roe;
1532                    }
1533    
1534                    if (remoteGroupId <= 0) {
1535                            roe = new RemoteOptionsException(
1536                                    RemoteOptionsException.REMOTE_GROUP_ID);
1537    
1538                            roe.setRemoteGroupId(remoteGroupId);
1539    
1540                            throw roe;
1541                    }
1542    
1543                    PermissionChecker permissionChecker =
1544                            PermissionThreadLocal.getPermissionChecker();
1545    
1546                    User user = UserLocalServiceUtil.getUser(permissionChecker.getUserId());
1547    
1548                    StringBundler sb = new StringBundler(4);
1549    
1550                    if (secureConnection) {
1551                            sb.append(Http.HTTPS_WITH_SLASH);
1552                    }
1553                    else {
1554                            sb.append(Http.HTTP_WITH_SLASH);
1555                    }
1556    
1557                    sb.append(remoteAddress);
1558                    sb.append(StringPool.COLON);
1559                    sb.append(remotePort);
1560    
1561                    String url = sb.toString();
1562    
1563                    HttpPrincipal httpPrincipal = new HttpPrincipal(
1564                            url, user.getEmailAddress(), user.getPassword(),
1565                            user.getPasswordEncrypted());
1566    
1567                    // Ping remote host and verify that the group exists
1568    
1569                    try {
1570                            GroupServiceHttp.getGroup(httpPrincipal, remoteGroupId);
1571                    }
1572                    catch (NoSuchGroupException nsge) {
1573                            RemoteExportException ree = new RemoteExportException(
1574                                    RemoteExportException.NO_GROUP);
1575    
1576                            ree.setGroupId(remoteGroupId);
1577    
1578                            throw ree;
1579                    }
1580                    catch (SystemException se) {
1581                            RemoteExportException ree = new RemoteExportException(
1582                                    RemoteExportException.BAD_CONNECTION);
1583    
1584                            ree.setURL(url);
1585    
1586                            throw ree;
1587                    }
1588    
1589            }
1590    
1591    }