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