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