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