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