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