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                    boolean forceDisable = ParamUtil.getBoolean(
1966                            portletRequest, "forceDisable");
1967    
1968                    ServiceContext serviceContext =
1969                            ServiceContextThreadLocal.getServiceContext();
1970    
1971                    serviceContext.setAttribute("forceDisable", forceDisable);
1972    
1973                    if (stagingType == StagingConstants.TYPE_NOT_STAGED) {
1974                            if (liveGroup.hasStagingGroup() || liveGroup.isStagedRemotely()) {
1975                                    StagingLocalServiceUtil.disableStaging(
1976                                            portletRequest, liveGroup, serviceContext);
1977                            }
1978                    }
1979                    else if (stagingType == StagingConstants.TYPE_LOCAL_STAGING) {
1980                            StagingLocalServiceUtil.enableLocalStaging(
1981                                    userId, liveGroup, branchingPublic, branchingPrivate,
1982                                    serviceContext);
1983                    }
1984                    else if (stagingType == StagingConstants.TYPE_REMOTE_STAGING) {
1985                            String remoteAddress = getString(
1986                                    portletRequest, liveGroup, "remoteAddress");
1987    
1988                            remoteAddress = stripProtocolFromRemoteAddress(remoteAddress);
1989    
1990                            int remotePort = getInteger(
1991                                    portletRequest, liveGroup, "remotePort");
1992                            String remotePathContext = getString(
1993                                    portletRequest, liveGroup, "remotePathContext");
1994                            boolean secureConnection = getBoolean(
1995                                    portletRequest, liveGroup, "secureConnection");
1996                            long remoteGroupId = getLong(
1997                                    portletRequest, liveGroup, "remoteGroupId");
1998    
1999                            StagingLocalServiceUtil.enableRemoteStaging(
2000                                    userId, liveGroup, branchingPublic, branchingPrivate,
2001                                    remoteAddress, remotePort, remotePathContext, secureConnection,
2002                                    remoteGroupId, serviceContext);
2003                    }
2004            }
2005    
2006            @Override
2007            public void validateRemote(
2008                            String remoteAddress, int remotePort, String remotePathContext,
2009                            boolean secureConnection, long remoteGroupId)
2010                    throws PortalException {
2011    
2012                    RemoteOptionsException roe = null;
2013    
2014                    if (!Validator.isDomain(remoteAddress) &&
2015                            !Validator.isIPAddress(remoteAddress)) {
2016    
2017                            roe = new RemoteOptionsException(
2018                                    RemoteOptionsException.REMOTE_ADDRESS);
2019    
2020                            roe.setRemoteAddress(remoteAddress);
2021    
2022                            throw roe;
2023                    }
2024    
2025                    if ((remotePort < 1) || (remotePort > 65535)) {
2026                            roe = new RemoteOptionsException(
2027                                    RemoteOptionsException.REMOTE_PORT);
2028    
2029                            roe.setRemotePort(remotePort);
2030    
2031                            throw roe;
2032                    }
2033    
2034                    if (Validator.isNotNull(remotePathContext) &&
2035                            (!remotePathContext.startsWith(StringPool.FORWARD_SLASH) ||
2036                             remotePathContext.endsWith(StringPool.FORWARD_SLASH))) {
2037    
2038                            roe = new RemoteOptionsException(
2039                                    RemoteOptionsException.REMOTE_PATH_CONTEXT);
2040    
2041                            roe.setRemotePathContext(remotePathContext);
2042    
2043                            throw roe;
2044                    }
2045    
2046                    if (remoteGroupId <= 0) {
2047                            roe = new RemoteOptionsException(
2048                                    RemoteOptionsException.REMOTE_GROUP_ID);
2049    
2050                            roe.setRemoteGroupId(remoteGroupId);
2051    
2052                            throw roe;
2053                    }
2054    
2055                    PermissionChecker permissionChecker =
2056                            PermissionThreadLocal.getPermissionChecker();
2057    
2058                    User user = permissionChecker.getUser();
2059    
2060                    String remoteURL = buildRemoteURL(
2061                            remoteAddress, remotePort, remotePathContext, secureConnection,
2062                            GroupConstants.DEFAULT_LIVE_GROUP_ID, false);
2063    
2064                    HttpPrincipal httpPrincipal = new HttpPrincipal(
2065                            remoteURL, user.getEmailAddress(), user.getPassword(),
2066                            user.getPasswordEncrypted());
2067    
2068                    // Ping remote host and verify that the group exists in the same company
2069                    // as the remote user
2070    
2071                    try {
2072                            GroupServiceHttp.checkRemoteStagingGroup(
2073                                    httpPrincipal, remoteGroupId);
2074                    }
2075                    catch (NoSuchGroupException nsge) {
2076                            RemoteExportException ree = new RemoteExportException(
2077                                    RemoteExportException.NO_GROUP);
2078    
2079                            ree.setGroupId(remoteGroupId);
2080    
2081                            throw ree;
2082                    }
2083                    catch (PrincipalException pe) {
2084                            RemoteExportException ree = new RemoteExportException(
2085                                    RemoteExportException.NO_PERMISSIONS);
2086    
2087                            ree.setGroupId(remoteGroupId);
2088    
2089                            throw ree;
2090                    }
2091                    catch (RemoteAuthException rae) {
2092                            rae.setURL(remoteURL);
2093    
2094                            throw rae;
2095                    }
2096                    catch (SystemException se) {
2097                            RemoteExportException ree = new RemoteExportException(
2098                                    RemoteExportException.BAD_CONNECTION, se.getMessage());
2099    
2100                            ree.setURL(remoteURL);
2101    
2102                            throw ree;
2103                    }
2104            }
2105    
2106            protected void deleteRecentLayoutRevisionId(
2107                    PortalPreferences portalPreferences, long layoutSetBranchId,
2108                    long plid) {
2109    
2110                    String oldPortalPreferences = portalPreferences.getValue(
2111                            Staging.class.getName(),
2112                            StagingConstants.STAGING_RECENT_LAYOUT_IDS_MAP);
2113    
2114                    try {
2115                            JSONArray jsonArray = JSONFactoryUtil.createJSONArray();
2116    
2117                            JSONArray oldJsonArray = JSONFactoryUtil.createJSONArray(
2118                                    oldPortalPreferences);
2119    
2120                            String recentLayoutRevisionIdKey = getRecentLayoutRevisionIdKey(
2121                                    layoutSetBranchId, plid);
2122    
2123                            for (int i = 0; i < oldJsonArray.length(); i ++) {
2124                                    JSONObject jsonObject = oldJsonArray.getJSONObject(i);
2125    
2126                                    if (Validator.isNotNull(
2127                                                    jsonObject.getString(recentLayoutRevisionIdKey))) {
2128    
2129                                            continue;
2130                                    }
2131    
2132                                    jsonArray.put(jsonObject);
2133                            }
2134    
2135                            portalPreferences.setValue(
2136                                    Staging.class.getName(),
2137                                    StagingConstants.STAGING_RECENT_LAYOUT_IDS_MAP,
2138                                    jsonArray.toString());
2139                    }
2140                    catch (JSONException jsone) {
2141                            if (_log.isWarnEnabled()) {
2142                                    _log.warn(
2143                                            "Unable to delete recent layout revision ID with layout " +
2144                                                    "set branch " + layoutSetBranchId + " and PLID " + plid,
2145                                            jsone);
2146                            }
2147                    }
2148            }
2149    
2150            protected boolean getBoolean(
2151                    PortletRequest portletRequest, Group group, String param) {
2152    
2153                    return ParamUtil.getBoolean(
2154                            portletRequest, param,
2155                            GetterUtil.getBoolean(group.getTypeSettingsProperty(param)));
2156            }
2157    
2158            protected int getInteger(
2159                    PortletRequest portletRequest, Group group, String param) {
2160    
2161                    return ParamUtil.getInteger(
2162                            portletRequest, param,
2163                            GetterUtil.getInteger(group.getTypeSettingsProperty(param)));
2164            }
2165    
2166            protected long getLong(
2167                    PortletRequest portletRequest, Group group, String param) {
2168    
2169                    return ParamUtil.getLong(
2170                            portletRequest, param,
2171                            GetterUtil.getLong(group.getTypeSettingsProperty(param)));
2172            }
2173    
2174            protected PortalPreferences getPortalPreferences(User user)
2175                    throws SystemException {
2176    
2177                    boolean signedIn = !user.isDefaultUser();
2178    
2179                    return PortletPreferencesFactoryUtil.getPortalPreferences(
2180                            user.getUserId(), signedIn);
2181            }
2182    
2183            protected long getRecentLayoutBranchId(
2184                    PortalPreferences portalPreferences, long layoutSetBranchId,
2185                    long plid) {
2186    
2187                    try {
2188                            return getRecentLayoutAttribute(
2189                                    portalPreferences,
2190                                    getRecentLayoutBranchIdKey(layoutSetBranchId, plid));
2191                    }
2192                    catch (JSONException jsone) {
2193                            if (_log.isWarnEnabled()) {
2194                                    _log.warn(
2195                                            "Unable to get recent layout branch ID with layout set " +
2196                                                    "branch " + layoutSetBranchId + " and PLID " + plid,
2197                                            jsone);
2198                            }
2199                    }
2200    
2201                    return 0;
2202            }
2203    
2204            protected String getRecentLayoutBranchIdKey(
2205                    long layoutSetBranchId, long plid) {
2206    
2207                    StringBundler sb = new StringBundler(4);
2208    
2209                    sb.append("layoutBranchId-");
2210                    sb.append(layoutSetBranchId);
2211                    sb.append(StringPool.DASH);
2212                    sb.append(plid);
2213    
2214                    return sb.toString();
2215            }
2216    
2217            protected long getRecentLayoutRevisionId(
2218                            PortalPreferences portalPreferences, long layoutSetBranchId,
2219                            long plid)
2220                    throws PortalException, SystemException {
2221    
2222                    long layoutRevisionId = 0;
2223    
2224                    try {
2225                            layoutRevisionId = getRecentLayoutAttribute(
2226                                    portalPreferences,
2227                                    getRecentLayoutRevisionIdKey(layoutSetBranchId, plid));
2228                    }
2229                    catch (JSONException jsone) {
2230                            if (_log.isWarnEnabled()) {
2231                                    _log.warn(
2232                                            "Unable to get recent layout revision ID with layout set " +
2233                                                    "branch " + layoutSetBranchId + " and PLID " + plid,
2234                                            jsone);
2235                            }
2236                    }
2237    
2238                    if (layoutRevisionId > 0) {
2239                            return layoutRevisionId;
2240                    }
2241    
2242                    long layoutBranchId = getRecentLayoutBranchId(
2243                            portalPreferences, layoutSetBranchId, plid);
2244    
2245                    if (layoutBranchId > 0) {
2246                            try {
2247                                    LayoutBranchLocalServiceUtil.getLayoutBranch(layoutBranchId);
2248                            }
2249                            catch (NoSuchLayoutBranchException nslbe) {
2250                                    LayoutBranch layoutBranch =
2251                                            LayoutBranchLocalServiceUtil.getMasterLayoutBranch(
2252                                                    layoutSetBranchId, plid);
2253    
2254                                    layoutBranchId = layoutBranch.getLayoutBranchId();
2255                            }
2256                    }
2257    
2258                    if (layoutBranchId > 0) {
2259                            try {
2260                                    LayoutRevision layoutRevision =
2261                                            LayoutRevisionLocalServiceUtil.getLayoutRevision(
2262                                                    layoutSetBranchId, layoutBranchId, plid);
2263    
2264                                    if (layoutRevision != null) {
2265                                            layoutRevisionId = layoutRevision.getLayoutRevisionId();
2266                                    }
2267                            }
2268                            catch (NoSuchLayoutRevisionException nslre) {
2269                            }
2270                    }
2271    
2272                    return layoutRevisionId;
2273            }
2274    
2275            protected String getRecentLayoutRevisionIdKey(
2276                    long layoutSetBranchId, long plid) {
2277    
2278                    StringBundler sb = new StringBundler(4);
2279    
2280                    sb.append("layoutRevisionId-");
2281                    sb.append(layoutSetBranchId);
2282                    sb.append(StringPool.DASH);
2283                    sb.append(plid);
2284    
2285                    return sb.toString();
2286            }
2287    
2288            protected String getRecentLayoutSetBranchIdKey(long layoutSetId) {
2289                    return "layoutSetBranchId_" + layoutSetId;
2290            }
2291    
2292            protected int getStagingType(
2293                    PortletRequest portletRequest, Group liveGroup) {
2294    
2295                    String stagingType = portletRequest.getParameter("stagingType");
2296    
2297                    if (stagingType != null) {
2298                            return GetterUtil.getInteger(stagingType);
2299                    }
2300    
2301                    if (liveGroup.isStagedRemotely()) {
2302                            return StagingConstants.TYPE_REMOTE_STAGING;
2303                    }
2304    
2305                    if (liveGroup.hasStagingGroup()) {
2306                            return StagingConstants.TYPE_LOCAL_STAGING;
2307                    }
2308    
2309                    return StagingConstants.TYPE_NOT_STAGED;
2310            }
2311    
2312            protected String getString(
2313                    PortletRequest portletRequest, Group group, String param) {
2314    
2315                    return ParamUtil.getString(
2316                            portletRequest, param,
2317                            GetterUtil.getString(group.getTypeSettingsProperty(param)));
2318            }
2319    
2320            protected static boolean isValidDateRange(
2321                    DateRange dateRange, Date originalLastPublishDate) {
2322    
2323                    if (dateRange == null) {
2324    
2325                            // This is a valid scenario when publishing all
2326    
2327                            return true;
2328                    }
2329    
2330                    Date startDate = dateRange.getStartDate();
2331                    Date endDate = dateRange.getEndDate();
2332    
2333                    if (originalLastPublishDate != null) {
2334                            if ((startDate != null) &&
2335                                    startDate.after(originalLastPublishDate)) {
2336    
2337                                    return false;
2338                            }
2339    
2340                            if ((endDate != null) && endDate.before(originalLastPublishDate)) {
2341                                    return false;
2342                            }
2343                    }
2344                    else if ((startDate != null) || (endDate != null)) {
2345                            return false;
2346                    }
2347    
2348                    return true;
2349            }
2350    
2351            protected void publishLayouts(
2352                            PortletRequest portletRequest, long sourceGroupId,
2353                            long targetGroupId, Map<String, String[]> parameterMap,
2354                            boolean schedule)
2355                    throws Exception {
2356    
2357                    ThemeDisplay themeDisplay = (ThemeDisplay)portletRequest.getAttribute(
2358                            WebKeys.THEME_DISPLAY);
2359    
2360                    String tabs1 = ParamUtil.getString(portletRequest, "tabs1");
2361    
2362                    boolean privateLayout = true;
2363    
2364                    if (tabs1.equals("public-pages")) {
2365                            privateLayout = false;
2366                    }
2367    
2368                    String scope = ParamUtil.getString(portletRequest, "scope");
2369    
2370                    Map<Long, Boolean> layoutIdMap = new LinkedHashMap<Long, Boolean>();
2371    
2372                    if (scope.equals("selected-pages")) {
2373                            layoutIdMap = ExportImportHelperUtil.getLayoutIdMap(portletRequest);
2374                    }
2375    
2376                    DateRange dateRange = ExportImportHelperUtil.getDateRange(
2377                            portletRequest, sourceGroupId, privateLayout, 0, null,
2378                            "fromLastPublishDate");
2379    
2380                    if (schedule) {
2381                            String groupName = getSchedulerGroupName(
2382                                    DestinationNames.LAYOUTS_LOCAL_PUBLISHER, targetGroupId);
2383    
2384                            int recurrenceType = ParamUtil.getInteger(
2385                                    portletRequest, "recurrenceType");
2386    
2387                            Calendar startCalendar = ExportImportHelperUtil.getCalendar(
2388                                    portletRequest, "schedulerStartDate", true);
2389    
2390                            String cronText = SchedulerEngineHelperUtil.getCronText(
2391                                    portletRequest, startCalendar, true, recurrenceType);
2392    
2393                            Date schedulerEndDate = null;
2394    
2395                            int endDateType = ParamUtil.getInteger(
2396                                    portletRequest, "endDateType");
2397    
2398                            if (endDateType == 1) {
2399                                    Calendar endCalendar = ExportImportHelperUtil.getCalendar(
2400                                            portletRequest, "schedulerEndDate", true);
2401    
2402                                    schedulerEndDate = endCalendar.getTime();
2403                            }
2404    
2405                            String description = ParamUtil.getString(
2406                                    portletRequest, "description");
2407    
2408                            LayoutServiceUtil.schedulePublishToLive(
2409                                    sourceGroupId, targetGroupId, privateLayout, layoutIdMap,
2410                                    parameterMap, scope, dateRange.getStartDate(),
2411                                    dateRange.getEndDate(), groupName, cronText,
2412                                    startCalendar.getTime(), schedulerEndDate, description);
2413                    }
2414                    else {
2415                            MessageStatus messageStatus = new MessageStatus();
2416    
2417                            messageStatus.startTimer();
2418    
2419                            String command =
2420                                    LayoutsLocalPublisherRequest.COMMAND_SELECTED_PAGES;
2421    
2422                            try {
2423                                    if (scope.equals("all-pages")) {
2424                                            command = LayoutsLocalPublisherRequest.COMMAND_ALL_PAGES;
2425    
2426                                            publishLayouts(
2427                                                    themeDisplay.getUserId(), sourceGroupId, targetGroupId,
2428                                                    privateLayout, parameterMap, dateRange.getStartDate(),
2429                                                    dateRange.getEndDate());
2430                                    }
2431                                    else {
2432                                            publishLayouts(
2433                                                    themeDisplay.getUserId(), sourceGroupId, targetGroupId,
2434                                                    privateLayout, layoutIdMap, parameterMap,
2435                                                    dateRange.getStartDate(), dateRange.getEndDate());
2436                                    }
2437                            }
2438                            catch (Exception e) {
2439                                    messageStatus.setException(e);
2440    
2441                                    throw e;
2442                            }
2443                            finally {
2444                                    messageStatus.stopTimer();
2445    
2446                                    LayoutsLocalPublisherRequest publisherRequest =
2447                                            new LayoutsLocalPublisherRequest(
2448                                                    command, themeDisplay.getUserId(), sourceGroupId,
2449                                                    targetGroupId, privateLayout, layoutIdMap, parameterMap,
2450                                                    dateRange.getStartDate(), dateRange.getEndDate());
2451    
2452                                    messageStatus.setPayload(publisherRequest);
2453    
2454                                    MessageBusUtil.sendMessage(
2455                                            DestinationNames.MESSAGE_BUS_MESSAGE_STATUS, messageStatus);
2456                            }
2457                    }
2458            }
2459    
2460            protected void publishToRemote(
2461                            PortletRequest portletRequest, boolean schedule)
2462                    throws Exception {
2463    
2464                    ThemeDisplay themeDisplay = (ThemeDisplay)portletRequest.getAttribute(
2465                            WebKeys.THEME_DISPLAY);
2466    
2467                    String tabs1 = ParamUtil.getString(portletRequest, "tabs1");
2468    
2469                    long groupId = ParamUtil.getLong(portletRequest, "groupId");
2470    
2471                    boolean privateLayout = true;
2472    
2473                    if (tabs1.equals("public-pages")) {
2474                            privateLayout = false;
2475                    }
2476    
2477                    String scope = ParamUtil.getString(portletRequest, "scope");
2478    
2479                    if (Validator.isNull(scope)) {
2480                            scope = "all-pages";
2481                    }
2482    
2483                    Map<Long, Boolean> layoutIdMap = null;
2484    
2485                    if (scope.equals("selected-pages")) {
2486                            layoutIdMap = ExportImportHelperUtil.getLayoutIdMap(portletRequest);
2487                    }
2488    
2489                    Map<String, String[]> parameterMap = getStagingParameters(
2490                            portletRequest);
2491    
2492                    parameterMap.put(
2493                            PortletDataHandlerKeys.PUBLISH_TO_REMOTE,
2494                            new String[] {Boolean.TRUE.toString()});
2495    
2496                    Group group = GroupLocalServiceUtil.getGroup(groupId);
2497    
2498                    UnicodeProperties groupTypeSettingsProperties =
2499                            group.getTypeSettingsProperties();
2500    
2501                    String remoteAddress = ParamUtil.getString(
2502                            portletRequest, "remoteAddress",
2503                            groupTypeSettingsProperties.getProperty("remoteAddress"));
2504    
2505                    remoteAddress = stripProtocolFromRemoteAddress(remoteAddress);
2506    
2507                    int remotePort = ParamUtil.getInteger(
2508                            portletRequest, "remotePort",
2509                            GetterUtil.getInteger(
2510                                    groupTypeSettingsProperties.getProperty("remotePort")));
2511                    String remotePathContext = ParamUtil.getString(
2512                            portletRequest, "remotePathContext",
2513                            groupTypeSettingsProperties.getProperty("remotePathContext"));
2514                    boolean secureConnection = ParamUtil.getBoolean(
2515                            portletRequest, "secureConnection",
2516                            GetterUtil.getBoolean(
2517                                    groupTypeSettingsProperties.getProperty("secureConnection")));
2518                    long remoteGroupId = ParamUtil.getLong(
2519                            portletRequest, "remoteGroupId",
2520                            GetterUtil.getLong(
2521                                    groupTypeSettingsProperties.getProperty("remoteGroupId")));
2522                    boolean remotePrivateLayout = ParamUtil.getBoolean(
2523                            portletRequest, "remotePrivateLayout");
2524    
2525                    validateRemote(
2526                            remoteAddress, remotePort, remotePathContext, secureConnection,
2527                            remoteGroupId);
2528    
2529                    DateRange dateRange = ExportImportHelperUtil.getDateRange(
2530                            portletRequest, groupId, privateLayout, 0, null,
2531                            "fromLastPublishDate");
2532    
2533                    if (schedule) {
2534                            String groupName = getSchedulerGroupName(
2535                                    DestinationNames.LAYOUTS_REMOTE_PUBLISHER, groupId);
2536    
2537                            int recurrenceType = ParamUtil.getInteger(
2538                                    portletRequest, "recurrenceType");
2539    
2540                            Calendar startCalendar = ExportImportHelperUtil.getCalendar(
2541                                    portletRequest, "schedulerStartDate", true);
2542    
2543                            String cronText = SchedulerEngineHelperUtil.getCronText(
2544                                    portletRequest, startCalendar, true, recurrenceType);
2545    
2546                            Date schedulerEndDate = null;
2547    
2548                            int endDateType = ParamUtil.getInteger(
2549                                    portletRequest, "endDateType");
2550    
2551                            if (endDateType == 1) {
2552                                    Calendar endCalendar = ExportImportHelperUtil.getCalendar(
2553                                            portletRequest, "schedulerEndDate", true);
2554    
2555                                    schedulerEndDate = endCalendar.getTime();
2556                            }
2557    
2558                            String description = ParamUtil.getString(
2559                                    portletRequest, "description");
2560    
2561                            LayoutServiceUtil.schedulePublishToRemote(
2562                                    groupId, privateLayout, layoutIdMap, parameterMap,
2563                                    remoteAddress, remotePort, remotePathContext, secureConnection,
2564                                    remoteGroupId, remotePrivateLayout, dateRange.getStartDate(),
2565                                    dateRange.getEndDate(), groupName, cronText,
2566                                    startCalendar.getTime(), schedulerEndDate, description);
2567                    }
2568                    else {
2569                            MessageStatus messageStatus = new MessageStatus();
2570    
2571                            messageStatus.startTimer();
2572    
2573                            try {
2574                                    copyRemoteLayouts(
2575                                            groupId, privateLayout, layoutIdMap, parameterMap,
2576                                            remoteAddress, remotePort, remotePathContext,
2577                                            secureConnection, remoteGroupId, remotePrivateLayout,
2578                                            dateRange.getStartDate(), dateRange.getEndDate());
2579                            }
2580                            catch (Exception e) {
2581                                    messageStatus.setException(e);
2582    
2583                                    throw e;
2584                            }
2585                            finally {
2586                                    messageStatus.stopTimer();
2587    
2588                                    LayoutsRemotePublisherRequest publisherRequest =
2589                                            new LayoutsRemotePublisherRequest(
2590                                                    themeDisplay.getUserId(), groupId, privateLayout,
2591                                                    layoutIdMap, parameterMap, remoteAddress, remotePort,
2592                                                    remotePathContext, secureConnection, remoteGroupId,
2593                                                    remotePrivateLayout, dateRange.getStartDate(),
2594                                                    dateRange.getEndDate());
2595    
2596                                    messageStatus.setPayload(publisherRequest);
2597    
2598                                    MessageBusUtil.sendMessage(
2599                                            DestinationNames.MESSAGE_BUS_MESSAGE_STATUS, messageStatus);
2600                            }
2601                    }
2602            }
2603    
2604            protected void setRecentLayoutBranchId(
2605                    PortalPreferences portalPreferences, long layoutSetBranchId, long plid,
2606                    long layoutBranchId) {
2607    
2608                    try {
2609                            setRecentLayoutAttribute(
2610                                    portalPreferences,
2611                                    getRecentLayoutBranchIdKey(layoutSetBranchId, plid),
2612                                    layoutBranchId);
2613                    }
2614                    catch (JSONException jsone) {
2615                            if (_log.isWarnEnabled()) {
2616                                    _log.warn(
2617                                            "Unable to set recent layout branch ID with layout set " +
2618                                                    "branch " + layoutSetBranchId + " and PLID " + plid +
2619                                                            " and layout branch " + layoutBranchId,
2620                                            jsone);
2621                            }
2622                    }
2623            }
2624    
2625            protected void setRecentLayoutRevisionId(
2626                            PortalPreferences portalPreferences, long layoutSetBranchId,
2627                            long plid, long layoutRevisionId)
2628                    throws SystemException {
2629    
2630                    long layoutBranchId = 0;
2631    
2632                    try {
2633                            LayoutRevision layoutRevision =
2634                                    LayoutRevisionLocalServiceUtil.getLayoutRevision(
2635                                            layoutRevisionId);
2636    
2637                            layoutBranchId = layoutRevision.getLayoutBranchId();
2638    
2639                            LayoutRevision lastLayoutRevision =
2640                                    LayoutRevisionLocalServiceUtil.getLayoutRevision(
2641                                            layoutSetBranchId, layoutBranchId, plid);
2642    
2643                            if (lastLayoutRevision.getLayoutRevisionId() == layoutRevisionId) {
2644                                    deleteRecentLayoutRevisionId(
2645                                            portalPreferences, layoutSetBranchId, plid);
2646                            }
2647                            else {
2648                                    setRecentLayoutAttribute(
2649                                            portalPreferences,
2650                                            getRecentLayoutRevisionIdKey(layoutSetBranchId, plid),
2651                                            layoutRevisionId);
2652                            }
2653                    }
2654                    catch (PortalException pe) {
2655                            if (_log.isWarnEnabled()) {
2656                                    _log.warn(
2657                                            "Unable to set recent layout revision ID with layout set " +
2658                                                    "branch " + layoutSetBranchId + " and PLID " + plid +
2659                                                            " and layout branch " + layoutBranchId,
2660                                            pe);
2661                            }
2662                    }
2663    
2664                    setRecentLayoutBranchId(
2665                            portalPreferences, layoutSetBranchId, plid, layoutBranchId);
2666            }
2667    
2668            protected String stripProtocolFromRemoteAddress(String remoteAddress) {
2669                    if (remoteAddress.startsWith(Http.HTTP_WITH_SLASH)) {
2670                            remoteAddress = remoteAddress.substring(
2671                                    Http.HTTP_WITH_SLASH.length());
2672                    }
2673                    else if (remoteAddress.startsWith(Http.HTTPS_WITH_SLASH)) {
2674                            remoteAddress = remoteAddress.substring(
2675                                    Http.HTTPS_WITH_SLASH.length());
2676                    }
2677    
2678                    return remoteAddress;
2679            }
2680    
2681            protected void updateGroupTypeSettingsProperties(
2682                            Group group, String remoteAddress, int remotePort,
2683                            String remotePathContext, boolean secureConnection,
2684                            long remoteGroupId)
2685                    throws Exception {
2686    
2687                    UnicodeProperties typeSettingsProperties =
2688                            group.getTypeSettingsProperties();
2689    
2690                    typeSettingsProperties.setProperty("remoteAddress", remoteAddress);
2691                    typeSettingsProperties.setProperty(
2692                            "remoteGroupId", String.valueOf(remoteGroupId));
2693                    typeSettingsProperties.setProperty(
2694                            "remotePathContext", remotePathContext);
2695                    typeSettingsProperties.setProperty(
2696                            "remotePort", String.valueOf(remotePort));
2697                    typeSettingsProperties.setProperty(
2698                            "secureConnection", String.valueOf(secureConnection));
2699    
2700                    group.setTypeSettingsProperties(typeSettingsProperties);
2701    
2702                    GroupLocalServiceUtil.updateGroup(group);
2703            }
2704    
2705            private long getRecentLayoutAttribute(
2706                            PortalPreferences portalPreferences, String key)
2707                    throws JSONException {
2708    
2709                    String preferencesString = portalPreferences.getValue(
2710                            Staging.class.getName(),
2711                            StagingConstants.STAGING_RECENT_LAYOUT_IDS_MAP);
2712    
2713                    JSONArray jsonArray = JSONFactoryUtil.createJSONArray(
2714                            preferencesString);
2715    
2716                    for (int i = 0; i < jsonArray.length(); i++) {
2717                            JSONObject jsonObject = jsonArray.getJSONObject(i);
2718    
2719                            if (jsonObject.has(key)) {
2720                                    return GetterUtil.getLong(jsonObject.getString(key));
2721                            }
2722                    }
2723    
2724                    return 0;
2725            }
2726    
2727            private void setRecentLayoutAttribute(
2728                            PortalPreferences portalPreferences, String key, long value)
2729                    throws JSONException {
2730    
2731                    String oldPortalPreferences = portalPreferences.getValue(
2732                            Staging.class.getName(),
2733                            StagingConstants.STAGING_RECENT_LAYOUT_IDS_MAP);
2734    
2735                    JSONArray oldJsonArray = JSONFactoryUtil.createJSONArray(
2736                            oldPortalPreferences);
2737    
2738                    boolean alreadyExists = false;
2739    
2740                    JSONArray jsonArray = JSONFactoryUtil.createJSONArray();
2741    
2742                    for (int i = 0; i < oldJsonArray.length(); i++) {
2743                            JSONObject jsonObject = oldJsonArray.getJSONObject(i);
2744    
2745                            if (Validator.isNotNull(jsonObject.getString(key))) {
2746                                    alreadyExists = true;
2747    
2748                                    jsonObject.remove(key);
2749    
2750                                    jsonObject.put(key, String.valueOf(value));
2751                            }
2752    
2753                            jsonArray.put(jsonObject);
2754                    }
2755    
2756                    if (!alreadyExists) {
2757                            JSONObject jsonObject = JSONFactoryUtil.createJSONObject();
2758    
2759                            jsonObject.put(key, String.valueOf(value));
2760    
2761                            jsonArray.put(jsonObject);
2762                    }
2763    
2764                    portalPreferences.setValue(
2765                            Staging.class.getName(),
2766                            StagingConstants.STAGING_RECENT_LAYOUT_IDS_MAP,
2767                            jsonArray.toString());
2768            }
2769    
2770            private static final String _LAST_PUBLISH_DATE = "last-publish-date";
2771    
2772            private static Log _log = LogFactoryUtil.getLog(StagingImpl.class);
2773    
2774    }