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