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                            errorType = ServletResponseConstants.SC_FILE_CUSTOM_EXCEPTION;
855    
856                            if (ree.getType() == RemoteExportException.NO_LAYOUTS) {
857                                    errorMessage = LanguageUtil.get(
858                                            locale, "no-pages-are-selected-for-export");
859                            }
860                    }
861                    else {
862                            errorType = ServletResponseConstants.SC_FILE_CUSTOM_EXCEPTION;
863                    }
864    
865                    exceptionMessagesJSONObject.put("message", errorMessage);
866    
867                    if ((errorMessagesJSONArray != null) &&
868                            (errorMessagesJSONArray.length() > 0)) {
869    
870                            exceptionMessagesJSONObject.put(
871                                    "messageListItems", errorMessagesJSONArray);
872                    }
873    
874                    exceptionMessagesJSONObject.put("status", errorType);
875    
876                    if ((warningMessagesJSONArray != null) &&
877                            (warningMessagesJSONArray.length() > 0)) {
878    
879                            exceptionMessagesJSONObject.put(
880                                    "warningMessages", warningMessagesJSONArray);
881                    }
882    
883                    return exceptionMessagesJSONObject;
884            }
885    
886            @Override
887            public Group getLiveGroup(long groupId)
888                    throws PortalException, SystemException {
889    
890                    if (groupId == 0) {
891                            return null;
892                    }
893    
894                    Group group = GroupLocalServiceUtil.getGroup(groupId);
895    
896                    if (group.isLayout()) {
897                            group = group.getParentGroup();
898                    }
899    
900                    if (group.isStagingGroup()) {
901                            return group.getLiveGroup();
902                    }
903                    else {
904                            return group;
905                    }
906            }
907    
908            @Override
909            public long getLiveGroupId(long groupId)
910                    throws PortalException, SystemException {
911    
912                    if (groupId == 0) {
913                            return groupId;
914                    }
915    
916                    Group group = getLiveGroup(groupId);
917    
918                    return group.getGroupId();
919            }
920    
921            /**
922             * @see LayoutRemoteStagingBackgroundTaskExecutor#getMissingRemoteParentLayouts(
923             *      HttpPrincipal, Layout, long)
924             */
925            @Override
926            public List<Layout> getMissingParentLayouts(Layout layout, long liveGroupId)
927                    throws Exception {
928    
929                    List<Layout> missingParentLayouts = new ArrayList<Layout>();
930    
931                    long parentLayoutId = layout.getParentLayoutId();
932    
933                    Layout parentLayout = null;
934    
935                    while (parentLayoutId > 0) {
936                            parentLayout = LayoutLocalServiceUtil.getLayout(
937                                    layout.getGroupId(), layout.isPrivateLayout(), parentLayoutId);
938    
939                            try {
940                                    LayoutLocalServiceUtil.getLayoutByUuidAndGroupId(
941                                            parentLayout.getUuid(), liveGroupId,
942                                            parentLayout.isPrivateLayout());
943    
944                                    // If one parent is found all others are assumed to exist
945    
946                                    break;
947                            }
948                            catch (NoSuchLayoutException nsle) {
949                                    missingParentLayouts.add(parentLayout);
950    
951                                    parentLayoutId = parentLayout.getParentLayoutId();
952                            }
953                    }
954    
955                    return missingParentLayouts;
956            }
957    
958            @Override
959            public long getRecentLayoutRevisionId(
960                            HttpServletRequest request, long layoutSetBranchId, long plid)
961                    throws PortalException, SystemException {
962    
963                    PortalPreferences portalPreferences =
964                            PortletPreferencesFactoryUtil.getPortalPreferences(request);
965    
966                    return getRecentLayoutRevisionId(
967                            portalPreferences, layoutSetBranchId, plid);
968            }
969    
970            @Override
971            public long getRecentLayoutRevisionId(
972                            User user, long layoutSetBranchId, long plid)
973                    throws PortalException, SystemException {
974    
975                    PortalPreferences portalPreferences = getPortalPreferences(user);
976    
977                    return getRecentLayoutRevisionId(
978                            portalPreferences, layoutSetBranchId, plid);
979            }
980    
981            @Override
982            public long getRecentLayoutSetBranchId(
983                    HttpServletRequest request, long layoutSetId) {
984    
985                    return GetterUtil.getLong(
986                            SessionClicks.get(
987                                    request, Staging.class.getName(),
988                                    getRecentLayoutSetBranchIdKey(layoutSetId)));
989            }
990    
991            @Override
992            public long getRecentLayoutSetBranchId(User user, long layoutSetId)
993                    throws SystemException {
994    
995                    PortalPreferences portalPreferences = getPortalPreferences(user);
996    
997                    return GetterUtil.getLong(
998                            portalPreferences.getValue(
999                                    Staging.class.getName(),
1000                                    getRecentLayoutSetBranchIdKey(layoutSetId)));
1001            }
1002    
1003            @Override
1004            public String getSchedulerGroupName(String destinationName, long groupId) {
1005                    return destinationName.concat(StringPool.SLASH).concat(
1006                            String.valueOf(groupId));
1007            }
1008    
1009            @Override
1010            public String getStagedPortletId(String portletId) {
1011                    String key = portletId;
1012    
1013                    if (key.startsWith(StagingConstants.STAGED_PORTLET)) {
1014                            return key;
1015                    }
1016    
1017                    return StagingConstants.STAGED_PORTLET.concat(portletId);
1018            }
1019    
1020            @Override
1021            public Map<String, String[]> getStagingParameters() {
1022                    Map<String, String[]> parameterMap =
1023                            new LinkedHashMap<String, String[]>();
1024    
1025                    parameterMap.put(
1026                            PortletDataHandlerKeys.CATEGORIES,
1027                            new String[] {Boolean.TRUE.toString()});
1028                    parameterMap.put(
1029                            PortletDataHandlerKeys.DATA_STRATEGY,
1030                            new String[] {
1031                                    PortletDataHandlerKeys.DATA_STRATEGY_MIRROR_OVERWRITE});
1032                    parameterMap.put(
1033                            PortletDataHandlerKeys.DELETE_MISSING_LAYOUTS,
1034                            new String[] {Boolean.TRUE.toString()});
1035                    parameterMap.put(
1036                            PortletDataHandlerKeys.DELETE_PORTLET_DATA,
1037                            new String[] {Boolean.FALSE.toString()});
1038                    parameterMap.put(
1039                            PortletDataHandlerKeys.IGNORE_LAST_PUBLISH_DATE,
1040                            new String[] {Boolean.TRUE.toString()});
1041                    parameterMap.put(
1042                            PortletDataHandlerKeys.LAYOUT_SET_PROTOTYPE_LINK_ENABLED,
1043                            new String[] {Boolean.FALSE.toString()});
1044                    parameterMap.put(
1045                            PortletDataHandlerKeys.LAYOUT_SET_SETTINGS,
1046                            new String[] {Boolean.FALSE.toString()});
1047                    parameterMap.put(
1048                            PortletDataHandlerKeys.LOGO,
1049                            new String[] {Boolean.FALSE.toString()});
1050                    parameterMap.put(
1051                            PortletDataHandlerKeys.PERMISSIONS,
1052                            new String[] {Boolean.TRUE.toString()});
1053                    parameterMap.put(
1054                            PortletDataHandlerKeys.PORTLET_CONFIGURATION,
1055                            new String[] {Boolean.TRUE.toString()});
1056                    parameterMap.put(
1057                            PortletDataHandlerKeys.PORTLET_CONFIGURATION_ALL,
1058                            new String[] {Boolean.TRUE.toString()});
1059                    parameterMap.put(
1060                            PortletDataHandlerKeys.PORTLET_DATA,
1061                            new String[] {Boolean.TRUE.toString()});
1062                    parameterMap.put(
1063                            PortletDataHandlerKeys.PORTLET_DATA_ALL,
1064                            new String[] {Boolean.TRUE.toString()});
1065                    parameterMap.put(
1066                            PortletDataHandlerKeys.PORTLET_SETUP_ALL,
1067                            new String[] {Boolean.TRUE.toString()});
1068                    parameterMap.put(
1069                            PortletDataHandlerKeys.THEME,
1070                            new String[] {Boolean.FALSE.toString()});
1071                    parameterMap.put(
1072                            PortletDataHandlerKeys.THEME_REFERENCE,
1073                            new String[] {Boolean.TRUE.toString()});
1074                    parameterMap.put(
1075                            PortletDataHandlerKeys.UPDATE_LAST_PUBLISH_DATE,
1076                            new String[] {Boolean.TRUE.toString()});
1077                    parameterMap.put(
1078                            PortletDataHandlerKeys.USER_ID_STRATEGY,
1079                            new String[] {UserIdStrategy.CURRENT_USER_ID});
1080    
1081                    return parameterMap;
1082            }
1083    
1084            @Override
1085            public Map<String, String[]> getStagingParameters(
1086                    PortletRequest portletRequest) {
1087    
1088                    Map<String, String[]> parameterMap =
1089                            new LinkedHashMap<String, String[]>(
1090                                    portletRequest.getParameterMap());
1091    
1092                    if (!parameterMap.containsKey(PortletDataHandlerKeys.DATA_STRATEGY)) {
1093                            parameterMap.put(
1094                                    PortletDataHandlerKeys.DATA_STRATEGY,
1095                                    new String[] {
1096                                            PortletDataHandlerKeys.DATA_STRATEGY_MIRROR_OVERWRITE});
1097                    }
1098    
1099                    /*if (!parameterMap.containsKey(
1100                                    PortletDataHandlerKeys.DELETE_MISSING_LAYOUTS)) {
1101    
1102                            parameterMap.put(
1103                                    PortletDataHandlerKeys.DELETE_MISSING_LAYOUTS,
1104                                    new String[] {Boolean.TRUE.toString()});
1105                    }*/
1106    
1107                    if (!parameterMap.containsKey(
1108                                    PortletDataHandlerKeys.DELETE_PORTLET_DATA)) {
1109    
1110                            parameterMap.put(
1111                                    PortletDataHandlerKeys.DELETE_PORTLET_DATA,
1112                                    new String[] {Boolean.FALSE.toString()});
1113                    }
1114    
1115                    if (!parameterMap.containsKey(
1116                                    PortletDataHandlerKeys.LAYOUT_SET_PROTOTYPE_LINK_ENABLED)) {
1117    
1118                            parameterMap.put(
1119                                    PortletDataHandlerKeys.LAYOUT_SET_PROTOTYPE_LINK_ENABLED,
1120                                    new String[] {Boolean.FALSE.toString()});
1121                    }
1122    
1123                    if (!parameterMap.containsKey(
1124                                    PortletDataHandlerKeys.LAYOUT_SET_SETTINGS)) {
1125    
1126                            parameterMap.put(
1127                                    PortletDataHandlerKeys.LAYOUT_SET_SETTINGS,
1128                                    new String[] {Boolean.FALSE.toString()});
1129                    }
1130    
1131                    if (!parameterMap.containsKey(PortletDataHandlerKeys.LOGO)) {
1132                            parameterMap.put(
1133                                    PortletDataHandlerKeys.LOGO,
1134                                    new String[] {Boolean.FALSE.toString()});
1135                    }
1136    
1137                    if (!parameterMap.containsKey(
1138                                    PortletDataHandlerKeys.PORTLET_CONFIGURATION)) {
1139    
1140                            parameterMap.put(
1141                                    PortletDataHandlerKeys.PORTLET_CONFIGURATION,
1142                                    new String[] {Boolean.TRUE.toString()});
1143                    }
1144    
1145                    if (!parameterMap.containsKey(PortletDataHandlerKeys.PORTLET_DATA)) {
1146                            parameterMap.put(
1147                                    PortletDataHandlerKeys.PORTLET_DATA,
1148                                    new String[] {Boolean.FALSE.toString()});
1149                    }
1150    
1151                    if (!parameterMap.containsKey(
1152                                    PortletDataHandlerKeys.PORTLET_DATA_ALL)) {
1153    
1154                            parameterMap.put(
1155                                    PortletDataHandlerKeys.PORTLET_DATA_ALL,
1156                                    new String[] {Boolean.FALSE.toString()});
1157                    }
1158    
1159                    if (!parameterMap.containsKey(PortletDataHandlerKeys.THEME)) {
1160                            parameterMap.put(
1161                                    PortletDataHandlerKeys.THEME,
1162                                    new String[] {Boolean.FALSE.toString()});
1163                    }
1164    
1165                    if (!parameterMap.containsKey(PortletDataHandlerKeys.THEME_REFERENCE)) {
1166                            parameterMap.put(
1167                                    PortletDataHandlerKeys.THEME_REFERENCE,
1168                                    new String[] {Boolean.FALSE.toString()});
1169                    }
1170    
1171                    if (!parameterMap.containsKey(
1172                                    PortletDataHandlerKeys.UPDATE_LAST_PUBLISH_DATE)) {
1173    
1174                            parameterMap.put(
1175                                    PortletDataHandlerKeys.UPDATE_LAST_PUBLISH_DATE,
1176                                    new String[] {Boolean.TRUE.toString()});
1177                    }
1178    
1179                    if (!parameterMap.containsKey(
1180                                    PortletDataHandlerKeys.USER_ID_STRATEGY)) {
1181    
1182                            parameterMap.put(
1183                                    PortletDataHandlerKeys.USER_ID_STRATEGY,
1184                                    new String[] {UserIdStrategy.CURRENT_USER_ID});
1185                    }
1186    
1187                    return parameterMap;
1188            }
1189    
1190            @Override
1191            public JSONArray getWarningMessagesJSONArray(
1192                    Locale locale, Map<String, MissingReference> missingReferences,
1193                    Map<String, Serializable> contextMap) {
1194    
1195                    JSONArray warningMessagesJSONArray = JSONFactoryUtil.createJSONArray();
1196    
1197                    for (String missingReferenceReferrerClassName :
1198                                    missingReferences.keySet()) {
1199    
1200                            MissingReference missingReference = missingReferences.get(
1201                                    missingReferenceReferrerClassName);
1202    
1203                            Map<String, String> referrers = missingReference.getReferrers();
1204    
1205                            JSONObject errorMessageJSONObject =
1206                                    JSONFactoryUtil.createJSONObject();
1207    
1208                            if (Validator.isNotNull(missingReference.getClassName())) {
1209                                    errorMessageJSONObject.put(
1210                                            "info",
1211                                            LanguageUtil.format(
1212                                                    locale,
1213                                                    "the-original-x-does-not-exist-in-the-current-" +
1214                                                            "environment",
1215                                                    ResourceActionsUtil.getModelResource(
1216                                                            locale, missingReference.getClassName())));
1217                            }
1218    
1219                            errorMessageJSONObject.put("size", referrers.size());
1220                            errorMessageJSONObject.put(
1221                                    "type",
1222                                    ResourceActionsUtil.getModelResource(
1223                                            locale, missingReferenceReferrerClassName));
1224    
1225                            warningMessagesJSONArray.put(errorMessageJSONObject);
1226                    }
1227    
1228                    return warningMessagesJSONArray;
1229            }
1230    
1231            @Override
1232            public WorkflowTask getWorkflowTask(
1233                            long userId, LayoutRevision layoutRevision)
1234                    throws PortalException, SystemException {
1235    
1236                    WorkflowInstanceLink workflowInstanceLink =
1237                            WorkflowInstanceLinkLocalServiceUtil.fetchWorkflowInstanceLink(
1238                                    layoutRevision.getCompanyId(), layoutRevision.getGroupId(),
1239                                    LayoutRevision.class.getName(),
1240                                    layoutRevision.getLayoutRevisionId());
1241    
1242                    if (workflowInstanceLink == null) {
1243                            return null;
1244                    }
1245    
1246                    List<WorkflowTask> workflowTasks =
1247                            WorkflowTaskManagerUtil.getWorkflowTasksByWorkflowInstance(
1248                                    layoutRevision.getCompanyId(), userId,
1249                                    workflowInstanceLink.getWorkflowInstanceId(), false, 0, 1,
1250                                    null);
1251    
1252                    if (!workflowTasks.isEmpty()) {
1253                            return workflowTasks.get(0);
1254                    }
1255    
1256                    return null;
1257            }
1258    
1259            @Override
1260            public boolean hasWorkflowTask(long userId, LayoutRevision layoutRevision)
1261                    throws PortalException, SystemException {
1262    
1263                    WorkflowTask workflowTask = getWorkflowTask(userId, layoutRevision);
1264    
1265                    if (workflowTask != null) {
1266                            return true;
1267                    }
1268    
1269                    return false;
1270            }
1271    
1272            @Override
1273            public boolean isIncomplete(Layout layout, long layoutSetBranchId) {
1274                    LayoutRevision layoutRevision = LayoutStagingUtil.getLayoutRevision(
1275                            layout);
1276    
1277                    if (layoutRevision == null) {
1278                            try {
1279                                    layoutRevision =
1280                                            LayoutRevisionLocalServiceUtil.getLayoutRevision(
1281                                                    layoutSetBranchId, layout.getPlid(), true);
1282    
1283                                    return false;
1284                            }
1285                            catch (Exception e) {
1286                            }
1287                    }
1288    
1289                    try {
1290                            layoutRevision = LayoutRevisionLocalServiceUtil.getLayoutRevision(
1291                                    layoutSetBranchId, layout.getPlid(), false);
1292                    }
1293                    catch (Exception e) {
1294                    }
1295    
1296                    if ((layoutRevision == null) ||
1297                            (layoutRevision.getStatus() ==
1298                                    WorkflowConstants.STATUS_INCOMPLETE)) {
1299    
1300                            return true;
1301                    }
1302    
1303                    return false;
1304            }
1305    
1306            @Override
1307            public void lockGroup(long userId, long groupId) throws Exception {
1308                    if (!PropsValues.STAGING_LOCK_ENABLED) {
1309                            return;
1310                    }
1311    
1312                    if (LockLocalServiceUtil.isLocked(Staging.class.getName(), groupId)) {
1313                            Lock lock = LockLocalServiceUtil.getLock(
1314                                    Staging.class.getName(), groupId);
1315    
1316                            throw new DuplicateLockException(lock);
1317                    }
1318    
1319                    LockLocalServiceUtil.lock(
1320                            userId, Staging.class.getName(), String.valueOf(groupId),
1321                            StagingImpl.class.getName(), false,
1322                            StagingConstants.LOCK_EXPIRATION_TIME);
1323            }
1324    
1325            @Override
1326            public void publishLayout(
1327                            long userId, long plid, long liveGroupId, boolean includeChildren)
1328                    throws Exception {
1329    
1330                    Map<String, String[]> parameterMap = getStagingParameters();
1331    
1332                    parameterMap.put(
1333                            PortletDataHandlerKeys.DELETE_MISSING_LAYOUTS,
1334                            new String[] {Boolean.FALSE.toString()});
1335    
1336                    Layout layout = LayoutLocalServiceUtil.getLayout(plid);
1337    
1338                    List<Layout> layouts = new ArrayList<Layout>();
1339    
1340                    layouts.add(layout);
1341    
1342                    layouts.addAll(getMissingParentLayouts(layout, liveGroupId));
1343    
1344                    if (includeChildren) {
1345                            layouts.addAll(layout.getAllChildren());
1346                    }
1347    
1348                    long[] layoutIds = getLayoutIds(layouts);
1349    
1350                    publishLayouts(
1351                            userId, layout.getGroupId(), liveGroupId, layout.isPrivateLayout(),
1352                            layoutIds, parameterMap, null, null);
1353            }
1354    
1355            @Override
1356            public void publishLayouts(
1357                            long userId, long sourceGroupId, long targetGroupId,
1358                            boolean privateLayout, long[] layoutIds,
1359                            Map<String, String[]> parameterMap, Date startDate, Date endDate)
1360                    throws Exception {
1361    
1362                    parameterMap.put(
1363                            PortletDataHandlerKeys.PERFORM_DIRECT_BINARY_IMPORT,
1364                            new String[] {Boolean.TRUE.toString()});
1365    
1366                    Map<String, Serializable> taskContextMap =
1367                            BackgroundTaskContextMapFactory.buildTaskContextMap(
1368                                    userId, sourceGroupId, privateLayout, layoutIds, parameterMap,
1369                                    Constants.PUBLISH, startDate, endDate, StringPool.BLANK);
1370    
1371                    taskContextMap.put("sourceGroupId", sourceGroupId);
1372                    taskContextMap.put("targetGroupId", targetGroupId);
1373    
1374                    BackgroundTaskLocalServiceUtil.addBackgroundTask(
1375                            userId, sourceGroupId, StringPool.BLANK, null,
1376                            LayoutStagingBackgroundTaskExecutor.class, taskContextMap,
1377                            new ServiceContext());
1378            }
1379    
1380            @Override
1381            public void publishLayouts(
1382                            long userId, long sourceGroupId, long targetGroupId,
1383                            boolean privateLayout, Map<Long, Boolean> layoutIdMap,
1384                            Map<String, String[]> parameterMap, Date startDate, Date endDate)
1385                    throws Exception {
1386    
1387                    List<Layout> layouts = new ArrayList<Layout>();
1388    
1389                    for (Map.Entry<Long, Boolean> entry : layoutIdMap.entrySet()) {
1390                            long plid = GetterUtil.getLong(String.valueOf(entry.getKey()));
1391                            boolean includeChildren = entry.getValue();
1392    
1393                            Layout layout = LayoutLocalServiceUtil.getLayout(plid);
1394    
1395                            if (!layouts.contains(layout)) {
1396                                    layouts.add(layout);
1397                            }
1398    
1399                            List<Layout> parentLayouts = getMissingParentLayouts(
1400                                    layout, targetGroupId);
1401    
1402                            for (Layout parentLayout : parentLayouts) {
1403                                    if (!layouts.contains(parentLayout)) {
1404                                            layouts.add(parentLayout);
1405                                    }
1406                            }
1407    
1408                            if (includeChildren) {
1409                                    for (Layout childLayout : layout.getAllChildren()) {
1410                                            if (!layouts.contains(childLayout)) {
1411                                                    layouts.add(childLayout);
1412                                            }
1413                                    }
1414                            }
1415                    }
1416    
1417                    long[] layoutIds = getLayoutIds(layouts);
1418    
1419                    publishLayouts(
1420                            userId, sourceGroupId, targetGroupId, privateLayout, layoutIds,
1421                            parameterMap, startDate, endDate);
1422            }
1423    
1424            @Override
1425            public void publishLayouts(
1426                            long userId, long sourceGroupId, long targetGroupId,
1427                            boolean privateLayout, Map<String, String[]> parameterMap,
1428                            Date startDate, Date endDate)
1429                    throws Exception {
1430    
1431                    publishLayouts(
1432                            userId, sourceGroupId, targetGroupId, privateLayout, (long[])null,
1433                            parameterMap, startDate, endDate);
1434            }
1435    
1436            @Override
1437            public void publishToLive(PortletRequest portletRequest) throws Exception {
1438                    long groupId = ParamUtil.getLong(portletRequest, "groupId");
1439    
1440                    Group liveGroup = GroupLocalServiceUtil.getGroup(groupId);
1441    
1442                    Map<String, String[]> parameterMap = getStagingParameters(
1443                            portletRequest);
1444    
1445                    if (liveGroup.isStaged()) {
1446                            if (liveGroup.isStagedRemotely()) {
1447                                    publishToRemote(portletRequest);
1448                            }
1449                            else {
1450                                    Group stagingGroup = liveGroup.getStagingGroup();
1451    
1452                                    publishLayouts(
1453                                            portletRequest, stagingGroup.getGroupId(), groupId,
1454                                            parameterMap, false);
1455                            }
1456                    }
1457            }
1458    
1459            @Override
1460            public void publishToLive(PortletRequest portletRequest, Portlet portlet)
1461                    throws Exception {
1462    
1463                    long plid = ParamUtil.getLong(portletRequest, "plid");
1464    
1465                    Layout sourceLayout = LayoutLocalServiceUtil.getLayout(plid);
1466    
1467                    Group stagingGroup = null;
1468                    Group liveGroup = null;
1469    
1470                    Layout targetLayout = null;
1471    
1472                    long scopeGroupId = PortalUtil.getScopeGroupId(portletRequest);
1473    
1474                    if (sourceLayout.hasScopeGroup() &&
1475                            (sourceLayout.getScopeGroup().getGroupId() == scopeGroupId)) {
1476    
1477                            stagingGroup = sourceLayout.getScopeGroup();
1478                            liveGroup = stagingGroup.getLiveGroup();
1479    
1480                            targetLayout = LayoutLocalServiceUtil.getLayout(
1481                                    liveGroup.getClassPK());
1482                    }
1483                    else {
1484                            stagingGroup = sourceLayout.getGroup();
1485                            liveGroup = stagingGroup.getLiveGroup();
1486    
1487                            targetLayout = LayoutLocalServiceUtil.getLayoutByUuidAndGroupId(
1488                                    sourceLayout.getUuid(), liveGroup.getGroupId(),
1489                                    sourceLayout.isPrivateLayout());
1490                    }
1491    
1492                    copyPortlet(
1493                            portletRequest, stagingGroup.getGroupId(), liveGroup.getGroupId(),
1494                            sourceLayout.getPlid(), targetLayout.getPlid(),
1495                            portlet.getPortletId());
1496            }
1497    
1498            @Override
1499            public void publishToRemote(PortletRequest portletRequest)
1500                    throws Exception {
1501    
1502                    publishToRemote(portletRequest, false);
1503            }
1504    
1505            @Override
1506            public void scheduleCopyFromLive(PortletRequest portletRequest)
1507                    throws Exception {
1508    
1509                    long stagingGroupId = ParamUtil.getLong(
1510                            portletRequest, "stagingGroupId");
1511    
1512                    Group stagingGroup = GroupLocalServiceUtil.getGroup(stagingGroupId);
1513    
1514                    long liveGroupId = stagingGroup.getLiveGroupId();
1515    
1516                    Map<String, String[]> parameterMap = getStagingParameters(
1517                            portletRequest);
1518    
1519                    publishLayouts(
1520                            portletRequest, liveGroupId, stagingGroupId, parameterMap, true);
1521            }
1522    
1523            @Override
1524            public void schedulePublishToLive(PortletRequest portletRequest)
1525                    throws Exception {
1526    
1527                    long stagingGroupId = ParamUtil.getLong(
1528                            portletRequest, "stagingGroupId");
1529    
1530                    Group stagingGroup = GroupLocalServiceUtil.getGroup(stagingGroupId);
1531    
1532                    long liveGroupId = stagingGroup.getLiveGroupId();
1533    
1534                    Map<String, String[]> parameterMap = getStagingParameters(
1535                            portletRequest);
1536    
1537                    publishLayouts(
1538                            portletRequest, stagingGroupId, liveGroupId, parameterMap, true);
1539            }
1540    
1541            @Override
1542            public void schedulePublishToRemote(PortletRequest portletRequest)
1543                    throws Exception {
1544    
1545                    publishToRemote(portletRequest, true);
1546            }
1547    
1548            @Override
1549            public void setRecentLayoutBranchId(
1550                            HttpServletRequest request, long layoutSetBranchId, long plid,
1551                            long layoutBranchId)
1552                    throws SystemException {
1553    
1554                    PortalPreferences portalPreferences =
1555                            PortletPreferencesFactoryUtil.getPortalPreferences(request);
1556    
1557                    setRecentLayoutBranchId(
1558                            portalPreferences, layoutSetBranchId, plid, layoutBranchId);
1559            }
1560    
1561            @Override
1562            public void setRecentLayoutBranchId(
1563                            User user, long layoutSetBranchId, long plid, long layoutBranchId)
1564                    throws SystemException {
1565    
1566                    PortalPreferences portalPreferences = getPortalPreferences(user);
1567    
1568                    setRecentLayoutBranchId(
1569                            portalPreferences, layoutSetBranchId, plid, layoutBranchId);
1570            }
1571    
1572            @Override
1573            public void setRecentLayoutRevisionId(
1574                            HttpServletRequest request, long layoutSetBranchId, long plid,
1575                            long layoutRevisionId)
1576                    throws SystemException {
1577    
1578                    PortalPreferences portalPreferences =
1579                            PortletPreferencesFactoryUtil.getPortalPreferences(request);
1580    
1581                    setRecentLayoutRevisionId(
1582                            portalPreferences, layoutSetBranchId, plid, layoutRevisionId);
1583            }
1584    
1585            @Override
1586            public void setRecentLayoutRevisionId(
1587                            User user, long layoutSetBranchId, long plid, long layoutRevisionId)
1588                    throws SystemException {
1589    
1590                    PortalPreferences portalPreferences = getPortalPreferences(user);
1591    
1592                    setRecentLayoutRevisionId(
1593                            portalPreferences, layoutSetBranchId, plid, layoutRevisionId);
1594            }
1595    
1596            @Override
1597            public void setRecentLayoutSetBranchId(
1598                    HttpServletRequest request, long layoutSetId, long layoutSetBranchId) {
1599    
1600                    SessionClicks.put(
1601                            request, Staging.class.getName(),
1602                            getRecentLayoutSetBranchIdKey(layoutSetId),
1603                            String.valueOf(layoutSetBranchId));
1604            }
1605    
1606            @Override
1607            public void setRecentLayoutSetBranchId(
1608                            User user, long layoutSetId, long layoutSetBranchId)
1609                    throws SystemException {
1610    
1611                    PortalPreferences portalPreferences = getPortalPreferences(user);
1612    
1613                    portalPreferences.setValue(
1614                            Staging.class.getName(), getRecentLayoutSetBranchIdKey(layoutSetId),
1615                            String.valueOf(layoutSetBranchId));
1616            }
1617    
1618            @Override
1619            public void unlockGroup(long groupId) throws SystemException {
1620                    if (!PropsValues.STAGING_LOCK_ENABLED) {
1621                            return;
1622                    }
1623    
1624                    LockLocalServiceUtil.unlock(Staging.class.getName(), groupId);
1625            }
1626    
1627            @Override
1628            public void unscheduleCopyFromLive(PortletRequest portletRequest)
1629                    throws Exception {
1630    
1631                    long stagingGroupId = ParamUtil.getLong(
1632                            portletRequest, "stagingGroupId");
1633    
1634                    String jobName = ParamUtil.getString(portletRequest, "jobName");
1635                    String groupName = getSchedulerGroupName(
1636                            DestinationNames.LAYOUTS_LOCAL_PUBLISHER, stagingGroupId);
1637    
1638                    LayoutServiceUtil.unschedulePublishToLive(
1639                            stagingGroupId, jobName, groupName);
1640            }
1641    
1642            @Override
1643            public void unschedulePublishToLive(PortletRequest portletRequest)
1644                    throws Exception {
1645    
1646                    long stagingGroupId = ParamUtil.getLong(
1647                            portletRequest, "stagingGroupId");
1648    
1649                    Group stagingGroup = GroupLocalServiceUtil.getGroup(stagingGroupId);
1650    
1651                    long liveGroupId = stagingGroup.getLiveGroupId();
1652    
1653                    String jobName = ParamUtil.getString(portletRequest, "jobName");
1654                    String groupName = getSchedulerGroupName(
1655                            DestinationNames.LAYOUTS_LOCAL_PUBLISHER, liveGroupId);
1656    
1657                    LayoutServiceUtil.unschedulePublishToLive(
1658                            liveGroupId, jobName, groupName);
1659            }
1660    
1661            @Override
1662            public void unschedulePublishToRemote(PortletRequest portletRequest)
1663                    throws Exception {
1664    
1665                    long groupId = ParamUtil.getLong(portletRequest, "groupId");
1666    
1667                    String jobName = ParamUtil.getString(portletRequest, "jobName");
1668                    String groupName = getSchedulerGroupName(
1669                            DestinationNames.LAYOUTS_REMOTE_PUBLISHER, groupId);
1670    
1671                    LayoutServiceUtil.unschedulePublishToRemote(
1672                            groupId, jobName, groupName);
1673            }
1674    
1675            @Override
1676            public void updateLastImportSettings(
1677                            Element layoutElement, Layout layout,
1678                            PortletDataContext portletDataContext)
1679                    throws Exception {
1680    
1681                    Map<String, String[]> parameterMap =
1682                            portletDataContext.getParameterMap();
1683    
1684                    String cmd = MapUtil.getString(parameterMap, Constants.CMD);
1685    
1686                    if (!cmd.equals("publish_to_live")) {
1687                            return;
1688                    }
1689    
1690                    UnicodeProperties typeSettingsProperties =
1691                            layout.getTypeSettingsProperties();
1692    
1693                    typeSettingsProperties.setProperty(
1694                            "last-import-date", String.valueOf(System.currentTimeMillis()));
1695    
1696                    String layoutRevisionId = GetterUtil.getString(
1697                            layoutElement.attributeValue("layout-revision-id"));
1698    
1699                    typeSettingsProperties.setProperty(
1700                            "last-import-layout-revision-id", layoutRevisionId);
1701    
1702                    String layoutSetBranchId = MapUtil.getString(
1703                            parameterMap, "layoutSetBranchId");
1704    
1705                    typeSettingsProperties.setProperty(
1706                            "last-import-layout-set-branch-id", layoutSetBranchId);
1707    
1708                    String layoutSetBranchName = MapUtil.getString(
1709                            parameterMap, "layoutSetBranchName");
1710    
1711                    typeSettingsProperties.setProperty(
1712                            "last-import-layout-set-branch-name", layoutSetBranchName);
1713    
1714                    String lastImportUserName = MapUtil.getString(
1715                            parameterMap, "lastImportUserName");
1716    
1717                    typeSettingsProperties.setProperty(
1718                            "last-import-user-name", lastImportUserName);
1719    
1720                    String lastImportUserUuid = MapUtil.getString(
1721                            parameterMap, "lastImportUserUuid");
1722    
1723                    typeSettingsProperties.setProperty(
1724                            "last-import-user-uuid", lastImportUserUuid);
1725    
1726                    String layoutBranchId = GetterUtil.getString(
1727                            layoutElement.attributeValue("layout-branch-id"));
1728    
1729                    typeSettingsProperties.setProperty(
1730                            "last-import-layout-branch-id", layoutBranchId);
1731    
1732                    String layoutBranchName = GetterUtil.getString(
1733                            layoutElement.attributeValue("layout-branch-name"));
1734    
1735                    typeSettingsProperties.setProperty(
1736                            "last-import-layout-branch-name", layoutBranchName);
1737    
1738                    layout.setTypeSettingsProperties(typeSettingsProperties);
1739            }
1740    
1741            @Override
1742            public void updateStaging(PortletRequest portletRequest, Group liveGroup)
1743                    throws Exception {
1744    
1745                    ThemeDisplay themeDisplay = (ThemeDisplay)portletRequest.getAttribute(
1746                            WebKeys.THEME_DISPLAY);
1747    
1748                    PermissionChecker permissionChecker =
1749                            themeDisplay.getPermissionChecker();
1750    
1751                    long userId = permissionChecker.getUserId();
1752    
1753                    Group scopeGroup = themeDisplay.getScopeGroup();
1754    
1755                    if (!GroupPermissionUtil.contains(
1756                                    permissionChecker, liveGroup.getGroupId(),
1757                                    ActionKeys.MANAGE_STAGING)) {
1758    
1759                            return;
1760                    }
1761    
1762                    int stagingType = getStagingType(portletRequest, liveGroup);
1763    
1764                    boolean branchingPublic = getBoolean(
1765                            portletRequest, liveGroup, "branchingPublic");
1766                    boolean branchingPrivate = getBoolean(
1767                            portletRequest, liveGroup, "branchingPrivate");
1768    
1769                    ServiceContext serviceContext =
1770                            ServiceContextThreadLocal.getServiceContext();
1771    
1772                    if (stagingType == StagingConstants.TYPE_NOT_STAGED) {
1773                            if (liveGroup.hasStagingGroup() || liveGroup.isStagedRemotely()) {
1774                                    disableStaging(portletRequest, liveGroup, serviceContext);
1775                            }
1776                    }
1777                    else if (stagingType == StagingConstants.TYPE_LOCAL_STAGING) {
1778                            enableLocalStaging(
1779                                    userId, scopeGroup, liveGroup, branchingPublic,
1780                                    branchingPrivate, serviceContext);
1781                    }
1782                    else if (stagingType == StagingConstants.TYPE_REMOTE_STAGING) {
1783                            String remoteAddress = getString(
1784                                    portletRequest, liveGroup, "remoteAddress");
1785    
1786                            remoteAddress = stripProtocolFromRemoteAddress(remoteAddress);
1787    
1788                            int remotePort = getInteger(
1789                                    portletRequest, liveGroup, "remotePort");
1790                            String remotePathContext = getString(
1791                                    portletRequest, liveGroup, "remotePathContext");
1792                            boolean secureConnection = getBoolean(
1793                                    portletRequest, liveGroup, "secureConnection");
1794                            long remoteGroupId = getLong(
1795                                    portletRequest, liveGroup, "remoteGroupId");
1796    
1797                            enableRemoteStaging(
1798                                    userId, scopeGroup, liveGroup, branchingPublic,
1799                                    branchingPrivate, remoteAddress, remotePort, remotePathContext,
1800                                    secureConnection, remoteGroupId, serviceContext);
1801                    }
1802            }
1803    
1804            protected void addDefaultLayoutSetBranch(
1805                            long userId, long groupId, String groupName, boolean privateLayout,
1806                            ServiceContext serviceContext)
1807                    throws PortalException, SystemException {
1808    
1809                    String masterBranchDescription =
1810                            LayoutSetBranchConstants.MASTER_BRANCH_DESCRIPTION_PUBLIC;
1811    
1812                    if (privateLayout) {
1813                            masterBranchDescription =
1814                                    LayoutSetBranchConstants.MASTER_BRANCH_DESCRIPTION_PRIVATE;
1815                    }
1816    
1817                    String description = LanguageUtil.format(
1818                            PortalUtil.getSiteDefaultLocale(groupId), masterBranchDescription,
1819                            groupName);
1820    
1821                    try {
1822                            LayoutSetBranch layoutSetBranch =
1823                                    LayoutSetBranchLocalServiceUtil.addLayoutSetBranch(
1824                                            userId, groupId, privateLayout,
1825                                            LayoutSetBranchConstants.MASTER_BRANCH_NAME, description,
1826                                            true, LayoutSetBranchConstants.ALL_BRANCHES,
1827                                            serviceContext);
1828    
1829                            List<LayoutRevision> layoutRevisions =
1830                                    LayoutRevisionLocalServiceUtil.getLayoutRevisions(
1831                                            layoutSetBranch.getLayoutSetBranchId(), false);
1832    
1833                            for (LayoutRevision layoutRevision : layoutRevisions) {
1834                                    LayoutRevisionLocalServiceUtil.updateStatus(
1835                                            userId, layoutRevision.getLayoutRevisionId(),
1836                                            WorkflowConstants.STATUS_APPROVED, serviceContext);
1837                            }
1838                    }
1839                    catch (PortalException pe) {
1840                            if (_log.isWarnEnabled()) {
1841                                    _log.warn(
1842                                            "Unable to create master branch for " +
1843                                                    (privateLayout ? "private" : "public") + " layouts",
1844                                            pe);
1845                            }
1846                    }
1847            }
1848    
1849            protected String buildRemoteURL(UnicodeProperties typeSettingsProperties) {
1850                    String remoteAddress = typeSettingsProperties.getProperty(
1851                            "remoteAddress");
1852                    int remotePort = GetterUtil.getInteger(
1853                            typeSettingsProperties.getProperty("remotePort"));
1854                    String remotePathContext = typeSettingsProperties.getProperty(
1855                            "remotePathContext");
1856                    boolean secureConnection = GetterUtil.getBoolean(
1857                            typeSettingsProperties.getProperty("secureConnection"));
1858    
1859                    return buildRemoteURL(
1860                            remoteAddress, remotePort, remotePathContext, secureConnection,
1861                            GroupConstants.DEFAULT_LIVE_GROUP_ID, false);
1862            }
1863    
1864            protected void checkDefaultLayoutSetBranches(
1865                            long userId, Group liveGroup, boolean branchingPublic,
1866                            boolean branchingPrivate, boolean remote,
1867                            ServiceContext serviceContext)
1868                    throws Exception {
1869    
1870                    long targetGroupId = 0;
1871    
1872                    if (remote) {
1873                            targetGroupId = liveGroup.getGroupId();
1874                    }
1875                    else {
1876                            Group stagingGroup = liveGroup.getStagingGroup();
1877    
1878                            if (stagingGroup == null) {
1879                                    return;
1880                            }
1881    
1882                            targetGroupId = stagingGroup.getGroupId();
1883                    }
1884    
1885                    if (branchingPublic) {
1886                            LayoutSetBranch layoutSetBranch =
1887                                    LayoutSetBranchLocalServiceUtil.fetchLayoutSetBranch(
1888                                            targetGroupId, false,
1889                                            LayoutSetBranchConstants.MASTER_BRANCH_NAME);
1890    
1891                            if (layoutSetBranch == null) {
1892                                    addDefaultLayoutSetBranch(
1893                                            userId, targetGroupId, liveGroup.getDescriptiveName(),
1894                                            false, serviceContext);
1895                            }
1896                    }
1897                    else {
1898                            LayoutSetBranchLocalServiceUtil.deleteLayoutSetBranches(
1899                                    targetGroupId, false, true);
1900                    }
1901    
1902                    if (branchingPrivate) {
1903                            LayoutSetBranch layoutSetBranch =
1904                                    LayoutSetBranchLocalServiceUtil.fetchLayoutSetBranch(
1905                                            targetGroupId, true,
1906                                            LayoutSetBranchConstants.MASTER_BRANCH_NAME);
1907    
1908                            if (layoutSetBranch == null) {
1909                                    addDefaultLayoutSetBranch(
1910                                            userId, targetGroupId, liveGroup.getDescriptiveName(), true,
1911                                            serviceContext);
1912                            }
1913                    }
1914                    else {
1915                            LayoutSetBranchLocalServiceUtil.deleteLayoutSetBranches(
1916                                    targetGroupId, true, true);
1917                    }
1918            }
1919    
1920            protected void deleteRecentLayoutRevisionId(
1921                    PortalPreferences portalPreferences, long layoutSetBranchId,
1922                    long plid) {
1923    
1924                    portalPreferences.setValue(
1925                            Staging.class.getName(),
1926                            getRecentLayoutRevisionIdKey(layoutSetBranchId, plid), null);
1927            }
1928    
1929            protected void disableRemoteStaging(String remoteURL, long remoteGroupId)
1930                    throws Exception {
1931    
1932                    PermissionChecker permissionChecker =
1933                            PermissionThreadLocal.getPermissionChecker();
1934    
1935                    User user = permissionChecker.getUser();
1936    
1937                    HttpPrincipal httpPrincipal = new HttpPrincipal(
1938                            remoteURL, user.getScreenName(), user.getPassword(),
1939                            user.getPasswordEncrypted());
1940    
1941                    try {
1942                            GroupServiceHttp.disableStaging(httpPrincipal, remoteGroupId);
1943                    }
1944                    catch (NoSuchGroupException nsge) {
1945                            RemoteExportException ree = new RemoteExportException(
1946                                    RemoteExportException.NO_GROUP);
1947    
1948                            ree.setGroupId(remoteGroupId);
1949    
1950                            throw ree;
1951                    }
1952                    catch (PrincipalException pe) {
1953                            RemoteExportException ree = new RemoteExportException(
1954                                    RemoteExportException.NO_PERMISSIONS);
1955    
1956                            ree.setGroupId(remoteGroupId);
1957    
1958                            throw ree;
1959                    }
1960                    catch (SystemException se) {
1961                            RemoteExportException ree = new RemoteExportException(
1962                                    RemoteExportException.BAD_CONNECTION);
1963    
1964                            ree.setURL(remoteURL);
1965    
1966                            throw ree;
1967                    }
1968            }
1969    
1970            protected void enableRemoteStaging(String remoteURL, long remoteGroupId)
1971                    throws Exception {
1972    
1973                    PermissionChecker permissionChecker =
1974                            PermissionThreadLocal.getPermissionChecker();
1975    
1976                    User user = permissionChecker.getUser();
1977    
1978                    HttpPrincipal httpPrincipal = new HttpPrincipal(
1979                            remoteURL, user.getScreenName(), user.getPassword(),
1980                            user.getPasswordEncrypted());
1981    
1982                    try {
1983                            GroupServiceHttp.enableStaging(httpPrincipal, remoteGroupId);
1984                    }
1985                    catch (NoSuchGroupException nsge) {
1986                            RemoteExportException ree = new RemoteExportException(
1987                                    RemoteExportException.NO_GROUP);
1988    
1989                            ree.setGroupId(remoteGroupId);
1990    
1991                            throw ree;
1992                    }
1993                    catch (PrincipalException pe) {
1994                            RemoteExportException ree = new RemoteExportException(
1995                                    RemoteExportException.NO_PERMISSIONS);
1996    
1997                            ree.setGroupId(remoteGroupId);
1998    
1999                            throw ree;
2000                    }
2001                    catch (SystemException se) {
2002                            RemoteExportException ree = new RemoteExportException(
2003                                    RemoteExportException.BAD_CONNECTION);
2004    
2005                            ree.setURL(remoteURL);
2006    
2007                            throw ree;
2008                    }
2009            }
2010    
2011            protected boolean getBoolean(
2012                    PortletRequest portletRequest, Group group, String param) {
2013    
2014                    return ParamUtil.getBoolean(
2015                            portletRequest, param,
2016                            GetterUtil.getBoolean(group.getTypeSettingsProperty(param)));
2017            }
2018    
2019            protected int getInteger(
2020                    PortletRequest portletRequest, Group group, String param) {
2021    
2022                    return ParamUtil.getInteger(
2023                            portletRequest, param,
2024                            GetterUtil.getInteger(group.getTypeSettingsProperty(param)));
2025            }
2026    
2027            protected long[] getLayoutIds(List<Layout> layouts) {
2028                    long[] layoutIds = new long[layouts.size()];
2029    
2030                    for (int i = 0; i < layouts.size(); i++) {
2031                            Layout layout = layouts.get(i);
2032    
2033                            layoutIds[i] = layout.getLayoutId();
2034                    }
2035    
2036                    return layoutIds;
2037            }
2038    
2039            protected long getLong(
2040                    PortletRequest portletRequest, Group group, String param) {
2041    
2042                    return ParamUtil.getLong(
2043                            portletRequest, param,
2044                            GetterUtil.getLong(group.getTypeSettingsProperty(param)));
2045            }
2046    
2047            protected PortalPreferences getPortalPreferences(User user)
2048                    throws SystemException {
2049    
2050                    boolean signedIn = !user.isDefaultUser();
2051    
2052                    PortalPreferences portalPreferences =
2053                            PortletPreferencesFactoryUtil.getPortalPreferences(
2054                                    user.getCompanyId(), user.getUserId(), signedIn);
2055    
2056                    return portalPreferences;
2057            }
2058    
2059            protected long getRecentLayoutBranchId(
2060                    PortalPreferences portalPreferences, long layoutSetBranchId,
2061                    long plid) {
2062    
2063                    return GetterUtil.getLong(
2064                            portalPreferences.getValue(
2065                                    Staging.class.getName(),
2066                                    getRecentLayoutBranchIdKey(layoutSetBranchId, plid)));
2067            }
2068    
2069            protected String getRecentLayoutBranchIdKey(
2070                    long layoutSetBranchId, long plid) {
2071    
2072                    StringBundler sb = new StringBundler(4);
2073    
2074                    sb.append("layoutBranchId-");
2075                    sb.append(layoutSetBranchId);
2076                    sb.append(StringPool.DASH);
2077                    sb.append(plid);
2078    
2079                    return sb.toString();
2080            }
2081    
2082            protected long getRecentLayoutRevisionId(
2083                            PortalPreferences portalPreferences, long layoutSetBranchId,
2084                            long plid)
2085                    throws PortalException, SystemException {
2086    
2087                    long layoutRevisionId = GetterUtil.getLong(
2088                            portalPreferences.getValue(
2089                                    Staging.class.getName(),
2090                                    getRecentLayoutRevisionIdKey(layoutSetBranchId, plid)));
2091    
2092                    if (layoutRevisionId > 0) {
2093                            return layoutRevisionId;
2094                    }
2095    
2096                    long layoutBranchId = getRecentLayoutBranchId(
2097                            portalPreferences, layoutSetBranchId, plid);
2098    
2099                    if (layoutBranchId > 0) {
2100                            try {
2101                                    LayoutBranchLocalServiceUtil.getLayoutBranch(layoutBranchId);
2102                            }
2103                            catch (NoSuchLayoutBranchException nslbe) {
2104                                    LayoutBranch layoutBranch =
2105                                            LayoutBranchLocalServiceUtil.getMasterLayoutBranch(
2106                                                    layoutSetBranchId, plid);
2107    
2108                                    layoutBranchId = layoutBranch.getLayoutBranchId();
2109                            }
2110                    }
2111    
2112                    if (layoutBranchId > 0) {
2113                            try {
2114                                    LayoutRevision layoutRevision =
2115                                            LayoutRevisionLocalServiceUtil.getLayoutRevision(
2116                                                    layoutSetBranchId, layoutBranchId, plid);
2117    
2118                                    if (layoutRevision != null) {
2119                                            layoutRevisionId = layoutRevision.getLayoutRevisionId();
2120                                    }
2121                            }
2122                            catch (NoSuchLayoutRevisionException nslre) {
2123                            }
2124                    }
2125    
2126                    return layoutRevisionId;
2127            }
2128    
2129            protected String getRecentLayoutRevisionIdKey(
2130                    long layoutSetBranchId, long plid) {
2131    
2132                    StringBundler sb = new StringBundler(4);
2133    
2134                    sb.append("layoutRevisionId-");
2135                    sb.append(layoutSetBranchId);
2136                    sb.append(StringPool.DASH);
2137                    sb.append(plid);
2138    
2139                    return sb.toString();
2140            }
2141    
2142            protected String getRecentLayoutSetBranchIdKey(long layoutSetId) {
2143                    return "layoutSetBranchId_" + layoutSetId;
2144            }
2145    
2146            protected int getStagingType(
2147                    PortletRequest portletRequest, Group liveGroup) {
2148    
2149                    String stagingType = portletRequest.getParameter("stagingType");
2150    
2151                    if (stagingType != null) {
2152                            return GetterUtil.getInteger(stagingType);
2153                    }
2154    
2155                    if (liveGroup.isStagedRemotely()) {
2156                            return StagingConstants.TYPE_REMOTE_STAGING;
2157                    }
2158    
2159                    if (liveGroup.hasStagingGroup()) {
2160                            return StagingConstants.TYPE_LOCAL_STAGING;
2161                    }
2162    
2163                    return StagingConstants.TYPE_NOT_STAGED;
2164            }
2165    
2166            protected String getString(
2167                    PortletRequest portletRequest, Group group, String param) {
2168    
2169                    return ParamUtil.getString(
2170                            portletRequest, param,
2171                            GetterUtil.getString(group.getTypeSettingsProperty(param)));
2172            }
2173    
2174            protected void publishLayouts(
2175                            PortletRequest portletRequest, long sourceGroupId,
2176                            long targetGroupId, Map<String, String[]> parameterMap,
2177                            boolean schedule)
2178                    throws Exception {
2179    
2180                    ThemeDisplay themeDisplay = (ThemeDisplay)portletRequest.getAttribute(
2181                            WebKeys.THEME_DISPLAY);
2182    
2183                    String tabs1 = ParamUtil.getString(portletRequest, "tabs1");
2184    
2185                    boolean privateLayout = true;
2186    
2187                    if (tabs1.equals("public-pages")) {
2188                            privateLayout = false;
2189                    }
2190    
2191                    String scope = ParamUtil.getString(portletRequest, "scope");
2192    
2193                    Map<Long, Boolean> layoutIdMap = new LinkedHashMap<Long, Boolean>();
2194    
2195                    if (scope.equals("selected-pages")) {
2196                            long[] rowIds = ParamUtil.getLongValues(portletRequest, "rowIds");
2197    
2198                            for (long selPlid : rowIds) {
2199                                    boolean delete = ParamUtil.getBoolean(
2200                                            portletRequest, "delete_" + selPlid);
2201                                    boolean includeChildren = ParamUtil.getBoolean(
2202                                            portletRequest, "includeChildren_" + selPlid);
2203    
2204                                    if (!delete && includeChildren) {
2205                                            layoutIdMap.put(selPlid, true);
2206                                    }
2207                                    else {
2208                                            layoutIdMap.put(selPlid, false);
2209                                    }
2210                            }
2211                    }
2212    
2213                    DateRange dateRange = ExportImportHelperUtil.getDateRange(
2214                            portletRequest, sourceGroupId, privateLayout, 0, null);
2215    
2216                    if (schedule) {
2217                            String groupName = getSchedulerGroupName(
2218                                    DestinationNames.LAYOUTS_LOCAL_PUBLISHER, targetGroupId);
2219    
2220                            int recurrenceType = ParamUtil.getInteger(
2221                                    portletRequest, "recurrenceType");
2222    
2223                            Calendar startCalendar = ExportImportHelperUtil.getCalendar(
2224                                    portletRequest, "schedulerStartDate", true);
2225    
2226                            String cronText = SchedulerEngineHelperUtil.getCronText(
2227                                    portletRequest, startCalendar, true, recurrenceType);
2228    
2229                            Date schedulerEndDate = null;
2230    
2231                            int endDateType = ParamUtil.getInteger(
2232                                    portletRequest, "endDateType");
2233    
2234                            if (endDateType == 1) {
2235                                    Calendar endCalendar = ExportImportHelperUtil.getCalendar(
2236                                            portletRequest, "schedulerEndDate", true);
2237    
2238                                    schedulerEndDate = endCalendar.getTime();
2239                            }
2240    
2241                            String description = ParamUtil.getString(
2242                                    portletRequest, "description");
2243    
2244                            LayoutServiceUtil.schedulePublishToLive(
2245                                    sourceGroupId, targetGroupId, privateLayout, layoutIdMap,
2246                                    parameterMap, scope, dateRange.getStartDate(),
2247                                    dateRange.getEndDate(), groupName, cronText,
2248                                    startCalendar.getTime(), schedulerEndDate, description);
2249                    }
2250                    else {
2251                            MessageStatus messageStatus = new MessageStatus();
2252    
2253                            messageStatus.startTimer();
2254    
2255                            String command =
2256                                    LayoutsLocalPublisherRequest.COMMAND_SELECTED_PAGES;
2257    
2258                            try {
2259                                    if (scope.equals("all-pages")) {
2260                                            command = LayoutsLocalPublisherRequest.COMMAND_ALL_PAGES;
2261    
2262                                            publishLayouts(
2263                                                    themeDisplay.getUserId(), sourceGroupId, targetGroupId,
2264                                                    privateLayout, parameterMap, dateRange.getStartDate(),
2265                                                    dateRange.getEndDate());
2266                                    }
2267                                    else {
2268                                            publishLayouts(
2269                                                    themeDisplay.getUserId(), sourceGroupId, targetGroupId,
2270                                                    privateLayout, layoutIdMap, parameterMap,
2271                                                    dateRange.getStartDate(), dateRange.getEndDate());
2272                                    }
2273                            }
2274                            catch (Exception e) {
2275                                    messageStatus.setException(e);
2276    
2277                                    throw e;
2278                            }
2279                            finally {
2280                                    messageStatus.stopTimer();
2281    
2282                                    LayoutsLocalPublisherRequest publisherRequest =
2283                                            new LayoutsLocalPublisherRequest(
2284                                                    command, themeDisplay.getUserId(), sourceGroupId,
2285                                                    targetGroupId, privateLayout, layoutIdMap, parameterMap,
2286                                                    dateRange.getStartDate(), dateRange.getEndDate());
2287    
2288                                    messageStatus.setPayload(publisherRequest);
2289    
2290                                    MessageBusUtil.sendMessage(
2291                                            DestinationNames.MESSAGE_BUS_MESSAGE_STATUS, messageStatus);
2292                            }
2293                    }
2294            }
2295    
2296            protected void publishToRemote(
2297                            PortletRequest portletRequest, boolean schedule)
2298                    throws Exception {
2299    
2300                    ThemeDisplay themeDisplay = (ThemeDisplay)portletRequest.getAttribute(
2301                            WebKeys.THEME_DISPLAY);
2302    
2303                    String tabs1 = ParamUtil.getString(portletRequest, "tabs1");
2304    
2305                    long groupId = ParamUtil.getLong(portletRequest, "groupId");
2306    
2307                    boolean privateLayout = true;
2308    
2309                    if (tabs1.equals("public-pages")) {
2310                            privateLayout = false;
2311                    }
2312    
2313                    String scope = ParamUtil.getString(portletRequest, "scope");
2314    
2315                    if (Validator.isNull(scope)) {
2316                            scope = "all-pages";
2317                    }
2318    
2319                    Map<Long, Boolean> layoutIdMap = null;
2320    
2321                    if (scope.equals("selected-pages")) {
2322                            layoutIdMap = new LinkedHashMap<Long, Boolean>();
2323    
2324                            long[] rowIds = ParamUtil.getLongValues(portletRequest, "rowIds");
2325    
2326                            for (long selPlid : rowIds) {
2327                                    boolean delete = ParamUtil.getBoolean(
2328                                            portletRequest, "delete_" + selPlid);
2329                                    boolean includeChildren = ParamUtil.getBoolean(
2330                                            portletRequest, "includeChildren_" + selPlid);
2331    
2332                                    if (!delete && includeChildren) {
2333                                            layoutIdMap.put(selPlid, true);
2334                                    }
2335                                    else {
2336                                            layoutIdMap.put(selPlid, false);
2337                                    }
2338                            }
2339                    }
2340    
2341                    Map<String, String[]> parameterMap = getStagingParameters(
2342                            portletRequest);
2343    
2344                    parameterMap.put(
2345                            PortletDataHandlerKeys.PUBLISH_TO_REMOTE,
2346                            new String[] {Boolean.TRUE.toString()});
2347    
2348                    Group group = GroupLocalServiceUtil.getGroup(groupId);
2349    
2350                    UnicodeProperties groupTypeSettingsProperties =
2351                            group.getTypeSettingsProperties();
2352    
2353                    String remoteAddress = ParamUtil.getString(
2354                            portletRequest, "remoteAddress",
2355                            groupTypeSettingsProperties.getProperty("remoteAddress"));
2356    
2357                    remoteAddress = stripProtocolFromRemoteAddress(remoteAddress);
2358    
2359                    int remotePort = ParamUtil.getInteger(
2360                            portletRequest, "remotePort",
2361                            GetterUtil.getInteger(
2362                                    groupTypeSettingsProperties.getProperty("remotePort")));
2363                    String remotePathContext = ParamUtil.getString(
2364                            portletRequest, "remotePathContext",
2365                            groupTypeSettingsProperties.getProperty("remotePathContext"));
2366                    boolean secureConnection = ParamUtil.getBoolean(
2367                            portletRequest, "secureConnection",
2368                            GetterUtil.getBoolean(
2369                                    groupTypeSettingsProperties.getProperty("secureConnection")));
2370                    long remoteGroupId = ParamUtil.getLong(
2371                            portletRequest, "remoteGroupId",
2372                            GetterUtil.getLong(
2373                                    groupTypeSettingsProperties.getProperty("remoteGroupId")));
2374                    boolean remotePrivateLayout = ParamUtil.getBoolean(
2375                            portletRequest, "remotePrivateLayout");
2376    
2377                    validate(
2378                            remoteAddress, remotePort, remotePathContext, secureConnection,
2379                            remoteGroupId);
2380    
2381                    if (group.isCompany()) {
2382                            updateGroupTypeSettingsProperties(
2383                                    group, remoteAddress, remotePort, remotePathContext,
2384                                    secureConnection, remoteGroupId);
2385                    }
2386    
2387                    DateRange dateRange = ExportImportHelperUtil.getDateRange(
2388                            portletRequest, groupId, privateLayout, 0, null);
2389    
2390                    if (schedule) {
2391                            String groupName = getSchedulerGroupName(
2392                                    DestinationNames.LAYOUTS_REMOTE_PUBLISHER, groupId);
2393    
2394                            int recurrenceType = ParamUtil.getInteger(
2395                                    portletRequest, "recurrenceType");
2396    
2397                            Calendar startCalendar = ExportImportHelperUtil.getCalendar(
2398                                    portletRequest, "schedulerStartDate", true);
2399    
2400                            String cronText = SchedulerEngineHelperUtil.getCronText(
2401                                    portletRequest, startCalendar, true, recurrenceType);
2402    
2403                            Date schedulerEndDate = null;
2404    
2405                            int endDateType = ParamUtil.getInteger(
2406                                    portletRequest, "endDateType");
2407    
2408                            if (endDateType == 1) {
2409                                    Calendar endCalendar = ExportImportHelperUtil.getCalendar(
2410                                            portletRequest, "schedulerEndDate", true);
2411    
2412                                    schedulerEndDate = endCalendar.getTime();
2413                            }
2414    
2415                            String description = ParamUtil.getString(
2416                                    portletRequest, "description");
2417    
2418                            LayoutServiceUtil.schedulePublishToRemote(
2419                                    groupId, privateLayout, layoutIdMap, parameterMap,
2420                                    remoteAddress, remotePort, remotePathContext, secureConnection,
2421                                    remoteGroupId, remotePrivateLayout, dateRange.getStartDate(),
2422                                    dateRange.getEndDate(), groupName, cronText,
2423                                    startCalendar.getTime(), schedulerEndDate, description);
2424                    }
2425                    else {
2426                            MessageStatus messageStatus = new MessageStatus();
2427    
2428                            messageStatus.startTimer();
2429    
2430                            try {
2431                                    copyRemoteLayouts(
2432                                            groupId, privateLayout, layoutIdMap, parameterMap,
2433                                            remoteAddress, remotePort, remotePathContext,
2434                                            secureConnection, remoteGroupId, remotePrivateLayout,
2435                                            dateRange.getStartDate(), dateRange.getEndDate());
2436                            }
2437                            catch (Exception e) {
2438                                    messageStatus.setException(e);
2439    
2440                                    throw e;
2441                            }
2442                            finally {
2443                                    messageStatus.stopTimer();
2444    
2445                                    LayoutsRemotePublisherRequest publisherRequest =
2446                                            new LayoutsRemotePublisherRequest(
2447                                                    themeDisplay.getUserId(), groupId, privateLayout,
2448                                                    layoutIdMap, parameterMap, remoteAddress, remotePort,
2449                                                    remotePathContext, secureConnection, remoteGroupId,
2450                                                    remotePrivateLayout, dateRange.getStartDate(),
2451                                                    dateRange.getEndDate());
2452    
2453                                    messageStatus.setPayload(publisherRequest);
2454    
2455                                    MessageBusUtil.sendMessage(
2456                                            DestinationNames.MESSAGE_BUS_MESSAGE_STATUS, messageStatus);
2457                            }
2458                    }
2459            }
2460    
2461            protected void setCommonStagingOptions(
2462                            Group liveGroup, UnicodeProperties typeSettingsProperties,
2463                            ServiceContext serviceContext)
2464                    throws Exception {
2465    
2466                    LayoutExporter.updateLastPublishDate(
2467                            liveGroup.getPrivateLayoutSet(), 0);
2468                    LayoutExporter.updateLastPublishDate(liveGroup.getPublicLayoutSet(), 0);
2469    
2470                    Set<String> parameterNames = serviceContext.getAttributes().keySet();
2471    
2472                    for (String parameterName : parameterNames) {
2473                            if (parameterName.startsWith(StagingConstants.STAGED_PORTLET) &&
2474                                    !parameterName.endsWith("Checkbox")) {
2475    
2476                                    boolean staged = ParamUtil.getBoolean(
2477                                            serviceContext, parameterName);
2478    
2479                                    typeSettingsProperties.setProperty(
2480                                            parameterName, String.valueOf(staged));
2481                            }
2482                    }
2483            }
2484    
2485            protected void setRecentLayoutBranchId(
2486                    PortalPreferences portalPreferences, long layoutSetBranchId, long plid,
2487                    long layoutBranchId) {
2488    
2489                    portalPreferences.setValue(
2490                            Staging.class.getName(),
2491                            getRecentLayoutBranchIdKey(layoutSetBranchId, plid),
2492                            String.valueOf(layoutBranchId));
2493            }
2494    
2495            protected void setRecentLayoutRevisionId(
2496                            PortalPreferences portalPreferences, long layoutSetBranchId,
2497                            long plid, long layoutRevisionId)
2498                    throws SystemException {
2499    
2500                    long layoutBranchId = 0;
2501    
2502                    try {
2503                            LayoutRevision layoutRevision =
2504                                    LayoutRevisionLocalServiceUtil.getLayoutRevision(
2505                                            layoutRevisionId);
2506    
2507                            layoutBranchId = layoutRevision.getLayoutBranchId();
2508    
2509                            LayoutRevision lastLayoutRevision =
2510                                    LayoutRevisionLocalServiceUtil.getLayoutRevision(
2511                                            layoutSetBranchId, layoutBranchId, plid);
2512    
2513                            if (lastLayoutRevision.getLayoutRevisionId() == layoutRevisionId) {
2514                                    deleteRecentLayoutRevisionId(
2515                                            portalPreferences, layoutSetBranchId, plid);
2516                            }
2517                            else {
2518                                    portalPreferences.setValue(
2519                                            Staging.class.getName(),
2520                                            getRecentLayoutRevisionIdKey(layoutSetBranchId, plid),
2521                                            String.valueOf(layoutRevisionId));
2522                            }
2523                    }
2524                    catch (PortalException pe) {
2525                            if (_log.isWarnEnabled()) {
2526                                    _log.warn("Unable to set recent layout revision ID", pe);
2527                            }
2528                    }
2529    
2530                    portalPreferences.setValue(
2531                            Staging.class.getName(),
2532                            getRecentLayoutBranchIdKey(layoutSetBranchId, plid),
2533                            String.valueOf(layoutBranchId));
2534            }
2535    
2536            protected String stripProtocolFromRemoteAddress(String remoteAddress) {
2537                    if (remoteAddress.startsWith(Http.HTTP_WITH_SLASH)) {
2538                            remoteAddress = remoteAddress.substring(
2539                                    Http.HTTP_WITH_SLASH.length());
2540                    }
2541                    else if (remoteAddress.startsWith(Http.HTTPS_WITH_SLASH)) {
2542                            remoteAddress = remoteAddress.substring(
2543                                    Http.HTTPS_WITH_SLASH.length());
2544                    }
2545    
2546                    return remoteAddress;
2547            }
2548    
2549            protected void updateGroupTypeSettingsProperties(
2550                            Group group, String remoteAddress, int remotePort,
2551                            String remotePathContext, boolean secureConnection,
2552                            long remoteGroupId)
2553                    throws Exception {
2554    
2555                    UnicodeProperties typeSettingsProperties =
2556                            group.getTypeSettingsProperties();
2557    
2558                    typeSettingsProperties.setProperty("remoteAddress", remoteAddress);
2559                    typeSettingsProperties.setProperty(
2560                            "remoteGroupId", String.valueOf(remoteGroupId));
2561                    typeSettingsProperties.setProperty(
2562                            "remotePathContext", remotePathContext);
2563                    typeSettingsProperties.setProperty(
2564                            "remotePort", String.valueOf(remotePort));
2565                    typeSettingsProperties.setProperty(
2566                            "secureConnection", String.valueOf(secureConnection));
2567    
2568                    group.setTypeSettingsProperties(typeSettingsProperties);
2569    
2570                    GroupLocalServiceUtil.updateGroup(group);
2571            }
2572    
2573            protected void updateStagedPortlets(
2574                            String remoteURL, long remoteGroupId,
2575                            UnicodeProperties typeSettingsProperties)
2576                    throws Exception {
2577    
2578                    PermissionChecker permissionChecker =
2579                            PermissionThreadLocal.getPermissionChecker();
2580    
2581                    User user = permissionChecker.getUser();
2582    
2583                    HttpPrincipal httpPrincipal = new HttpPrincipal(
2584                            remoteURL, user.getScreenName(), user.getPassword(),
2585                            user.getPasswordEncrypted());
2586    
2587                    List<String> stagedPortletIds = new ArrayList<String>();
2588    
2589                    for (String key : typeSettingsProperties.keySet()) {
2590                            if (key.startsWith(StagingConstants.STAGED_PORTLET)) {
2591                                    stagedPortletIds.add(key);
2592                            }
2593                    }
2594    
2595                    try {
2596                            GroupServiceHttp.updateStagedPortlets(
2597                                    httpPrincipal, remoteGroupId,
2598                                    StringUtil.merge(stagedPortletIds));
2599                    }
2600                    catch (NoSuchGroupException nsge) {
2601                            RemoteExportException ree = new RemoteExportException(
2602                                    RemoteExportException.NO_GROUP);
2603    
2604                            ree.setGroupId(remoteGroupId);
2605    
2606                            throw ree;
2607                    }
2608                    catch (PrincipalException pe) {
2609                            RemoteExportException ree = new RemoteExportException(
2610                                    RemoteExportException.NO_PERMISSIONS);
2611    
2612                            ree.setGroupId(remoteGroupId);
2613    
2614                            throw ree;
2615                    }
2616                    catch (SystemException se) {
2617                            RemoteExportException ree = new RemoteExportException(
2618                                    RemoteExportException.BAD_CONNECTION);
2619    
2620                            ree.setURL(remoteURL);
2621    
2622                            throw ree;
2623                    }
2624            }
2625    
2626            protected void validate(
2627                            String remoteAddress, int remotePort, String remotePathContext,
2628                            boolean secureConnection, long remoteGroupId)
2629                    throws Exception {
2630    
2631                    RemoteOptionsException roe = null;
2632    
2633                    if (!Validator.isDomain(remoteAddress) &&
2634                            !Validator.isIPAddress(remoteAddress)) {
2635    
2636                            roe = new RemoteOptionsException(
2637                                    RemoteOptionsException.REMOTE_ADDRESS);
2638    
2639                            roe.setRemoteAddress(remoteAddress);
2640    
2641                            throw roe;
2642                    }
2643    
2644                    if ((remotePort < 1) || (remotePort > 65535)) {
2645                            roe = new RemoteOptionsException(
2646                                    RemoteOptionsException.REMOTE_PORT);
2647    
2648                            roe.setRemotePort(remotePort);
2649    
2650                            throw roe;
2651                    }
2652    
2653                    if (Validator.isNotNull(remotePathContext) &&
2654                            (!remotePathContext.startsWith(StringPool.FORWARD_SLASH) ||
2655                             remotePathContext.endsWith(StringPool.FORWARD_SLASH))) {
2656    
2657                            roe = new RemoteOptionsException(
2658                                    RemoteOptionsException.REMOTE_PATH_CONTEXT);
2659    
2660                            roe.setRemotePathContext(remotePathContext);
2661    
2662                            throw roe;
2663                    }
2664    
2665                    if (remoteGroupId <= 0) {
2666                            roe = new RemoteOptionsException(
2667                                    RemoteOptionsException.REMOTE_GROUP_ID);
2668    
2669                            roe.setRemoteGroupId(remoteGroupId);
2670    
2671                            throw roe;
2672                    }
2673    
2674                    PermissionChecker permissionChecker =
2675                            PermissionThreadLocal.getPermissionChecker();
2676    
2677                    User user = permissionChecker.getUser();
2678    
2679                    String remoteURL = buildRemoteURL(
2680                            remoteAddress, remotePort, remotePathContext, secureConnection,
2681                            GroupConstants.DEFAULT_LIVE_GROUP_ID, false);
2682    
2683                    HttpPrincipal httpPrincipal = new HttpPrincipal(
2684                            remoteURL, user.getEmailAddress(), user.getPassword(),
2685                            user.getPasswordEncrypted());
2686    
2687                    // Ping remote host and verify that the group exists in the same company
2688                    // as the remote user
2689    
2690                    try {
2691                            GroupServiceHttp.checkRemoteStagingGroup(
2692                                    httpPrincipal, remoteGroupId);
2693                    }
2694                    catch (NoSuchGroupException nsge) {
2695                            RemoteExportException ree = new RemoteExportException(
2696                                    RemoteExportException.NO_GROUP);
2697    
2698                            ree.setGroupId(remoteGroupId);
2699    
2700                            throw ree;
2701                    }
2702                    catch (PrincipalException pe) {
2703                            RemoteExportException ree = new RemoteExportException(
2704                                    RemoteExportException.NO_PERMISSIONS);
2705    
2706                            ree.setGroupId(remoteGroupId);
2707    
2708                            throw ree;
2709                    }
2710                    catch (SystemException se) {
2711                            RemoteExportException ree = new RemoteExportException(
2712                                    RemoteExportException.BAD_CONNECTION);
2713    
2714                            ree.setURL(remoteURL);
2715    
2716                            throw ree;
2717                    }
2718    
2719            }
2720    
2721            private static Log _log = LogFactoryUtil.getLog(StagingImpl.class);
2722    
2723    }