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