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