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