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