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