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                    catch (JSONException jsone) {
1698                            if (_log.isWarnEnabled()) {
1699                                    _log.warn(
1700                                            "Unable to set recent layout set branch ID with " +
1701                                                    layoutSetId + " and layout set branch " +
1702                                                            layoutSetBranchId, jsone);
1703                            }
1704                    }
1705                    catch (SystemException se) {
1706                            if (_log.isWarnEnabled()) {
1707                                    _log.warn("Unable to get portal preferences", se);
1708                            }
1709                    }
1710            }
1711    
1712            @Override
1713            public void setRecentLayoutSetBranchId(
1714                            User user, long layoutSetId, long layoutSetBranchId)
1715                    throws SystemException {
1716    
1717                    PortalPreferences portalPreferences = getPortalPreferences(user);
1718    
1719                    try {
1720                            setRecentLayoutAttribute(
1721                                    portalPreferences, getRecentLayoutSetBranchIdKey(layoutSetId),
1722                                    layoutSetBranchId);
1723                    }
1724                    catch (JSONException jsone) {
1725                            if (_log.isWarnEnabled()) {
1726                                    _log.warn(
1727                                            "Unable to set recent layout set branch ID with user " +
1728                                                    user.getUserId() + " and layout set " + layoutSetId +
1729                                                            " and layout set branch " + layoutSetBranchId,
1730                                            jsone);
1731                            }
1732                    }
1733            }
1734    
1735            @Override
1736            public void unlockGroup(long groupId) throws SystemException {
1737                    if (!PropsValues.STAGING_LOCK_ENABLED) {
1738                            return;
1739                    }
1740    
1741                    LockLocalServiceUtil.unlock(Staging.class.getName(), groupId);
1742            }
1743    
1744            @Override
1745            public void unscheduleCopyFromLive(PortletRequest portletRequest)
1746                    throws Exception {
1747    
1748                    long stagingGroupId = ParamUtil.getLong(
1749                            portletRequest, "stagingGroupId");
1750    
1751                    String jobName = ParamUtil.getString(portletRequest, "jobName");
1752                    String groupName = getSchedulerGroupName(
1753                            DestinationNames.LAYOUTS_LOCAL_PUBLISHER, stagingGroupId);
1754    
1755                    LayoutServiceUtil.unschedulePublishToLive(
1756                            stagingGroupId, jobName, groupName);
1757            }
1758    
1759            @Override
1760            public void unschedulePublishToLive(PortletRequest portletRequest)
1761                    throws Exception {
1762    
1763                    long stagingGroupId = ParamUtil.getLong(
1764                            portletRequest, "stagingGroupId");
1765    
1766                    Group stagingGroup = GroupLocalServiceUtil.getGroup(stagingGroupId);
1767    
1768                    long liveGroupId = stagingGroup.getLiveGroupId();
1769    
1770                    String jobName = ParamUtil.getString(portletRequest, "jobName");
1771                    String groupName = getSchedulerGroupName(
1772                            DestinationNames.LAYOUTS_LOCAL_PUBLISHER, liveGroupId);
1773    
1774                    LayoutServiceUtil.unschedulePublishToLive(
1775                            liveGroupId, jobName, groupName);
1776            }
1777    
1778            @Override
1779            public void unschedulePublishToRemote(PortletRequest portletRequest)
1780                    throws Exception {
1781    
1782                    long groupId = ParamUtil.getLong(portletRequest, "groupId");
1783    
1784                    String jobName = ParamUtil.getString(portletRequest, "jobName");
1785                    String groupName = getSchedulerGroupName(
1786                            DestinationNames.LAYOUTS_REMOTE_PUBLISHER, groupId);
1787    
1788                    LayoutServiceUtil.unschedulePublishToRemote(
1789                            groupId, jobName, groupName);
1790            }
1791    
1792            @Override
1793            public void updateLastImportSettings(
1794                            Element layoutElement, Layout layout,
1795                            PortletDataContext portletDataContext)
1796                    throws Exception {
1797    
1798                    Map<String, String[]> parameterMap =
1799                            portletDataContext.getParameterMap();
1800    
1801                    String cmd = MapUtil.getString(parameterMap, Constants.CMD);
1802    
1803                    if (!cmd.equals("publish_to_live")) {
1804                            return;
1805                    }
1806    
1807                    UnicodeProperties typeSettingsProperties =
1808                            layout.getTypeSettingsProperties();
1809    
1810                    typeSettingsProperties.setProperty(
1811                            "last-import-date", String.valueOf(System.currentTimeMillis()));
1812    
1813                    String layoutRevisionId = GetterUtil.getString(
1814                            layoutElement.attributeValue("layout-revision-id"));
1815    
1816                    typeSettingsProperties.setProperty(
1817                            "last-import-layout-revision-id", layoutRevisionId);
1818    
1819                    String layoutSetBranchId = MapUtil.getString(
1820                            parameterMap, "layoutSetBranchId");
1821    
1822                    typeSettingsProperties.setProperty(
1823                            "last-import-layout-set-branch-id", layoutSetBranchId);
1824    
1825                    String layoutSetBranchName = MapUtil.getString(
1826                            parameterMap, "layoutSetBranchName");
1827    
1828                    typeSettingsProperties.setProperty(
1829                            "last-import-layout-set-branch-name", layoutSetBranchName);
1830    
1831                    String lastImportUserName = MapUtil.getString(
1832                            parameterMap, "lastImportUserName");
1833    
1834                    typeSettingsProperties.setProperty(
1835                            "last-import-user-name", lastImportUserName);
1836    
1837                    String lastImportUserUuid = MapUtil.getString(
1838                            parameterMap, "lastImportUserUuid");
1839    
1840                    typeSettingsProperties.setProperty(
1841                            "last-import-user-uuid", lastImportUserUuid);
1842    
1843                    String layoutBranchId = GetterUtil.getString(
1844                            layoutElement.attributeValue("layout-branch-id"));
1845    
1846                    typeSettingsProperties.setProperty(
1847                            "last-import-layout-branch-id", layoutBranchId);
1848    
1849                    String layoutBranchName = GetterUtil.getString(
1850                            layoutElement.attributeValue("layout-branch-name"));
1851    
1852                    typeSettingsProperties.setProperty(
1853                            "last-import-layout-branch-name", layoutBranchName);
1854    
1855                    layout.setTypeSettingsProperties(typeSettingsProperties);
1856            }
1857    
1858            @Override
1859            public void updateLastPublishDate(
1860                            long groupId, boolean privateLayout, Date lastPublishDate)
1861                    throws Exception {
1862    
1863                    updateLastPublishDate(groupId, privateLayout, null, lastPublishDate);
1864            }
1865    
1866            @Override
1867            public void updateLastPublishDate(
1868                            long groupId, boolean privateLayout, DateRange dateRange,
1869                            Date lastPublishDate)
1870                    throws Exception {
1871    
1872                    LayoutSet layoutSet = LayoutSetLocalServiceUtil.getLayoutSet(
1873                            groupId, privateLayout);
1874    
1875                    Date originalLastPublishDate = getLastPublishDate(layoutSet);
1876    
1877                    if (!isValidDateRange(dateRange, originalLastPublishDate)) {
1878                            return;
1879                    }
1880    
1881                    if (lastPublishDate == null) {
1882                            lastPublishDate = new Date();
1883                    }
1884    
1885                    UnicodeProperties settingsProperties =
1886                            layoutSet.getSettingsProperties();
1887    
1888                    settingsProperties.setProperty(
1889                            _LAST_PUBLISH_DATE, String.valueOf(lastPublishDate.getTime()));
1890    
1891                    LayoutSetLocalServiceUtil.updateSettings(
1892                            layoutSet.getGroupId(), layoutSet.isPrivateLayout(),
1893                            settingsProperties.toString());
1894            }
1895    
1896            @Override
1897            public void updateLastPublishDate(
1898                            String portletId, PortletPreferences portletPreferences,
1899                            Date lastPublishDate)
1900                    throws Exception {
1901    
1902                    updateLastPublishDate(
1903                            portletId, portletPreferences, null, lastPublishDate);
1904            }
1905    
1906            @Override
1907            public void updateLastPublishDate(
1908                    String portletId, PortletPreferences portletPreferences,
1909                    DateRange dateRange, Date lastPublishDate) {
1910    
1911                    Date originalLastPublishDate = getLastPublishDate(portletPreferences);
1912    
1913                    if (!isValidDateRange(dateRange, originalLastPublishDate)) {
1914                            return;
1915                    }
1916    
1917                    if (lastPublishDate == null) {
1918                            lastPublishDate = new Date();
1919                    }
1920    
1921                    try {
1922                            portletPreferences.setValue(
1923                                    _LAST_PUBLISH_DATE, String.valueOf(lastPublishDate.getTime()));
1924    
1925                            portletPreferences.store();
1926                    }
1927                    catch (UnsupportedOperationException uoe) {
1928                            if (_log.isDebugEnabled()) {
1929                                    _log.debug(
1930                                            "Not updating the portlet setup for " + portletId +
1931                                                    " because no setup was returned for the current " +
1932                                                            "page");
1933                            }
1934                    }
1935                    catch (Exception e) {
1936                            _log.error(e, e);
1937                    }
1938            }
1939    
1940            @Override
1941            public void updateStaging(PortletRequest portletRequest, Group liveGroup)
1942                    throws Exception {
1943    
1944                    ThemeDisplay themeDisplay = (ThemeDisplay)portletRequest.getAttribute(
1945                            WebKeys.THEME_DISPLAY);
1946    
1947                    PermissionChecker permissionChecker =
1948                            themeDisplay.getPermissionChecker();
1949    
1950                    long userId = permissionChecker.getUserId();
1951    
1952                    if (!GroupPermissionUtil.contains(
1953                                    permissionChecker, liveGroup.getGroupId(),
1954                                    ActionKeys.MANAGE_STAGING)) {
1955    
1956                            return;
1957                    }
1958    
1959                    int stagingType = getStagingType(portletRequest, liveGroup);
1960    
1961                    boolean branchingPublic = getBoolean(
1962                            portletRequest, liveGroup, "branchingPublic");
1963                    boolean branchingPrivate = getBoolean(
1964                            portletRequest, liveGroup, "branchingPrivate");
1965    
1966                    ServiceContext serviceContext =
1967                            ServiceContextThreadLocal.getServiceContext();
1968    
1969                    if (stagingType == StagingConstants.TYPE_NOT_STAGED) {
1970                            if (liveGroup.hasStagingGroup() || liveGroup.isStagedRemotely()) {
1971                                    StagingLocalServiceUtil.disableStaging(
1972                                            portletRequest, liveGroup, serviceContext);
1973                            }
1974                    }
1975                    else if (stagingType == StagingConstants.TYPE_LOCAL_STAGING) {
1976                            StagingLocalServiceUtil.enableLocalStaging(
1977                                    userId, liveGroup, branchingPublic, branchingPrivate,
1978                                    serviceContext);
1979                    }
1980                    else if (stagingType == StagingConstants.TYPE_REMOTE_STAGING) {
1981                            String remoteAddress = getString(
1982                                    portletRequest, liveGroup, "remoteAddress");
1983    
1984                            remoteAddress = stripProtocolFromRemoteAddress(remoteAddress);
1985    
1986                            int remotePort = getInteger(
1987                                    portletRequest, liveGroup, "remotePort");
1988                            String remotePathContext = getString(
1989                                    portletRequest, liveGroup, "remotePathContext");
1990                            boolean secureConnection = getBoolean(
1991                                    portletRequest, liveGroup, "secureConnection");
1992                            long remoteGroupId = getLong(
1993                                    portletRequest, liveGroup, "remoteGroupId");
1994    
1995                            StagingLocalServiceUtil.enableRemoteStaging(
1996                                    userId, liveGroup, branchingPublic, branchingPrivate,
1997                                    remoteAddress, remotePort, remotePathContext, secureConnection,
1998                                    remoteGroupId, serviceContext);
1999                    }
2000            }
2001    
2002            @Override
2003            public void validateRemote(
2004                            String remoteAddress, int remotePort, String remotePathContext,
2005                            boolean secureConnection, long remoteGroupId)
2006                    throws PortalException {
2007    
2008                    RemoteOptionsException roe = null;
2009    
2010                    if (!Validator.isDomain(remoteAddress) &&
2011                            !Validator.isIPAddress(remoteAddress)) {
2012    
2013                            roe = new RemoteOptionsException(
2014                                    RemoteOptionsException.REMOTE_ADDRESS);
2015    
2016                            roe.setRemoteAddress(remoteAddress);
2017    
2018                            throw roe;
2019                    }
2020    
2021                    if ((remotePort < 1) || (remotePort > 65535)) {
2022                            roe = new RemoteOptionsException(
2023                                    RemoteOptionsException.REMOTE_PORT);
2024    
2025                            roe.setRemotePort(remotePort);
2026    
2027                            throw roe;
2028                    }
2029    
2030                    if (Validator.isNotNull(remotePathContext) &&
2031                            (!remotePathContext.startsWith(StringPool.FORWARD_SLASH) ||
2032                             remotePathContext.endsWith(StringPool.FORWARD_SLASH))) {
2033    
2034                            roe = new RemoteOptionsException(
2035                                    RemoteOptionsException.REMOTE_PATH_CONTEXT);
2036    
2037                            roe.setRemotePathContext(remotePathContext);
2038    
2039                            throw roe;
2040                    }
2041    
2042                    if (remoteGroupId <= 0) {
2043                            roe = new RemoteOptionsException(
2044                                    RemoteOptionsException.REMOTE_GROUP_ID);
2045    
2046                            roe.setRemoteGroupId(remoteGroupId);
2047    
2048                            throw roe;
2049                    }
2050    
2051                    PermissionChecker permissionChecker =
2052                            PermissionThreadLocal.getPermissionChecker();
2053    
2054                    User user = permissionChecker.getUser();
2055    
2056                    String remoteURL = buildRemoteURL(
2057                            remoteAddress, remotePort, remotePathContext, secureConnection,
2058                            GroupConstants.DEFAULT_LIVE_GROUP_ID, false);
2059    
2060                    HttpPrincipal httpPrincipal = new HttpPrincipal(
2061                            remoteURL, user.getEmailAddress(), user.getPassword(),
2062                            user.getPasswordEncrypted());
2063    
2064                    // Ping remote host and verify that the group exists in the same company
2065                    // as the remote user
2066    
2067                    try {
2068                            GroupServiceHttp.checkRemoteStagingGroup(
2069                                    httpPrincipal, remoteGroupId);
2070                    }
2071                    catch (NoSuchGroupException nsge) {
2072                            RemoteExportException ree = new RemoteExportException(
2073                                    RemoteExportException.NO_GROUP);
2074    
2075                            ree.setGroupId(remoteGroupId);
2076    
2077                            throw ree;
2078                    }
2079                    catch (PrincipalException pe) {
2080                            RemoteExportException ree = new RemoteExportException(
2081                                    RemoteExportException.NO_PERMISSIONS);
2082    
2083                            ree.setGroupId(remoteGroupId);
2084    
2085                            throw ree;
2086                    }
2087                    catch (RemoteAuthException rae) {
2088                            rae.setURL(remoteURL);
2089    
2090                            throw rae;
2091                    }
2092                    catch (SystemException se) {
2093                            RemoteExportException ree = new RemoteExportException(
2094                                    RemoteExportException.BAD_CONNECTION, se.getMessage());
2095    
2096                            ree.setURL(remoteURL);
2097    
2098                            throw ree;
2099                    }
2100            }
2101    
2102            protected void deleteRecentLayoutRevisionId(
2103                    PortalPreferences portalPreferences, long layoutSetBranchId,
2104                    long plid) {
2105    
2106                    String oldPortalPreferences = portalPreferences.getValue(
2107                            Staging.class.getName(),
2108                            StagingConstants.STAGING_RECENT_LAYOUT_IDS_MAP);
2109    
2110                    try {
2111                            JSONArray jsonArray = JSONFactoryUtil.createJSONArray();
2112    
2113                            JSONArray oldJsonArray = JSONFactoryUtil.createJSONArray(
2114                                    oldPortalPreferences);
2115    
2116                            String recentLayoutRevisionIdKey = getRecentLayoutRevisionIdKey(
2117                                    layoutSetBranchId, plid);
2118    
2119                            for (int i = 0; i < oldJsonArray.length(); i ++) {
2120                                    JSONObject jsonObject = oldJsonArray.getJSONObject(i);
2121    
2122                                    if (Validator.isNotNull(
2123                                                    jsonObject.getString(recentLayoutRevisionIdKey))) {
2124    
2125                                            continue;
2126                                    }
2127    
2128                                    jsonArray.put(jsonObject);
2129                            }
2130    
2131                            portalPreferences.setValue(
2132                                    Staging.class.getName(),
2133                                    StagingConstants.STAGING_RECENT_LAYOUT_IDS_MAP,
2134                                    jsonArray.toString());
2135                    }
2136                    catch (JSONException jsone) {
2137                            if (_log.isWarnEnabled()) {
2138                                    _log.warn(
2139                                            "Unable to delete recent layout revision ID with layout " +
2140                                                    "set branch " + layoutSetBranchId + " and PLID " + plid,
2141                                            jsone);
2142                            }
2143                    }
2144            }
2145    
2146            protected boolean getBoolean(
2147                    PortletRequest portletRequest, Group group, String param) {
2148    
2149                    return ParamUtil.getBoolean(
2150                            portletRequest, param,
2151                            GetterUtil.getBoolean(group.getTypeSettingsProperty(param)));
2152            }
2153    
2154            protected int getInteger(
2155                    PortletRequest portletRequest, Group group, String param) {
2156    
2157                    return ParamUtil.getInteger(
2158                            portletRequest, param,
2159                            GetterUtil.getInteger(group.getTypeSettingsProperty(param)));
2160            }
2161    
2162            protected long getLong(
2163                    PortletRequest portletRequest, Group group, String param) {
2164    
2165                    return ParamUtil.getLong(
2166                            portletRequest, param,
2167                            GetterUtil.getLong(group.getTypeSettingsProperty(param)));
2168            }
2169    
2170            protected PortalPreferences getPortalPreferences(User user)
2171                    throws SystemException {
2172    
2173                    boolean signedIn = !user.isDefaultUser();
2174    
2175                    return PortletPreferencesFactoryUtil.getPortalPreferences(
2176                            user.getUserId(), signedIn);
2177            }
2178    
2179            protected long getRecentLayoutBranchId(
2180                    PortalPreferences portalPreferences, long layoutSetBranchId,
2181                    long plid) {
2182    
2183                    try {
2184                            return getRecentLayoutAttribute(
2185                                    portalPreferences,
2186                                    getRecentLayoutBranchIdKey(layoutSetBranchId, plid));
2187                    }
2188                    catch (JSONException jsone) {
2189                            if (_log.isWarnEnabled()) {
2190                                    _log.warn(
2191                                            "Unable to get recent layout branch ID with layout set " +
2192                                                    "branch " + layoutSetBranchId + " and PLID " + plid,
2193                                            jsone);
2194                            }
2195                    }
2196    
2197                    return 0;
2198            }
2199    
2200            protected String getRecentLayoutBranchIdKey(
2201                    long layoutSetBranchId, long plid) {
2202    
2203                    StringBundler sb = new StringBundler(4);
2204    
2205                    sb.append("layoutBranchId-");
2206                    sb.append(layoutSetBranchId);
2207                    sb.append(StringPool.DASH);
2208                    sb.append(plid);
2209    
2210                    return sb.toString();
2211            }
2212    
2213            protected long getRecentLayoutRevisionId(
2214                            PortalPreferences portalPreferences, long layoutSetBranchId,
2215                            long plid)
2216                    throws PortalException, SystemException {
2217    
2218                    long layoutRevisionId = 0;
2219    
2220                    try {
2221                            layoutRevisionId = getRecentLayoutAttribute(
2222                                    portalPreferences,
2223                                    getRecentLayoutRevisionIdKey(layoutSetBranchId, plid));
2224                    }
2225                    catch (JSONException jsone) {
2226                            if (_log.isWarnEnabled()) {
2227                                    _log.warn(
2228                                            "Unable to get recent layout revision ID with layout set " +
2229                                                    "branch " + layoutSetBranchId + " and PLID " + plid,
2230                                            jsone);
2231                            }
2232                    }
2233    
2234                    if (layoutRevisionId > 0) {
2235                            return layoutRevisionId;
2236                    }
2237    
2238                    long layoutBranchId = getRecentLayoutBranchId(
2239                            portalPreferences, layoutSetBranchId, plid);
2240    
2241                    if (layoutBranchId > 0) {
2242                            try {
2243                                    LayoutBranchLocalServiceUtil.getLayoutBranch(layoutBranchId);
2244                            }
2245                            catch (NoSuchLayoutBranchException nslbe) {
2246                                    LayoutBranch layoutBranch =
2247                                            LayoutBranchLocalServiceUtil.getMasterLayoutBranch(
2248                                                    layoutSetBranchId, plid);
2249    
2250                                    layoutBranchId = layoutBranch.getLayoutBranchId();
2251                            }
2252                    }
2253    
2254                    if (layoutBranchId > 0) {
2255                            try {
2256                                    LayoutRevision layoutRevision =
2257                                            LayoutRevisionLocalServiceUtil.getLayoutRevision(
2258                                                    layoutSetBranchId, layoutBranchId, plid);
2259    
2260                                    if (layoutRevision != null) {
2261                                            layoutRevisionId = layoutRevision.getLayoutRevisionId();
2262                                    }
2263                            }
2264                            catch (NoSuchLayoutRevisionException nslre) {
2265                            }
2266                    }
2267    
2268                    return layoutRevisionId;
2269            }
2270    
2271            protected String getRecentLayoutRevisionIdKey(
2272                    long layoutSetBranchId, long plid) {
2273    
2274                    StringBundler sb = new StringBundler(4);
2275    
2276                    sb.append("layoutRevisionId-");
2277                    sb.append(layoutSetBranchId);
2278                    sb.append(StringPool.DASH);
2279                    sb.append(plid);
2280    
2281                    return sb.toString();
2282            }
2283    
2284            protected String getRecentLayoutSetBranchIdKey(long layoutSetId) {
2285                    return "layoutSetBranchId_" + layoutSetId;
2286            }
2287    
2288            protected int getStagingType(
2289                    PortletRequest portletRequest, Group liveGroup) {
2290    
2291                    String stagingType = portletRequest.getParameter("stagingType");
2292    
2293                    if (stagingType != null) {
2294                            return GetterUtil.getInteger(stagingType);
2295                    }
2296    
2297                    if (liveGroup.isStagedRemotely()) {
2298                            return StagingConstants.TYPE_REMOTE_STAGING;
2299                    }
2300    
2301                    if (liveGroup.hasStagingGroup()) {
2302                            return StagingConstants.TYPE_LOCAL_STAGING;
2303                    }
2304    
2305                    return StagingConstants.TYPE_NOT_STAGED;
2306            }
2307    
2308            protected String getString(
2309                    PortletRequest portletRequest, Group group, String param) {
2310    
2311                    return ParamUtil.getString(
2312                            portletRequest, param,
2313                            GetterUtil.getString(group.getTypeSettingsProperty(param)));
2314            }
2315    
2316            protected static boolean isValidDateRange(
2317                    DateRange dateRange, Date originalLastPublishDate) {
2318    
2319                    if (dateRange == null) {
2320    
2321                            // This is a valid scenario when publishing all
2322    
2323                            return true;
2324                    }
2325    
2326                    Date startDate = dateRange.getStartDate();
2327                    Date endDate = dateRange.getEndDate();
2328    
2329                    if (originalLastPublishDate != null) {
2330                            if ((startDate != null) &&
2331                                    startDate.after(originalLastPublishDate)) {
2332    
2333                                    return false;
2334                            }
2335    
2336                            if ((endDate != null) && endDate.before(originalLastPublishDate)) {
2337                                    return false;
2338                            }
2339                    }
2340                    else if ((startDate != null) || (endDate != null)) {
2341                            return false;
2342                    }
2343    
2344                    return true;
2345            }
2346    
2347            protected void publishLayouts(
2348                            PortletRequest portletRequest, long sourceGroupId,
2349                            long targetGroupId, Map<String, String[]> parameterMap,
2350                            boolean schedule)
2351                    throws Exception {
2352    
2353                    ThemeDisplay themeDisplay = (ThemeDisplay)portletRequest.getAttribute(
2354                            WebKeys.THEME_DISPLAY);
2355    
2356                    String tabs1 = ParamUtil.getString(portletRequest, "tabs1");
2357    
2358                    boolean privateLayout = true;
2359    
2360                    if (tabs1.equals("public-pages")) {
2361                            privateLayout = false;
2362                    }
2363    
2364                    String scope = ParamUtil.getString(portletRequest, "scope");
2365    
2366                    Map<Long, Boolean> layoutIdMap = new LinkedHashMap<Long, Boolean>();
2367    
2368                    if (scope.equals("selected-pages")) {
2369                            layoutIdMap = ExportImportHelperUtil.getLayoutIdMap(portletRequest);
2370                    }
2371    
2372                    DateRange dateRange = ExportImportHelperUtil.getDateRange(
2373                            portletRequest, sourceGroupId, privateLayout, 0, null,
2374                            "fromLastPublishDate");
2375    
2376                    if (schedule) {
2377                            String groupName = getSchedulerGroupName(
2378                                    DestinationNames.LAYOUTS_LOCAL_PUBLISHER, targetGroupId);
2379    
2380                            int recurrenceType = ParamUtil.getInteger(
2381                                    portletRequest, "recurrenceType");
2382    
2383                            Calendar startCalendar = ExportImportHelperUtil.getCalendar(
2384                                    portletRequest, "schedulerStartDate", true);
2385    
2386                            String cronText = SchedulerEngineHelperUtil.getCronText(
2387                                    portletRequest, startCalendar, true, recurrenceType);
2388    
2389                            Date schedulerEndDate = null;
2390    
2391                            int endDateType = ParamUtil.getInteger(
2392                                    portletRequest, "endDateType");
2393    
2394                            if (endDateType == 1) {
2395                                    Calendar endCalendar = ExportImportHelperUtil.getCalendar(
2396                                            portletRequest, "schedulerEndDate", true);
2397    
2398                                    schedulerEndDate = endCalendar.getTime();
2399                            }
2400    
2401                            String description = ParamUtil.getString(
2402                                    portletRequest, "description");
2403    
2404                            LayoutServiceUtil.schedulePublishToLive(
2405                                    sourceGroupId, targetGroupId, privateLayout, layoutIdMap,
2406                                    parameterMap, scope, dateRange.getStartDate(),
2407                                    dateRange.getEndDate(), groupName, cronText,
2408                                    startCalendar.getTime(), schedulerEndDate, description);
2409                    }
2410                    else {
2411                            MessageStatus messageStatus = new MessageStatus();
2412    
2413                            messageStatus.startTimer();
2414    
2415                            String command =
2416                                    LayoutsLocalPublisherRequest.COMMAND_SELECTED_PAGES;
2417    
2418                            try {
2419                                    if (scope.equals("all-pages")) {
2420                                            command = LayoutsLocalPublisherRequest.COMMAND_ALL_PAGES;
2421    
2422                                            publishLayouts(
2423                                                    themeDisplay.getUserId(), sourceGroupId, targetGroupId,
2424                                                    privateLayout, parameterMap, dateRange.getStartDate(),
2425                                                    dateRange.getEndDate());
2426                                    }
2427                                    else {
2428                                            publishLayouts(
2429                                                    themeDisplay.getUserId(), sourceGroupId, targetGroupId,
2430                                                    privateLayout, layoutIdMap, parameterMap,
2431                                                    dateRange.getStartDate(), dateRange.getEndDate());
2432                                    }
2433                            }
2434                            catch (Exception e) {
2435                                    messageStatus.setException(e);
2436    
2437                                    throw e;
2438                            }
2439                            finally {
2440                                    messageStatus.stopTimer();
2441    
2442                                    LayoutsLocalPublisherRequest publisherRequest =
2443                                            new LayoutsLocalPublisherRequest(
2444                                                    command, themeDisplay.getUserId(), sourceGroupId,
2445                                                    targetGroupId, privateLayout, layoutIdMap, parameterMap,
2446                                                    dateRange.getStartDate(), dateRange.getEndDate());
2447    
2448                                    messageStatus.setPayload(publisherRequest);
2449    
2450                                    MessageBusUtil.sendMessage(
2451                                            DestinationNames.MESSAGE_BUS_MESSAGE_STATUS, messageStatus);
2452                            }
2453                    }
2454            }
2455    
2456            protected void publishToRemote(
2457                            PortletRequest portletRequest, boolean schedule)
2458                    throws Exception {
2459    
2460                    ThemeDisplay themeDisplay = (ThemeDisplay)portletRequest.getAttribute(
2461                            WebKeys.THEME_DISPLAY);
2462    
2463                    String tabs1 = ParamUtil.getString(portletRequest, "tabs1");
2464    
2465                    long groupId = ParamUtil.getLong(portletRequest, "groupId");
2466    
2467                    boolean privateLayout = true;
2468    
2469                    if (tabs1.equals("public-pages")) {
2470                            privateLayout = false;
2471                    }
2472    
2473                    String scope = ParamUtil.getString(portletRequest, "scope");
2474    
2475                    if (Validator.isNull(scope)) {
2476                            scope = "all-pages";
2477                    }
2478    
2479                    Map<Long, Boolean> layoutIdMap = null;
2480    
2481                    if (scope.equals("selected-pages")) {
2482                            layoutIdMap = ExportImportHelperUtil.getLayoutIdMap(portletRequest);
2483                    }
2484    
2485                    Map<String, String[]> parameterMap = getStagingParameters(
2486                            portletRequest);
2487    
2488                    parameterMap.put(
2489                            PortletDataHandlerKeys.PUBLISH_TO_REMOTE,
2490                            new String[] {Boolean.TRUE.toString()});
2491    
2492                    Group group = GroupLocalServiceUtil.getGroup(groupId);
2493    
2494                    UnicodeProperties groupTypeSettingsProperties =
2495                            group.getTypeSettingsProperties();
2496    
2497                    String remoteAddress = ParamUtil.getString(
2498                            portletRequest, "remoteAddress",
2499                            groupTypeSettingsProperties.getProperty("remoteAddress"));
2500    
2501                    remoteAddress = stripProtocolFromRemoteAddress(remoteAddress);
2502    
2503                    int remotePort = ParamUtil.getInteger(
2504                            portletRequest, "remotePort",
2505                            GetterUtil.getInteger(
2506                                    groupTypeSettingsProperties.getProperty("remotePort")));
2507                    String remotePathContext = ParamUtil.getString(
2508                            portletRequest, "remotePathContext",
2509                            groupTypeSettingsProperties.getProperty("remotePathContext"));
2510                    boolean secureConnection = ParamUtil.getBoolean(
2511                            portletRequest, "secureConnection",
2512                            GetterUtil.getBoolean(
2513                                    groupTypeSettingsProperties.getProperty("secureConnection")));
2514                    long remoteGroupId = ParamUtil.getLong(
2515                            portletRequest, "remoteGroupId",
2516                            GetterUtil.getLong(
2517                                    groupTypeSettingsProperties.getProperty("remoteGroupId")));
2518                    boolean remotePrivateLayout = ParamUtil.getBoolean(
2519                            portletRequest, "remotePrivateLayout");
2520    
2521                    validateRemote(
2522                            remoteAddress, remotePort, remotePathContext, secureConnection,
2523                            remoteGroupId);
2524    
2525                    DateRange dateRange = ExportImportHelperUtil.getDateRange(
2526                            portletRequest, groupId, privateLayout, 0, null,
2527                            "fromLastPublishDate");
2528    
2529                    if (schedule) {
2530                            String groupName = getSchedulerGroupName(
2531                                    DestinationNames.LAYOUTS_REMOTE_PUBLISHER, groupId);
2532    
2533                            int recurrenceType = ParamUtil.getInteger(
2534                                    portletRequest, "recurrenceType");
2535    
2536                            Calendar startCalendar = ExportImportHelperUtil.getCalendar(
2537                                    portletRequest, "schedulerStartDate", true);
2538    
2539                            String cronText = SchedulerEngineHelperUtil.getCronText(
2540                                    portletRequest, startCalendar, true, recurrenceType);
2541    
2542                            Date schedulerEndDate = null;
2543    
2544                            int endDateType = ParamUtil.getInteger(
2545                                    portletRequest, "endDateType");
2546    
2547                            if (endDateType == 1) {
2548                                    Calendar endCalendar = ExportImportHelperUtil.getCalendar(
2549                                            portletRequest, "schedulerEndDate", true);
2550    
2551                                    schedulerEndDate = endCalendar.getTime();
2552                            }
2553    
2554                            String description = ParamUtil.getString(
2555                                    portletRequest, "description");
2556    
2557                            LayoutServiceUtil.schedulePublishToRemote(
2558                                    groupId, privateLayout, layoutIdMap, parameterMap,
2559                                    remoteAddress, remotePort, remotePathContext, secureConnection,
2560                                    remoteGroupId, remotePrivateLayout, dateRange.getStartDate(),
2561                                    dateRange.getEndDate(), groupName, cronText,
2562                                    startCalendar.getTime(), schedulerEndDate, description);
2563                    }
2564                    else {
2565                            MessageStatus messageStatus = new MessageStatus();
2566    
2567                            messageStatus.startTimer();
2568    
2569                            try {
2570                                    copyRemoteLayouts(
2571                                            groupId, privateLayout, layoutIdMap, parameterMap,
2572                                            remoteAddress, remotePort, remotePathContext,
2573                                            secureConnection, remoteGroupId, remotePrivateLayout,
2574                                            dateRange.getStartDate(), dateRange.getEndDate());
2575                            }
2576                            catch (Exception e) {
2577                                    messageStatus.setException(e);
2578    
2579                                    throw e;
2580                            }
2581                            finally {
2582                                    messageStatus.stopTimer();
2583    
2584                                    LayoutsRemotePublisherRequest publisherRequest =
2585                                            new LayoutsRemotePublisherRequest(
2586                                                    themeDisplay.getUserId(), groupId, privateLayout,
2587                                                    layoutIdMap, parameterMap, remoteAddress, remotePort,
2588                                                    remotePathContext, secureConnection, remoteGroupId,
2589                                                    remotePrivateLayout, dateRange.getStartDate(),
2590                                                    dateRange.getEndDate());
2591    
2592                                    messageStatus.setPayload(publisherRequest);
2593    
2594                                    MessageBusUtil.sendMessage(
2595                                            DestinationNames.MESSAGE_BUS_MESSAGE_STATUS, messageStatus);
2596                            }
2597                    }
2598            }
2599    
2600            protected void setRecentLayoutBranchId(
2601                    PortalPreferences portalPreferences, long layoutSetBranchId, long plid,
2602                    long layoutBranchId) {
2603    
2604                    try {
2605                            setRecentLayoutAttribute(
2606                                    portalPreferences,
2607                                    getRecentLayoutBranchIdKey(layoutSetBranchId, plid),
2608                                    layoutBranchId);
2609                    }
2610                    catch (JSONException jsone) {
2611                            if (_log.isWarnEnabled()) {
2612                                    _log.warn(
2613                                            "Unable to set recent layout branch ID with layout set " +
2614                                                    "branch " + layoutSetBranchId + " and PLID " + plid +
2615                                                            " and layout branch " + layoutBranchId,
2616                                            jsone);
2617                            }
2618                    }
2619            }
2620    
2621            protected void setRecentLayoutRevisionId(
2622                            PortalPreferences portalPreferences, long layoutSetBranchId,
2623                            long plid, long layoutRevisionId)
2624                    throws SystemException {
2625    
2626                    long layoutBranchId = 0;
2627    
2628                    try {
2629                            LayoutRevision layoutRevision =
2630                                    LayoutRevisionLocalServiceUtil.getLayoutRevision(
2631                                            layoutRevisionId);
2632    
2633                            layoutBranchId = layoutRevision.getLayoutBranchId();
2634    
2635                            LayoutRevision lastLayoutRevision =
2636                                    LayoutRevisionLocalServiceUtil.getLayoutRevision(
2637                                            layoutSetBranchId, layoutBranchId, plid);
2638    
2639                            if (lastLayoutRevision.getLayoutRevisionId() == layoutRevisionId) {
2640                                    deleteRecentLayoutRevisionId(
2641                                            portalPreferences, layoutSetBranchId, plid);
2642                            }
2643                            else {
2644                                    setRecentLayoutAttribute(
2645                                            portalPreferences,
2646                                            getRecentLayoutRevisionIdKey(layoutSetBranchId, plid),
2647                                            layoutRevisionId);
2648                            }
2649                    }
2650                    catch (PortalException pe) {
2651                            if (_log.isWarnEnabled()) {
2652                                    _log.warn(
2653                                            "Unable to set recent layout revision ID with layout set " +
2654                                                    "branch " + layoutSetBranchId + " and PLID " + plid +
2655                                                            " and layout branch " + layoutBranchId,
2656                                            pe);
2657                            }
2658                    }
2659    
2660                    setRecentLayoutBranchId(
2661                            portalPreferences, layoutSetBranchId, plid, layoutBranchId);
2662            }
2663    
2664            protected String stripProtocolFromRemoteAddress(String remoteAddress) {
2665                    if (remoteAddress.startsWith(Http.HTTP_WITH_SLASH)) {
2666                            remoteAddress = remoteAddress.substring(
2667                                    Http.HTTP_WITH_SLASH.length());
2668                    }
2669                    else if (remoteAddress.startsWith(Http.HTTPS_WITH_SLASH)) {
2670                            remoteAddress = remoteAddress.substring(
2671                                    Http.HTTPS_WITH_SLASH.length());
2672                    }
2673    
2674                    return remoteAddress;
2675            }
2676    
2677            protected void updateGroupTypeSettingsProperties(
2678                            Group group, String remoteAddress, int remotePort,
2679                            String remotePathContext, boolean secureConnection,
2680                            long remoteGroupId)
2681                    throws Exception {
2682    
2683                    UnicodeProperties typeSettingsProperties =
2684                            group.getTypeSettingsProperties();
2685    
2686                    typeSettingsProperties.setProperty("remoteAddress", remoteAddress);
2687                    typeSettingsProperties.setProperty(
2688                            "remoteGroupId", String.valueOf(remoteGroupId));
2689                    typeSettingsProperties.setProperty(
2690                            "remotePathContext", remotePathContext);
2691                    typeSettingsProperties.setProperty(
2692                            "remotePort", String.valueOf(remotePort));
2693                    typeSettingsProperties.setProperty(
2694                            "secureConnection", String.valueOf(secureConnection));
2695    
2696                    group.setTypeSettingsProperties(typeSettingsProperties);
2697    
2698                    GroupLocalServiceUtil.updateGroup(group);
2699            }
2700    
2701            private long getRecentLayoutAttribute(
2702                            PortalPreferences portalPreferences, String key)
2703                    throws JSONException {
2704    
2705                    String preferencesString = portalPreferences.getValue(
2706                            Staging.class.getName(),
2707                            StagingConstants.STAGING_RECENT_LAYOUT_IDS_MAP);
2708    
2709                    JSONArray jsonArray = JSONFactoryUtil.createJSONArray(
2710                            preferencesString);
2711    
2712                    for (int i = 0; i < jsonArray.length(); i++) {
2713                            JSONObject jsonObject = jsonArray.getJSONObject(i);
2714    
2715                            if (jsonObject.has(key)) {
2716                                    return GetterUtil.getLong(jsonObject.getString(key));
2717                            }
2718                    }
2719    
2720                    return 0;
2721            }
2722    
2723            private void setRecentLayoutAttribute(
2724                            PortalPreferences portalPreferences, String key, long value)
2725                    throws JSONException {
2726    
2727                    String oldPortalPreferences = portalPreferences.getValue(
2728                            Staging.class.getName(),
2729                            StagingConstants.STAGING_RECENT_LAYOUT_IDS_MAP);
2730    
2731                    JSONArray oldJsonArray = JSONFactoryUtil.createJSONArray(
2732                            oldPortalPreferences);
2733    
2734                    boolean alreadyExists = false;
2735    
2736                    JSONArray jsonArray = JSONFactoryUtil.createJSONArray();
2737    
2738                    for (int i = 0; i < oldJsonArray.length(); i++) {
2739                            JSONObject jsonObject = oldJsonArray.getJSONObject(i);
2740    
2741                            if (Validator.isNotNull(jsonObject.getString(key))) {
2742                                    alreadyExists = true;
2743    
2744                                    jsonObject.remove(key);
2745    
2746                                    jsonObject.put(key, String.valueOf(value));
2747                            }
2748    
2749                            jsonArray.put(jsonObject);
2750                    }
2751    
2752                    if (!alreadyExists) {
2753                            JSONObject jsonObject = JSONFactoryUtil.createJSONObject();
2754    
2755                            jsonObject.put(key, String.valueOf(value));
2756    
2757                            jsonArray.put(jsonObject);
2758                    }
2759    
2760                    portalPreferences.setValue(
2761                            Staging.class.getName(),
2762                            StagingConstants.STAGING_RECENT_LAYOUT_IDS_MAP,
2763                            jsonArray.toString());
2764            }
2765    
2766            private static final String _LAST_PUBLISH_DATE = "last-publish-date";
2767    
2768            private static Log _log = LogFactoryUtil.getLog(StagingImpl.class);
2769    
2770    }