001    /**
002     * Copyright (c) 2000-2013 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.LARFileException;
019    import com.liferay.portal.LARFileSizeException;
020    import com.liferay.portal.LARTypeException;
021    import com.liferay.portal.LayoutPrototypeException;
022    import com.liferay.portal.LocaleException;
023    import com.liferay.portal.MissingReferenceException;
024    import com.liferay.portal.NoSuchGroupException;
025    import com.liferay.portal.NoSuchLayoutBranchException;
026    import com.liferay.portal.NoSuchLayoutException;
027    import com.liferay.portal.NoSuchLayoutRevisionException;
028    import com.liferay.portal.PortletIdException;
029    import com.liferay.portal.RemoteExportException;
030    import com.liferay.portal.RemoteOptionsException;
031    import com.liferay.portal.kernel.exception.PortalException;
032    import com.liferay.portal.kernel.exception.SystemException;
033    import com.liferay.portal.kernel.json.JSONArray;
034    import com.liferay.portal.kernel.json.JSONFactoryUtil;
035    import com.liferay.portal.kernel.json.JSONObject;
036    import com.liferay.portal.kernel.language.LanguageUtil;
037    import com.liferay.portal.kernel.lar.ExportImportHelperUtil;
038    import com.liferay.portal.kernel.lar.MissingReference;
039    import com.liferay.portal.kernel.lar.MissingReferences;
040    import com.liferay.portal.kernel.lar.PortletDataContext;
041    import com.liferay.portal.kernel.lar.PortletDataHandlerKeys;
042    import com.liferay.portal.kernel.lar.UserIdStrategy;
043    import com.liferay.portal.kernel.log.Log;
044    import com.liferay.portal.kernel.log.LogFactoryUtil;
045    import com.liferay.portal.kernel.messaging.DestinationNames;
046    import com.liferay.portal.kernel.messaging.MessageBusUtil;
047    import com.liferay.portal.kernel.messaging.MessageStatus;
048    import com.liferay.portal.kernel.scheduler.SchedulerEngineHelperUtil;
049    import com.liferay.portal.kernel.security.pacl.DoPrivileged;
050    import com.liferay.portal.kernel.servlet.ServletResponseConstants;
051    import com.liferay.portal.kernel.staging.LayoutStagingUtil;
052    import com.liferay.portal.kernel.staging.Staging;
053    import com.liferay.portal.kernel.staging.StagingConstants;
054    import com.liferay.portal.kernel.util.Constants;
055    import com.liferay.portal.kernel.util.DateRange;
056    import com.liferay.portal.kernel.util.GetterUtil;
057    import com.liferay.portal.kernel.util.Http;
058    import com.liferay.portal.kernel.util.MapUtil;
059    import com.liferay.portal.kernel.util.ParamUtil;
060    import com.liferay.portal.kernel.util.PropsKeys;
061    import com.liferay.portal.kernel.util.StringBundler;
062    import com.liferay.portal.kernel.util.StringPool;
063    import com.liferay.portal.kernel.util.StringUtil;
064    import com.liferay.portal.kernel.util.Tuple;
065    import com.liferay.portal.kernel.util.UnicodeProperties;
066    import com.liferay.portal.kernel.util.Validator;
067    import com.liferay.portal.kernel.workflow.WorkflowConstants;
068    import com.liferay.portal.kernel.workflow.WorkflowTask;
069    import com.liferay.portal.kernel.workflow.WorkflowTaskManagerUtil;
070    import com.liferay.portal.kernel.xml.Element;
071    import com.liferay.portal.lar.backgroundtask.BackgroundTaskContextMapFactory;
072    import com.liferay.portal.lar.backgroundtask.LayoutRemoteStagingBackgroundTaskExecutor;
073    import com.liferay.portal.lar.backgroundtask.LayoutStagingBackgroundTaskExecutor;
074    import com.liferay.portal.lar.backgroundtask.PortletStagingBackgroundTaskExecutor;
075    import com.liferay.portal.messaging.LayoutsLocalPublisherRequest;
076    import com.liferay.portal.messaging.LayoutsRemotePublisherRequest;
077    import com.liferay.portal.model.Group;
078    import com.liferay.portal.model.GroupConstants;
079    import com.liferay.portal.model.Layout;
080    import com.liferay.portal.model.LayoutBranch;
081    import com.liferay.portal.model.LayoutRevision;
082    import com.liferay.portal.model.LayoutSet;
083    import com.liferay.portal.model.LayoutSetBranch;
084    import com.liferay.portal.model.LayoutSetBranchConstants;
085    import com.liferay.portal.model.Lock;
086    import com.liferay.portal.model.Portlet;
087    import com.liferay.portal.model.User;
088    import com.liferay.portal.model.WorkflowInstanceLink;
089    import com.liferay.portal.security.auth.HttpPrincipal;
090    import com.liferay.portal.security.auth.PrincipalException;
091    import com.liferay.portal.security.auth.RemoteAuthException;
092    import com.liferay.portal.security.permission.ActionKeys;
093    import com.liferay.portal.security.permission.PermissionChecker;
094    import com.liferay.portal.security.permission.PermissionThreadLocal;
095    import com.liferay.portal.security.permission.ResourceActionsUtil;
096    import com.liferay.portal.service.BackgroundTaskLocalServiceUtil;
097    import com.liferay.portal.service.GroupLocalServiceUtil;
098    import com.liferay.portal.service.LayoutBranchLocalServiceUtil;
099    import com.liferay.portal.service.LayoutLocalServiceUtil;
100    import com.liferay.portal.service.LayoutRevisionLocalServiceUtil;
101    import com.liferay.portal.service.LayoutServiceUtil;
102    import com.liferay.portal.service.LayoutSetBranchLocalServiceUtil;
103    import com.liferay.portal.service.LayoutSetLocalServiceUtil;
104    import com.liferay.portal.service.LockLocalServiceUtil;
105    import com.liferay.portal.service.ServiceContext;
106    import com.liferay.portal.service.ServiceContextThreadLocal;
107    import com.liferay.portal.service.WorkflowInstanceLinkLocalServiceUtil;
108    import com.liferay.portal.service.http.GroupServiceHttp;
109    import com.liferay.portal.service.permission.GroupPermissionUtil;
110    import com.liferay.portal.theme.ThemeDisplay;
111    import com.liferay.portal.util.PortalUtil;
112    import com.liferay.portal.util.PrefsPropsUtil;
113    import com.liferay.portal.util.PropsValues;
114    import com.liferay.portal.util.SessionClicks;
115    import com.liferay.portal.util.WebKeys;
116    import com.liferay.portlet.PortalPreferences;
117    import com.liferay.portlet.PortletPreferencesFactoryUtil;
118    import com.liferay.portlet.documentlibrary.DuplicateFileException;
119    import com.liferay.portlet.documentlibrary.FileExtensionException;
120    import com.liferay.portlet.documentlibrary.FileNameException;
121    import com.liferay.portlet.documentlibrary.FileSizeException;
122    
123    import java.io.Serializable;
124    
125    import java.util.ArrayList;
126    import java.util.Calendar;
127    import java.util.Date;
128    import java.util.HashMap;
129    import java.util.HashSet;
130    import java.util.Iterator;
131    import java.util.LinkedHashMap;
132    import java.util.List;
133    import java.util.Locale;
134    import java.util.Map;
135    import java.util.Set;
136    
137    import javax.portlet.PortletPreferences;
138    import javax.portlet.PortletRequest;
139    
140    import javax.servlet.http.HttpServletRequest;
141    
142    /**
143     * @author Raymond Aug??
144     * @author Bruno Farache
145     * @author Wesley Gong
146     * @author Zsolt Balogh
147     */
148    @DoPrivileged
149    public class StagingImpl implements Staging {
150    
151            @Override
152            public String buildRemoteURL(
153                    String remoteAddress, int remotePort, String remotePathContext,
154                    boolean secureConnection, long remoteGroupId, boolean privateLayout) {
155    
156                    StringBundler sb = new StringBundler((remoteGroupId > 0) ? 4 : 9);
157    
158                    if (secureConnection) {
159                            sb.append(Http.HTTPS_WITH_SLASH);
160                    }
161                    else {
162                            sb.append(Http.HTTP_WITH_SLASH);
163                    }
164    
165                    sb.append(remoteAddress);
166    
167                    if (remotePort > 0) {
168                            sb.append(StringPool.COLON);
169                            sb.append(remotePort);
170                    }
171    
172                    if (Validator.isNotNull(remotePathContext)) {
173                            sb.append(remotePathContext);
174                    }
175    
176                    if (remoteGroupId > 0) {
177                            sb.append("/c/my_sites/view?");
178                            sb.append("groupId=");
179                            sb.append(remoteGroupId);
180                            sb.append("&privateLayout=");
181                            sb.append(privateLayout);
182                    }
183    
184                    return sb.toString();
185            }
186    
187            @Override
188            public void copyFromLive(PortletRequest portletRequest) throws Exception {
189                    long stagingGroupId = ParamUtil.getLong(
190                            portletRequest, "stagingGroupId");
191    
192                    Group stagingGroup = GroupLocalServiceUtil.getGroup(stagingGroupId);
193    
194                    long liveGroupId = stagingGroup.getLiveGroupId();
195    
196                    Map<String, String[]> parameterMap = getStagingParameters(
197                            portletRequest);
198    
199                    publishLayouts(
200                            portletRequest, liveGroupId, stagingGroupId, parameterMap, false);
201            }
202    
203            @Override
204            public void copyFromLive(PortletRequest portletRequest, Portlet portlet)
205                    throws Exception {
206    
207                    long plid = ParamUtil.getLong(portletRequest, "plid");
208    
209                    Layout targetLayout = LayoutLocalServiceUtil.getLayout(plid);
210    
211                    Group stagingGroup = targetLayout.getGroup();
212                    Group liveGroup = stagingGroup.getLiveGroup();
213    
214                    Layout sourceLayout = LayoutLocalServiceUtil.getLayoutByUuidAndGroupId(
215                            targetLayout.getUuid(), liveGroup.getGroupId(),
216                            targetLayout.isPrivateLayout());
217    
218                    copyPortlet(
219                            portletRequest, liveGroup.getGroupId(), stagingGroup.getGroupId(),
220                            sourceLayout.getPlid(), targetLayout.getPlid(),
221                            portlet.getPortletId());
222            }
223    
224            @Override
225            public void copyPortlet(
226                            PortletRequest portletRequest, long sourceGroupId,
227                            long targetGroupId, long sourcePlid, long targetPlid,
228                            String portletId)
229                    throws Exception {
230    
231                    long userId = PortalUtil.getUserId(portletRequest);
232    
233                    Map<String, String[]> parameterMap = getStagingParameters(
234                            portletRequest);
235    
236                    DateRange dateRange = ExportImportHelperUtil.getDateRange(
237                            portletRequest, sourceGroupId, false, sourcePlid, portletId);
238    
239                    Map<String, Serializable> taskContextMap =
240                            BackgroundTaskContextMapFactory.buildTaskContextMap(
241                                    userId, sourceGroupId, false, null, parameterMap,
242                                    Constants.PUBLISH, dateRange.getStartDate(),
243                                    dateRange.getEndDate(), StringPool.BLANK);
244    
245                    taskContextMap.put("sourceGroupId", sourceGroupId);
246                    taskContextMap.put("sourcePlid", sourcePlid);
247                    taskContextMap.put("portletId", portletId);
248                    taskContextMap.put("targetGroupId", targetGroupId);
249                    taskContextMap.put("targetPlid", targetPlid);
250    
251                    BackgroundTaskLocalServiceUtil.addBackgroundTask(
252                            userId, sourceGroupId, portletId, null,
253                            PortletStagingBackgroundTaskExecutor.class, taskContextMap,
254                            new ServiceContext());
255            }
256    
257            @Override
258            public void copyRemoteLayouts(
259                            long sourceGroupId, boolean privateLayout,
260                            Map<Long, Boolean> layoutIdMap, Map<String, String[]> parameterMap,
261                            String remoteAddress, int remotePort, String remotePathContext,
262                            boolean secureConnection, long remoteGroupId,
263                            boolean remotePrivateLayout, Date startDate, Date endDate)
264                    throws Exception {
265    
266                    PermissionChecker permissionChecker =
267                            PermissionThreadLocal.getPermissionChecker();
268    
269                    User user = permissionChecker.getUser();
270    
271                    StringBundler sb = new StringBundler(4);
272    
273                    if (secureConnection) {
274                            sb.append(Http.HTTPS_WITH_SLASH);
275                    }
276                    else {
277                            sb.append(Http.HTTP_WITH_SLASH);
278                    }
279    
280                    sb.append(remoteAddress);
281                    sb.append(StringPool.COLON);
282                    sb.append(remotePort);
283                    sb.append(remotePathContext);
284    
285                    String url = sb.toString();
286    
287                    HttpPrincipal httpPrincipal = new HttpPrincipal(
288                            url, user.getEmailAddress(), user.getPassword(),
289                            user.getPasswordEncrypted());
290    
291                    // Ping remote host and verify that the group exists in the same company
292                    // as the remote user
293    
294                    try {
295                            GroupServiceHttp.checkRemoteStagingGroup(
296                                    httpPrincipal, remoteGroupId);
297                    }
298                    catch (NoSuchGroupException nsge) {
299                            RemoteExportException ree = new RemoteExportException(
300                                    RemoteExportException.NO_GROUP);
301    
302                            ree.setGroupId(remoteGroupId);
303    
304                            throw ree;
305                    }
306                    catch (RemoteAuthException rae) {
307                            rae.setURL(url);
308    
309                            throw rae;
310                    }
311                    catch (SystemException se) {
312                            RemoteExportException ree = new RemoteExportException(
313                                    RemoteExportException.BAD_CONNECTION);
314    
315                            ree.setURL(url);
316    
317                            throw ree;
318                    }
319    
320                    Map<String, Serializable> taskContextMap =
321                            BackgroundTaskContextMapFactory.buildTaskContextMap(
322                                    user.getUserId(), sourceGroupId, privateLayout, null,
323                                    parameterMap, Constants.PUBLISH, startDate, endDate, null);
324    
325                    taskContextMap.put("httpPrincipal", httpPrincipal);
326    
327                    if (layoutIdMap != null) {
328                            HashMap<Long, Boolean> serializableLayoutIdMap =
329                                    new HashMap<Long, Boolean>(layoutIdMap);
330    
331                            taskContextMap.put("layoutIdMap", serializableLayoutIdMap);
332                    }
333    
334                    taskContextMap.put("remoteGroupId", remoteGroupId);
335    
336                    BackgroundTaskLocalServiceUtil.addBackgroundTask(
337                            user.getUserId(), sourceGroupId, StringPool.BLANK, null,
338                            LayoutRemoteStagingBackgroundTaskExecutor.class, taskContextMap,
339                            new ServiceContext());
340            }
341    
342            @Override
343            public void deleteLastImportSettings(Group liveGroup, boolean privateLayout)
344                    throws Exception {
345    
346                    List<Layout> layouts = LayoutLocalServiceUtil.getLayouts(
347                            liveGroup.getGroupId(), privateLayout);
348    
349                    for (Layout layout : layouts) {
350                            UnicodeProperties typeSettingsProperties =
351                                    layout.getTypeSettingsProperties();
352    
353                            Set<String> keys = new HashSet<String>();
354    
355                            for (String key : typeSettingsProperties.keySet()) {
356                                    if (key.startsWith("last-import-")) {
357                                            keys.add(key);
358                                    }
359                            }
360    
361                            if (keys.isEmpty()) {
362                                    continue;
363                            }
364    
365                            for (String key : keys) {
366                                    typeSettingsProperties.remove(key);
367                            }
368    
369                            LayoutLocalServiceUtil.updateLayout(
370                                    layout.getGroupId(), layout.getPrivateLayout(),
371                                    layout.getLayoutId(), typeSettingsProperties.toString());
372                    }
373            }
374    
375            @Override
376            public void deleteRecentLayoutRevisionId(
377                            HttpServletRequest request, long layoutSetBranchId, long plid)
378                    throws SystemException {
379    
380                    PortalPreferences portalPreferences =
381                            PortletPreferencesFactoryUtil.getPortalPreferences(request);
382    
383                    deleteRecentLayoutRevisionId(
384                            portalPreferences, layoutSetBranchId, plid);
385            }
386    
387            @Override
388            public void deleteRecentLayoutRevisionId(
389                            User user, long layoutSetBranchId, long plid)
390                    throws SystemException {
391    
392                    PortalPreferences portalPreferences = getPortalPreferences(user);
393    
394                    deleteRecentLayoutRevisionId(
395                            portalPreferences, layoutSetBranchId, plid);
396            }
397    
398            @Deprecated
399            @Override
400            public void disableStaging(
401                            Group scopeGroup, Group liveGroup, ServiceContext serviceContext)
402                    throws Exception {
403    
404                    disableStaging((PortletRequest)null, liveGroup, serviceContext);
405            }
406    
407            @Override
408            public void disableStaging(Group liveGroup, ServiceContext serviceContext)
409                    throws Exception {
410    
411                    disableStaging((PortletRequest)null, liveGroup, serviceContext);
412            }
413    
414            @Deprecated
415            @Override
416            public void disableStaging(
417                            PortletRequest portletRequest, Group scopeGroup, Group liveGroup,
418                            ServiceContext serviceContext)
419                    throws Exception {
420    
421                    disableStaging(portletRequest, liveGroup, serviceContext);
422            }
423    
424            @Override
425            public void disableStaging(
426                            PortletRequest portletRequest, Group liveGroup,
427                            ServiceContext serviceContext)
428                    throws Exception {
429    
430                    UnicodeProperties typeSettingsProperties =
431                            liveGroup.getTypeSettingsProperties();
432    
433                    boolean stagedRemotely = GetterUtil.getBoolean(
434                            typeSettingsProperties.getProperty("stagedRemotely"));
435    
436                    if (stagedRemotely) {
437                            String remoteURL = buildRemoteURL(typeSettingsProperties);
438    
439                            long remoteGroupId = GetterUtil.getLong(
440                                    typeSettingsProperties.getProperty("remoteGroupId"));
441    
442                            disableRemoteStaging(remoteURL, remoteGroupId);
443                    }
444    
445                    typeSettingsProperties.remove("branchingPrivate");
446                    typeSettingsProperties.remove("branchingPublic");
447                    typeSettingsProperties.remove("remoteAddress");
448                    typeSettingsProperties.remove("remoteGroupId");
449                    typeSettingsProperties.remove("remotePathContext");
450                    typeSettingsProperties.remove("remotePort");
451                    typeSettingsProperties.remove("secureConnection");
452                    typeSettingsProperties.remove("staged");
453                    typeSettingsProperties.remove("stagedRemotely");
454    
455                    Set<String> keys = new HashSet<String>();
456    
457                    for (String key : typeSettingsProperties.keySet()) {
458                            if (key.startsWith(StagingConstants.STAGED_PORTLET)) {
459                                    keys.add(key);
460                            }
461                    }
462    
463                    for (String key : keys) {
464                            typeSettingsProperties.remove(key);
465                    }
466    
467                    deleteLastImportSettings(liveGroup, true);
468                    deleteLastImportSettings(liveGroup, false);
469    
470                    if (liveGroup.hasStagingGroup()) {
471                            Group stagingGroup = liveGroup.getStagingGroup();
472    
473                            LayoutSetBranchLocalServiceUtil.deleteLayoutSetBranches(
474                                    stagingGroup.getGroupId(), true, true);
475                            LayoutSetBranchLocalServiceUtil.deleteLayoutSetBranches(
476                                    stagingGroup.getGroupId(), false, true);
477    
478                            GroupLocalServiceUtil.deleteGroup(stagingGroup.getGroupId());
479                    }
480                    else {
481                            LayoutSetBranchLocalServiceUtil.deleteLayoutSetBranches(
482                                    liveGroup.getGroupId(), true, true);
483                            LayoutSetBranchLocalServiceUtil.deleteLayoutSetBranches(
484                                    liveGroup.getGroupId(), false, true);
485                    }
486    
487                    GroupLocalServiceUtil.updateGroup(
488                            liveGroup.getGroupId(), typeSettingsProperties.toString());
489            }
490    
491            @Override
492            public void enableLocalStaging(
493                            long userId, Group scopeGroup, Group liveGroup,
494                            boolean branchingPublic, boolean branchingPrivate,
495                            ServiceContext serviceContext)
496                    throws Exception {
497    
498                    if (liveGroup.isStagedRemotely()) {
499                            disableStaging(liveGroup, serviceContext);
500                    }
501    
502                    UnicodeProperties typeSettingsProperties =
503                            liveGroup.getTypeSettingsProperties();
504    
505                    typeSettingsProperties.setProperty(
506                            "branchingPrivate", String.valueOf(branchingPrivate));
507                    typeSettingsProperties.setProperty(
508                            "branchingPublic", String.valueOf(branchingPublic));
509                    typeSettingsProperties.setProperty("staged", Boolean.TRUE.toString());
510                    typeSettingsProperties.setProperty(
511                            "stagedRemotely", String.valueOf(false));
512    
513                    setCommonStagingOptions(
514                            liveGroup, typeSettingsProperties, serviceContext);
515    
516                    GroupLocalServiceUtil.updateGroup(
517                            liveGroup.getGroupId(), typeSettingsProperties.toString());
518    
519                    if (!liveGroup.hasStagingGroup()) {
520                            serviceContext.setAttribute("staging", String.valueOf(true));
521    
522                            Group stagingGroup = GroupLocalServiceUtil.addGroup(
523                                    userId, GroupConstants.DEFAULT_PARENT_GROUP_ID,
524                                    liveGroup.getClassName(), liveGroup.getClassPK(),
525                                    liveGroup.getGroupId(), liveGroup.getDescriptiveName(),
526                                    liveGroup.getDescription(), liveGroup.getType(),
527                                    liveGroup.isManualMembership(),
528                                    liveGroup.getMembershipRestriction(),
529                                    liveGroup.getFriendlyURL(), false, liveGroup.isActive(),
530                                    serviceContext);
531    
532                            Map<String, String[]> parameterMap = getStagingParameters();
533    
534                            if (liveGroup.hasPrivateLayouts()) {
535                                    publishLayouts(
536                                            userId, liveGroup.getGroupId(), stagingGroup.getGroupId(),
537                                            true, parameterMap, null, null);
538                            }
539    
540                            if (liveGroup.hasPublicLayouts() ||
541                                    !liveGroup.hasPrivateLayouts()) {
542    
543                                    publishLayouts(
544                                            userId, liveGroup.getGroupId(), stagingGroup.getGroupId(),
545                                            false, parameterMap, null, null);
546                            }
547                    }
548    
549                    checkDefaultLayoutSetBranches(
550                            userId, liveGroup, branchingPublic, branchingPrivate, false,
551                            serviceContext);
552            }
553    
554            @Override
555            public void enableRemoteStaging(
556                            long userId, Group scopeGroup, Group liveGroup,
557                            boolean branchingPublic, boolean branchingPrivate,
558                            String remoteAddress, int remotePort, String remotePathContext,
559                            boolean secureConnection, long remoteGroupId,
560                            ServiceContext serviceContext)
561                    throws Exception {
562    
563                    validate(
564                            remoteAddress, remotePort, remotePathContext, secureConnection,
565                            remoteGroupId);
566    
567                    if (liveGroup.hasStagingGroup()) {
568                            disableStaging(liveGroup, serviceContext);
569                    }
570    
571                    String remoteURL = buildRemoteURL(
572                            remoteAddress, remotePort, remotePathContext, secureConnection,
573                            GroupConstants.DEFAULT_LIVE_GROUP_ID, false);
574    
575                    UnicodeProperties typeSettingsProperties =
576                            liveGroup.getTypeSettingsProperties();
577    
578                    boolean stagedRemotely = GetterUtil.getBoolean(
579                            typeSettingsProperties.getProperty("stagedRemotely"));
580    
581                    if (stagedRemotely) {
582                            long oldRemoteGroupId = GetterUtil.getLong(
583                                    typeSettingsProperties.getProperty("remoteGroupId"));
584    
585                            String oldRemoteURL = buildRemoteURL(typeSettingsProperties);
586    
587                            if (!remoteURL.equals(oldRemoteURL) ||
588                                    (remoteGroupId != oldRemoteGroupId)) {
589    
590                                    disableRemoteStaging(oldRemoteURL, oldRemoteGroupId);
591    
592                                    stagedRemotely = false;
593                            }
594                    }
595    
596                    if (!stagedRemotely) {
597                            enableRemoteStaging(remoteURL, remoteGroupId);
598                    }
599    
600                    typeSettingsProperties.setProperty(
601                            "branchingPrivate", String.valueOf(branchingPrivate));
602                    typeSettingsProperties.setProperty(
603                            "branchingPublic", String.valueOf(branchingPublic));
604                    typeSettingsProperties.setProperty("remoteAddress", remoteAddress);
605                    typeSettingsProperties.setProperty(
606                            "remoteGroupId", String.valueOf(remoteGroupId));
607                    typeSettingsProperties.setProperty(
608                            "remotePathContext", remotePathContext);
609                    typeSettingsProperties.setProperty(
610                            "remotePort", String.valueOf(remotePort));
611                    typeSettingsProperties.setProperty(
612                            "secureConnection", String.valueOf(secureConnection));
613                    typeSettingsProperties.setProperty("staged", Boolean.TRUE.toString());
614                    typeSettingsProperties.setProperty(
615                            "stagedRemotely", Boolean.TRUE.toString());
616    
617                    setCommonStagingOptions(
618                            liveGroup, typeSettingsProperties, serviceContext);
619    
620                    GroupLocalServiceUtil.updateGroup(
621                            liveGroup.getGroupId(), typeSettingsProperties.toString());
622    
623                    updateStagedPortlets(remoteURL, remoteGroupId, typeSettingsProperties);
624    
625                    checkDefaultLayoutSetBranches(
626                            userId, liveGroup, branchingPublic, branchingPrivate, true,
627                            serviceContext);
628            }
629    
630            @Override
631            public JSONArray getErrorMessagesJSONArray(
632                    Locale locale, Map<String, MissingReference> missingReferences,
633                    Map<String, Serializable> contextMap) {
634    
635                    JSONArray errorMessagesJSONArray = JSONFactoryUtil.createJSONArray();
636    
637                    for (String missingReferenceDisplayName : missingReferences.keySet()) {
638                            MissingReference missingReference = missingReferences.get(
639                                    missingReferenceDisplayName);
640    
641                            JSONObject errorMessageJSONObject =
642                                    JSONFactoryUtil.createJSONObject();
643    
644                            Map<String, String> referrers = missingReference.getReferrers();
645    
646                            if (referrers.size() == 1) {
647                                    Set<Map.Entry<String, String>> referrerDisplayNames =
648                                            referrers.entrySet();
649    
650                                    Iterator<Map.Entry<String, String>> iterator =
651                                            referrerDisplayNames.iterator();
652    
653                                    Map.Entry<String, String> entry = iterator.next();
654    
655                                    String referrerDisplayName = entry.getKey();
656                                    String referrerClassName = entry.getValue();
657    
658                                    if (referrerClassName.equals(Portlet.class.getName())) {
659                                            referrerDisplayName = PortalUtil.getPortletTitle(
660                                                    referrerDisplayName, locale);
661                                    }
662    
663                                    errorMessageJSONObject.put(
664                                            "info",
665                                            LanguageUtil.format(
666                                                    locale, "referenced-by-a-x-x",
667                                                    new String[] {
668                                                            ResourceActionsUtil.getModelResource(
669                                                                    locale, referrerClassName),
670                                                            referrerDisplayName
671                                                    }
672                                            ));
673                            }
674                            else {
675                                    errorMessageJSONObject.put(
676                                            "info",
677                                            LanguageUtil.format(
678                                                    locale, "referenced-by-x-elements", referrers.size()));
679                            }
680    
681                            errorMessageJSONObject.put("name", missingReferenceDisplayName);
682                            errorMessageJSONObject.put(
683                                    "type",
684                                    ResourceActionsUtil.getModelResource(
685                                            locale, missingReference.getClassName()));
686    
687                            errorMessagesJSONArray.put(errorMessageJSONObject);
688                    }
689    
690                    return errorMessagesJSONArray;
691            }
692    
693            @Override
694            public JSONObject getExceptionMessagesJSONObject(
695                    Locale locale, Exception e, Map<String, Serializable> contextMap) {
696    
697                    JSONObject exceptionMessagesJSONObject =
698                            JSONFactoryUtil.createJSONObject();
699    
700                    String errorMessage = StringPool.BLANK;
701                    JSONArray errorMessagesJSONArray = null;
702                    int errorType = 0;
703                    JSONArray warningMessagesJSONArray = null;
704    
705                    if (e instanceof DuplicateFileException) {
706                            errorMessage = LanguageUtil.get(
707                                    locale, "please-enter-a-unique-document-name");
708                            errorType = ServletResponseConstants.SC_DUPLICATE_FILE_EXCEPTION;
709                    }
710                    else if (e instanceof FileExtensionException) {
711                            errorMessage = LanguageUtil.format(
712                                    locale,
713                                    "document-names-must-end-with-one-of-the-following-extensions",
714                                    ".lar");
715                            errorType = ServletResponseConstants.SC_FILE_EXTENSION_EXCEPTION;
716                    }
717                    else if (e instanceof FileNameException) {
718                            errorMessage = LanguageUtil.get(
719                                    locale, "please-enter-a-file-with-a-valid-file-name");
720                            errorType = ServletResponseConstants.SC_FILE_NAME_EXCEPTION;
721                    }
722                    else if (e instanceof FileSizeException ||
723                                     e instanceof LARFileSizeException) {
724    
725                            long fileMaxSize = PropsValues.DL_FILE_MAX_SIZE;
726    
727                            try {
728                                    fileMaxSize = PrefsPropsUtil.getLong(
729                                            PropsKeys.DL_FILE_MAX_SIZE);
730    
731                                    if (fileMaxSize == 0) {
732                                            fileMaxSize = PrefsPropsUtil.getLong(
733                                                    PropsKeys.UPLOAD_SERVLET_REQUEST_IMPL_MAX_SIZE);
734                                    }
735                            }
736                            catch (Exception ex) {
737                            }
738    
739                            errorMessage = LanguageUtil.format(
740                                    locale,
741                                    "please-enter-a-file-with-a-valid-file-size-no-larger-than-x",
742                                    fileMaxSize/1024);
743                            errorType = ServletResponseConstants.SC_FILE_SIZE_EXCEPTION;
744                    }
745                    else if (e instanceof LARTypeException) {
746                            LARTypeException lte = (LARTypeException)e;
747    
748                            errorMessage = LanguageUtil.format(
749                                    locale,
750                                    "please-import-a-lar-file-of-the-correct-type-x-is-not-valid",
751                                    lte.getMessage());
752                            errorType = ServletResponseConstants.SC_FILE_CUSTOM_EXCEPTION;
753                    }
754                    else if (e instanceof LARFileException) {
755                            errorMessage = LanguageUtil.get(
756                                    locale, "please-specify-a-lar-file-to-import");
757                            errorType = ServletResponseConstants.SC_FILE_CUSTOM_EXCEPTION;
758                    }
759                    else if (e instanceof LayoutPrototypeException) {
760                            LayoutPrototypeException lpe = (LayoutPrototypeException)e;
761    
762                            StringBundler sb = new StringBundler(4);
763    
764                            sb.append("the-lar-file-could-not-be-imported-because-it-");
765                            sb.append("requires-page-templates-or-site-templates-that-could-");
766                            sb.append("not-be-found.-please-import-the-following-templates-");
767                            sb.append("manually");
768    
769                            errorMessage = LanguageUtil.get(locale, sb.toString());
770    
771                            errorMessagesJSONArray = JSONFactoryUtil.createJSONArray();
772    
773                            List<Tuple> missingLayoutPrototypes =
774                                    lpe.getMissingLayoutPrototypes();
775    
776                            for (Tuple missingLayoutPrototype : missingLayoutPrototypes) {
777                                    JSONObject errorMessageJSONObject =
778                                            JSONFactoryUtil.createJSONObject();
779    
780                                    String layoutPrototypeUuid =
781                                            (String)missingLayoutPrototype.getObject(1);
782    
783                                    errorMessageJSONObject.put("info", layoutPrototypeUuid);
784    
785                                    String layoutPrototypeName =
786                                            (String)missingLayoutPrototype.getObject(2);
787    
788                                    errorMessageJSONObject.put("name", layoutPrototypeName);
789    
790                                    String layoutPrototypeClassName =
791                                            (String)missingLayoutPrototype.getObject(0);
792    
793                                    errorMessageJSONObject.put(
794                                            "type",
795                                            ResourceActionsUtil.getModelResource(
796                                                    locale, layoutPrototypeClassName));
797    
798                                    errorMessagesJSONArray.put(errorMessageJSONObject);
799                            }
800    
801                            errorType = ServletResponseConstants.SC_FILE_CUSTOM_EXCEPTION;
802                    }
803                    else if (e instanceof LocaleException) {
804                            LocaleException le = (LocaleException)e;
805    
806                            errorMessage = LanguageUtil.format(
807                                    locale,
808                                    "the-available-languages-in-the-lar-file-x-do-not-match-the-" +
809                                            "site's-available-languages-x",
810                                    new String[] {
811                                            StringUtil.merge(
812                                                    le.getSourceAvailableLocales(),
813                                                    StringPool.COMMA_AND_SPACE),
814                                            StringUtil.merge(
815                                                    le.getTargetAvailableLocales(),
816                                                    StringPool.COMMA_AND_SPACE)
817                                    });
818                            errorType = ServletResponseConstants.SC_FILE_CUSTOM_EXCEPTION;
819                    }
820                    else if (e instanceof MissingReferenceException) {
821                            MissingReferenceException mre = (MissingReferenceException)e;
822    
823                            String cmd = null;
824    
825                            if (contextMap != null) {
826                                    cmd = (String)contextMap.get(Constants.CMD);
827                            }
828    
829                            if (Validator.equals(cmd, Constants.PUBLISH)) {
830                                    errorMessage = LanguageUtil.get(
831                                            locale,
832                                            "there-are-missing-references-that-could-not-be-found-in-" +
833                                                    "the-live-environment.-please-publish-again-to-live-" +
834                                                            "ensuring-the-following-elements-are-published");
835                            }
836                            else {
837                                    errorMessage = LanguageUtil.get(
838                                            locale,
839                                            "there-are-missing-references-that-could-not-be-found-in-" +
840                                                    "the-current-site.-please-import-another-lar-file-" +
841                                                            "containing-the-following-elements");
842                            }
843    
844                            MissingReferences missingReferences = mre.getMissingReferences();
845    
846                            errorMessagesJSONArray = getErrorMessagesJSONArray(
847                                    locale, missingReferences.getDependencyMissingReferences(),
848                                    contextMap);
849                            errorType = ServletResponseConstants.SC_FILE_CUSTOM_EXCEPTION;
850                            warningMessagesJSONArray = getWarningMessagesJSONArray(
851                                    locale, missingReferences.getWeakMissingReferences(),
852                                    contextMap);
853                    }
854                    else if (e instanceof PortletIdException) {
855                            errorMessage = LanguageUtil.get(
856                                    locale, "please-import-a-lar-file-for-the-current-portlet");
857                            errorType = ServletResponseConstants.SC_FILE_CUSTOM_EXCEPTION;
858                    }
859                    else if (e instanceof RemoteExportException) {
860                            RemoteExportException ree = (RemoteExportException)e;
861    
862                            if (ree.getType() == RemoteExportException.NO_LAYOUTS) {
863                                    errorMessage = LanguageUtil.get(
864                                            locale, "no-pages-are-selected-for-export");
865                            }
866    
867                            errorType = ServletResponseConstants.SC_FILE_CUSTOM_EXCEPTION;
868                    }
869                    else {
870                            errorMessage = e.getLocalizedMessage();
871                            errorType = ServletResponseConstants.SC_FILE_CUSTOM_EXCEPTION;
872                    }
873    
874                    exceptionMessagesJSONObject.put("message", errorMessage);
875    
876                    if ((errorMessagesJSONArray != null) &&
877                            (errorMessagesJSONArray.length() > 0)) {
878    
879                            exceptionMessagesJSONObject.put(
880                                    "messageListItems", errorMessagesJSONArray);
881                    }
882    
883                    exceptionMessagesJSONObject.put("status", errorType);
884    
885                    if ((warningMessagesJSONArray != null) &&
886                            (warningMessagesJSONArray.length() > 0)) {
887    
888                            exceptionMessagesJSONObject.put(
889                                    "warningMessages", warningMessagesJSONArray);
890                    }
891    
892                    return exceptionMessagesJSONObject;
893            }
894    
895            @Override
896            public Group getLiveGroup(long groupId)
897                    throws PortalException, SystemException {
898    
899                    if (groupId == 0) {
900                            return null;
901                    }
902    
903                    Group group = GroupLocalServiceUtil.getGroup(groupId);
904    
905                    if (group.isLayout()) {
906                            group = group.getParentGroup();
907                    }
908    
909                    if (group.isStagingGroup()) {
910                            return group.getLiveGroup();
911                    }
912                    else {
913                            return group;
914                    }
915            }
916    
917            @Override
918            public long getLiveGroupId(long groupId)
919                    throws PortalException, SystemException {
920    
921                    if (groupId == 0) {
922                            return groupId;
923                    }
924    
925                    Group group = getLiveGroup(groupId);
926    
927                    return group.getGroupId();
928            }
929    
930            /**
931             * @see LayoutRemoteStagingBackgroundTaskExecutor#getMissingRemoteParentLayouts(
932             *      HttpPrincipal, Layout, long)
933             */
934            @Override
935            public List<Layout> getMissingParentLayouts(Layout layout, long liveGroupId)
936                    throws Exception {
937    
938                    List<Layout> missingParentLayouts = new ArrayList<Layout>();
939    
940                    long parentLayoutId = layout.getParentLayoutId();
941    
942                    Layout parentLayout = null;
943    
944                    while (parentLayoutId > 0) {
945                            parentLayout = LayoutLocalServiceUtil.getLayout(
946                                    layout.getGroupId(), layout.isPrivateLayout(), parentLayoutId);
947    
948                            try {
949                                    LayoutLocalServiceUtil.getLayoutByUuidAndGroupId(
950                                            parentLayout.getUuid(), liveGroupId,
951                                            parentLayout.isPrivateLayout());
952    
953                                    // If one parent is found all others are assumed to exist
954    
955                                    break;
956                            }
957                            catch (NoSuchLayoutException nsle) {
958                                    missingParentLayouts.add(parentLayout);
959    
960                                    parentLayoutId = parentLayout.getParentLayoutId();
961                            }
962                    }
963    
964                    return missingParentLayouts;
965            }
966    
967            @Override
968            public long getRecentLayoutRevisionId(
969                            HttpServletRequest request, long layoutSetBranchId, long plid)
970                    throws PortalException, SystemException {
971    
972                    PortalPreferences portalPreferences =
973                            PortletPreferencesFactoryUtil.getPortalPreferences(request);
974    
975                    return getRecentLayoutRevisionId(
976                            portalPreferences, layoutSetBranchId, plid);
977            }
978    
979            @Override
980            public long getRecentLayoutRevisionId(
981                            User user, long layoutSetBranchId, long plid)
982                    throws PortalException, SystemException {
983    
984                    PortalPreferences portalPreferences = getPortalPreferences(user);
985    
986                    return getRecentLayoutRevisionId(
987                            portalPreferences, layoutSetBranchId, plid);
988            }
989    
990            @Override
991            public long getRecentLayoutSetBranchId(
992                    HttpServletRequest request, long layoutSetId) {
993    
994                    return GetterUtil.getLong(
995                            SessionClicks.get(
996                                    request, Staging.class.getName(),
997                                    getRecentLayoutSetBranchIdKey(layoutSetId)));
998            }
999    
1000            @Override
1001            public long getRecentLayoutSetBranchId(User user, long layoutSetId)
1002                    throws SystemException {
1003    
1004                    PortalPreferences portalPreferences = getPortalPreferences(user);
1005    
1006                    return GetterUtil.getLong(
1007                            portalPreferences.getValue(
1008                                    Staging.class.getName(),
1009                                    getRecentLayoutSetBranchIdKey(layoutSetId)));
1010            }
1011    
1012            @Override
1013            public String getSchedulerGroupName(String destinationName, long groupId) {
1014                    return destinationName.concat(StringPool.SLASH).concat(
1015                            String.valueOf(groupId));
1016            }
1017    
1018            @Override
1019            public String getStagedPortletId(String portletId) {
1020                    String key = portletId;
1021    
1022                    if (key.startsWith(StagingConstants.STAGED_PORTLET)) {
1023                            return key;
1024                    }
1025    
1026                    return StagingConstants.STAGED_PORTLET.concat(portletId);
1027            }
1028    
1029            @Override
1030            public Map<String, String[]> getStagingParameters() {
1031                    Map<String, String[]> parameterMap =
1032                            new LinkedHashMap<String, String[]>();
1033    
1034                    parameterMap.put(
1035                            PortletDataHandlerKeys.CATEGORIES,
1036                            new String[] {Boolean.TRUE.toString()});
1037                    parameterMap.put(
1038                            PortletDataHandlerKeys.DATA_STRATEGY,
1039                            new String[] {
1040                                    PortletDataHandlerKeys.DATA_STRATEGY_MIRROR_OVERWRITE});
1041                    parameterMap.put(
1042                            PortletDataHandlerKeys.DELETE_MISSING_LAYOUTS,
1043                            new String[] {Boolean.TRUE.toString()});
1044                    parameterMap.put(
1045                            PortletDataHandlerKeys.DELETE_PORTLET_DATA,
1046                            new String[] {Boolean.FALSE.toString()});
1047                    parameterMap.put(
1048                            PortletDataHandlerKeys.IGNORE_LAST_PUBLISH_DATE,
1049                            new String[] {Boolean.TRUE.toString()});
1050                    parameterMap.put(
1051                            PortletDataHandlerKeys.LAYOUT_SET_PROTOTYPE_LINK_ENABLED,
1052                            new String[] {Boolean.FALSE.toString()});
1053                    parameterMap.put(
1054                            PortletDataHandlerKeys.LAYOUT_SET_SETTINGS,
1055                            new String[] {Boolean.FALSE.toString()});
1056                    parameterMap.put(
1057                            PortletDataHandlerKeys.LOGO,
1058                            new String[] {Boolean.FALSE.toString()});
1059                    parameterMap.put(
1060                            PortletDataHandlerKeys.PERMISSIONS,
1061                            new String[] {Boolean.TRUE.toString()});
1062                    parameterMap.put(
1063                            PortletDataHandlerKeys.PORTLET_CONFIGURATION,
1064                            new String[] {Boolean.TRUE.toString()});
1065                    parameterMap.put(
1066                            PortletDataHandlerKeys.PORTLET_CONFIGURATION_ALL,
1067                            new String[] {Boolean.TRUE.toString()});
1068                    parameterMap.put(
1069                            PortletDataHandlerKeys.PORTLET_DATA,
1070                            new String[] {Boolean.TRUE.toString()});
1071                    parameterMap.put(
1072                            PortletDataHandlerKeys.PORTLET_DATA_ALL,
1073                            new String[] {Boolean.TRUE.toString()});
1074                    parameterMap.put(
1075                            PortletDataHandlerKeys.PORTLET_SETUP_ALL,
1076                            new String[] {Boolean.TRUE.toString()});
1077                    parameterMap.put(
1078                            PortletDataHandlerKeys.THEME,
1079                            new String[] {Boolean.FALSE.toString()});
1080                    parameterMap.put(
1081                            PortletDataHandlerKeys.THEME_REFERENCE,
1082                            new String[] {Boolean.TRUE.toString()});
1083                    parameterMap.put(
1084                            PortletDataHandlerKeys.UPDATE_LAST_PUBLISH_DATE,
1085                            new String[] {Boolean.TRUE.toString()});
1086                    parameterMap.put(
1087                            PortletDataHandlerKeys.USER_ID_STRATEGY,
1088                            new String[] {UserIdStrategy.CURRENT_USER_ID});
1089    
1090                    return parameterMap;
1091            }
1092    
1093            @Override
1094            public Map<String, String[]> getStagingParameters(
1095                    PortletRequest portletRequest) {
1096    
1097                    Map<String, String[]> parameterMap =
1098                            new LinkedHashMap<String, String[]>(
1099                                    portletRequest.getParameterMap());
1100    
1101                    if (!parameterMap.containsKey(PortletDataHandlerKeys.DATA_STRATEGY)) {
1102                            parameterMap.put(
1103                                    PortletDataHandlerKeys.DATA_STRATEGY,
1104                                    new String[] {
1105                                            PortletDataHandlerKeys.DATA_STRATEGY_MIRROR_OVERWRITE});
1106                    }
1107    
1108                    /*if (!parameterMap.containsKey(
1109                                    PortletDataHandlerKeys.DELETE_MISSING_LAYOUTS)) {
1110    
1111                            parameterMap.put(
1112                                    PortletDataHandlerKeys.DELETE_MISSING_LAYOUTS,
1113                                    new String[] {Boolean.TRUE.toString()});
1114                    }*/
1115    
1116                    if (!parameterMap.containsKey(
1117                                    PortletDataHandlerKeys.DELETE_PORTLET_DATA)) {
1118    
1119                            parameterMap.put(
1120                                    PortletDataHandlerKeys.DELETE_PORTLET_DATA,
1121                                    new String[] {Boolean.FALSE.toString()});
1122                    }
1123    
1124                    if (!parameterMap.containsKey(
1125                                    PortletDataHandlerKeys.LAYOUT_SET_PROTOTYPE_LINK_ENABLED)) {
1126    
1127                            parameterMap.put(
1128                                    PortletDataHandlerKeys.LAYOUT_SET_PROTOTYPE_LINK_ENABLED,
1129                                    new String[] {Boolean.FALSE.toString()});
1130                    }
1131    
1132                    if (!parameterMap.containsKey(
1133                                    PortletDataHandlerKeys.LAYOUT_SET_SETTINGS)) {
1134    
1135                            parameterMap.put(
1136                                    PortletDataHandlerKeys.LAYOUT_SET_SETTINGS,
1137                                    new String[] {Boolean.FALSE.toString()});
1138                    }
1139    
1140                    if (!parameterMap.containsKey(PortletDataHandlerKeys.LOGO)) {
1141                            parameterMap.put(
1142                                    PortletDataHandlerKeys.LOGO,
1143                                    new String[] {Boolean.FALSE.toString()});
1144                    }
1145    
1146                    if (!parameterMap.containsKey(
1147                                    PortletDataHandlerKeys.PORTLET_CONFIGURATION)) {
1148    
1149                            parameterMap.put(
1150                                    PortletDataHandlerKeys.PORTLET_CONFIGURATION,
1151                                    new String[] {Boolean.TRUE.toString()});
1152                    }
1153    
1154                    if (!parameterMap.containsKey(PortletDataHandlerKeys.PORTLET_DATA)) {
1155                            parameterMap.put(
1156                                    PortletDataHandlerKeys.PORTLET_DATA,
1157                                    new String[] {Boolean.FALSE.toString()});
1158                    }
1159    
1160                    if (!parameterMap.containsKey(
1161                                    PortletDataHandlerKeys.PORTLET_DATA_ALL)) {
1162    
1163                            parameterMap.put(
1164                                    PortletDataHandlerKeys.PORTLET_DATA_ALL,
1165                                    new String[] {Boolean.FALSE.toString()});
1166                    }
1167    
1168                    if (!parameterMap.containsKey(PortletDataHandlerKeys.THEME)) {
1169                            parameterMap.put(
1170                                    PortletDataHandlerKeys.THEME,
1171                                    new String[] {Boolean.FALSE.toString()});
1172                    }
1173    
1174                    if (!parameterMap.containsKey(PortletDataHandlerKeys.THEME_REFERENCE)) {
1175                            parameterMap.put(
1176                                    PortletDataHandlerKeys.THEME_REFERENCE,
1177                                    new String[] {Boolean.FALSE.toString()});
1178                    }
1179    
1180                    if (!parameterMap.containsKey(
1181                                    PortletDataHandlerKeys.UPDATE_LAST_PUBLISH_DATE)) {
1182    
1183                            parameterMap.put(
1184                                    PortletDataHandlerKeys.UPDATE_LAST_PUBLISH_DATE,
1185                                    new String[] {Boolean.TRUE.toString()});
1186                    }
1187    
1188                    if (!parameterMap.containsKey(
1189                                    PortletDataHandlerKeys.USER_ID_STRATEGY)) {
1190    
1191                            parameterMap.put(
1192                                    PortletDataHandlerKeys.USER_ID_STRATEGY,
1193                                    new String[] {UserIdStrategy.CURRENT_USER_ID});
1194                    }
1195    
1196                    return parameterMap;
1197            }
1198    
1199            @Override
1200            public JSONArray getWarningMessagesJSONArray(
1201                    Locale locale, Map<String, MissingReference> missingReferences,
1202                    Map<String, Serializable> contextMap) {
1203    
1204                    JSONArray warningMessagesJSONArray = JSONFactoryUtil.createJSONArray();
1205    
1206                    for (String missingReferenceReferrerClassName :
1207                                    missingReferences.keySet()) {
1208    
1209                            MissingReference missingReference = missingReferences.get(
1210                                    missingReferenceReferrerClassName);
1211    
1212                            Map<String, String> referrers = missingReference.getReferrers();
1213    
1214                            JSONObject errorMessageJSONObject =
1215                                    JSONFactoryUtil.createJSONObject();
1216    
1217                            if (Validator.isNotNull(missingReference.getClassName())) {
1218                                    errorMessageJSONObject.put(
1219                                            "info",
1220                                            LanguageUtil.format(
1221                                                    locale,
1222                                                    "the-original-x-does-not-exist-in-the-current-" +
1223                                                            "environment",
1224                                                    ResourceActionsUtil.getModelResource(
1225                                                            locale, missingReference.getClassName())));
1226                            }
1227    
1228                            errorMessageJSONObject.put("size", referrers.size());
1229                            errorMessageJSONObject.put(
1230                                    "type",
1231                                    ResourceActionsUtil.getModelResource(
1232                                            locale, missingReferenceReferrerClassName));
1233    
1234                            warningMessagesJSONArray.put(errorMessageJSONObject);
1235                    }
1236    
1237                    return warningMessagesJSONArray;
1238            }
1239    
1240            @Override
1241            public WorkflowTask getWorkflowTask(
1242                            long userId, LayoutRevision layoutRevision)
1243                    throws PortalException, SystemException {
1244    
1245                    WorkflowInstanceLink workflowInstanceLink =
1246                            WorkflowInstanceLinkLocalServiceUtil.fetchWorkflowInstanceLink(
1247                                    layoutRevision.getCompanyId(), layoutRevision.getGroupId(),
1248                                    LayoutRevision.class.getName(),
1249                                    layoutRevision.getLayoutRevisionId());
1250    
1251                    if (workflowInstanceLink == null) {
1252                            return null;
1253                    }
1254    
1255                    List<WorkflowTask> workflowTasks =
1256                            WorkflowTaskManagerUtil.getWorkflowTasksByWorkflowInstance(
1257                                    layoutRevision.getCompanyId(), userId,
1258                                    workflowInstanceLink.getWorkflowInstanceId(), false, 0, 1,
1259                                    null);
1260    
1261                    if (!workflowTasks.isEmpty()) {
1262                            return workflowTasks.get(0);
1263                    }
1264    
1265                    return null;
1266            }
1267    
1268            @Override
1269            public boolean hasWorkflowTask(long userId, LayoutRevision layoutRevision)
1270                    throws PortalException, SystemException {
1271    
1272                    WorkflowTask workflowTask = getWorkflowTask(userId, layoutRevision);
1273    
1274                    if (workflowTask != null) {
1275                            return true;
1276                    }
1277    
1278                    return false;
1279            }
1280    
1281            @Override
1282            public boolean isIncomplete(Layout layout, long layoutSetBranchId) {
1283                    LayoutRevision layoutRevision = LayoutStagingUtil.getLayoutRevision(
1284                            layout);
1285    
1286                    if (layoutRevision == null) {
1287                            try {
1288                                    layoutRevision =
1289                                            LayoutRevisionLocalServiceUtil.getLayoutRevision(
1290                                                    layoutSetBranchId, layout.getPlid(), true);
1291    
1292                                    return false;
1293                            }
1294                            catch (Exception e) {
1295                            }
1296                    }
1297    
1298                    try {
1299                            layoutRevision = LayoutRevisionLocalServiceUtil.getLayoutRevision(
1300                                    layoutSetBranchId, layout.getPlid(), false);
1301                    }
1302                    catch (Exception e) {
1303                    }
1304    
1305                    if ((layoutRevision == null) ||
1306                            (layoutRevision.getStatus() ==
1307                                    WorkflowConstants.STATUS_INCOMPLETE)) {
1308    
1309                            return true;
1310                    }
1311    
1312                    return false;
1313            }
1314    
1315            @Override
1316            public void lockGroup(long userId, long groupId) throws Exception {
1317                    if (!PropsValues.STAGING_LOCK_ENABLED) {
1318                            return;
1319                    }
1320    
1321                    if (LockLocalServiceUtil.isLocked(Staging.class.getName(), groupId)) {
1322                            Lock lock = LockLocalServiceUtil.getLock(
1323                                    Staging.class.getName(), groupId);
1324    
1325                            throw new DuplicateLockException(lock);
1326                    }
1327    
1328                    LockLocalServiceUtil.lock(
1329                            userId, Staging.class.getName(), String.valueOf(groupId),
1330                            StagingImpl.class.getName(), false,
1331                            StagingConstants.LOCK_EXPIRATION_TIME);
1332            }
1333    
1334            @Override
1335            public void publishLayout(
1336                            long userId, long plid, long liveGroupId, boolean includeChildren)
1337                    throws Exception {
1338    
1339                    Map<String, String[]> parameterMap = getStagingParameters();
1340    
1341                    parameterMap.put(
1342                            PortletDataHandlerKeys.DELETE_MISSING_LAYOUTS,
1343                            new String[] {Boolean.FALSE.toString()});
1344    
1345                    Layout layout = LayoutLocalServiceUtil.getLayout(plid);
1346    
1347                    List<Layout> layouts = new ArrayList<Layout>();
1348    
1349                    layouts.add(layout);
1350    
1351                    layouts.addAll(getMissingParentLayouts(layout, liveGroupId));
1352    
1353                    if (includeChildren) {
1354                            layouts.addAll(layout.getAllChildren());
1355                    }
1356    
1357                    long[] layoutIds = ExportImportHelperUtil.getLayoutIds(layouts);
1358    
1359                    publishLayouts(
1360                            userId, layout.getGroupId(), liveGroupId, layout.isPrivateLayout(),
1361                            layoutIds, parameterMap, null, null);
1362            }
1363    
1364            @Override
1365            public void publishLayouts(
1366                            long userId, long sourceGroupId, long targetGroupId,
1367                            boolean privateLayout, long[] layoutIds,
1368                            Map<String, String[]> parameterMap, Date startDate, Date endDate)
1369                    throws Exception {
1370    
1371                    parameterMap.put(
1372                            PortletDataHandlerKeys.PERFORM_DIRECT_BINARY_IMPORT,
1373                            new String[] {Boolean.TRUE.toString()});
1374    
1375                    Map<String, Serializable> taskContextMap =
1376                            BackgroundTaskContextMapFactory.buildTaskContextMap(
1377                                    userId, sourceGroupId, privateLayout, layoutIds, parameterMap,
1378                                    Constants.PUBLISH, startDate, endDate, StringPool.BLANK);
1379    
1380                    taskContextMap.put("sourceGroupId", sourceGroupId);
1381                    taskContextMap.put("targetGroupId", targetGroupId);
1382    
1383                    BackgroundTaskLocalServiceUtil.addBackgroundTask(
1384                            userId, sourceGroupId, StringPool.BLANK, null,
1385                            LayoutStagingBackgroundTaskExecutor.class, taskContextMap,
1386                            new ServiceContext());
1387            }
1388    
1389            @Override
1390            public void publishLayouts(
1391                            long userId, long sourceGroupId, long targetGroupId,
1392                            boolean privateLayout, Map<Long, Boolean> layoutIdMap,
1393                            Map<String, String[]> parameterMap, Date startDate, Date endDate)
1394                    throws Exception {
1395    
1396                    List<Layout> layouts = new ArrayList<Layout>();
1397    
1398                    for (Map.Entry<Long, Boolean> entry : layoutIdMap.entrySet()) {
1399                            long plid = GetterUtil.getLong(String.valueOf(entry.getKey()));
1400                            boolean includeChildren = entry.getValue();
1401    
1402                            Layout layout = LayoutLocalServiceUtil.getLayout(plid);
1403    
1404                            if (!layouts.contains(layout)) {
1405                                    layouts.add(layout);
1406                            }
1407    
1408                            List<Layout> parentLayouts = getMissingParentLayouts(
1409                                    layout, targetGroupId);
1410    
1411                            for (Layout parentLayout : parentLayouts) {
1412                                    if (!layouts.contains(parentLayout)) {
1413                                            layouts.add(parentLayout);
1414                                    }
1415                            }
1416    
1417                            if (includeChildren) {
1418                                    for (Layout childLayout : layout.getAllChildren()) {
1419                                            if (!layouts.contains(childLayout)) {
1420                                                    layouts.add(childLayout);
1421                                            }
1422                                    }
1423                            }
1424                    }
1425    
1426                    long[] layoutIds = ExportImportHelperUtil.getLayoutIds(layouts);
1427    
1428                    publishLayouts(
1429                            userId, sourceGroupId, targetGroupId, privateLayout, layoutIds,
1430                            parameterMap, startDate, endDate);
1431            }
1432    
1433            @Override
1434            public void publishLayouts(
1435                            long userId, long sourceGroupId, long targetGroupId,
1436                            boolean privateLayout, Map<String, String[]> parameterMap,
1437                            Date startDate, Date endDate)
1438                    throws Exception {
1439    
1440                    publishLayouts(
1441                            userId, sourceGroupId, targetGroupId, privateLayout, (long[])null,
1442                            parameterMap, startDate, endDate);
1443            }
1444    
1445            @Override
1446            public void publishToLive(PortletRequest portletRequest) throws Exception {
1447                    long groupId = ParamUtil.getLong(portletRequest, "groupId");
1448    
1449                    Group liveGroup = GroupLocalServiceUtil.getGroup(groupId);
1450    
1451                    Map<String, String[]> parameterMap = getStagingParameters(
1452                            portletRequest);
1453    
1454                    if (liveGroup.isStaged()) {
1455                            if (liveGroup.isStagedRemotely()) {
1456                                    publishToRemote(portletRequest);
1457                            }
1458                            else {
1459                                    Group stagingGroup = liveGroup.getStagingGroup();
1460    
1461                                    publishLayouts(
1462                                            portletRequest, stagingGroup.getGroupId(), groupId,
1463                                            parameterMap, false);
1464                            }
1465                    }
1466            }
1467    
1468            @Override
1469            public void publishToLive(PortletRequest portletRequest, Portlet portlet)
1470                    throws Exception {
1471    
1472                    long plid = ParamUtil.getLong(portletRequest, "plid");
1473    
1474                    Layout sourceLayout = LayoutLocalServiceUtil.getLayout(plid);
1475    
1476                    Group stagingGroup = null;
1477                    Group liveGroup = null;
1478    
1479                    Layout targetLayout = null;
1480    
1481                    long scopeGroupId = PortalUtil.getScopeGroupId(portletRequest);
1482    
1483                    if (sourceLayout.hasScopeGroup() &&
1484                            (sourceLayout.getScopeGroup().getGroupId() == scopeGroupId)) {
1485    
1486                            stagingGroup = sourceLayout.getScopeGroup();
1487                            liveGroup = stagingGroup.getLiveGroup();
1488    
1489                            targetLayout = LayoutLocalServiceUtil.getLayout(
1490                                    liveGroup.getClassPK());
1491                    }
1492                    else {
1493                            stagingGroup = sourceLayout.getGroup();
1494                            liveGroup = stagingGroup.getLiveGroup();
1495    
1496                            targetLayout = LayoutLocalServiceUtil.getLayoutByUuidAndGroupId(
1497                                    sourceLayout.getUuid(), liveGroup.getGroupId(),
1498                                    sourceLayout.isPrivateLayout());
1499                    }
1500    
1501                    copyPortlet(
1502                            portletRequest, stagingGroup.getGroupId(), liveGroup.getGroupId(),
1503                            sourceLayout.getPlid(), targetLayout.getPlid(),
1504                            portlet.getPortletId());
1505            }
1506    
1507            @Override
1508            public void publishToRemote(PortletRequest portletRequest)
1509                    throws Exception {
1510    
1511                    publishToRemote(portletRequest, false);
1512            }
1513    
1514            @Override
1515            public void scheduleCopyFromLive(PortletRequest portletRequest)
1516                    throws Exception {
1517    
1518                    long stagingGroupId = ParamUtil.getLong(
1519                            portletRequest, "stagingGroupId");
1520    
1521                    Group stagingGroup = GroupLocalServiceUtil.getGroup(stagingGroupId);
1522    
1523                    long liveGroupId = stagingGroup.getLiveGroupId();
1524    
1525                    Map<String, String[]> parameterMap = getStagingParameters(
1526                            portletRequest);
1527    
1528                    publishLayouts(
1529                            portletRequest, liveGroupId, stagingGroupId, parameterMap, true);
1530            }
1531    
1532            @Override
1533            public void schedulePublishToLive(PortletRequest portletRequest)
1534                    throws Exception {
1535    
1536                    long stagingGroupId = ParamUtil.getLong(
1537                            portletRequest, "stagingGroupId");
1538    
1539                    Group stagingGroup = GroupLocalServiceUtil.getGroup(stagingGroupId);
1540    
1541                    long liveGroupId = stagingGroup.getLiveGroupId();
1542    
1543                    Map<String, String[]> parameterMap = getStagingParameters(
1544                            portletRequest);
1545    
1546                    publishLayouts(
1547                            portletRequest, stagingGroupId, liveGroupId, parameterMap, true);
1548            }
1549    
1550            @Override
1551            public void schedulePublishToRemote(PortletRequest portletRequest)
1552                    throws Exception {
1553    
1554                    publishToRemote(portletRequest, true);
1555            }
1556    
1557            @Override
1558            public void setRecentLayoutBranchId(
1559                            HttpServletRequest request, long layoutSetBranchId, long plid,
1560                            long layoutBranchId)
1561                    throws SystemException {
1562    
1563                    PortalPreferences portalPreferences =
1564                            PortletPreferencesFactoryUtil.getPortalPreferences(request);
1565    
1566                    setRecentLayoutBranchId(
1567                            portalPreferences, layoutSetBranchId, plid, layoutBranchId);
1568            }
1569    
1570            @Override
1571            public void setRecentLayoutBranchId(
1572                            User user, long layoutSetBranchId, long plid, long layoutBranchId)
1573                    throws SystemException {
1574    
1575                    PortalPreferences portalPreferences = getPortalPreferences(user);
1576    
1577                    setRecentLayoutBranchId(
1578                            portalPreferences, layoutSetBranchId, plid, layoutBranchId);
1579            }
1580    
1581            @Override
1582            public void setRecentLayoutRevisionId(
1583                            HttpServletRequest request, long layoutSetBranchId, long plid,
1584                            long layoutRevisionId)
1585                    throws SystemException {
1586    
1587                    PortalPreferences portalPreferences =
1588                            PortletPreferencesFactoryUtil.getPortalPreferences(request);
1589    
1590                    setRecentLayoutRevisionId(
1591                            portalPreferences, layoutSetBranchId, plid, layoutRevisionId);
1592            }
1593    
1594            @Override
1595            public void setRecentLayoutRevisionId(
1596                            User user, long layoutSetBranchId, long plid, long layoutRevisionId)
1597                    throws SystemException {
1598    
1599                    PortalPreferences portalPreferences = getPortalPreferences(user);
1600    
1601                    setRecentLayoutRevisionId(
1602                            portalPreferences, layoutSetBranchId, plid, layoutRevisionId);
1603            }
1604    
1605            @Override
1606            public void setRecentLayoutSetBranchId(
1607                    HttpServletRequest request, long layoutSetId, long layoutSetBranchId) {
1608    
1609                    SessionClicks.put(
1610                            request, Staging.class.getName(),
1611                            getRecentLayoutSetBranchIdKey(layoutSetId),
1612                            String.valueOf(layoutSetBranchId));
1613            }
1614    
1615            @Override
1616            public void setRecentLayoutSetBranchId(
1617                            User user, long layoutSetId, long layoutSetBranchId)
1618                    throws SystemException {
1619    
1620                    PortalPreferences portalPreferences = getPortalPreferences(user);
1621    
1622                    portalPreferences.setValue(
1623                            Staging.class.getName(), getRecentLayoutSetBranchIdKey(layoutSetId),
1624                            String.valueOf(layoutSetBranchId));
1625            }
1626    
1627            @Override
1628            public void unlockGroup(long groupId) throws SystemException {
1629                    if (!PropsValues.STAGING_LOCK_ENABLED) {
1630                            return;
1631                    }
1632    
1633                    LockLocalServiceUtil.unlock(Staging.class.getName(), groupId);
1634            }
1635    
1636            @Override
1637            public void unscheduleCopyFromLive(PortletRequest portletRequest)
1638                    throws Exception {
1639    
1640                    long stagingGroupId = ParamUtil.getLong(
1641                            portletRequest, "stagingGroupId");
1642    
1643                    String jobName = ParamUtil.getString(portletRequest, "jobName");
1644                    String groupName = getSchedulerGroupName(
1645                            DestinationNames.LAYOUTS_LOCAL_PUBLISHER, stagingGroupId);
1646    
1647                    LayoutServiceUtil.unschedulePublishToLive(
1648                            stagingGroupId, jobName, groupName);
1649            }
1650    
1651            @Override
1652            public void unschedulePublishToLive(PortletRequest portletRequest)
1653                    throws Exception {
1654    
1655                    long stagingGroupId = ParamUtil.getLong(
1656                            portletRequest, "stagingGroupId");
1657    
1658                    Group stagingGroup = GroupLocalServiceUtil.getGroup(stagingGroupId);
1659    
1660                    long liveGroupId = stagingGroup.getLiveGroupId();
1661    
1662                    String jobName = ParamUtil.getString(portletRequest, "jobName");
1663                    String groupName = getSchedulerGroupName(
1664                            DestinationNames.LAYOUTS_LOCAL_PUBLISHER, liveGroupId);
1665    
1666                    LayoutServiceUtil.unschedulePublishToLive(
1667                            liveGroupId, jobName, groupName);
1668            }
1669    
1670            @Override
1671            public void unschedulePublishToRemote(PortletRequest portletRequest)
1672                    throws Exception {
1673    
1674                    long groupId = ParamUtil.getLong(portletRequest, "groupId");
1675    
1676                    String jobName = ParamUtil.getString(portletRequest, "jobName");
1677                    String groupName = getSchedulerGroupName(
1678                            DestinationNames.LAYOUTS_REMOTE_PUBLISHER, groupId);
1679    
1680                    LayoutServiceUtil.unschedulePublishToRemote(
1681                            groupId, jobName, groupName);
1682            }
1683    
1684            @Override
1685            public void updateLastImportSettings(
1686                            Element layoutElement, Layout layout,
1687                            PortletDataContext portletDataContext)
1688                    throws Exception {
1689    
1690                    Map<String, String[]> parameterMap =
1691                            portletDataContext.getParameterMap();
1692    
1693                    String cmd = MapUtil.getString(parameterMap, Constants.CMD);
1694    
1695                    if (!cmd.equals("publish_to_live")) {
1696                            return;
1697                    }
1698    
1699                    UnicodeProperties typeSettingsProperties =
1700                            layout.getTypeSettingsProperties();
1701    
1702                    typeSettingsProperties.setProperty(
1703                            "last-import-date", String.valueOf(System.currentTimeMillis()));
1704    
1705                    String layoutRevisionId = GetterUtil.getString(
1706                            layoutElement.attributeValue("layout-revision-id"));
1707    
1708                    typeSettingsProperties.setProperty(
1709                            "last-import-layout-revision-id", layoutRevisionId);
1710    
1711                    String layoutSetBranchId = MapUtil.getString(
1712                            parameterMap, "layoutSetBranchId");
1713    
1714                    typeSettingsProperties.setProperty(
1715                            "last-import-layout-set-branch-id", layoutSetBranchId);
1716    
1717                    String layoutSetBranchName = MapUtil.getString(
1718                            parameterMap, "layoutSetBranchName");
1719    
1720                    typeSettingsProperties.setProperty(
1721                            "last-import-layout-set-branch-name", layoutSetBranchName);
1722    
1723                    String lastImportUserName = MapUtil.getString(
1724                            parameterMap, "lastImportUserName");
1725    
1726                    typeSettingsProperties.setProperty(
1727                            "last-import-user-name", lastImportUserName);
1728    
1729                    String lastImportUserUuid = MapUtil.getString(
1730                            parameterMap, "lastImportUserUuid");
1731    
1732                    typeSettingsProperties.setProperty(
1733                            "last-import-user-uuid", lastImportUserUuid);
1734    
1735                    String layoutBranchId = GetterUtil.getString(
1736                            layoutElement.attributeValue("layout-branch-id"));
1737    
1738                    typeSettingsProperties.setProperty(
1739                            "last-import-layout-branch-id", layoutBranchId);
1740    
1741                    String layoutBranchName = GetterUtil.getString(
1742                            layoutElement.attributeValue("layout-branch-name"));
1743    
1744                    typeSettingsProperties.setProperty(
1745                            "last-import-layout-branch-name", layoutBranchName);
1746    
1747                    layout.setTypeSettingsProperties(typeSettingsProperties);
1748            }
1749    
1750            @Override
1751            public void updateLastPublishDate(
1752                            long groupId, boolean privateLayout, Date lastPublishDate)
1753                    throws Exception {
1754    
1755                    LayoutSet layoutSet = LayoutSetLocalServiceUtil.getLayoutSet(
1756                            groupId, privateLayout);
1757    
1758                    UnicodeProperties settingsProperties =
1759                            layoutSet.getSettingsProperties();
1760    
1761                    settingsProperties.setProperty(
1762                            "last-publish-date", String.valueOf(lastPublishDate.getTime()));
1763    
1764                    LayoutSetLocalServiceUtil.updateSettings(
1765                            layoutSet.getGroupId(), layoutSet.isPrivateLayout(),
1766                            settingsProperties.toString());
1767            }
1768    
1769            @Override
1770            public void updateLastPublishDate(
1771                            String portletId, PortletPreferences portletPreferences,
1772                            Date lastPublishDate)
1773                    throws Exception {
1774    
1775                    try {
1776                            portletPreferences.setValue(
1777                                    "last-publish-date", String.valueOf(lastPublishDate.getTime()));
1778    
1779                            portletPreferences.store();
1780                    }
1781                    catch (UnsupportedOperationException uoe) {
1782                            if (_log.isDebugEnabled()) {
1783                                    _log.debug(
1784                                            "Not updating the portlet setup for " + portletId +
1785                                                    " because no setup was returned for the current " +
1786                                                            "page");
1787                            }
1788                    }
1789                    catch (Exception e) {
1790                            _log.error(e, e);
1791                    }
1792            }
1793    
1794            @Override
1795            public void updateStaging(PortletRequest portletRequest, Group liveGroup)
1796                    throws Exception {
1797    
1798                    ThemeDisplay themeDisplay = (ThemeDisplay)portletRequest.getAttribute(
1799                            WebKeys.THEME_DISPLAY);
1800    
1801                    PermissionChecker permissionChecker =
1802                            themeDisplay.getPermissionChecker();
1803    
1804                    long userId = permissionChecker.getUserId();
1805    
1806                    Group scopeGroup = themeDisplay.getScopeGroup();
1807    
1808                    if (!GroupPermissionUtil.contains(
1809                                    permissionChecker, liveGroup.getGroupId(),
1810                                    ActionKeys.MANAGE_STAGING)) {
1811    
1812                            return;
1813                    }
1814    
1815                    int stagingType = getStagingType(portletRequest, liveGroup);
1816    
1817                    boolean branchingPublic = getBoolean(
1818                            portletRequest, liveGroup, "branchingPublic");
1819                    boolean branchingPrivate = getBoolean(
1820                            portletRequest, liveGroup, "branchingPrivate");
1821    
1822                    ServiceContext serviceContext =
1823                            ServiceContextThreadLocal.getServiceContext();
1824    
1825                    if (stagingType == StagingConstants.TYPE_NOT_STAGED) {
1826                            if (liveGroup.hasStagingGroup() || liveGroup.isStagedRemotely()) {
1827                                    disableStaging(portletRequest, liveGroup, serviceContext);
1828                            }
1829                    }
1830                    else if (stagingType == StagingConstants.TYPE_LOCAL_STAGING) {
1831                            enableLocalStaging(
1832                                    userId, scopeGroup, liveGroup, branchingPublic,
1833                                    branchingPrivate, serviceContext);
1834                    }
1835                    else if (stagingType == StagingConstants.TYPE_REMOTE_STAGING) {
1836                            String remoteAddress = getString(
1837                                    portletRequest, liveGroup, "remoteAddress");
1838    
1839                            remoteAddress = stripProtocolFromRemoteAddress(remoteAddress);
1840    
1841                            int remotePort = getInteger(
1842                                    portletRequest, liveGroup, "remotePort");
1843                            String remotePathContext = getString(
1844                                    portletRequest, liveGroup, "remotePathContext");
1845                            boolean secureConnection = getBoolean(
1846                                    portletRequest, liveGroup, "secureConnection");
1847                            long remoteGroupId = getLong(
1848                                    portletRequest, liveGroup, "remoteGroupId");
1849    
1850                            enableRemoteStaging(
1851                                    userId, scopeGroup, liveGroup, branchingPublic,
1852                                    branchingPrivate, remoteAddress, remotePort, remotePathContext,
1853                                    secureConnection, remoteGroupId, serviceContext);
1854                    }
1855            }
1856    
1857            protected void addDefaultLayoutSetBranch(
1858                            long userId, long groupId, String groupName, boolean privateLayout,
1859                            ServiceContext serviceContext)
1860                    throws PortalException, SystemException {
1861    
1862                    String masterBranchDescription =
1863                            LayoutSetBranchConstants.MASTER_BRANCH_DESCRIPTION_PUBLIC;
1864    
1865                    if (privateLayout) {
1866                            masterBranchDescription =
1867                                    LayoutSetBranchConstants.MASTER_BRANCH_DESCRIPTION_PRIVATE;
1868                    }
1869    
1870                    String description = LanguageUtil.format(
1871                            PortalUtil.getSiteDefaultLocale(groupId), masterBranchDescription,
1872                            groupName);
1873    
1874                    try {
1875                            LayoutSetBranch layoutSetBranch =
1876                                    LayoutSetBranchLocalServiceUtil.addLayoutSetBranch(
1877                                            userId, groupId, privateLayout,
1878                                            LayoutSetBranchConstants.MASTER_BRANCH_NAME, description,
1879                                            true, LayoutSetBranchConstants.ALL_BRANCHES,
1880                                            serviceContext);
1881    
1882                            List<LayoutRevision> layoutRevisions =
1883                                    LayoutRevisionLocalServiceUtil.getLayoutRevisions(
1884                                            layoutSetBranch.getLayoutSetBranchId(), false);
1885    
1886                            for (LayoutRevision layoutRevision : layoutRevisions) {
1887                                    LayoutRevisionLocalServiceUtil.updateStatus(
1888                                            userId, layoutRevision.getLayoutRevisionId(),
1889                                            WorkflowConstants.STATUS_APPROVED, serviceContext);
1890                            }
1891                    }
1892                    catch (PortalException pe) {
1893                            if (_log.isWarnEnabled()) {
1894                                    _log.warn(
1895                                            "Unable to create master branch for " +
1896                                                    (privateLayout ? "private" : "public") + " layouts",
1897                                            pe);
1898                            }
1899                    }
1900            }
1901    
1902            protected String buildRemoteURL(UnicodeProperties typeSettingsProperties) {
1903                    String remoteAddress = typeSettingsProperties.getProperty(
1904                            "remoteAddress");
1905                    int remotePort = GetterUtil.getInteger(
1906                            typeSettingsProperties.getProperty("remotePort"));
1907                    String remotePathContext = typeSettingsProperties.getProperty(
1908                            "remotePathContext");
1909                    boolean secureConnection = GetterUtil.getBoolean(
1910                            typeSettingsProperties.getProperty("secureConnection"));
1911    
1912                    return buildRemoteURL(
1913                            remoteAddress, remotePort, remotePathContext, secureConnection,
1914                            GroupConstants.DEFAULT_LIVE_GROUP_ID, false);
1915            }
1916    
1917            protected void checkDefaultLayoutSetBranches(
1918                            long userId, Group liveGroup, boolean branchingPublic,
1919                            boolean branchingPrivate, boolean remote,
1920                            ServiceContext serviceContext)
1921                    throws Exception {
1922    
1923                    long targetGroupId = 0;
1924    
1925                    if (remote) {
1926                            targetGroupId = liveGroup.getGroupId();
1927                    }
1928                    else {
1929                            Group stagingGroup = liveGroup.getStagingGroup();
1930    
1931                            if (stagingGroup == null) {
1932                                    return;
1933                            }
1934    
1935                            targetGroupId = stagingGroup.getGroupId();
1936                    }
1937    
1938                    if (branchingPublic) {
1939                            LayoutSetBranch layoutSetBranch =
1940                                    LayoutSetBranchLocalServiceUtil.fetchLayoutSetBranch(
1941                                            targetGroupId, false,
1942                                            LayoutSetBranchConstants.MASTER_BRANCH_NAME);
1943    
1944                            if (layoutSetBranch == null) {
1945                                    addDefaultLayoutSetBranch(
1946                                            userId, targetGroupId, liveGroup.getDescriptiveName(),
1947                                            false, serviceContext);
1948                            }
1949                    }
1950                    else {
1951                            LayoutSetBranchLocalServiceUtil.deleteLayoutSetBranches(
1952                                    targetGroupId, false, true);
1953                    }
1954    
1955                    if (branchingPrivate) {
1956                            LayoutSetBranch layoutSetBranch =
1957                                    LayoutSetBranchLocalServiceUtil.fetchLayoutSetBranch(
1958                                            targetGroupId, true,
1959                                            LayoutSetBranchConstants.MASTER_BRANCH_NAME);
1960    
1961                            if (layoutSetBranch == null) {
1962                                    addDefaultLayoutSetBranch(
1963                                            userId, targetGroupId, liveGroup.getDescriptiveName(), true,
1964                                            serviceContext);
1965                            }
1966                    }
1967                    else {
1968                            LayoutSetBranchLocalServiceUtil.deleteLayoutSetBranches(
1969                                    targetGroupId, true, true);
1970                    }
1971            }
1972    
1973            protected void clearLastPublishDate(long groupId, boolean privateLayout)
1974                    throws Exception {
1975    
1976                    LayoutSet layoutSet = LayoutSetLocalServiceUtil.getLayoutSet(
1977                            groupId, privateLayout);
1978    
1979                    UnicodeProperties settingsProperties =
1980                            layoutSet.getSettingsProperties();
1981    
1982                    settingsProperties.remove("last-publish-date");
1983    
1984                    LayoutSetLocalServiceUtil.updateSettings(
1985                            groupId, privateLayout, settingsProperties.toString());
1986            }
1987    
1988            protected void deleteRecentLayoutRevisionId(
1989                    PortalPreferences portalPreferences, long layoutSetBranchId,
1990                    long plid) {
1991    
1992                    portalPreferences.setValue(
1993                            Staging.class.getName(),
1994                            getRecentLayoutRevisionIdKey(layoutSetBranchId, plid), null);
1995            }
1996    
1997            protected void disableRemoteStaging(String remoteURL, long remoteGroupId)
1998                    throws Exception {
1999    
2000                    PermissionChecker permissionChecker =
2001                            PermissionThreadLocal.getPermissionChecker();
2002    
2003                    User user = permissionChecker.getUser();
2004    
2005                    HttpPrincipal httpPrincipal = new HttpPrincipal(
2006                            remoteURL, user.getScreenName(), user.getPassword(),
2007                            user.getPasswordEncrypted());
2008    
2009                    try {
2010                            GroupServiceHttp.disableStaging(httpPrincipal, remoteGroupId);
2011                    }
2012                    catch (NoSuchGroupException nsge) {
2013                            RemoteExportException ree = new RemoteExportException(
2014                                    RemoteExportException.NO_GROUP);
2015    
2016                            ree.setGroupId(remoteGroupId);
2017    
2018                            throw ree;
2019                    }
2020                    catch (PrincipalException pe) {
2021                            RemoteExportException ree = new RemoteExportException(
2022                                    RemoteExportException.NO_PERMISSIONS);
2023    
2024                            ree.setGroupId(remoteGroupId);
2025    
2026                            throw ree;
2027                    }
2028                    catch (RemoteAuthException rae) {
2029                            rae.setURL(remoteURL);
2030    
2031                            throw rae;
2032                    }
2033                    catch (SystemException se) {
2034                            RemoteExportException ree = new RemoteExportException(
2035                                    RemoteExportException.BAD_CONNECTION);
2036    
2037                            ree.setURL(remoteURL);
2038    
2039                            throw ree;
2040                    }
2041            }
2042    
2043            protected void enableRemoteStaging(String remoteURL, long remoteGroupId)
2044                    throws Exception {
2045    
2046                    PermissionChecker permissionChecker =
2047                            PermissionThreadLocal.getPermissionChecker();
2048    
2049                    User user = permissionChecker.getUser();
2050    
2051                    HttpPrincipal httpPrincipal = new HttpPrincipal(
2052                            remoteURL, user.getScreenName(), user.getPassword(),
2053                            user.getPasswordEncrypted());
2054    
2055                    try {
2056                            GroupServiceHttp.enableStaging(httpPrincipal, remoteGroupId);
2057                    }
2058                    catch (NoSuchGroupException nsge) {
2059                            RemoteExportException ree = new RemoteExportException(
2060                                    RemoteExportException.NO_GROUP);
2061    
2062                            ree.setGroupId(remoteGroupId);
2063    
2064                            throw ree;
2065                    }
2066                    catch (PrincipalException pe) {
2067                            RemoteExportException ree = new RemoteExportException(
2068                                    RemoteExportException.NO_PERMISSIONS);
2069    
2070                            ree.setGroupId(remoteGroupId);
2071    
2072                            throw ree;
2073                    }
2074                    catch (RemoteAuthException rae) {
2075                            rae.setURL(remoteURL);
2076    
2077                            throw rae;
2078                    }
2079                    catch (SystemException se) {
2080                            RemoteExportException ree = new RemoteExportException(
2081                                    RemoteExportException.BAD_CONNECTION);
2082    
2083                            ree.setURL(remoteURL);
2084    
2085                            throw ree;
2086                    }
2087            }
2088    
2089            protected boolean getBoolean(
2090                    PortletRequest portletRequest, Group group, String param) {
2091    
2092                    return ParamUtil.getBoolean(
2093                            portletRequest, param,
2094                            GetterUtil.getBoolean(group.getTypeSettingsProperty(param)));
2095            }
2096    
2097            protected int getInteger(
2098                    PortletRequest portletRequest, Group group, String param) {
2099    
2100                    return ParamUtil.getInteger(
2101                            portletRequest, param,
2102                            GetterUtil.getInteger(group.getTypeSettingsProperty(param)));
2103            }
2104    
2105            protected long getLong(
2106                    PortletRequest portletRequest, Group group, String param) {
2107    
2108                    return ParamUtil.getLong(
2109                            portletRequest, param,
2110                            GetterUtil.getLong(group.getTypeSettingsProperty(param)));
2111            }
2112    
2113            protected PortalPreferences getPortalPreferences(User user)
2114                    throws SystemException {
2115    
2116                    boolean signedIn = !user.isDefaultUser();
2117    
2118                    PortalPreferences portalPreferences =
2119                            PortletPreferencesFactoryUtil.getPortalPreferences(
2120                                    user.getUserId(), signedIn);
2121    
2122                    return portalPreferences;
2123            }
2124    
2125            protected long getRecentLayoutBranchId(
2126                    PortalPreferences portalPreferences, long layoutSetBranchId,
2127                    long plid) {
2128    
2129                    return GetterUtil.getLong(
2130                            portalPreferences.getValue(
2131                                    Staging.class.getName(),
2132                                    getRecentLayoutBranchIdKey(layoutSetBranchId, plid)));
2133            }
2134    
2135            protected String getRecentLayoutBranchIdKey(
2136                    long layoutSetBranchId, long plid) {
2137    
2138                    StringBundler sb = new StringBundler(4);
2139    
2140                    sb.append("layoutBranchId-");
2141                    sb.append(layoutSetBranchId);
2142                    sb.append(StringPool.DASH);
2143                    sb.append(plid);
2144    
2145                    return sb.toString();
2146            }
2147    
2148            protected long getRecentLayoutRevisionId(
2149                            PortalPreferences portalPreferences, long layoutSetBranchId,
2150                            long plid)
2151                    throws PortalException, SystemException {
2152    
2153                    long layoutRevisionId = GetterUtil.getLong(
2154                            portalPreferences.getValue(
2155                                    Staging.class.getName(),
2156                                    getRecentLayoutRevisionIdKey(layoutSetBranchId, plid)));
2157    
2158                    if (layoutRevisionId > 0) {
2159                            return layoutRevisionId;
2160                    }
2161    
2162                    long layoutBranchId = getRecentLayoutBranchId(
2163                            portalPreferences, layoutSetBranchId, plid);
2164    
2165                    if (layoutBranchId > 0) {
2166                            try {
2167                                    LayoutBranchLocalServiceUtil.getLayoutBranch(layoutBranchId);
2168                            }
2169                            catch (NoSuchLayoutBranchException nslbe) {
2170                                    LayoutBranch layoutBranch =
2171                                            LayoutBranchLocalServiceUtil.getMasterLayoutBranch(
2172                                                    layoutSetBranchId, plid);
2173    
2174                                    layoutBranchId = layoutBranch.getLayoutBranchId();
2175                            }
2176                    }
2177    
2178                    if (layoutBranchId > 0) {
2179                            try {
2180                                    LayoutRevision layoutRevision =
2181                                            LayoutRevisionLocalServiceUtil.getLayoutRevision(
2182                                                    layoutSetBranchId, layoutBranchId, plid);
2183    
2184                                    if (layoutRevision != null) {
2185                                            layoutRevisionId = layoutRevision.getLayoutRevisionId();
2186                                    }
2187                            }
2188                            catch (NoSuchLayoutRevisionException nslre) {
2189                            }
2190                    }
2191    
2192                    return layoutRevisionId;
2193            }
2194    
2195            protected String getRecentLayoutRevisionIdKey(
2196                    long layoutSetBranchId, long plid) {
2197    
2198                    StringBundler sb = new StringBundler(4);
2199    
2200                    sb.append("layoutRevisionId-");
2201                    sb.append(layoutSetBranchId);
2202                    sb.append(StringPool.DASH);
2203                    sb.append(plid);
2204    
2205                    return sb.toString();
2206            }
2207    
2208            protected String getRecentLayoutSetBranchIdKey(long layoutSetId) {
2209                    return "layoutSetBranchId_" + layoutSetId;
2210            }
2211    
2212            protected int getStagingType(
2213                    PortletRequest portletRequest, Group liveGroup) {
2214    
2215                    String stagingType = portletRequest.getParameter("stagingType");
2216    
2217                    if (stagingType != null) {
2218                            return GetterUtil.getInteger(stagingType);
2219                    }
2220    
2221                    if (liveGroup.isStagedRemotely()) {
2222                            return StagingConstants.TYPE_REMOTE_STAGING;
2223                    }
2224    
2225                    if (liveGroup.hasStagingGroup()) {
2226                            return StagingConstants.TYPE_LOCAL_STAGING;
2227                    }
2228    
2229                    return StagingConstants.TYPE_NOT_STAGED;
2230            }
2231    
2232            protected String getString(
2233                    PortletRequest portletRequest, Group group, String param) {
2234    
2235                    return ParamUtil.getString(
2236                            portletRequest, param,
2237                            GetterUtil.getString(group.getTypeSettingsProperty(param)));
2238            }
2239    
2240            protected void publishLayouts(
2241                            PortletRequest portletRequest, long sourceGroupId,
2242                            long targetGroupId, Map<String, String[]> parameterMap,
2243                            boolean schedule)
2244                    throws Exception {
2245    
2246                    ThemeDisplay themeDisplay = (ThemeDisplay)portletRequest.getAttribute(
2247                            WebKeys.THEME_DISPLAY);
2248    
2249                    String tabs1 = ParamUtil.getString(portletRequest, "tabs1");
2250    
2251                    boolean privateLayout = true;
2252    
2253                    if (tabs1.equals("public-pages")) {
2254                            privateLayout = false;
2255                    }
2256    
2257                    String scope = ParamUtil.getString(portletRequest, "scope");
2258    
2259                    Map<Long, Boolean> layoutIdMap = new LinkedHashMap<Long, Boolean>();
2260    
2261                    if (scope.equals("selected-pages")) {
2262                            layoutIdMap = ExportImportHelperUtil.getLayoutIdMap(portletRequest);
2263                    }
2264    
2265                    DateRange dateRange = ExportImportHelperUtil.getDateRange(
2266                            portletRequest, sourceGroupId, privateLayout, 0, null);
2267    
2268                    if (schedule) {
2269                            String groupName = getSchedulerGroupName(
2270                                    DestinationNames.LAYOUTS_LOCAL_PUBLISHER, targetGroupId);
2271    
2272                            int recurrenceType = ParamUtil.getInteger(
2273                                    portletRequest, "recurrenceType");
2274    
2275                            Calendar startCalendar = ExportImportHelperUtil.getCalendar(
2276                                    portletRequest, "schedulerStartDate", true);
2277    
2278                            String cronText = SchedulerEngineHelperUtil.getCronText(
2279                                    portletRequest, startCalendar, true, recurrenceType);
2280    
2281                            Date schedulerEndDate = null;
2282    
2283                            int endDateType = ParamUtil.getInteger(
2284                                    portletRequest, "endDateType");
2285    
2286                            if (endDateType == 1) {
2287                                    Calendar endCalendar = ExportImportHelperUtil.getCalendar(
2288                                            portletRequest, "schedulerEndDate", true);
2289    
2290                                    schedulerEndDate = endCalendar.getTime();
2291                            }
2292    
2293                            String description = ParamUtil.getString(
2294                                    portletRequest, "description");
2295    
2296                            LayoutServiceUtil.schedulePublishToLive(
2297                                    sourceGroupId, targetGroupId, privateLayout, layoutIdMap,
2298                                    parameterMap, scope, dateRange.getStartDate(),
2299                                    dateRange.getEndDate(), groupName, cronText,
2300                                    startCalendar.getTime(), schedulerEndDate, description);
2301                    }
2302                    else {
2303                            MessageStatus messageStatus = new MessageStatus();
2304    
2305                            messageStatus.startTimer();
2306    
2307                            String command =
2308                                    LayoutsLocalPublisherRequest.COMMAND_SELECTED_PAGES;
2309    
2310                            try {
2311                                    if (scope.equals("all-pages")) {
2312                                            command = LayoutsLocalPublisherRequest.COMMAND_ALL_PAGES;
2313    
2314                                            publishLayouts(
2315                                                    themeDisplay.getUserId(), sourceGroupId, targetGroupId,
2316                                                    privateLayout, parameterMap, dateRange.getStartDate(),
2317                                                    dateRange.getEndDate());
2318                                    }
2319                                    else {
2320                                            publishLayouts(
2321                                                    themeDisplay.getUserId(), sourceGroupId, targetGroupId,
2322                                                    privateLayout, layoutIdMap, parameterMap,
2323                                                    dateRange.getStartDate(), dateRange.getEndDate());
2324                                    }
2325                            }
2326                            catch (Exception e) {
2327                                    messageStatus.setException(e);
2328    
2329                                    throw e;
2330                            }
2331                            finally {
2332                                    messageStatus.stopTimer();
2333    
2334                                    LayoutsLocalPublisherRequest publisherRequest =
2335                                            new LayoutsLocalPublisherRequest(
2336                                                    command, themeDisplay.getUserId(), sourceGroupId,
2337                                                    targetGroupId, privateLayout, layoutIdMap, parameterMap,
2338                                                    dateRange.getStartDate(), dateRange.getEndDate());
2339    
2340                                    messageStatus.setPayload(publisherRequest);
2341    
2342                                    MessageBusUtil.sendMessage(
2343                                            DestinationNames.MESSAGE_BUS_MESSAGE_STATUS, messageStatus);
2344                            }
2345                    }
2346            }
2347    
2348            protected void publishToRemote(
2349                            PortletRequest portletRequest, boolean schedule)
2350                    throws Exception {
2351    
2352                    ThemeDisplay themeDisplay = (ThemeDisplay)portletRequest.getAttribute(
2353                            WebKeys.THEME_DISPLAY);
2354    
2355                    String tabs1 = ParamUtil.getString(portletRequest, "tabs1");
2356    
2357                    long groupId = ParamUtil.getLong(portletRequest, "groupId");
2358    
2359                    boolean privateLayout = true;
2360    
2361                    if (tabs1.equals("public-pages")) {
2362                            privateLayout = false;
2363                    }
2364    
2365                    String scope = ParamUtil.getString(portletRequest, "scope");
2366    
2367                    if (Validator.isNull(scope)) {
2368                            scope = "all-pages";
2369                    }
2370    
2371                    Map<Long, Boolean> layoutIdMap = null;
2372    
2373                    if (scope.equals("selected-pages")) {
2374                            layoutIdMap = ExportImportHelperUtil.getLayoutIdMap(portletRequest);
2375                    }
2376    
2377                    Map<String, String[]> parameterMap = getStagingParameters(
2378                            portletRequest);
2379    
2380                    parameterMap.put(
2381                            PortletDataHandlerKeys.PUBLISH_TO_REMOTE,
2382                            new String[] {Boolean.TRUE.toString()});
2383    
2384                    Group group = GroupLocalServiceUtil.getGroup(groupId);
2385    
2386                    UnicodeProperties groupTypeSettingsProperties =
2387                            group.getTypeSettingsProperties();
2388    
2389                    String remoteAddress = ParamUtil.getString(
2390                            portletRequest, "remoteAddress",
2391                            groupTypeSettingsProperties.getProperty("remoteAddress"));
2392    
2393                    remoteAddress = stripProtocolFromRemoteAddress(remoteAddress);
2394    
2395                    int remotePort = ParamUtil.getInteger(
2396                            portletRequest, "remotePort",
2397                            GetterUtil.getInteger(
2398                                    groupTypeSettingsProperties.getProperty("remotePort")));
2399                    String remotePathContext = ParamUtil.getString(
2400                            portletRequest, "remotePathContext",
2401                            groupTypeSettingsProperties.getProperty("remotePathContext"));
2402                    boolean secureConnection = ParamUtil.getBoolean(
2403                            portletRequest, "secureConnection",
2404                            GetterUtil.getBoolean(
2405                                    groupTypeSettingsProperties.getProperty("secureConnection")));
2406                    long remoteGroupId = ParamUtil.getLong(
2407                            portletRequest, "remoteGroupId",
2408                            GetterUtil.getLong(
2409                                    groupTypeSettingsProperties.getProperty("remoteGroupId")));
2410                    boolean remotePrivateLayout = ParamUtil.getBoolean(
2411                            portletRequest, "remotePrivateLayout");
2412    
2413                    validate(
2414                            remoteAddress, remotePort, remotePathContext, secureConnection,
2415                            remoteGroupId);
2416    
2417                    DateRange dateRange = ExportImportHelperUtil.getDateRange(
2418                            portletRequest, groupId, privateLayout, 0, null);
2419    
2420                    if (schedule) {
2421                            String groupName = getSchedulerGroupName(
2422                                    DestinationNames.LAYOUTS_REMOTE_PUBLISHER, groupId);
2423    
2424                            int recurrenceType = ParamUtil.getInteger(
2425                                    portletRequest, "recurrenceType");
2426    
2427                            Calendar startCalendar = ExportImportHelperUtil.getCalendar(
2428                                    portletRequest, "schedulerStartDate", true);
2429    
2430                            String cronText = SchedulerEngineHelperUtil.getCronText(
2431                                    portletRequest, startCalendar, true, recurrenceType);
2432    
2433                            Date schedulerEndDate = null;
2434    
2435                            int endDateType = ParamUtil.getInteger(
2436                                    portletRequest, "endDateType");
2437    
2438                            if (endDateType == 1) {
2439                                    Calendar endCalendar = ExportImportHelperUtil.getCalendar(
2440                                            portletRequest, "schedulerEndDate", true);
2441    
2442                                    schedulerEndDate = endCalendar.getTime();
2443                            }
2444    
2445                            String description = ParamUtil.getString(
2446                                    portletRequest, "description");
2447    
2448                            LayoutServiceUtil.schedulePublishToRemote(
2449                                    groupId, privateLayout, layoutIdMap, parameterMap,
2450                                    remoteAddress, remotePort, remotePathContext, secureConnection,
2451                                    remoteGroupId, remotePrivateLayout, dateRange.getStartDate(),
2452                                    dateRange.getEndDate(), groupName, cronText,
2453                                    startCalendar.getTime(), schedulerEndDate, description);
2454                    }
2455                    else {
2456                            MessageStatus messageStatus = new MessageStatus();
2457    
2458                            messageStatus.startTimer();
2459    
2460                            try {
2461                                    copyRemoteLayouts(
2462                                            groupId, privateLayout, layoutIdMap, parameterMap,
2463                                            remoteAddress, remotePort, remotePathContext,
2464                                            secureConnection, remoteGroupId, remotePrivateLayout,
2465                                            dateRange.getStartDate(), dateRange.getEndDate());
2466                            }
2467                            catch (Exception e) {
2468                                    messageStatus.setException(e);
2469    
2470                                    throw e;
2471                            }
2472                            finally {
2473                                    messageStatus.stopTimer();
2474    
2475                                    LayoutsRemotePublisherRequest publisherRequest =
2476                                            new LayoutsRemotePublisherRequest(
2477                                                    themeDisplay.getUserId(), groupId, privateLayout,
2478                                                    layoutIdMap, parameterMap, remoteAddress, remotePort,
2479                                                    remotePathContext, secureConnection, remoteGroupId,
2480                                                    remotePrivateLayout, dateRange.getStartDate(),
2481                                                    dateRange.getEndDate());
2482    
2483                                    messageStatus.setPayload(publisherRequest);
2484    
2485                                    MessageBusUtil.sendMessage(
2486                                            DestinationNames.MESSAGE_BUS_MESSAGE_STATUS, messageStatus);
2487                            }
2488                    }
2489            }
2490    
2491            protected void setCommonStagingOptions(
2492                            Group liveGroup, UnicodeProperties typeSettingsProperties,
2493                            ServiceContext serviceContext)
2494                    throws Exception {
2495    
2496                    clearLastPublishDate(liveGroup.getGroupId(), true);
2497                    clearLastPublishDate(liveGroup.getGroupId(), false);
2498    
2499                    Set<String> parameterNames = serviceContext.getAttributes().keySet();
2500    
2501                    for (String parameterName : parameterNames) {
2502                            if (parameterName.startsWith(StagingConstants.STAGED_PORTLET) &&
2503                                    !parameterName.endsWith("Checkbox")) {
2504    
2505                                    boolean staged = ParamUtil.getBoolean(
2506                                            serviceContext, parameterName);
2507    
2508                                    typeSettingsProperties.setProperty(
2509                                            parameterName, String.valueOf(staged));
2510                            }
2511                    }
2512            }
2513    
2514            protected void setRecentLayoutBranchId(
2515                    PortalPreferences portalPreferences, long layoutSetBranchId, long plid,
2516                    long layoutBranchId) {
2517    
2518                    portalPreferences.setValue(
2519                            Staging.class.getName(),
2520                            getRecentLayoutBranchIdKey(layoutSetBranchId, plid),
2521                            String.valueOf(layoutBranchId));
2522            }
2523    
2524            protected void setRecentLayoutRevisionId(
2525                            PortalPreferences portalPreferences, long layoutSetBranchId,
2526                            long plid, long layoutRevisionId)
2527                    throws SystemException {
2528    
2529                    long layoutBranchId = 0;
2530    
2531                    try {
2532                            LayoutRevision layoutRevision =
2533                                    LayoutRevisionLocalServiceUtil.getLayoutRevision(
2534                                            layoutRevisionId);
2535    
2536                            layoutBranchId = layoutRevision.getLayoutBranchId();
2537    
2538                            LayoutRevision lastLayoutRevision =
2539                                    LayoutRevisionLocalServiceUtil.getLayoutRevision(
2540                                            layoutSetBranchId, layoutBranchId, plid);
2541    
2542                            if (lastLayoutRevision.getLayoutRevisionId() == layoutRevisionId) {
2543                                    deleteRecentLayoutRevisionId(
2544                                            portalPreferences, layoutSetBranchId, plid);
2545                            }
2546                            else {
2547                                    portalPreferences.setValue(
2548                                            Staging.class.getName(),
2549                                            getRecentLayoutRevisionIdKey(layoutSetBranchId, plid),
2550                                            String.valueOf(layoutRevisionId));
2551                            }
2552                    }
2553                    catch (PortalException pe) {
2554                            if (_log.isWarnEnabled()) {
2555                                    _log.warn("Unable to set recent layout revision ID", pe);
2556                            }
2557                    }
2558    
2559                    portalPreferences.setValue(
2560                            Staging.class.getName(),
2561                            getRecentLayoutBranchIdKey(layoutSetBranchId, plid),
2562                            String.valueOf(layoutBranchId));
2563            }
2564    
2565            protected String stripProtocolFromRemoteAddress(String remoteAddress) {
2566                    if (remoteAddress.startsWith(Http.HTTP_WITH_SLASH)) {
2567                            remoteAddress = remoteAddress.substring(
2568                                    Http.HTTP_WITH_SLASH.length());
2569                    }
2570                    else if (remoteAddress.startsWith(Http.HTTPS_WITH_SLASH)) {
2571                            remoteAddress = remoteAddress.substring(
2572                                    Http.HTTPS_WITH_SLASH.length());
2573                    }
2574    
2575                    return remoteAddress;
2576            }
2577    
2578            protected void updateGroupTypeSettingsProperties(
2579                            Group group, String remoteAddress, int remotePort,
2580                            String remotePathContext, boolean secureConnection,
2581                            long remoteGroupId)
2582                    throws Exception {
2583    
2584                    UnicodeProperties typeSettingsProperties =
2585                            group.getTypeSettingsProperties();
2586    
2587                    typeSettingsProperties.setProperty("remoteAddress", remoteAddress);
2588                    typeSettingsProperties.setProperty(
2589                            "remoteGroupId", String.valueOf(remoteGroupId));
2590                    typeSettingsProperties.setProperty(
2591                            "remotePathContext", remotePathContext);
2592                    typeSettingsProperties.setProperty(
2593                            "remotePort", String.valueOf(remotePort));
2594                    typeSettingsProperties.setProperty(
2595                            "secureConnection", String.valueOf(secureConnection));
2596    
2597                    group.setTypeSettingsProperties(typeSettingsProperties);
2598    
2599                    GroupLocalServiceUtil.updateGroup(group);
2600            }
2601    
2602            protected void updateStagedPortlets(
2603                            String remoteURL, long remoteGroupId,
2604                            UnicodeProperties typeSettingsProperties)
2605                    throws Exception {
2606    
2607                    PermissionChecker permissionChecker =
2608                            PermissionThreadLocal.getPermissionChecker();
2609    
2610                    User user = permissionChecker.getUser();
2611    
2612                    HttpPrincipal httpPrincipal = new HttpPrincipal(
2613                            remoteURL, user.getScreenName(), user.getPassword(),
2614                            user.getPasswordEncrypted());
2615    
2616                    Map<String, String> stagedPortletIds = new HashMap<String, String>();
2617    
2618                    for (String key : typeSettingsProperties.keySet()) {
2619                            if (key.startsWith(StagingConstants.STAGED_PORTLET)) {
2620                                    stagedPortletIds.put(
2621                                            key, typeSettingsProperties.getProperty(key));
2622                            }
2623                    }
2624    
2625                    try {
2626                            GroupServiceHttp.updateStagedPortlets(
2627                                    httpPrincipal, remoteGroupId, stagedPortletIds);
2628                    }
2629                    catch (NoSuchGroupException nsge) {
2630                            RemoteExportException ree = new RemoteExportException(
2631                                    RemoteExportException.NO_GROUP);
2632    
2633                            ree.setGroupId(remoteGroupId);
2634    
2635                            throw ree;
2636                    }
2637                    catch (PrincipalException pe) {
2638                            RemoteExportException ree = new RemoteExportException(
2639                                    RemoteExportException.NO_PERMISSIONS);
2640    
2641                            ree.setGroupId(remoteGroupId);
2642    
2643                            throw ree;
2644                    }
2645                    catch (RemoteAuthException rae) {
2646                            rae.setURL(remoteURL);
2647    
2648                            throw rae;
2649                    }
2650                    catch (SystemException se) {
2651                            RemoteExportException ree = new RemoteExportException(
2652                                    RemoteExportException.BAD_CONNECTION);
2653    
2654                            ree.setURL(remoteURL);
2655    
2656                            throw ree;
2657                    }
2658            }
2659    
2660            protected void validate(
2661                            String remoteAddress, int remotePort, String remotePathContext,
2662                            boolean secureConnection, long remoteGroupId)
2663                    throws Exception {
2664    
2665                    RemoteOptionsException roe = null;
2666    
2667                    if (!Validator.isDomain(remoteAddress) &&
2668                            !Validator.isIPAddress(remoteAddress)) {
2669    
2670                            roe = new RemoteOptionsException(
2671                                    RemoteOptionsException.REMOTE_ADDRESS);
2672    
2673                            roe.setRemoteAddress(remoteAddress);
2674    
2675                            throw roe;
2676                    }
2677    
2678                    if ((remotePort < 1) || (remotePort > 65535)) {
2679                            roe = new RemoteOptionsException(
2680                                    RemoteOptionsException.REMOTE_PORT);
2681    
2682                            roe.setRemotePort(remotePort);
2683    
2684                            throw roe;
2685                    }
2686    
2687                    if (Validator.isNotNull(remotePathContext) &&
2688                            (!remotePathContext.startsWith(StringPool.FORWARD_SLASH) ||
2689                             remotePathContext.endsWith(StringPool.FORWARD_SLASH))) {
2690    
2691                            roe = new RemoteOptionsException(
2692                                    RemoteOptionsException.REMOTE_PATH_CONTEXT);
2693    
2694                            roe.setRemotePathContext(remotePathContext);
2695    
2696                            throw roe;
2697                    }
2698    
2699                    if (remoteGroupId <= 0) {
2700                            roe = new RemoteOptionsException(
2701                                    RemoteOptionsException.REMOTE_GROUP_ID);
2702    
2703                            roe.setRemoteGroupId(remoteGroupId);
2704    
2705                            throw roe;
2706                    }
2707    
2708                    PermissionChecker permissionChecker =
2709                            PermissionThreadLocal.getPermissionChecker();
2710    
2711                    User user = permissionChecker.getUser();
2712    
2713                    String remoteURL = buildRemoteURL(
2714                            remoteAddress, remotePort, remotePathContext, secureConnection,
2715                            GroupConstants.DEFAULT_LIVE_GROUP_ID, false);
2716    
2717                    HttpPrincipal httpPrincipal = new HttpPrincipal(
2718                            remoteURL, user.getEmailAddress(), user.getPassword(),
2719                            user.getPasswordEncrypted());
2720    
2721                    // Ping remote host and verify that the group exists in the same company
2722                    // as the remote user
2723    
2724                    try {
2725                            GroupServiceHttp.checkRemoteStagingGroup(
2726                                    httpPrincipal, remoteGroupId);
2727                    }
2728                    catch (NoSuchGroupException nsge) {
2729                            RemoteExportException ree = new RemoteExportException(
2730                                    RemoteExportException.NO_GROUP);
2731    
2732                            ree.setGroupId(remoteGroupId);
2733    
2734                            throw ree;
2735                    }
2736                    catch (PrincipalException pe) {
2737                            RemoteExportException ree = new RemoteExportException(
2738                                    RemoteExportException.NO_PERMISSIONS);
2739    
2740                            ree.setGroupId(remoteGroupId);
2741    
2742                            throw ree;
2743                    }
2744                    catch (RemoteAuthException rae) {
2745                            rae.setURL(remoteURL);
2746    
2747                            throw rae;
2748                    }
2749                    catch (SystemException se) {
2750                            RemoteExportException ree = new RemoteExportException(
2751                                    RemoteExportException.BAD_CONNECTION, se.getMessage());
2752    
2753                            ree.setURL(remoteURL);
2754    
2755                            throw ree;
2756                    }
2757            }
2758    
2759            private static Log _log = LogFactoryUtil.getLog(StagingImpl.class);
2760    
2761    }