001    /**
002     * Copyright (c) 2000-2012 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.LayoutSetBranchNameException;
018    import com.liferay.portal.NoSuchGroupException;
019    import com.liferay.portal.NoSuchLayoutBranchException;
020    import com.liferay.portal.NoSuchLayoutException;
021    import com.liferay.portal.NoSuchLayoutRevisionException;
022    import com.liferay.portal.RemoteExportException;
023    import com.liferay.portal.RemoteOptionsException;
024    import com.liferay.portal.kernel.cal.DayAndPosition;
025    import com.liferay.portal.kernel.cal.Duration;
026    import com.liferay.portal.kernel.cal.Recurrence;
027    import com.liferay.portal.kernel.cal.RecurrenceSerializer;
028    import com.liferay.portal.kernel.exception.PortalException;
029    import com.liferay.portal.kernel.exception.SystemException;
030    import com.liferay.portal.kernel.language.LanguageUtil;
031    import com.liferay.portal.kernel.lar.PortletDataContext;
032    import com.liferay.portal.kernel.lar.PortletDataHandlerKeys;
033    import com.liferay.portal.kernel.lar.UserIdStrategy;
034    import com.liferay.portal.kernel.messaging.DestinationNames;
035    import com.liferay.portal.kernel.messaging.MessageBusUtil;
036    import com.liferay.portal.kernel.messaging.MessageStatus;
037    import com.liferay.portal.kernel.staging.LayoutStagingUtil;
038    import com.liferay.portal.kernel.staging.Staging;
039    import com.liferay.portal.kernel.staging.StagingConstants;
040    import com.liferay.portal.kernel.util.CalendarFactoryUtil;
041    import com.liferay.portal.kernel.util.GetterUtil;
042    import com.liferay.portal.kernel.util.Http;
043    import com.liferay.portal.kernel.util.LocaleUtil;
044    import com.liferay.portal.kernel.util.MapUtil;
045    import com.liferay.portal.kernel.util.ParamUtil;
046    import com.liferay.portal.kernel.util.StringBundler;
047    import com.liferay.portal.kernel.util.StringPool;
048    import com.liferay.portal.kernel.util.Time;
049    import com.liferay.portal.kernel.util.TimeZoneUtil;
050    import com.liferay.portal.kernel.util.UnicodeProperties;
051    import com.liferay.portal.kernel.util.Validator;
052    import com.liferay.portal.kernel.workflow.WorkflowConstants;
053    import com.liferay.portal.kernel.xml.Element;
054    import com.liferay.portal.lar.LayoutExporter;
055    import com.liferay.portal.messaging.LayoutsLocalPublisherRequest;
056    import com.liferay.portal.messaging.LayoutsRemotePublisherRequest;
057    import com.liferay.portal.model.Group;
058    import com.liferay.portal.model.GroupConstants;
059    import com.liferay.portal.model.Layout;
060    import com.liferay.portal.model.LayoutBranch;
061    import com.liferay.portal.model.LayoutRevision;
062    import com.liferay.portal.model.LayoutSet;
063    import com.liferay.portal.model.LayoutSetBranchConstants;
064    import com.liferay.portal.model.Portlet;
065    import com.liferay.portal.model.User;
066    import com.liferay.portal.security.auth.HttpPrincipal;
067    import com.liferay.portal.security.auth.PrincipalException;
068    import com.liferay.portal.security.permission.ActionKeys;
069    import com.liferay.portal.security.permission.PermissionChecker;
070    import com.liferay.portal.security.permission.PermissionThreadLocal;
071    import com.liferay.portal.service.GroupLocalServiceUtil;
072    import com.liferay.portal.service.LayoutBranchLocalServiceUtil;
073    import com.liferay.portal.service.LayoutLocalServiceUtil;
074    import com.liferay.portal.service.LayoutRevisionLocalServiceUtil;
075    import com.liferay.portal.service.LayoutServiceUtil;
076    import com.liferay.portal.service.LayoutSetBranchLocalServiceUtil;
077    import com.liferay.portal.service.LayoutSetLocalServiceUtil;
078    import com.liferay.portal.service.ServiceContext;
079    import com.liferay.portal.service.ServiceContextThreadLocal;
080    import com.liferay.portal.service.UserLocalServiceUtil;
081    import com.liferay.portal.service.http.GroupServiceHttp;
082    import com.liferay.portal.service.http.LayoutServiceHttp;
083    import com.liferay.portal.service.permission.GroupPermissionUtil;
084    import com.liferay.portal.theme.ThemeDisplay;
085    import com.liferay.portal.util.PortalUtil;
086    import com.liferay.portal.util.SessionClicks;
087    import com.liferay.portal.util.WebKeys;
088    import com.liferay.portlet.PortalPreferences;
089    import com.liferay.portlet.PortletPreferencesFactoryUtil;
090    
091    import java.io.File;
092    
093    import java.util.ArrayList;
094    import java.util.Calendar;
095    import java.util.Date;
096    import java.util.HashSet;
097    import java.util.Iterator;
098    import java.util.LinkedHashMap;
099    import java.util.List;
100    import java.util.Locale;
101    import java.util.Map.Entry;
102    import java.util.Map;
103    import java.util.Set;
104    import java.util.TimeZone;
105    
106    import javax.portlet.PortletRequest;
107    
108    import javax.servlet.http.HttpServletRequest;
109    
110    /**
111     * @author Raymond Augé
112     * @author Bruno Farache
113     * @author Wesley Gong
114     */
115    public class StagingImpl implements Staging {
116    
117            public String buildRemoteURL(
118                    String remoteAddress, int remotePort, boolean secureConnection,
119                    long remoteGroupId, boolean privateLayout) {
120    
121                    StringBundler sb = new StringBundler((remoteGroupId > 0) ? 4 : 9);
122    
123                    if (secureConnection) {
124                            sb.append(Http.HTTPS_WITH_SLASH);
125                    }
126                    else {
127                            sb.append(Http.HTTP_WITH_SLASH);
128                    }
129    
130                    sb.append(remoteAddress);
131                    sb.append(StringPool.COLON);
132                    sb.append(remotePort);
133    
134                    if (remoteGroupId > 0) {
135                            sb.append("/c/my_sites/view?");
136                            sb.append("groupId=");
137                            sb.append(remoteGroupId);
138                            sb.append("&privateLayout=");
139                            sb.append(privateLayout);
140                    }
141    
142                    return sb.toString();
143            }
144    
145            public void copyFromLive(PortletRequest portletRequest) throws Exception {
146                    long stagingGroupId = ParamUtil.getLong(
147                            portletRequest, "stagingGroupId");
148    
149                    Group stagingGroup = GroupLocalServiceUtil.getGroup(stagingGroupId);
150    
151                    long liveGroupId = stagingGroup.getLiveGroupId();
152    
153                    Map<String, String[]> parameterMap = getStagingParameters(
154                            portletRequest);
155    
156                    publishLayouts(
157                            portletRequest, liveGroupId, stagingGroupId, parameterMap, false);
158            }
159    
160            public void copyFromLive(PortletRequest portletRequest, Portlet portlet)
161                    throws Exception {
162    
163                    long plid = ParamUtil.getLong(portletRequest, "plid");
164    
165                    Layout targetLayout = LayoutLocalServiceUtil.getLayout(plid);
166    
167                    Group stagingGroup = targetLayout.getGroup();
168                    Group liveGroup = stagingGroup.getLiveGroup();
169    
170                    Layout sourceLayout = LayoutLocalServiceUtil.getLayoutByUuidAndGroupId(
171                            targetLayout.getUuid(), liveGroup.getGroupId());
172    
173                    copyPortlet(
174                            portletRequest, liveGroup.getGroupId(), stagingGroup.getGroupId(),
175                            sourceLayout.getPlid(), targetLayout.getPlid(),
176                            portlet.getPortletId());
177            }
178    
179            public void copyPortlet(
180                            PortletRequest portletRequest, long sourceGroupId,
181                            long targetGroupId, long sourcePlid, long targetPlid,
182                            String portletId)
183                    throws Exception {
184    
185                    long userId = PortalUtil.getUserId(portletRequest);
186    
187                    Map<String, String[]> parameterMap = getStagingParameters(
188                            portletRequest);
189    
190                    File file = LayoutLocalServiceUtil.exportPortletInfoAsFile(
191                            sourcePlid, sourceGroupId, portletId, parameterMap, null, null);
192    
193                    try {
194                            LayoutLocalServiceUtil.importPortletInfo(
195                                    userId, targetPlid, targetGroupId, portletId, parameterMap,
196                                    file);
197                    }
198                    finally {
199                            file.delete();
200                    }
201            }
202    
203            public void copyRemoteLayouts(
204                            long sourceGroupId, boolean privateLayout,
205                            Map<Long, Boolean> layoutIdMap, Map<String, String[]> parameterMap,
206                            String remoteAddress, int remotePort, boolean secureConnection,
207                            long remoteGroupId, boolean remotePrivateLayout, Date startDate,
208                            Date endDate)
209                    throws Exception {
210    
211                    PermissionChecker permissionChecker =
212                            PermissionThreadLocal.getPermissionChecker();
213    
214                    User user = UserLocalServiceUtil.getUser(permissionChecker.getUserId());
215    
216                    StringBundler sb = new StringBundler(4);
217    
218                    if (secureConnection) {
219                            sb.append(Http.HTTPS_WITH_SLASH);
220                    }
221                    else {
222                            sb.append(Http.HTTP_WITH_SLASH);
223                    }
224    
225                    sb.append(remoteAddress);
226                    sb.append(StringPool.COLON);
227                    sb.append(remotePort);
228    
229                    String url = sb.toString();
230    
231                    HttpPrincipal httpPrincipal = new HttpPrincipal(
232                            url, user.getEmailAddress(), user.getPassword(),
233                            user.getPasswordEncrypted());
234    
235                    // Ping remote host and verify that the group exists
236    
237                    try {
238                            GroupServiceHttp.getGroup(httpPrincipal, remoteGroupId);
239                    }
240                    catch (NoSuchGroupException nsge) {
241                            RemoteExportException ree = new RemoteExportException(
242                                    RemoteExportException.NO_GROUP);
243    
244                            ree.setGroupId(remoteGroupId);
245    
246                            throw ree;
247                    }
248                    catch (SystemException se) {
249                            RemoteExportException ree = new RemoteExportException(
250                                    RemoteExportException.BAD_CONNECTION);
251    
252                            ree.setURL(url);
253    
254                            throw ree;
255                    }
256    
257                    byte[] bytes = null;
258    
259                    if (layoutIdMap == null) {
260                            bytes = LayoutLocalServiceUtil.exportLayouts(
261                                    sourceGroupId, privateLayout, parameterMap, startDate, endDate);
262                    }
263                    else {
264                            List<Layout> layouts = new ArrayList<Layout>();
265    
266                            Iterator<Map.Entry<Long, Boolean>> itr1 =
267                                    layoutIdMap.entrySet().iterator();
268    
269                            while (itr1.hasNext()) {
270                                    Entry<Long, Boolean> entry = itr1.next();
271    
272                                    long plid = GetterUtil.getLong(String.valueOf(entry.getKey()));
273                                    boolean includeChildren = entry.getValue();
274    
275                                    Layout layout = LayoutLocalServiceUtil.getLayout(plid);
276    
277                                    if (!layouts.contains(layout)) {
278                                            layouts.add(layout);
279                                    }
280    
281                                    Iterator<Layout> itr2 = getMissingParentLayouts(
282                                            layout, sourceGroupId).iterator();
283    
284                                    while (itr2.hasNext()) {
285                                            Layout parentLayout = itr2.next();
286    
287                                            if (!layouts.contains(parentLayout)) {
288                                                    layouts.add(parentLayout);
289                                            }
290                                    }
291    
292                                    if (includeChildren) {
293                                            itr2 = layout.getAllChildren().iterator();
294    
295                                            while (itr2.hasNext()) {
296                                                    Layout childLayout = itr2.next();
297    
298                                                    if (!layouts.contains(childLayout)) {
299                                                            layouts.add(childLayout);
300                                                    }
301                                            }
302                                    }
303                            }
304    
305                            long[] layoutIds = new long[layouts.size()];
306    
307                            for (int i = 0; i < layouts.size(); i++) {
308                                    Layout curLayout = layouts.get(i);
309    
310                                    layoutIds[i] = curLayout.getLayoutId();
311                            }
312    
313                            if (layoutIds.length <= 0) {
314                                    throw new RemoteExportException(
315                                            RemoteExportException.NO_LAYOUTS);
316                            }
317    
318                            bytes = LayoutLocalServiceUtil.exportLayouts(
319                                    sourceGroupId, privateLayout, layoutIds, parameterMap,
320                                    startDate, endDate);
321                    }
322    
323                    LayoutServiceHttp.importLayouts(
324                            httpPrincipal, remoteGroupId, remotePrivateLayout, parameterMap,
325                            bytes);
326            }
327    
328            public void deleteLastImportSettings(Group liveGroup, boolean privateLayout)
329                    throws Exception {
330    
331                    List<Layout> layouts = LayoutLocalServiceUtil.getLayouts(
332                            liveGroup.getGroupId(), privateLayout);
333    
334                    for (Layout layout : layouts) {
335                            UnicodeProperties typeSettingsProperties =
336                                    layout.getTypeSettingsProperties();
337    
338                            Set<String> keys = new HashSet<String>();
339    
340                            for (String key : typeSettingsProperties.keySet()) {
341                                    if (key.startsWith("last-import-")) {
342                                            keys.add(key);
343                                    }
344                            }
345    
346                            if (keys.isEmpty()) {
347                                    continue;
348                            }
349    
350                            for (String key : keys) {
351                                    typeSettingsProperties.remove(key);
352                            }
353    
354                            LayoutLocalServiceUtil.updateLayout(
355                                    layout.getGroupId(), layout.getPrivateLayout(),
356                                    layout.getLayoutId(), typeSettingsProperties.toString());
357                    }
358            }
359    
360            public void deleteRecentLayoutRevisionId(
361                            HttpServletRequest request, long layoutSetBranchId, long plid)
362                    throws SystemException {
363    
364                    PortalPreferences portalPreferences =
365                            PortletPreferencesFactoryUtil.getPortalPreferences(request);
366    
367                    deleteRecentLayoutRevisionId(
368                            portalPreferences, layoutSetBranchId, plid);
369            }
370    
371            public void deleteRecentLayoutRevisionId(
372                            User user, long layoutSetBranchId, long plid)
373                    throws SystemException {
374    
375                    PortalPreferences portalPreferences = getPortalPreferences(user);
376    
377                    deleteRecentLayoutRevisionId(
378                            portalPreferences, layoutSetBranchId, plid);
379            }
380    
381            public void disableStaging(
382                            Group scopeGroup, Group liveGroup, ServiceContext serviceContext)
383                    throws Exception {
384    
385                    disableStaging(null, scopeGroup, liveGroup, serviceContext);
386            }
387    
388            public void disableStaging(
389                            PortletRequest portletRequest, Group scopeGroup, Group liveGroup,
390                            ServiceContext serviceContext)
391                    throws Exception {
392    
393                    UnicodeProperties typeSettingsProperties =
394                            liveGroup.getTypeSettingsProperties();
395    
396                    typeSettingsProperties.remove("branchingPrivate");
397                    typeSettingsProperties.remove("branchingPublic");
398                    typeSettingsProperties.remove("remoteAddress");
399                    typeSettingsProperties.remove("remoteGroupId");
400                    typeSettingsProperties.remove("remotePort");
401                    typeSettingsProperties.remove("secureConnection");
402                    typeSettingsProperties.remove("staged");
403                    typeSettingsProperties.remove("stagedRemotely");
404    
405                    Set<String> keys = new HashSet<String>();
406    
407                    for (String key : typeSettingsProperties.keySet()) {
408                            if (key.startsWith(StagingConstants.STAGED_PORTLET)) {
409                                    keys.add(key);
410                            }
411                    }
412    
413                    for (String key : keys) {
414                            typeSettingsProperties.remove(key);
415                    }
416    
417                    deleteLastImportSettings(liveGroup, true);
418                    deleteLastImportSettings(liveGroup, false);
419    
420                    if (liveGroup.hasStagingGroup()) {
421                            Group stagingGroup = liveGroup.getStagingGroup();
422    
423                            LayoutSetBranchLocalServiceUtil.deleteLayoutSetBranches(
424                                    stagingGroup.getGroupId(), true, true);
425                            LayoutSetBranchLocalServiceUtil.deleteLayoutSetBranches(
426                                    stagingGroup.getGroupId(), false, true);
427    
428                            GroupLocalServiceUtil.deleteGroup(stagingGroup.getGroupId());
429                    }
430                    else {
431                            LayoutSetBranchLocalServiceUtil.deleteLayoutSetBranches(
432                                    liveGroup.getGroupId(), true, true);
433                            LayoutSetBranchLocalServiceUtil.deleteLayoutSetBranches(
434                                    liveGroup.getGroupId(), false, true);
435                    }
436    
437                    GroupLocalServiceUtil.updateGroup(
438                            liveGroup.getGroupId(), typeSettingsProperties.toString());
439            }
440    
441            public void enableLocalStaging(
442                            long userId, Group scopeGroup, Group liveGroup,
443                            boolean branchingPublic, boolean branchingPrivate,
444                            ServiceContext serviceContext)
445                    throws Exception {
446    
447                    if (liveGroup.isStagedRemotely()) {
448                            disableStaging(scopeGroup, liveGroup, serviceContext);
449                    }
450    
451                    UnicodeProperties typeSettingsProperties =
452                            liveGroup.getTypeSettingsProperties();
453    
454                    typeSettingsProperties.setProperty(
455                            "branchingPrivate", String.valueOf(branchingPrivate));
456                    typeSettingsProperties.setProperty(
457                            "branchingPublic", String.valueOf(branchingPublic));
458                    typeSettingsProperties.setProperty("staged", Boolean.TRUE.toString());
459                    typeSettingsProperties.setProperty(
460                            "stagedRemotely", String.valueOf(false));
461    
462                    setCommonStagingOptions(
463                            liveGroup, typeSettingsProperties, serviceContext);
464    
465                    if (!liveGroup.hasStagingGroup()) {
466                            serviceContext.setAttribute("staging", String.valueOf(true));
467    
468                            Group stagingGroup = GroupLocalServiceUtil.addGroup(
469                                    userId, liveGroup.getClassName(), liveGroup.getClassPK(),
470                                    liveGroup.getGroupId(), liveGroup.getDescriptiveName(),
471                                    liveGroup.getDescription(), liveGroup.getType(),
472                                    liveGroup.getFriendlyURL(), false, liveGroup.isActive(),
473                                    serviceContext);
474    
475                            GroupLocalServiceUtil.updateGroup(
476                                    liveGroup.getGroupId(), typeSettingsProperties.toString());
477    
478                            if (liveGroup.hasPrivateLayouts()) {
479                                    Map<String, String[]> parameterMap = getStagingParameters();
480    
481                                    publishLayouts(
482                                            userId, liveGroup.getGroupId(), stagingGroup.getGroupId(),
483                                            true, parameterMap, null, null);
484                            }
485    
486                            if (liveGroup.hasPublicLayouts()) {
487                                    Map<String, String[]> parameterMap = getStagingParameters();
488    
489                                    publishLayouts(
490                                            userId, liveGroup.getGroupId(), stagingGroup.getGroupId(),
491                                            false, parameterMap, null, null);
492                            }
493    
494                            checkDefaultLayoutSetBranches(
495                                    userId, liveGroup, branchingPublic, branchingPrivate, false,
496                                    serviceContext);
497                    }
498                    else {
499                            GroupLocalServiceUtil.updateGroup(
500                                    liveGroup.getGroupId(), typeSettingsProperties.toString());
501    
502                            checkDefaultLayoutSetBranches(
503                                    userId, liveGroup, branchingPublic, branchingPrivate, false,
504                                    serviceContext);
505    
506                            if (!branchingPublic) {
507                                    LayoutSetBranchLocalServiceUtil.deleteLayoutSetBranches(
508                                            liveGroup.getStagingGroup().getGroupId(), false, true);
509                            }
510    
511                            if (!branchingPrivate) {
512                                    LayoutSetBranchLocalServiceUtil.deleteLayoutSetBranches(
513                                            liveGroup.getStagingGroup().getGroupId(), true, true);
514                            }
515                    }
516            }
517    
518            public void enableRemoteStaging(
519                            long userId, Group scopeGroup, Group liveGroup,
520                            boolean branchingPublic, boolean branchingPrivate,
521                            String remoteAddress, long remoteGroupId, int remotePort,
522                            boolean secureConnection, ServiceContext serviceContext)
523                    throws Exception {
524    
525                    validate(remoteAddress, remoteGroupId, remotePort, secureConnection);
526    
527                    if (liveGroup.hasStagingGroup()) {
528                            disableStaging(scopeGroup, liveGroup, serviceContext);
529                    }
530    
531                    UnicodeProperties typeSettingsProperties =
532                            liveGroup.getTypeSettingsProperties();
533    
534                    typeSettingsProperties.setProperty(
535                            "branchingPrivate", String.valueOf(branchingPrivate));
536                    typeSettingsProperties.setProperty(
537                            "branchingPublic", String.valueOf(branchingPublic));
538                    typeSettingsProperties.setProperty("remoteAddress", remoteAddress);
539                    typeSettingsProperties.setProperty(
540                            "remoteGroupId", String.valueOf(remoteGroupId));
541                    typeSettingsProperties.setProperty(
542                            "remotePort", String.valueOf(remotePort));
543                    typeSettingsProperties.setProperty(
544                            "secureConnection", String.valueOf(secureConnection));
545                    typeSettingsProperties.setProperty("staged", Boolean.TRUE.toString());
546                    typeSettingsProperties.setProperty(
547                            "stagedRemotely", Boolean.TRUE.toString());
548    
549                    setCommonStagingOptions(
550                            liveGroup, typeSettingsProperties, serviceContext);
551    
552                    GroupLocalServiceUtil.updateGroup(
553                            liveGroup.getGroupId(), typeSettingsProperties.toString());
554    
555                    checkDefaultLayoutSetBranches(
556                            userId, liveGroup, branchingPublic, branchingPrivate, true,
557                            serviceContext);
558            }
559    
560            public Group getLiveGroup(long groupId)
561                    throws PortalException, SystemException {
562    
563                    if (groupId == 0) {
564                            return null;
565                    }
566    
567                    Group group = GroupLocalServiceUtil.getGroup(groupId);
568    
569                    if (group.isLayout()) {
570                            group = group.getParentGroup();
571                    }
572    
573                    if (group.isStagingGroup()) {
574                            return group.getLiveGroup();
575                    }
576                    else {
577                            return group;
578                    }
579            }
580    
581            public long getLiveGroupId(long groupId)
582                    throws PortalException, SystemException {
583    
584                    if (groupId == 0) {
585                            return groupId;
586                    }
587    
588                    Group group = getLiveGroup(groupId);
589    
590                    return group.getGroupId();
591            }
592    
593            public List<Layout> getMissingParentLayouts(Layout layout, long liveGroupId)
594                    throws Exception {
595    
596                    List<Layout> missingParentLayouts = new ArrayList<Layout>();
597    
598                    long parentLayoutId = layout.getParentLayoutId();
599    
600                    Layout parentLayout = null;
601    
602                    while (parentLayoutId > 0) {
603                            parentLayout = LayoutLocalServiceUtil.getLayout(
604                                    layout.getGroupId(), layout.isPrivateLayout(),
605                                    parentLayoutId);
606    
607                            try {
608                                    LayoutLocalServiceUtil.getLayoutByUuidAndGroupId(
609                                            parentLayout.getUuid(), liveGroupId);
610    
611                                    // If one parent is found all others are assumed to exist
612    
613                                    break;
614                            }
615                            catch (NoSuchLayoutException nsle) {
616                                    missingParentLayouts.add(parentLayout);
617    
618                                    parentLayoutId = parentLayout.getParentLayoutId();
619                            }
620                    }
621    
622                    return missingParentLayouts;
623            }
624    
625            public long getRecentLayoutRevisionId(
626                            HttpServletRequest request, long layoutSetBranchId, long plid)
627                    throws PortalException, SystemException {
628    
629                    PortalPreferences portalPreferences =
630                            PortletPreferencesFactoryUtil.getPortalPreferences(request);
631    
632                    return getRecentLayoutRevisionId(
633                            portalPreferences, layoutSetBranchId, plid);
634            }
635    
636            public long getRecentLayoutRevisionId(
637                            User user, long layoutSetBranchId, long plid)
638                    throws PortalException, SystemException {
639    
640                    PortalPreferences portalPreferences = getPortalPreferences(user);
641    
642                    return getRecentLayoutRevisionId(
643                            portalPreferences, layoutSetBranchId, plid);
644            }
645    
646            public long getRecentLayoutSetBranchId(
647                    HttpServletRequest request, long layoutSetId) {
648    
649                    return GetterUtil.getLong(
650                            SessionClicks.get(
651                                    request, Staging.class.getName(),
652                                    getRecentLayoutSetBranchIdKey(layoutSetId)));
653            }
654    
655            public long getRecentLayoutSetBranchId(User user, long layoutSetId)
656                    throws SystemException {
657    
658                    PortalPreferences portalPreferences = getPortalPreferences(user);
659    
660                    return GetterUtil.getLong(
661                            portalPreferences.getValue(
662                                    Staging.class.getName(),
663                                    getRecentLayoutSetBranchIdKey(layoutSetId)));
664            }
665    
666            public String getSchedulerGroupName(String destinationName, long groupId) {
667                    return destinationName.concat(StringPool.SLASH).concat(
668                            String.valueOf(groupId));
669            }
670    
671            public Map<String, String[]> getStagingParameters() {
672                    Map<String, String[]> parameterMap =
673                            new LinkedHashMap<String, String[]>();
674    
675                    parameterMap.put(
676                            PortletDataHandlerKeys.CATEGORIES,
677                            new String[] {Boolean.TRUE.toString()});
678                    parameterMap.put(
679                            PortletDataHandlerKeys.DATA_STRATEGY,
680                            new String[] {
681                                    PortletDataHandlerKeys.DATA_STRATEGY_MIRROR_OVERWRITE});
682                    parameterMap.put(
683                            PortletDataHandlerKeys.DELETE_MISSING_LAYOUTS,
684                            new String[] {Boolean.TRUE.toString()});
685                    parameterMap.put(
686                            PortletDataHandlerKeys.DELETE_PORTLET_DATA,
687                            new String[] {Boolean.FALSE.toString()});
688                    parameterMap.put(
689                            PortletDataHandlerKeys.IGNORE_LAST_PUBLISH_DATE,
690                            new String[] {Boolean.TRUE.toString()});
691                    parameterMap.put(
692                            PortletDataHandlerKeys.PERMISSIONS,
693                            new String[] {Boolean.TRUE.toString()});
694                    parameterMap.put(
695                            PortletDataHandlerKeys.PORTLET_DATA,
696                            new String[] {Boolean.TRUE.toString()});
697                    parameterMap.put(
698                            PortletDataHandlerKeys.PORTLET_DATA_ALL,
699                            new String[] {Boolean.TRUE.toString()});
700                    parameterMap.put(
701                            PortletDataHandlerKeys.PORTLET_SETUP,
702                            new String[] {Boolean.TRUE.toString()});
703                    parameterMap.put(
704                            PortletDataHandlerKeys.PORTLET_USER_PREFERENCES,
705                            new String[] {Boolean.TRUE.toString()});
706                    parameterMap.put(
707                            PortletDataHandlerKeys.THEME,
708                            new String[] {Boolean.FALSE.toString()});
709                    parameterMap.put(
710                            PortletDataHandlerKeys.THEME_REFERENCE,
711                            new String[] {Boolean.TRUE.toString()});
712                    parameterMap.put(
713                            PortletDataHandlerKeys.UPDATE_LAST_PUBLISH_DATE,
714                            new String[] {Boolean.TRUE.toString()});
715                    parameterMap.put(
716                            PortletDataHandlerKeys.USER_ID_STRATEGY,
717                            new String[] {UserIdStrategy.CURRENT_USER_ID});
718                    parameterMap.put(
719                            PortletDataHandlerKeys.USER_PERMISSIONS,
720                            new String[] {Boolean.FALSE.toString()});
721    
722                    return parameterMap;
723            }
724    
725            public Map<String, String[]> getStagingParameters(
726                    PortletRequest portletRequest) {
727    
728                    Map<String, String[]> parameterMap =
729                            new LinkedHashMap<String, String[]>(
730                                    portletRequest.getParameterMap());
731    
732                    if (!parameterMap.containsKey(PortletDataHandlerKeys.DATA_STRATEGY)) {
733                            parameterMap.put(
734                                    PortletDataHandlerKeys.DATA_STRATEGY,
735                                    new String[] {
736                                            PortletDataHandlerKeys.DATA_STRATEGY_MIRROR_OVERWRITE});
737                    }
738    
739                    /*if (!parameterMap.containsKey(
740                                    PortletDataHandlerKeys.DELETE_MISSING_LAYOUTS)) {
741    
742                            parameterMap.put(
743                                    PortletDataHandlerKeys.DELETE_MISSING_LAYOUTS,
744                                    new String[] {Boolean.TRUE.toString()});
745                    }*/
746    
747                    if (!parameterMap.containsKey(
748                                    PortletDataHandlerKeys.DELETE_PORTLET_DATA)) {
749    
750                            parameterMap.put(
751                                    PortletDataHandlerKeys.DELETE_PORTLET_DATA,
752                                    new String[] {Boolean.FALSE.toString()});
753                    }
754    
755                    if (!parameterMap.containsKey(PortletDataHandlerKeys.PORTLET_DATA)) {
756                            parameterMap.put(
757                                    PortletDataHandlerKeys.PORTLET_DATA,
758                                    new String[] {Boolean.FALSE.toString()});
759                    }
760    
761                    if (!parameterMap.containsKey(
762                                    PortletDataHandlerKeys.PORTLET_DATA_ALL)) {
763    
764                            parameterMap.put(
765                                    PortletDataHandlerKeys.PORTLET_DATA_ALL,
766                                    new String[] {Boolean.FALSE.toString()});
767                    }
768    
769                    if (!parameterMap.containsKey(PortletDataHandlerKeys.PORTLET_SETUP)) {
770                            parameterMap.put(
771                                    PortletDataHandlerKeys.PORTLET_SETUP,
772                                    new String[] {Boolean.TRUE.toString()});
773                    }
774    
775                    if (!parameterMap.containsKey(
776                                    PortletDataHandlerKeys.PORTLET_USER_PREFERENCES)) {
777    
778                            parameterMap.put(
779                                    PortletDataHandlerKeys.PORTLET_USER_PREFERENCES,
780                                    new String[] {Boolean.TRUE.toString()});
781                    }
782    
783                    if (!parameterMap.containsKey(PortletDataHandlerKeys.THEME)) {
784                            parameterMap.put(
785                                    PortletDataHandlerKeys.THEME,
786                                    new String[] {Boolean.FALSE.toString()});
787                    }
788    
789                    if (!parameterMap.containsKey(PortletDataHandlerKeys.THEME_REFERENCE)) {
790                            parameterMap.put(
791                                    PortletDataHandlerKeys.THEME_REFERENCE,
792                                    new String[] {Boolean.FALSE.toString()});
793                    }
794    
795                    if (!parameterMap.containsKey(
796                                    PortletDataHandlerKeys.UPDATE_LAST_PUBLISH_DATE)) {
797    
798                            parameterMap.put(
799                                    PortletDataHandlerKeys.UPDATE_LAST_PUBLISH_DATE,
800                                    new String[] {Boolean.TRUE.toString()});
801                    }
802    
803                    if (!parameterMap.containsKey(
804                                    PortletDataHandlerKeys.USER_ID_STRATEGY)) {
805    
806                            parameterMap.put(
807                                    PortletDataHandlerKeys.USER_ID_STRATEGY,
808                                    new String[] {UserIdStrategy.CURRENT_USER_ID});
809                    }
810    
811                    return parameterMap;
812            }
813    
814            public boolean isIncomplete(Layout layout, long layoutSetBranchId) {
815                    LayoutRevision layoutRevision = LayoutStagingUtil.getLayoutRevision(
816                            layout);
817    
818                    if (layoutRevision == null) {
819                            try {
820                                    layoutRevision =
821                                            LayoutRevisionLocalServiceUtil.getLayoutRevision(
822                                                    layoutSetBranchId, layout.getPlid(), true);
823    
824                                    return false;
825                            }
826                            catch (Exception e) {
827                            }
828                    }
829    
830                    try {
831                            layoutRevision = LayoutRevisionLocalServiceUtil.getLayoutRevision(
832                                    layoutSetBranchId, layout.getPlid(), false);
833                    }
834                    catch (Exception e) {
835                    }
836    
837                    if (layoutRevision == null ||
838                            (layoutRevision.getStatus() ==
839                                    WorkflowConstants.STATUS_INCOMPLETE)) {
840    
841                            return true;
842                    }
843    
844                    return false;
845            }
846    
847            public void publishLayout(
848                            long userId, long plid, long liveGroupId, boolean includeChildren)
849                    throws Exception {
850    
851                    Map<String, String[]> parameterMap = getStagingParameters();
852    
853                    parameterMap.put(
854                            PortletDataHandlerKeys.DELETE_MISSING_LAYOUTS,
855                            new String[] {Boolean.FALSE.toString()});
856    
857                    Layout layout = LayoutLocalServiceUtil.getLayout(plid);
858    
859                    List<Layout> layouts = new ArrayList<Layout>();
860    
861                    layouts.add(layout);
862    
863                    layouts.addAll(getMissingParentLayouts(layout, liveGroupId));
864    
865                    if (includeChildren) {
866                            layouts.addAll(layout.getAllChildren());
867                    }
868    
869                    Iterator<Layout> itr = layouts.iterator();
870    
871                    long[] layoutIds = new long[layouts.size()];
872    
873                    for (int i = 0; itr.hasNext(); i++) {
874                            Layout curLayout = itr.next();
875    
876                            layoutIds[i] = curLayout.getLayoutId();
877                    }
878    
879                    publishLayouts(
880                            userId, layout.getGroupId(), liveGroupId, layout.isPrivateLayout(),
881                            layoutIds, parameterMap, null, null);
882            }
883    
884            public void publishLayouts(
885                            long userId, long sourceGroupId, long targetGroupId,
886                            boolean privateLayout, long[] layoutIds,
887                            Map<String, String[]> parameterMap, Date startDate, Date endDate)
888                    throws Exception {
889    
890                    parameterMap.put(
891                            PortletDataHandlerKeys.PERFORM_DIRECT_BINARY_IMPORT,
892                            new String[] {Boolean.TRUE.toString()});
893    
894                    File file = LayoutLocalServiceUtil.exportLayoutsAsFile(
895                            sourceGroupId, privateLayout, layoutIds, parameterMap, startDate,
896                            endDate);
897    
898                    try {
899                            LayoutLocalServiceUtil.importLayouts(
900                                    userId, targetGroupId, privateLayout, parameterMap, file);
901                    }
902                    finally {
903                            file.delete();
904                    }
905            }
906    
907            public void publishLayouts(
908                            long userId, long sourceGroupId, long targetGroupId,
909                            boolean privateLayout, Map<Long, Boolean> layoutIdMap,
910                            Map<String, String[]> parameterMap, Date startDate, Date endDate)
911                    throws Exception {
912    
913                    List<Layout> layouts = new ArrayList<Layout>();
914    
915                    Iterator<Map.Entry<Long, Boolean>> itr1 =
916                            layoutIdMap.entrySet().iterator();
917    
918                    while (itr1.hasNext()) {
919                            Entry<Long, Boolean> entry = itr1.next();
920    
921                            long plid = GetterUtil.getLong(String.valueOf(entry.getKey()));
922                            boolean includeChildren = entry.getValue();
923    
924                            Layout layout = LayoutLocalServiceUtil.getLayout(plid);
925    
926                            if (!layouts.contains(layout)) {
927                                    layouts.add(layout);
928                            }
929    
930                            Iterator<Layout> itr2 = getMissingParentLayouts(
931                                    layout, targetGroupId).iterator();
932    
933                            while (itr2.hasNext()) {
934                                    Layout parentLayout = itr2.next();
935    
936                                    if (!layouts.contains(parentLayout)) {
937                                            layouts.add(parentLayout);
938                                    }
939                            }
940    
941                            if (includeChildren) {
942                                    itr2 = layout.getAllChildren().iterator();
943    
944                                    while (itr2.hasNext()) {
945                                            Layout childLayout = itr2.next();
946    
947                                            if (!layouts.contains(childLayout)) {
948                                                    layouts.add(childLayout);
949                                            }
950                                    }
951                            }
952                    }
953    
954                    long[] layoutIds = new long[layouts.size()];
955    
956                    for (int i = 0; i < layouts.size(); i++) {
957                            Layout curLayout = layouts.get(i);
958    
959                            layoutIds[i] = curLayout.getLayoutId();
960                    }
961    
962                    publishLayouts(
963                            userId, sourceGroupId, targetGroupId, privateLayout, layoutIds,
964                            parameterMap, startDate, endDate);
965            }
966    
967            public void publishLayouts(
968                            long userId, long sourceGroupId, long targetGroupId,
969                            boolean privateLayout, Map<String, String[]> parameterMap,
970                            Date startDate, Date endDate)
971                    throws Exception {
972    
973                    publishLayouts(
974                            userId, sourceGroupId, targetGroupId, privateLayout, (long[])null,
975                            parameterMap, startDate, endDate);
976            }
977    
978            public void publishToLive(PortletRequest portletRequest) throws Exception {
979                    long groupId = ParamUtil.getLong(portletRequest, "groupId");
980    
981                    Group liveGroup = GroupLocalServiceUtil.getGroup(groupId);
982    
983                    Map<String, String[]> parameterMap = getStagingParameters(
984                            portletRequest);
985    
986                    if (liveGroup.isStaged()) {
987                            if (liveGroup.isStagedRemotely()) {
988                                    publishToRemote(portletRequest);
989                            }
990                            else {
991                                    Group stagingGroup = liveGroup.getStagingGroup();
992    
993                                    publishLayouts(
994                                            portletRequest, stagingGroup.getGroupId(), groupId,
995                                            parameterMap, false);
996                            }
997                    }
998            }
999    
1000            public void publishToLive(PortletRequest portletRequest, Portlet portlet)
1001                    throws Exception {
1002    
1003                    long plid = ParamUtil.getLong(portletRequest, "plid");
1004    
1005                    Layout sourceLayout = LayoutLocalServiceUtil.getLayout(plid);
1006    
1007                    Group stagingGroup = null;
1008                    Group liveGroup = null;
1009    
1010                    Layout targetLayout = null;
1011    
1012                    long scopeGroupId = PortalUtil.getScopeGroupId(portletRequest);
1013    
1014                    if (sourceLayout.hasScopeGroup() &&
1015                            (sourceLayout.getScopeGroup().getGroupId() == scopeGroupId)) {
1016    
1017                            stagingGroup = sourceLayout.getScopeGroup();
1018                            liveGroup = stagingGroup.getLiveGroup();
1019    
1020                            targetLayout = LayoutLocalServiceUtil.getLayout(
1021                                    liveGroup.getClassPK());
1022                    }
1023                    else {
1024                            stagingGroup = sourceLayout.getGroup();
1025                            liveGroup = stagingGroup.getLiveGroup();
1026    
1027                            targetLayout = LayoutLocalServiceUtil.getLayoutByUuidAndGroupId(
1028                                    sourceLayout.getUuid(), liveGroup.getGroupId());
1029                    }
1030    
1031                    copyPortlet(
1032                            portletRequest, stagingGroup.getGroupId(), liveGroup.getGroupId(),
1033                            sourceLayout.getPlid(), targetLayout.getPlid(),
1034                            portlet.getPortletId());
1035            }
1036    
1037            public void publishToRemote(PortletRequest portletRequest)
1038                    throws Exception {
1039    
1040                    publishToRemote(portletRequest, false);
1041            }
1042    
1043            public void scheduleCopyFromLive(PortletRequest portletRequest)
1044                    throws Exception {
1045    
1046                    long stagingGroupId = ParamUtil.getLong(
1047                            portletRequest, "stagingGroupId");
1048    
1049                    Group stagingGroup = GroupLocalServiceUtil.getGroup(stagingGroupId);
1050    
1051                    long liveGroupId = stagingGroup.getLiveGroupId();
1052    
1053                    Map<String, String[]> parameterMap = getStagingParameters(
1054                            portletRequest);
1055    
1056                    publishLayouts(
1057                            portletRequest, liveGroupId, stagingGroupId, parameterMap, true);
1058            }
1059    
1060            public void schedulePublishToLive(PortletRequest portletRequest)
1061                    throws Exception {
1062    
1063                    long stagingGroupId = ParamUtil.getLong(
1064                            portletRequest, "stagingGroupId");
1065    
1066                    Group stagingGroup = GroupLocalServiceUtil.getGroup(stagingGroupId);
1067    
1068                    long liveGroupId = stagingGroup.getLiveGroupId();
1069    
1070                    Map<String, String[]> parameterMap = getStagingParameters(
1071                            portletRequest);
1072    
1073                    publishLayouts(
1074                            portletRequest, stagingGroupId, liveGroupId, parameterMap, true);
1075            }
1076    
1077            public void schedulePublishToRemote(PortletRequest portletRequest)
1078                    throws Exception {
1079    
1080                    publishToRemote(portletRequest, true);
1081            }
1082    
1083            public void setRecentLayoutBranchId(
1084                    HttpServletRequest request, long layoutSetBranchId, long plid,
1085                    long layoutBranchId)
1086                    throws SystemException {
1087    
1088                    PortalPreferences portalPreferences =
1089                            PortletPreferencesFactoryUtil.getPortalPreferences(request);
1090    
1091                    setRecentLayoutBranchId(
1092                            portalPreferences, layoutSetBranchId, plid, layoutBranchId);
1093            }
1094    
1095            public void setRecentLayoutBranchId(
1096                    User user, long layoutSetBranchId, long plid, long layoutBranchId)
1097                    throws SystemException {
1098    
1099                    PortalPreferences portalPreferences = getPortalPreferences(user);
1100    
1101                    setRecentLayoutBranchId(
1102                            portalPreferences, layoutSetBranchId, plid, layoutBranchId);
1103            }
1104    
1105            public void setRecentLayoutRevisionId(
1106                            HttpServletRequest request, long layoutSetBranchId, long plid,
1107                            long layoutRevisionId)
1108                    throws SystemException {
1109    
1110                    PortalPreferences portalPreferences =
1111                            PortletPreferencesFactoryUtil.getPortalPreferences(request);
1112    
1113                    setRecentLayoutRevisionId(
1114                            portalPreferences, layoutSetBranchId, plid, layoutRevisionId);
1115            }
1116    
1117            public void setRecentLayoutRevisionId(
1118                            User user, long layoutSetBranchId, long plid, long layoutRevisionId)
1119                    throws SystemException {
1120    
1121                    PortalPreferences portalPreferences = getPortalPreferences(user);
1122    
1123                    setRecentLayoutRevisionId(
1124                            portalPreferences, layoutSetBranchId, plid, layoutRevisionId);
1125            }
1126    
1127            public void setRecentLayoutSetBranchId(
1128                    HttpServletRequest request, long layoutSetId, long layoutSetBranchId) {
1129    
1130                    SessionClicks.put(
1131                            request, Staging.class.getName(),
1132                            getRecentLayoutSetBranchIdKey(layoutSetId),
1133                            String.valueOf(layoutSetBranchId));
1134            }
1135    
1136            public void setRecentLayoutSetBranchId(
1137                            User user, long layoutSetId, long layoutSetBranchId)
1138                    throws SystemException {
1139    
1140                    PortalPreferences portalPreferences = getPortalPreferences(user);
1141    
1142                    portalPreferences.setValue(
1143                            Staging.class.getName(), getRecentLayoutSetBranchIdKey(layoutSetId),
1144                            String.valueOf(layoutSetBranchId));
1145            }
1146    
1147            public void unscheduleCopyFromLive(PortletRequest portletRequest)
1148                    throws Exception {
1149    
1150                    long stagingGroupId = ParamUtil.getLong(
1151                            portletRequest, "stagingGroupId");
1152    
1153                    String jobName = ParamUtil.getString(portletRequest, "jobName");
1154                    String groupName = getSchedulerGroupName(
1155                            DestinationNames.LAYOUTS_LOCAL_PUBLISHER, stagingGroupId);
1156    
1157                    LayoutServiceUtil.unschedulePublishToLive(
1158                            stagingGroupId, jobName, groupName);
1159            }
1160    
1161            public void unschedulePublishToLive(PortletRequest portletRequest)
1162                    throws Exception {
1163    
1164                    long stagingGroupId = ParamUtil.getLong(
1165                            portletRequest, "stagingGroupId");
1166    
1167                    Group stagingGroup = GroupLocalServiceUtil.getGroup(stagingGroupId);
1168    
1169                    long liveGroupId = stagingGroup.getLiveGroupId();
1170    
1171                    String jobName = ParamUtil.getString(portletRequest, "jobName");
1172                    String groupName = getSchedulerGroupName(
1173                            DestinationNames.LAYOUTS_LOCAL_PUBLISHER, liveGroupId);
1174    
1175                    LayoutServiceUtil.unschedulePublishToLive(
1176                            liveGroupId, jobName, groupName);
1177            }
1178    
1179            public void unschedulePublishToRemote(PortletRequest portletRequest)
1180                    throws Exception {
1181    
1182                    long groupId = ParamUtil.getLong(portletRequest, "groupId");
1183    
1184                    String jobName = ParamUtil.getString(portletRequest, "jobName");
1185                    String groupName = getSchedulerGroupName(
1186                            DestinationNames.LAYOUTS_REMOTE_PUBLISHER, groupId);
1187    
1188                    LayoutServiceUtil.unschedulePublishToRemote(
1189                            groupId, jobName, groupName);
1190            }
1191    
1192            public void updateLastImportSettings(
1193                            Element layoutElement, Layout layout,
1194                            PortletDataContext portletDataContext)
1195                    throws Exception {
1196    
1197                    Map<String, String[]> parameterMap =
1198                            portletDataContext.getParameterMap();
1199    
1200                    String cmd = MapUtil.getString(parameterMap, "cmd");
1201    
1202                    if (!cmd.equals("publish_to_live")) {
1203                            return;
1204                    }
1205    
1206                    UnicodeProperties typeSettingsProperties =
1207                            layout.getTypeSettingsProperties();
1208    
1209                    typeSettingsProperties.setProperty(
1210                            "last-import-date", String.valueOf(System.currentTimeMillis()));
1211    
1212                    String layoutRevisionId = GetterUtil.getString(
1213                            layoutElement.attributeValue("layout-revision-id"));
1214    
1215                    typeSettingsProperties.setProperty(
1216                            "last-import-layout-revision-id", layoutRevisionId);
1217    
1218                    String layoutSetBranchId = MapUtil.getString(
1219                            parameterMap, "layoutSetBranchId");
1220    
1221                    typeSettingsProperties.setProperty(
1222                            "last-import-layout-set-branch-id", layoutSetBranchId);
1223    
1224                    String layoutSetBranchName = MapUtil.getString(
1225                            parameterMap, "layoutSetBranchName");
1226    
1227                    typeSettingsProperties.setProperty(
1228                            "last-import-layout-set-branch-name", layoutSetBranchName);
1229    
1230                    String lastImportUserName = MapUtil.getString(
1231                            parameterMap, "lastImportUserName");
1232    
1233                    typeSettingsProperties.setProperty(
1234                            "last-import-user-name", lastImportUserName);
1235    
1236                    String lastImportUserUuid = MapUtil.getString(
1237                            parameterMap, "lastImportUserUuid");
1238    
1239                    typeSettingsProperties.setProperty(
1240                            "last-import-user-uuid", lastImportUserUuid);
1241    
1242                    String layoutBranchId = GetterUtil.getString(
1243                            layoutElement.attributeValue("layout-branch-id"));
1244    
1245                    typeSettingsProperties.setProperty(
1246                            "last-import-layout-branch-id", layoutBranchId);
1247    
1248                    String layoutBranchName = GetterUtil.getString(
1249                            layoutElement.attributeValue("layout-branch-name"));
1250    
1251                    typeSettingsProperties.setProperty(
1252                            "last-import-layout-branch-name", layoutBranchName);
1253    
1254                    layout.setTypeSettingsProperties(typeSettingsProperties);
1255            }
1256    
1257            public void updateStaging(PortletRequest portletRequest, Group liveGroup)
1258                    throws Exception {
1259    
1260                    ThemeDisplay themeDisplay = (ThemeDisplay)portletRequest.getAttribute(
1261                            WebKeys.THEME_DISPLAY);
1262    
1263                    PermissionChecker permissionChecker =
1264                            themeDisplay.getPermissionChecker();
1265    
1266                    long userId = permissionChecker.getUserId();
1267    
1268                    Group scopeGroup = themeDisplay.getScopeGroup();
1269    
1270                    if (!GroupPermissionUtil.contains(
1271                                    permissionChecker, liveGroup.getGroupId(),
1272                                    ActionKeys.MANAGE_STAGING)) {
1273    
1274                            return;
1275                    }
1276    
1277                    int stagingType = ParamUtil.getInteger(portletRequest, "stagingType");
1278    
1279                    boolean branchingPublic = ParamUtil.getBoolean(
1280                            portletRequest, "branchingPublic");
1281                    boolean branchingPrivate = ParamUtil.getBoolean(
1282                            portletRequest, "branchingPrivate");
1283    
1284                    ServiceContext serviceContext =
1285                            ServiceContextThreadLocal.getServiceContext();
1286    
1287                    if (stagingType == StagingConstants.TYPE_NOT_STAGED) {
1288                            if (liveGroup.hasStagingGroup() || liveGroup.isStagedRemotely()) {
1289                                    disableStaging(
1290                                            portletRequest, scopeGroup, liveGroup, serviceContext);
1291                            }
1292                    }
1293                    else if (stagingType == StagingConstants.TYPE_LOCAL_STAGING) {
1294                            enableLocalStaging(
1295                                    userId, scopeGroup, liveGroup, branchingPublic,
1296                                    branchingPrivate, serviceContext);
1297                    }
1298                    else if (stagingType == StagingConstants.TYPE_REMOTE_STAGING) {
1299                            String remoteAddress = ParamUtil.getString(
1300                                    portletRequest, "remoteAddress");
1301    
1302                            remoteAddress = stripProtocolFromRemoteAddress(remoteAddress);
1303    
1304                            long remoteGroupId = ParamUtil.getLong(
1305                                    portletRequest, "remoteGroupId");
1306                            int remotePort = ParamUtil.getInteger(portletRequest, "remotePort");
1307                            boolean secureConnection = ParamUtil.getBoolean(
1308                                    portletRequest, "secureConnection");
1309    
1310                            enableRemoteStaging(
1311                                    userId, scopeGroup, liveGroup, branchingPublic,
1312                                    branchingPrivate, remoteAddress, remoteGroupId, remotePort,
1313                                    secureConnection, serviceContext);
1314                    }
1315            }
1316    
1317            protected void addWeeklyDayPos(
1318                    PortletRequest portletRequest, List<DayAndPosition> list, int day) {
1319    
1320                    if (ParamUtil.getBoolean(portletRequest, "weeklyDayPos" + day)) {
1321                            list.add(new DayAndPosition(day, 0));
1322                    }
1323            }
1324    
1325            protected void checkDefaultLayoutSetBranches(
1326                            long userId, Group liveGroup, boolean branchingPublic,
1327                            boolean branchingPrivate, boolean remote,
1328                            ServiceContext serviceContext)
1329                    throws Exception {
1330    
1331                    long targetGroupId = 0;
1332    
1333                    if (remote) {
1334                            targetGroupId = liveGroup.getGroupId();
1335                    }
1336                    else {
1337                            Group stagingGroup = liveGroup.getStagingGroup();
1338    
1339                            if (stagingGroup == null) {
1340                                    return;
1341                            }
1342    
1343                            targetGroupId = stagingGroup.getGroupId();
1344                    }
1345    
1346                    if (branchingPublic) {
1347                            Locale locale = LocaleUtil.getDefault();
1348    
1349                            String description = LanguageUtil.format(
1350                                    locale,
1351                                    LayoutSetBranchConstants.MASTER_BRANCH_DESCRIPTION_PUBLIC,
1352                                    liveGroup.getDescriptiveName());
1353    
1354                            try {
1355                                    LayoutSetBranchLocalServiceUtil.addLayoutSetBranch(
1356                                            userId, targetGroupId, false,
1357                                            LayoutSetBranchConstants.MASTER_BRANCH_NAME,
1358                                            description, true, LayoutSetBranchConstants.ALL_BRANCHES,
1359                                            serviceContext);
1360                            }
1361                            catch (LayoutSetBranchNameException lsbne) {
1362                            }
1363                    }
1364    
1365                    if (branchingPrivate) {
1366                            Locale locale = LocaleUtil.getDefault();
1367    
1368                            String description = LanguageUtil.format(
1369                                    locale,
1370                                    LayoutSetBranchConstants.MASTER_BRANCH_DESCRIPTION_PRIVATE,
1371                                    liveGroup.getDescriptiveName());
1372    
1373                            try {
1374                                    LayoutSetBranchLocalServiceUtil.addLayoutSetBranch(
1375                                            userId, targetGroupId, true,
1376                                            LayoutSetBranchConstants.MASTER_BRANCH_NAME,
1377                                            description, true, LayoutSetBranchConstants.ALL_BRANCHES,
1378                                            serviceContext);
1379                            }
1380                            catch (LayoutSetBranchNameException lsbne) {
1381                            }
1382                    }
1383            }
1384    
1385            protected void deleteRecentLayoutRevisionId(
1386                    PortalPreferences portalPreferences, long layoutSetBranchId,
1387                    long plid) {
1388    
1389                    portalPreferences.setValue(
1390                            Staging.class.getName(),
1391                            getRecentLayoutRevisionIdKey(layoutSetBranchId, plid), null);
1392            }
1393    
1394            protected String getCronText(
1395                            PortletRequest portletRequest, Calendar startDate,
1396                            boolean timeZoneSensitive, int recurrenceType)
1397                    throws Exception {
1398    
1399                    Calendar startCal = null;
1400    
1401                    if (timeZoneSensitive) {
1402                            startCal = CalendarFactoryUtil.getCalendar();
1403    
1404                            startCal.setTime(startDate.getTime());
1405                    }
1406                    else {
1407                            startCal = (Calendar)startDate.clone();
1408                    }
1409    
1410                    Recurrence recurrence = new Recurrence(
1411                            startCal, new Duration(1, 0, 0, 0), recurrenceType);
1412    
1413                    recurrence.setWeekStart(Calendar.SUNDAY);
1414    
1415                    if (recurrenceType == Recurrence.DAILY) {
1416                            int dailyType = ParamUtil.getInteger(portletRequest, "dailyType");
1417    
1418                            if (dailyType == 0) {
1419                                    int dailyInterval = ParamUtil.getInteger(
1420                                            portletRequest, "dailyInterval", 1);
1421    
1422                                    recurrence.setInterval(dailyInterval);
1423                            }
1424                            else {
1425                                    DayAndPosition[] dayPos = {
1426                                            new DayAndPosition(Calendar.MONDAY, 0),
1427                                            new DayAndPosition(Calendar.TUESDAY, 0),
1428                                            new DayAndPosition(Calendar.WEDNESDAY, 0),
1429                                            new DayAndPosition(Calendar.THURSDAY, 0),
1430                                            new DayAndPosition(Calendar.FRIDAY, 0)};
1431    
1432                                    recurrence.setByDay(dayPos);
1433                            }
1434                    }
1435                    else if (recurrenceType == Recurrence.WEEKLY) {
1436                            int weeklyInterval = ParamUtil.getInteger(
1437                                    portletRequest, "weeklyInterval", 1);
1438    
1439                            recurrence.setInterval(weeklyInterval);
1440    
1441                            List<DayAndPosition> dayPos = new ArrayList<DayAndPosition>();
1442    
1443                            addWeeklyDayPos(portletRequest, dayPos, Calendar.SUNDAY);
1444                            addWeeklyDayPos(portletRequest, dayPos, Calendar.MONDAY);
1445                            addWeeklyDayPos(portletRequest, dayPos, Calendar.TUESDAY);
1446                            addWeeklyDayPos(portletRequest, dayPos, Calendar.WEDNESDAY);
1447                            addWeeklyDayPos(portletRequest, dayPos, Calendar.THURSDAY);
1448                            addWeeklyDayPos(portletRequest, dayPos, Calendar.FRIDAY);
1449                            addWeeklyDayPos(portletRequest, dayPos, Calendar.SATURDAY);
1450    
1451                            if (dayPos.size() == 0) {
1452                                    dayPos.add(new DayAndPosition(Calendar.MONDAY, 0));
1453                            }
1454    
1455                            recurrence.setByDay(dayPos.toArray(new DayAndPosition[0]));
1456                    }
1457                    else if (recurrenceType == Recurrence.MONTHLY) {
1458                            int monthlyType = ParamUtil.getInteger(
1459                                    portletRequest, "monthlyType");
1460    
1461                            if (monthlyType == 0) {
1462                                    int monthlyDay = ParamUtil.getInteger(
1463                                            portletRequest, "monthlyDay0", 1);
1464    
1465                                    recurrence.setByMonthDay(new int[] {monthlyDay});
1466    
1467                                    int monthlyInterval = ParamUtil.getInteger(
1468                                            portletRequest, "monthlyInterval0", 1);
1469    
1470                                    recurrence.setInterval(monthlyInterval);
1471                            }
1472                            else {
1473                                    int monthlyPos = ParamUtil.getInteger(
1474                                            portletRequest, "monthlyPos");
1475                                    int monthlyDay = ParamUtil.getInteger(
1476                                            portletRequest, "monthlyDay1");
1477    
1478                                    DayAndPosition[] dayPos = {
1479                                            new DayAndPosition(monthlyDay, monthlyPos)};
1480    
1481                                    recurrence.setByDay(dayPos);
1482    
1483                                    int monthlyInterval = ParamUtil.getInteger(
1484                                            portletRequest, "monthlyInterval1", 1);
1485    
1486                                    recurrence.setInterval(monthlyInterval);
1487                            }
1488                    }
1489                    else if (recurrenceType == Recurrence.YEARLY) {
1490                            int yearlyType = ParamUtil.getInteger(portletRequest, "yearlyType");
1491    
1492                            if (yearlyType == 0) {
1493                                    int yearlyMonth = ParamUtil.getInteger(
1494                                            portletRequest, "yearlyMonth0");
1495                                    int yearlyDay = ParamUtil.getInteger(
1496                                            portletRequest, "yearlyDay0", 1);
1497    
1498                                    recurrence.setByMonth(new int[] {yearlyMonth});
1499                                    recurrence.setByMonthDay(new int[] {yearlyDay});
1500    
1501                                    int yearlyInterval = ParamUtil.getInteger(
1502                                            portletRequest, "yearlyInterval0", 1);
1503    
1504                                    recurrence.setInterval(yearlyInterval);
1505                            }
1506                            else {
1507                                    int yearlyPos = ParamUtil.getInteger(
1508                                            portletRequest, "yearlyPos");
1509                                    int yearlyDay = ParamUtil.getInteger(
1510                                            portletRequest, "yearlyDay1");
1511                                    int yearlyMonth = ParamUtil.getInteger(
1512                                            portletRequest, "yearlyMonth1");
1513    
1514                                    DayAndPosition[] dayPos = {
1515                                            new DayAndPosition(yearlyDay, yearlyPos)};
1516    
1517                                    recurrence.setByDay(dayPos);
1518    
1519                                    recurrence.setByMonth(new int[] {yearlyMonth});
1520    
1521                                    int yearlyInterval = ParamUtil.getInteger(
1522                                            portletRequest, "yearlyInterval1", 1);
1523    
1524                                    recurrence.setInterval(yearlyInterval);
1525                            }
1526                    }
1527    
1528                    return RecurrenceSerializer.toCronText(recurrence);
1529            }
1530    
1531            protected Calendar getDate(
1532                            PortletRequest portletRequest, String paramPrefix,
1533                            boolean timeZoneSensitive)
1534                    throws Exception {
1535    
1536                    ThemeDisplay themeDisplay = (ThemeDisplay)portletRequest.getAttribute(
1537                            WebKeys.THEME_DISPLAY);
1538    
1539                    int dateMonth = ParamUtil.getInteger(
1540                            portletRequest, paramPrefix + "Month");
1541                    int dateDay = ParamUtil.getInteger(portletRequest, paramPrefix + "Day");
1542                    int dateYear = ParamUtil.getInteger(
1543                            portletRequest, paramPrefix + "Year");
1544                    int dateHour = ParamUtil.getInteger(
1545                            portletRequest, paramPrefix + "Hour");
1546                    int dateMinute = ParamUtil.getInteger(
1547                            portletRequest, paramPrefix + "Minute");
1548                    int dateAmPm = ParamUtil.getInteger(
1549                            portletRequest, paramPrefix + "AmPm");
1550    
1551                    if (dateAmPm == Calendar.PM) {
1552                            dateHour += 12;
1553                    }
1554    
1555                    Locale locale = null;
1556                    TimeZone timeZone = null;
1557    
1558                    if (timeZoneSensitive) {
1559                            locale = themeDisplay.getLocale();
1560                            timeZone = themeDisplay.getTimeZone();
1561                    }
1562                    else {
1563                            locale = LocaleUtil.getDefault();
1564                            timeZone = TimeZoneUtil.getDefault();
1565                    }
1566    
1567                    Calendar cal = CalendarFactoryUtil.getCalendar(timeZone, locale);
1568    
1569                    cal.set(Calendar.MONTH, dateMonth);
1570                    cal.set(Calendar.DATE, dateDay);
1571                    cal.set(Calendar.YEAR, dateYear);
1572                    cal.set(Calendar.HOUR_OF_DAY, dateHour);
1573                    cal.set(Calendar.MINUTE, dateMinute);
1574                    cal.set(Calendar.SECOND, 0);
1575                    cal.set(Calendar.MILLISECOND, 0);
1576    
1577                    return cal;
1578            }
1579    
1580            protected PortalPreferences getPortalPreferences(User user)
1581                    throws SystemException {
1582    
1583                    boolean signedIn = !user.isDefaultUser();
1584    
1585                    PortalPreferences portalPreferences =
1586                            PortletPreferencesFactoryUtil.getPortalPreferences(
1587                                    user.getCompanyId(), user.getUserId(), signedIn);
1588    
1589                    return portalPreferences;
1590            }
1591    
1592            protected long getRecentLayoutBranchId(
1593                    PortalPreferences portalPreferences, long layoutSetBranchId,
1594                    long plid) {
1595    
1596                    return GetterUtil.getLong(
1597                            portalPreferences.getValue(
1598                                    Staging.class.getName(),
1599                                    getRecentLayoutBranchIdKey(layoutSetBranchId, plid)));
1600            }
1601    
1602            protected String getRecentLayoutBranchIdKey(
1603                    long layoutSetBranchId, long plid) {
1604    
1605                    StringBundler sb = new StringBundler(4);
1606    
1607                    sb.append("layoutBranchId-");
1608                    sb.append(layoutSetBranchId);
1609                    sb.append(StringPool.DASH);
1610                    sb.append(plid);
1611    
1612                    return sb.toString();
1613            }
1614    
1615            protected long getRecentLayoutRevisionId(
1616                            PortalPreferences portalPreferences, long layoutSetBranchId,
1617                            long plid)
1618                    throws PortalException, SystemException {
1619    
1620                    long layoutRevisionId = GetterUtil.getLong(
1621                            portalPreferences.getValue(
1622                                    Staging.class.getName(),
1623                                    getRecentLayoutRevisionIdKey(layoutSetBranchId, plid)));
1624    
1625                    if (layoutRevisionId > 0) {
1626                            return layoutRevisionId;
1627                    }
1628    
1629                    long layoutBranchId = getRecentLayoutBranchId(
1630                            portalPreferences, layoutSetBranchId, plid);
1631    
1632                    if (layoutBranchId > 0) {
1633                            try {
1634                                    LayoutBranchLocalServiceUtil.getLayoutBranch(layoutBranchId);
1635                            }
1636                            catch (NoSuchLayoutBranchException nlbe) {
1637                                    LayoutBranch layoutBranch =
1638                                            LayoutBranchLocalServiceUtil.getMasterLayoutBranch(
1639                                                    layoutSetBranchId, plid);
1640    
1641                                    layoutBranchId = layoutBranch.getLayoutBranchId();
1642                            }
1643                    }
1644    
1645                    if (layoutBranchId > 0) {
1646                            try {
1647                                    LayoutRevision layoutRevision =
1648                                            LayoutRevisionLocalServiceUtil.getLayoutRevision(
1649                                                    layoutSetBranchId, layoutBranchId, plid);
1650    
1651                                    if (layoutRevision != null) {
1652                                            layoutRevisionId = layoutRevision.getLayoutRevisionId();
1653                                    }
1654                            }
1655                            catch (NoSuchLayoutRevisionException nslre) {
1656                            }
1657                    }
1658    
1659                    return layoutRevisionId;
1660            }
1661    
1662            protected String getRecentLayoutRevisionIdKey(
1663                    long layoutSetBranchId, long plid) {
1664    
1665                    StringBundler sb = new StringBundler(4);
1666    
1667                    sb.append("layoutRevisionId-");
1668                    sb.append(layoutSetBranchId);
1669                    sb.append(StringPool.DASH);
1670                    sb.append(plid);
1671    
1672                    return sb.toString();
1673            }
1674    
1675            protected String getRecentLayoutSetBranchIdKey(long layoutSetId) {
1676                    return "layoutSetBranchId_" + layoutSetId;
1677            }
1678    
1679            protected void publishLayouts(
1680                            PortletRequest portletRequest, long sourceGroupId,
1681                            long targetGroupId, Map<String, String[]> parameterMap,
1682                            boolean schedule)
1683                    throws Exception {
1684    
1685                    ThemeDisplay themeDisplay = (ThemeDisplay)portletRequest.getAttribute(
1686                            WebKeys.THEME_DISPLAY);
1687    
1688                    String tabs1 = ParamUtil.getString(portletRequest, "tabs1");
1689    
1690                    boolean privateLayout = true;
1691    
1692                    if (tabs1.equals("public-pages")) {
1693                            privateLayout = false;
1694                    }
1695    
1696                    String scope = ParamUtil.getString(portletRequest, "scope");
1697    
1698                    Map<Long, Boolean> layoutIdMap = new LinkedHashMap<Long, Boolean>();
1699    
1700                    if (scope.equals("selected-pages")) {
1701                            long[] rowIds = ParamUtil.getLongValues(portletRequest, "rowIds");
1702    
1703                            for (long selPlid : rowIds) {
1704                                    boolean includeChildren = ParamUtil.getBoolean(
1705                                            portletRequest, "includeChildren_" + selPlid);
1706    
1707                                    layoutIdMap.put(selPlid, includeChildren);
1708                            }
1709                    }
1710    
1711                    String range = ParamUtil.getString(portletRequest, "range");
1712    
1713                    Date startDate = null;
1714                    Date endDate = null;
1715    
1716                    if (range.equals("dateRange")) {
1717                            startDate = getDate(portletRequest, "startDate", true).getTime();
1718    
1719                            endDate = getDate(portletRequest, "endDate", true).getTime();
1720                    }
1721                    else if (range.equals("fromLastPublishDate")) {
1722                            LayoutSet layoutSet = LayoutSetLocalServiceUtil.getLayoutSet(
1723                                    sourceGroupId, privateLayout);
1724    
1725                            UnicodeProperties settingsProperties =
1726                                    layoutSet.getSettingsProperties();
1727    
1728                            long lastPublishDate = GetterUtil.getLong(
1729                                    settingsProperties.getProperty("last-publish-date"));
1730    
1731                            if (lastPublishDate > 0) {
1732                                    Calendar cal = Calendar.getInstance(
1733                                            themeDisplay.getTimeZone(), themeDisplay.getLocale());
1734    
1735                                    endDate = cal.getTime();
1736    
1737                                    cal.setTimeInMillis(lastPublishDate);
1738    
1739                                    startDate = cal.getTime();
1740                            }
1741                    }
1742                    else if (range.equals("last")) {
1743                            int rangeLast = ParamUtil.getInteger(portletRequest, "last");
1744    
1745                            Date now = new Date();
1746    
1747                            startDate = new Date(now.getTime() - (rangeLast * Time.HOUR));
1748    
1749                            endDate = now;
1750                    }
1751    
1752                    if (schedule) {
1753                            String groupName = getSchedulerGroupName(
1754                                    DestinationNames.LAYOUTS_LOCAL_PUBLISHER, targetGroupId);
1755    
1756                            int recurrenceType = ParamUtil.getInteger(
1757                                    portletRequest, "recurrenceType");
1758    
1759                            Calendar startCal = getDate(
1760                                    portletRequest, "schedulerStartDate", true);
1761    
1762                            String cronText = getCronText(
1763                                    portletRequest, startCal, true, recurrenceType);
1764    
1765                            Date schedulerEndDate = null;
1766    
1767                            int endDateType = ParamUtil.getInteger(
1768                                    portletRequest, "endDateType");
1769    
1770                            if (endDateType == 1) {
1771                                    Calendar endCal = getDate(
1772                                            portletRequest, "schedulerEndDate", true);
1773    
1774                                    schedulerEndDate = endCal.getTime();
1775                            }
1776    
1777                            String description = ParamUtil.getString(
1778                                    portletRequest, "description");
1779    
1780                            LayoutServiceUtil.schedulePublishToLive(
1781                                    sourceGroupId, targetGroupId, privateLayout, layoutIdMap,
1782                                    parameterMap, scope, startDate, endDate, groupName, cronText,
1783                                    startCal.getTime(), schedulerEndDate, description);
1784                    }
1785                    else {
1786                            MessageStatus messageStatus = new MessageStatus();
1787    
1788                            messageStatus.startTimer();
1789    
1790                            String command =
1791                                    LayoutsLocalPublisherRequest.COMMAND_SELECTED_PAGES;
1792    
1793                            try {
1794                                    if (scope.equals("all-pages")) {
1795                                            command = LayoutsLocalPublisherRequest.COMMAND_ALL_PAGES;
1796    
1797                                            publishLayouts(
1798                                                    themeDisplay.getUserId(), sourceGroupId, targetGroupId,
1799                                                    privateLayout, parameterMap, startDate, endDate);
1800                                    }
1801                                    else {
1802                                            publishLayouts(
1803                                                    themeDisplay.getUserId(), sourceGroupId, targetGroupId,
1804                                                    privateLayout, layoutIdMap, parameterMap, startDate,
1805                                                    endDate);
1806                                    }
1807                            }
1808                            catch (Exception e) {
1809                                    messageStatus.setException(e);
1810    
1811                                    throw e;
1812                            }
1813                            finally {
1814                                    messageStatus.stopTimer();
1815    
1816                                    LayoutsLocalPublisherRequest publisherRequest =
1817                                            new LayoutsLocalPublisherRequest(
1818                                                    command, themeDisplay.getUserId(), sourceGroupId,
1819                                                    targetGroupId, privateLayout, layoutIdMap, parameterMap,
1820                                                    startDate, endDate);
1821    
1822                                    messageStatus.setPayload(publisherRequest);
1823    
1824                                    MessageBusUtil.sendMessage(
1825                                            DestinationNames.MESSAGE_BUS_MESSAGE_STATUS, messageStatus);
1826                            }
1827                    }
1828            }
1829    
1830            protected void publishToRemote(
1831                            PortletRequest portletRequest, boolean schedule)
1832                    throws Exception {
1833    
1834                    ThemeDisplay themeDisplay = (ThemeDisplay)portletRequest.getAttribute(
1835                            WebKeys.THEME_DISPLAY);
1836    
1837                    String tabs1 = ParamUtil.getString(portletRequest, "tabs1");
1838    
1839                    long groupId = ParamUtil.getLong(portletRequest, "groupId");
1840    
1841                    boolean privateLayout = true;
1842    
1843                    if (tabs1.equals("public-pages")) {
1844                            privateLayout = false;
1845                    }
1846    
1847                    String scope = ParamUtil.getString(portletRequest, "scope");
1848    
1849                    if (Validator.isNull(scope)) {
1850                            scope = "all-pages";
1851                    }
1852    
1853                    Map<Long, Boolean> layoutIdMap = null;
1854    
1855                    if (scope.equals("selected-pages")) {
1856                            layoutIdMap = new LinkedHashMap<Long, Boolean>();
1857    
1858                            long[] rowIds = ParamUtil.getLongValues(portletRequest, "rowIds");
1859    
1860                            for (long selPlid : rowIds) {
1861                                    boolean includeChildren = ParamUtil.getBoolean(
1862                                            portletRequest, "includeChildren_" + selPlid);
1863    
1864                                    layoutIdMap.put(selPlid, includeChildren);
1865                            }
1866                    }
1867    
1868                    Map<String, String[]> parameterMap = getStagingParameters(
1869                            portletRequest);
1870    
1871                    parameterMap.put(
1872                            PortletDataHandlerKeys.PUBLISH_TO_REMOTE,
1873                            new String[] {Boolean.TRUE.toString()});
1874    
1875                    Group group = GroupLocalServiceUtil.getGroup(groupId);
1876    
1877                    UnicodeProperties groupTypeSettingsProperties =
1878                            group.getTypeSettingsProperties();
1879    
1880                    String remoteAddress = ParamUtil.getString(
1881                            portletRequest, "remoteAddress",
1882                            groupTypeSettingsProperties.getProperty("remoteAddress"));
1883    
1884                    remoteAddress = stripProtocolFromRemoteAddress(remoteAddress);
1885    
1886                    long remoteGroupId = ParamUtil.getLong(
1887                            portletRequest, "remoteGroupId",
1888                            GetterUtil.getLong(
1889                                    groupTypeSettingsProperties.getProperty("remoteGroupId")));
1890                    int remotePort = ParamUtil.getInteger(
1891                            portletRequest, "remotePort",
1892                            GetterUtil.getInteger(
1893                                    groupTypeSettingsProperties.getProperty("remotePort")));
1894                    boolean remotePrivateLayout = ParamUtil.getBoolean(
1895                            portletRequest, "remotePrivateLayout");
1896                    boolean secureConnection = ParamUtil.getBoolean(
1897                            portletRequest, "secureConnection",
1898                            GetterUtil.getBoolean(
1899                                    groupTypeSettingsProperties.getProperty("secureConnection")));
1900    
1901                    validate(remoteAddress, remoteGroupId, remotePort, secureConnection);
1902    
1903                    String range = ParamUtil.getString(portletRequest, "range");
1904    
1905                    Date startDate = null;
1906                    Date endDate = null;
1907    
1908                    if (range.equals("dateRange")) {
1909                            startDate = getDate(portletRequest, "startDate", true).getTime();
1910    
1911                            endDate = getDate(portletRequest, "endDate", true).getTime();
1912                    }
1913                    else if (range.equals("fromLastPublishDate")) {
1914                            LayoutSet layoutSet = LayoutSetLocalServiceUtil.getLayoutSet(
1915                                    groupId, privateLayout);
1916    
1917                            UnicodeProperties layoutTypeSettingsProperties =
1918                                    layoutSet.getSettingsProperties();
1919    
1920                            long lastPublishDate = GetterUtil.getLong(
1921                                    layoutTypeSettingsProperties.getProperty("last-publish-date"));
1922    
1923                            if (lastPublishDate > 0) {
1924                                    Calendar cal = Calendar.getInstance(
1925                                            themeDisplay.getTimeZone(), themeDisplay.getLocale());
1926    
1927                                    endDate = cal.getTime();
1928    
1929                                    cal.setTimeInMillis(lastPublishDate);
1930    
1931                                    startDate = cal.getTime();
1932                            }
1933                    }
1934                    else if (range.equals("last")) {
1935                            int rangeLast = ParamUtil.getInteger(portletRequest, "last");
1936    
1937                            Date now = new Date();
1938    
1939                            startDate = new Date(now.getTime() - (rangeLast * Time.HOUR));
1940    
1941                            endDate = now;
1942                    }
1943    
1944                    if (schedule) {
1945                            String groupName = getSchedulerGroupName(
1946                                    DestinationNames.LAYOUTS_REMOTE_PUBLISHER, groupId);
1947    
1948                            int recurrenceType = ParamUtil.getInteger(
1949                                    portletRequest, "recurrenceType");
1950    
1951                            Calendar startCal = getDate(
1952                                    portletRequest, "schedulerStartDate", true);
1953    
1954                            String cronText = getCronText(
1955                                    portletRequest, startCal, true, recurrenceType);
1956    
1957                            Date schedulerEndDate = null;
1958    
1959                            int endDateType = ParamUtil.getInteger(
1960                                    portletRequest, "endDateType");
1961    
1962                            if (endDateType == 1) {
1963                                    Calendar endCal = getDate(
1964                                            portletRequest, "schedulerEndDate", true);
1965    
1966                                    schedulerEndDate = endCal.getTime();
1967                            }
1968    
1969                            String description = ParamUtil.getString(
1970                                    portletRequest, "description");
1971    
1972                            LayoutServiceUtil.schedulePublishToRemote(
1973                                    groupId, privateLayout, layoutIdMap, parameterMap,
1974                                    remoteAddress, remotePort, secureConnection, remoteGroupId,
1975                                    remotePrivateLayout, startDate, endDate, groupName, cronText,
1976                                    startCal.getTime(), schedulerEndDate, description);
1977                    }
1978                    else {
1979                            MessageStatus messageStatus = new MessageStatus();
1980    
1981                            messageStatus.startTimer();
1982    
1983                            try {
1984                                    copyRemoteLayouts(
1985                                            groupId, privateLayout, layoutIdMap, parameterMap,
1986                                            remoteAddress, remotePort, secureConnection, remoteGroupId,
1987                                            remotePrivateLayout, startDate, endDate);
1988                            }
1989                            catch (Exception e) {
1990                                    messageStatus.setException(e);
1991    
1992                                    throw e;
1993                            }
1994                            finally {
1995                                    messageStatus.stopTimer();
1996    
1997                                    LayoutsRemotePublisherRequest publisherRequest =
1998                                            new LayoutsRemotePublisherRequest(
1999                                                    themeDisplay.getUserId(), groupId, privateLayout,
2000                                                    layoutIdMap, parameterMap, remoteAddress, remotePort,
2001                                                    secureConnection, remoteGroupId, remotePrivateLayout,
2002                                                    startDate, endDate);
2003    
2004                                    messageStatus.setPayload(publisherRequest);
2005    
2006                                    MessageBusUtil.sendMessage(
2007                                            DestinationNames.MESSAGE_BUS_MESSAGE_STATUS, messageStatus);
2008                            }
2009                    }
2010            }
2011    
2012            protected void setCommonStagingOptions(
2013                            Group liveGroup, UnicodeProperties typeSettingsProperties,
2014                            ServiceContext serviceContext)
2015                    throws Exception {
2016    
2017                    LayoutExporter.updateLastPublishDate(
2018                            liveGroup.getPrivateLayoutSet(), 0);
2019                    LayoutExporter.updateLastPublishDate(liveGroup.getPublicLayoutSet(), 0);
2020    
2021                    Set<String> parameterNames = serviceContext.getAttributes().keySet();
2022    
2023                    for (String parameterName : parameterNames) {
2024                            boolean staged = ParamUtil.getBoolean(
2025                                    serviceContext, parameterName);
2026    
2027                            if (parameterName.startsWith(StagingConstants.STAGED_PORTLET) &&
2028                                    !parameterName.endsWith("Checkbox")) {
2029    
2030                                    typeSettingsProperties.setProperty(
2031                                            parameterName, String.valueOf(staged));
2032                            }
2033                    }
2034            }
2035    
2036            protected void setRecentLayoutBranchId(
2037                    PortalPreferences portalPreferences, long layoutSetBranchId, long plid,
2038                    long layoutBranchId) {
2039    
2040                    portalPreferences.setValue(
2041                            Staging.class.getName(),
2042                            getRecentLayoutBranchIdKey(layoutSetBranchId, plid),
2043                            String.valueOf(layoutBranchId));
2044            }
2045    
2046            protected void setRecentLayoutRevisionId(
2047                            PortalPreferences portalPreferences, long layoutSetBranchId,
2048                            long plid, long layoutRevisionId)
2049                    throws SystemException {
2050    
2051                    long layoutBranchId = 0;
2052    
2053                    try {
2054                            LayoutRevision layoutRevision =
2055                                    LayoutRevisionLocalServiceUtil.getLayoutRevision(
2056                                            layoutRevisionId);
2057    
2058                            layoutBranchId = layoutRevision.getLayoutBranchId();
2059    
2060                            LayoutRevision lastLayoutRevision =
2061                                    LayoutRevisionLocalServiceUtil.getLayoutRevision(
2062                                            layoutSetBranchId, layoutBranchId, plid);
2063    
2064                            if (lastLayoutRevision.getLayoutRevisionId() == layoutRevisionId) {
2065                                    deleteRecentLayoutRevisionId(
2066                                            portalPreferences, layoutSetBranchId, plid);
2067                            }
2068                            else {
2069                                    portalPreferences.setValue(
2070                                            Staging.class.getName(),
2071                                            getRecentLayoutRevisionIdKey(layoutSetBranchId, plid),
2072                                            String.valueOf(layoutRevisionId));
2073                            }
2074                    }
2075                    catch (PortalException pe) {
2076                    }
2077    
2078                    portalPreferences.setValue(
2079                            Staging.class.getName(),
2080                            getRecentLayoutBranchIdKey(layoutSetBranchId, plid),
2081                            String.valueOf(layoutBranchId));
2082            }
2083    
2084            protected String stripProtocolFromRemoteAddress(String remoteAddress) {
2085                    if (remoteAddress.startsWith(Http.HTTP_WITH_SLASH)) {
2086                            remoteAddress = remoteAddress.substring(
2087                                    Http.HTTP_WITH_SLASH.length());
2088                    }
2089                    else if (remoteAddress.startsWith(Http.HTTPS_WITH_SLASH)) {
2090                            remoteAddress = remoteAddress.substring(
2091                                    Http.HTTPS_WITH_SLASH.length());
2092                    }
2093    
2094                    return remoteAddress;
2095            }
2096    
2097            protected void validate(
2098                            String remoteAddress, long remoteGroupId, int remotePort,
2099                            boolean secureConnection)
2100                    throws Exception {
2101    
2102                    RemoteOptionsException roe = null;
2103    
2104                    if (!Validator.isDomain(remoteAddress) &&
2105                            !Validator.isIPAddress(remoteAddress)) {
2106    
2107                            roe = new RemoteOptionsException(
2108                                    RemoteOptionsException.REMOTE_ADDRESS);
2109    
2110                            roe.setRemoteAddress(remoteAddress);
2111    
2112                            throw roe;
2113                    }
2114    
2115                    if ((remotePort < 1) || (remotePort > 65535)) {
2116                            roe = new RemoteOptionsException(
2117                                    RemoteOptionsException.REMOTE_PORT);
2118    
2119                            roe.setRemotePort(remotePort);
2120    
2121                            throw roe;
2122                    }
2123    
2124                    if (remoteGroupId <= 0) {
2125                            roe = new RemoteOptionsException(
2126                                    RemoteOptionsException.REMOTE_GROUP_ID);
2127    
2128                            roe.setRemoteGroupId(remoteGroupId);
2129    
2130                            throw roe;
2131                    }
2132    
2133                    PermissionChecker permissionChecker =
2134                            PermissionThreadLocal.getPermissionChecker();
2135    
2136                    User user = UserLocalServiceUtil.getUser(permissionChecker.getUserId());
2137    
2138                    String url = buildRemoteURL(
2139                            remoteAddress, remotePort, secureConnection,
2140                            GroupConstants.DEFAULT_LIVE_GROUP_ID, false);
2141    
2142                    HttpPrincipal httpPrincipal = new HttpPrincipal(
2143                            url, user.getEmailAddress(), user.getPassword(),
2144                            user.getPasswordEncrypted());
2145    
2146                    // Ping remote host and verify that the group exists
2147    
2148                    try {
2149                            GroupServiceHttp.getGroup(httpPrincipal, remoteGroupId);
2150                    }
2151                    catch (NoSuchGroupException nsge) {
2152                            RemoteExportException ree = new RemoteExportException(
2153                                    RemoteExportException.NO_GROUP);
2154    
2155                            ree.setGroupId(remoteGroupId);
2156    
2157                            throw ree;
2158                    }
2159                    catch (PrincipalException pe) {
2160                            RemoteExportException ree = new RemoteExportException(
2161                                    RemoteExportException.NO_PERMISSIONS);
2162    
2163                            ree.setGroupId(remoteGroupId);
2164    
2165                            throw ree;
2166                    }
2167                    catch (SystemException se) {
2168                            RemoteExportException ree = new RemoteExportException(
2169                                    RemoteExportException.BAD_CONNECTION);
2170    
2171                            ree.setURL(url);
2172    
2173                            throw ree;
2174                    }
2175    
2176            }
2177    
2178    }