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