001    /**
002     * Copyright (c) 2000-2012 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.LayoutSetBranchNameException;
019    import com.liferay.portal.NoSuchGroupException;
020    import com.liferay.portal.NoSuchLayoutBranchException;
021    import com.liferay.portal.NoSuchLayoutException;
022    import com.liferay.portal.NoSuchLayoutRevisionException;
023    import com.liferay.portal.RemoteExportException;
024    import com.liferay.portal.RemoteOptionsException;
025    import com.liferay.portal.kernel.exception.PortalException;
026    import com.liferay.portal.kernel.exception.SystemException;
027    import com.liferay.portal.kernel.language.LanguageUtil;
028    import com.liferay.portal.kernel.lar.PortletDataContext;
029    import com.liferay.portal.kernel.lar.PortletDataHandlerKeys;
030    import com.liferay.portal.kernel.lar.UserIdStrategy;
031    import com.liferay.portal.kernel.messaging.DestinationNames;
032    import com.liferay.portal.kernel.messaging.MessageBusUtil;
033    import com.liferay.portal.kernel.messaging.MessageStatus;
034    import com.liferay.portal.kernel.scheduler.SchedulerEngineHelperUtil;
035    import com.liferay.portal.kernel.staging.LayoutStagingUtil;
036    import com.liferay.portal.kernel.staging.Staging;
037    import com.liferay.portal.kernel.staging.StagingConstants;
038    import com.liferay.portal.kernel.util.CalendarFactoryUtil;
039    import com.liferay.portal.kernel.util.GetterUtil;
040    import com.liferay.portal.kernel.util.Http;
041    import com.liferay.portal.kernel.util.LocaleUtil;
042    import com.liferay.portal.kernel.util.MapUtil;
043    import com.liferay.portal.kernel.util.ParamUtil;
044    import com.liferay.portal.kernel.util.StringBundler;
045    import com.liferay.portal.kernel.util.StringPool;
046    import com.liferay.portal.kernel.util.Time;
047    import com.liferay.portal.kernel.util.TimeZoneUtil;
048    import com.liferay.portal.kernel.util.UnicodeProperties;
049    import com.liferay.portal.kernel.util.Validator;
050    import com.liferay.portal.kernel.workflow.WorkflowConstants;
051    import com.liferay.portal.kernel.workflow.WorkflowTask;
052    import com.liferay.portal.kernel.workflow.WorkflowTaskManagerUtil;
053    import com.liferay.portal.kernel.xml.Element;
054    import com.liferay.portal.lar.LayoutExporter;
055    import com.liferay.portal.messaging.LayoutsLocalPublisherRequest;
056    import com.liferay.portal.messaging.LayoutsRemotePublisherRequest;
057    import com.liferay.portal.model.Group;
058    import com.liferay.portal.model.GroupConstants;
059    import com.liferay.portal.model.Layout;
060    import com.liferay.portal.model.LayoutBranch;
061    import com.liferay.portal.model.LayoutRevision;
062    import com.liferay.portal.model.LayoutSet;
063    import com.liferay.portal.model.LayoutSetBranch;
064    import com.liferay.portal.model.LayoutSetBranchConstants;
065    import com.liferay.portal.model.Lock;
066    import com.liferay.portal.model.Portlet;
067    import com.liferay.portal.model.User;
068    import com.liferay.portal.model.WorkflowInstanceLink;
069    import com.liferay.portal.security.auth.HttpPrincipal;
070    import com.liferay.portal.security.auth.PrincipalException;
071    import com.liferay.portal.security.permission.ActionKeys;
072    import com.liferay.portal.security.permission.PermissionChecker;
073    import com.liferay.portal.security.permission.PermissionThreadLocal;
074    import com.liferay.portal.service.GroupLocalServiceUtil;
075    import com.liferay.portal.service.LayoutBranchLocalServiceUtil;
076    import com.liferay.portal.service.LayoutLocalServiceUtil;
077    import com.liferay.portal.service.LayoutRevisionLocalServiceUtil;
078    import com.liferay.portal.service.LayoutServiceUtil;
079    import com.liferay.portal.service.LayoutSetBranchLocalServiceUtil;
080    import com.liferay.portal.service.LayoutSetLocalServiceUtil;
081    import com.liferay.portal.service.LockLocalServiceUtil;
082    import com.liferay.portal.service.ServiceContext;
083    import com.liferay.portal.service.ServiceContextThreadLocal;
084    import com.liferay.portal.service.WorkflowInstanceLinkLocalServiceUtil;
085    import com.liferay.portal.service.http.GroupServiceHttp;
086    import com.liferay.portal.service.http.LayoutServiceHttp;
087    import com.liferay.portal.service.permission.GroupPermissionUtil;
088    import com.liferay.portal.theme.ThemeDisplay;
089    import com.liferay.portal.util.PortalUtil;
090    import com.liferay.portal.util.PropsValues;
091    import com.liferay.portal.util.SessionClicks;
092    import com.liferay.portal.util.WebKeys;
093    import com.liferay.portlet.PortalPreferences;
094    import com.liferay.portlet.PortletPreferencesFactoryUtil;
095    
096    import java.io.File;
097    
098    import java.util.ArrayList;
099    import java.util.Calendar;
100    import java.util.Date;
101    import java.util.HashSet;
102    import java.util.LinkedHashMap;
103    import java.util.List;
104    import java.util.Locale;
105    import java.util.Map;
106    import java.util.Set;
107    import java.util.TimeZone;
108    
109    import javax.portlet.PortletRequest;
110    
111    import javax.servlet.http.HttpServletRequest;
112    
113    /**
114     * @author Raymond Augé
115     * @author Bruno Farache
116     * @author Wesley Gong
117     * @author Zsolt Balogh
118     */
119    public class StagingImpl implements Staging {
120    
121            public String buildRemoteURL(
122                    String remoteAddress, int remotePort, String remotePathContext,
123                    boolean secureConnection, long remoteGroupId, boolean privateLayout) {
124    
125                    StringBundler sb = new StringBundler((remoteGroupId > 0) ? 4 : 9);
126    
127                    if (secureConnection) {
128                            sb.append(Http.HTTPS_WITH_SLASH);
129                    }
130                    else {
131                            sb.append(Http.HTTP_WITH_SLASH);
132                    }
133    
134                    sb.append(remoteAddress);
135    
136                    if (remotePort > 0) {
137                            sb.append(StringPool.COLON);
138                            sb.append(remotePort);
139                    }
140    
141                    if (Validator.isNotNull(remotePathContext)) {
142                            sb.append(remotePathContext);
143                    }
144    
145                    if (remoteGroupId > 0) {
146                            sb.append("/c/my_sites/view?");
147                            sb.append("groupId=");
148                            sb.append(remoteGroupId);
149                            sb.append("&privateLayout=");
150                            sb.append(privateLayout);
151                    }
152    
153                    return sb.toString();
154            }
155    
156            public void copyFromLive(PortletRequest portletRequest) throws Exception {
157                    long stagingGroupId = ParamUtil.getLong(
158                            portletRequest, "stagingGroupId");
159    
160                    Group stagingGroup = GroupLocalServiceUtil.getGroup(stagingGroupId);
161    
162                    long liveGroupId = stagingGroup.getLiveGroupId();
163    
164                    Map<String, String[]> parameterMap = getStagingParameters(
165                            portletRequest);
166    
167                    publishLayouts(
168                            portletRequest, liveGroupId, stagingGroupId, parameterMap, false);
169            }
170    
171            public void copyFromLive(PortletRequest portletRequest, Portlet portlet)
172                    throws Exception {
173    
174                    long plid = ParamUtil.getLong(portletRequest, "plid");
175    
176                    Layout targetLayout = LayoutLocalServiceUtil.getLayout(plid);
177    
178                    Group stagingGroup = targetLayout.getGroup();
179                    Group liveGroup = stagingGroup.getLiveGroup();
180    
181                    Layout sourceLayout = LayoutLocalServiceUtil.getLayoutByUuidAndGroupId(
182                            targetLayout.getUuid(), liveGroup.getGroupId());
183    
184                    copyPortlet(
185                            portletRequest, liveGroup.getGroupId(), stagingGroup.getGroupId(),
186                            sourceLayout.getPlid(), targetLayout.getPlid(),
187                            portlet.getPortletId());
188            }
189    
190            public void copyPortlet(
191                            PortletRequest portletRequest, long sourceGroupId,
192                            long targetGroupId, long sourcePlid, long targetPlid,
193                            String portletId)
194                    throws Exception {
195    
196                    long userId = PortalUtil.getUserId(portletRequest);
197    
198                    Map<String, String[]> parameterMap = getStagingParameters(
199                            portletRequest);
200    
201                    File file = LayoutLocalServiceUtil.exportPortletInfoAsFile(
202                            sourcePlid, sourceGroupId, portletId, parameterMap, null, null);
203    
204                    try {
205                            LayoutLocalServiceUtil.importPortletInfo(
206                                    userId, targetPlid, targetGroupId, portletId, parameterMap,
207                                    file);
208                    }
209                    finally {
210                            file.delete();
211                    }
212            }
213    
214            public void copyRemoteLayouts(
215                            long sourceGroupId, boolean privateLayout,
216                            Map<Long, Boolean> layoutIdMap, Map<String, String[]> parameterMap,
217                            String remoteAddress, int remotePort, String remotePathContext,
218                            boolean secureConnection, long remoteGroupId,
219                            boolean remotePrivateLayout, Date startDate, Date endDate)
220                    throws Exception {
221    
222                    PermissionChecker permissionChecker =
223                            PermissionThreadLocal.getPermissionChecker();
224    
225                    User user = permissionChecker.getUser();
226    
227                    StringBundler sb = new StringBundler(4);
228    
229                    if (secureConnection) {
230                            sb.append(Http.HTTPS_WITH_SLASH);
231                    }
232                    else {
233                            sb.append(Http.HTTP_WITH_SLASH);
234                    }
235    
236                    sb.append(remoteAddress);
237                    sb.append(StringPool.COLON);
238                    sb.append(remotePort);
239                    sb.append(remotePathContext);
240    
241                    String url = sb.toString();
242    
243                    HttpPrincipal httpPrincipal = new HttpPrincipal(
244                            url, user.getEmailAddress(), user.getPassword(),
245                            user.getPasswordEncrypted());
246    
247                    // Ping remote host and verify that the group exists
248    
249                    try {
250                            GroupServiceHttp.getGroup(httpPrincipal, remoteGroupId);
251                    }
252                    catch (NoSuchGroupException nsge) {
253                            RemoteExportException ree = new RemoteExportException(
254                                    RemoteExportException.NO_GROUP);
255    
256                            ree.setGroupId(remoteGroupId);
257    
258                            throw ree;
259                    }
260                    catch (SystemException se) {
261                            RemoteExportException ree = new RemoteExportException(
262                                    RemoteExportException.BAD_CONNECTION);
263    
264                            ree.setURL(url);
265    
266                            throw ree;
267                    }
268    
269                    byte[] bytes = null;
270    
271                    if (layoutIdMap == null) {
272                            bytes = LayoutLocalServiceUtil.exportLayouts(
273                                    sourceGroupId, privateLayout, parameterMap, startDate, endDate);
274                    }
275                    else {
276                            List<Layout> layouts = new ArrayList<Layout>();
277    
278                            for (Map.Entry<Long, Boolean> entry : layoutIdMap.entrySet()) {
279                                    long plid = GetterUtil.getLong(String.valueOf(entry.getKey()));
280                                    boolean includeChildren = entry.getValue();
281    
282                                    Layout layout = LayoutLocalServiceUtil.getLayout(plid);
283    
284                                    if (!layouts.contains(layout)) {
285                                            layouts.add(layout);
286                                    }
287    
288                                    List<Layout> parentLayouts = getMissingParentLayouts(
289                                            layout, sourceGroupId);
290    
291                                    for (Layout parentLayout : parentLayouts) {
292                                            if (!layouts.contains(parentLayout)) {
293                                                    layouts.add(parentLayout);
294                                            }
295                                    }
296    
297                                    if (includeChildren) {
298                                            for (Layout childLayout : layout.getAllChildren()) {
299                                                    if (!layouts.contains(childLayout)) {
300                                                            layouts.add(childLayout);
301                                                    }
302                                            }
303                                    }
304                            }
305    
306                            long[] layoutIds = getLayoutIds(layouts);
307    
308                            if (layoutIds.length <= 0) {
309                                    throw new RemoteExportException(
310                                            RemoteExportException.NO_LAYOUTS);
311                            }
312    
313                            bytes = LayoutLocalServiceUtil.exportLayouts(
314                                    sourceGroupId, privateLayout, layoutIds, parameterMap,
315                                    startDate, endDate);
316                    }
317    
318                    LayoutServiceHttp.importLayouts(
319                            httpPrincipal, remoteGroupId, remotePrivateLayout, parameterMap,
320                            bytes);
321            }
322    
323            public void deleteLastImportSettings(Group liveGroup, boolean privateLayout)
324                    throws Exception {
325    
326                    List<Layout> layouts = LayoutLocalServiceUtil.getLayouts(
327                            liveGroup.getGroupId(), privateLayout);
328    
329                    for (Layout layout : layouts) {
330                            UnicodeProperties typeSettingsProperties =
331                                    layout.getTypeSettingsProperties();
332    
333                            Set<String> keys = new HashSet<String>();
334    
335                            for (String key : typeSettingsProperties.keySet()) {
336                                    if (key.startsWith("last-import-")) {
337                                            keys.add(key);
338                                    }
339                            }
340    
341                            if (keys.isEmpty()) {
342                                    continue;
343                            }
344    
345                            for (String key : keys) {
346                                    typeSettingsProperties.remove(key);
347                            }
348    
349                            LayoutLocalServiceUtil.updateLayout(
350                                    layout.getGroupId(), layout.getPrivateLayout(),
351                                    layout.getLayoutId(), typeSettingsProperties.toString());
352                    }
353            }
354    
355            public void deleteRecentLayoutRevisionId(
356                            HttpServletRequest request, long layoutSetBranchId, long plid)
357                    throws SystemException {
358    
359                    PortalPreferences portalPreferences =
360                            PortletPreferencesFactoryUtil.getPortalPreferences(request);
361    
362                    deleteRecentLayoutRevisionId(
363                            portalPreferences, layoutSetBranchId, plid);
364            }
365    
366            public void deleteRecentLayoutRevisionId(
367                            User user, long layoutSetBranchId, long plid)
368                    throws SystemException {
369    
370                    PortalPreferences portalPreferences = getPortalPreferences(user);
371    
372                    deleteRecentLayoutRevisionId(
373                            portalPreferences, layoutSetBranchId, plid);
374            }
375    
376            @Deprecated
377            public void disableStaging(
378                            Group scopeGroup, Group liveGroup, ServiceContext serviceContext)
379                    throws Exception {
380    
381                    disableStaging((PortletRequest)null, liveGroup, serviceContext);
382            }
383    
384            public void disableStaging(Group liveGroup, ServiceContext serviceContext)
385                    throws Exception {
386    
387                    disableStaging((PortletRequest)null, liveGroup, serviceContext);
388            }
389    
390            @Deprecated
391            public void disableStaging(
392                            PortletRequest portletRequest, Group scopeGroup, Group liveGroup,
393                            ServiceContext serviceContext)
394                    throws Exception {
395    
396                    disableStaging(portletRequest, liveGroup, serviceContext);
397            }
398    
399            public void disableStaging(
400                            PortletRequest portletRequest, Group liveGroup,
401                            ServiceContext serviceContext)
402                    throws Exception {
403    
404                    UnicodeProperties typeSettingsProperties =
405                            liveGroup.getTypeSettingsProperties();
406    
407                    typeSettingsProperties.remove("branchingPrivate");
408                    typeSettingsProperties.remove("branchingPublic");
409                    typeSettingsProperties.remove("remoteAddress");
410                    typeSettingsProperties.remove("remoteGroupId");
411                    typeSettingsProperties.remove("remotePathContext");
412                    typeSettingsProperties.remove("remotePort");
413                    typeSettingsProperties.remove("secureConnection");
414                    typeSettingsProperties.remove("staged");
415                    typeSettingsProperties.remove("stagedRemotely");
416    
417                    Set<String> keys = new HashSet<String>();
418    
419                    for (String key : typeSettingsProperties.keySet()) {
420                            if (key.startsWith(StagingConstants.STAGED_PORTLET)) {
421                                    keys.add(key);
422                            }
423                    }
424    
425                    for (String key : keys) {
426                            typeSettingsProperties.remove(key);
427                    }
428    
429                    deleteLastImportSettings(liveGroup, true);
430                    deleteLastImportSettings(liveGroup, false);
431    
432                    if (liveGroup.hasStagingGroup()) {
433                            Group stagingGroup = liveGroup.getStagingGroup();
434    
435                            LayoutSetBranchLocalServiceUtil.deleteLayoutSetBranches(
436                                    stagingGroup.getGroupId(), true, true);
437                            LayoutSetBranchLocalServiceUtil.deleteLayoutSetBranches(
438                                    stagingGroup.getGroupId(), false, true);
439    
440                            GroupLocalServiceUtil.deleteGroup(stagingGroup.getGroupId());
441                    }
442                    else {
443                            LayoutSetBranchLocalServiceUtil.deleteLayoutSetBranches(
444                                    liveGroup.getGroupId(), true, true);
445                            LayoutSetBranchLocalServiceUtil.deleteLayoutSetBranches(
446                                    liveGroup.getGroupId(), false, true);
447                    }
448    
449                    GroupLocalServiceUtil.updateGroup(
450                            liveGroup.getGroupId(), typeSettingsProperties.toString());
451            }
452    
453            public void enableLocalStaging(
454                            long userId, Group scopeGroup, Group liveGroup,
455                            boolean branchingPublic, boolean branchingPrivate,
456                            ServiceContext serviceContext)
457                    throws Exception {
458    
459                    if (liveGroup.isStagedRemotely()) {
460                            disableStaging(liveGroup, serviceContext);
461                    }
462    
463                    UnicodeProperties typeSettingsProperties =
464                            liveGroup.getTypeSettingsProperties();
465    
466                    typeSettingsProperties.setProperty(
467                            "branchingPrivate", String.valueOf(branchingPrivate));
468                    typeSettingsProperties.setProperty(
469                            "branchingPublic", String.valueOf(branchingPublic));
470                    typeSettingsProperties.setProperty("staged", Boolean.TRUE.toString());
471                    typeSettingsProperties.setProperty(
472                            "stagedRemotely", String.valueOf(false));
473    
474                    setCommonStagingOptions(
475                            liveGroup, typeSettingsProperties, serviceContext);
476    
477                    if (!liveGroup.hasStagingGroup()) {
478                            serviceContext.setAttribute("staging", String.valueOf(true));
479    
480                            Group stagingGroup = GroupLocalServiceUtil.addGroup(
481                                    userId, GroupConstants.DEFAULT_PARENT_GROUP_ID,
482                                    liveGroup.getClassName(), liveGroup.getClassPK(),
483                                    liveGroup.getGroupId(), liveGroup.getDescriptiveName(),
484                                    liveGroup.getDescription(), liveGroup.getType(),
485                                    liveGroup.getFriendlyURL(), false, liveGroup.isActive(),
486                                    serviceContext);
487    
488                            GroupLocalServiceUtil.updateGroup(
489                                    liveGroup.getGroupId(), typeSettingsProperties.toString());
490    
491                            if (liveGroup.hasPrivateLayouts()) {
492                                    Map<String, String[]> parameterMap = getStagingParameters();
493    
494                                    publishLayouts(
495                                            userId, liveGroup.getGroupId(), stagingGroup.getGroupId(),
496                                            true, parameterMap, null, null);
497                            }
498    
499                            if (liveGroup.hasPublicLayouts()) {
500                                    Map<String, String[]> parameterMap = getStagingParameters();
501    
502                                    publishLayouts(
503                                            userId, liveGroup.getGroupId(), stagingGroup.getGroupId(),
504                                            false, parameterMap, null, null);
505                            }
506    
507                            checkDefaultLayoutSetBranches(
508                                    userId, liveGroup, branchingPublic, branchingPrivate, false,
509                                    serviceContext);
510                    }
511                    else {
512                            GroupLocalServiceUtil.updateGroup(
513                                    liveGroup.getGroupId(), typeSettingsProperties.toString());
514    
515                            checkDefaultLayoutSetBranches(
516                                    userId, liveGroup, branchingPublic, branchingPrivate, false,
517                                    serviceContext);
518    
519                            if (!branchingPublic) {
520                                    LayoutSetBranchLocalServiceUtil.deleteLayoutSetBranches(
521                                            liveGroup.getStagingGroup().getGroupId(), false, true);
522                            }
523    
524                            if (!branchingPrivate) {
525                                    LayoutSetBranchLocalServiceUtil.deleteLayoutSetBranches(
526                                            liveGroup.getStagingGroup().getGroupId(), true, true);
527                            }
528                    }
529            }
530    
531            public void enableRemoteStaging(
532                            long userId, Group scopeGroup, Group liveGroup,
533                            boolean branchingPublic, boolean branchingPrivate,
534                            String remoteAddress, int remotePort, String remotePathContext,
535                            boolean secureConnection, long remoteGroupId,
536                            ServiceContext serviceContext)
537                    throws Exception {
538    
539                    validate(
540                            remoteAddress, remotePort, remotePathContext, secureConnection,
541                            remoteGroupId);
542    
543                    if (liveGroup.hasStagingGroup()) {
544                            disableStaging(liveGroup, serviceContext);
545                    }
546    
547                    UnicodeProperties typeSettingsProperties =
548                            liveGroup.getTypeSettingsProperties();
549    
550                    typeSettingsProperties.setProperty(
551                            "branchingPrivate", String.valueOf(branchingPrivate));
552                    typeSettingsProperties.setProperty(
553                            "branchingPublic", String.valueOf(branchingPublic));
554                    typeSettingsProperties.setProperty("remoteAddress", remoteAddress);
555                    typeSettingsProperties.setProperty(
556                            "remoteGroupId", String.valueOf(remoteGroupId));
557                    typeSettingsProperties.setProperty(
558                            "remotePathContext", remotePathContext);
559                    typeSettingsProperties.setProperty(
560                            "remotePort", String.valueOf(remotePort));
561                    typeSettingsProperties.setProperty(
562                            "secureConnection", String.valueOf(secureConnection));
563                    typeSettingsProperties.setProperty("staged", Boolean.TRUE.toString());
564                    typeSettingsProperties.setProperty(
565                            "stagedRemotely", Boolean.TRUE.toString());
566    
567                    setCommonStagingOptions(
568                            liveGroup, typeSettingsProperties, serviceContext);
569    
570                    GroupLocalServiceUtil.updateGroup(
571                            liveGroup.getGroupId(), typeSettingsProperties.toString());
572    
573                    checkDefaultLayoutSetBranches(
574                            userId, liveGroup, branchingPublic, branchingPrivate, true,
575                            serviceContext);
576            }
577    
578            public Group getLiveGroup(long groupId)
579                    throws PortalException, SystemException {
580    
581                    if (groupId == 0) {
582                            return null;
583                    }
584    
585                    Group group = GroupLocalServiceUtil.getGroup(groupId);
586    
587                    if (group.isLayout()) {
588                            group = group.getParentGroup();
589                    }
590    
591                    if (group.isStagingGroup()) {
592                            return group.getLiveGroup();
593                    }
594                    else {
595                            return group;
596                    }
597            }
598    
599            public long getLiveGroupId(long groupId)
600                    throws PortalException, SystemException {
601    
602                    if (groupId == 0) {
603                            return groupId;
604                    }
605    
606                    Group group = getLiveGroup(groupId);
607    
608                    return group.getGroupId();
609            }
610    
611            public List<Layout> getMissingParentLayouts(Layout layout, long liveGroupId)
612                    throws Exception {
613    
614                    List<Layout> missingParentLayouts = new ArrayList<Layout>();
615    
616                    long parentLayoutId = layout.getParentLayoutId();
617    
618                    Layout parentLayout = null;
619    
620                    while (parentLayoutId > 0) {
621                            parentLayout = LayoutLocalServiceUtil.getLayout(
622                                    layout.getGroupId(), layout.isPrivateLayout(), parentLayoutId);
623    
624                            try {
625                                    LayoutLocalServiceUtil.getLayoutByUuidAndGroupId(
626                                            parentLayout.getUuid(), liveGroupId);
627    
628                                    // If one parent is found all others are assumed to exist
629    
630                                    break;
631                            }
632                            catch (NoSuchLayoutException nsle) {
633                                    missingParentLayouts.add(parentLayout);
634    
635                                    parentLayoutId = parentLayout.getParentLayoutId();
636                            }
637                    }
638    
639                    return missingParentLayouts;
640            }
641    
642            public long getRecentLayoutRevisionId(
643                            HttpServletRequest request, long layoutSetBranchId, long plid)
644                    throws PortalException, SystemException {
645    
646                    PortalPreferences portalPreferences =
647                            PortletPreferencesFactoryUtil.getPortalPreferences(request);
648    
649                    return getRecentLayoutRevisionId(
650                            portalPreferences, layoutSetBranchId, plid);
651            }
652    
653            public long getRecentLayoutRevisionId(
654                            User user, long layoutSetBranchId, long plid)
655                    throws PortalException, SystemException {
656    
657                    PortalPreferences portalPreferences = getPortalPreferences(user);
658    
659                    return getRecentLayoutRevisionId(
660                            portalPreferences, layoutSetBranchId, plid);
661            }
662    
663            public long getRecentLayoutSetBranchId(
664                    HttpServletRequest request, long layoutSetId) {
665    
666                    return GetterUtil.getLong(
667                            SessionClicks.get(
668                                    request, Staging.class.getName(),
669                                    getRecentLayoutSetBranchIdKey(layoutSetId)));
670            }
671    
672            public long getRecentLayoutSetBranchId(User user, long layoutSetId)
673                    throws SystemException {
674    
675                    PortalPreferences portalPreferences = getPortalPreferences(user);
676    
677                    return GetterUtil.getLong(
678                            portalPreferences.getValue(
679                                    Staging.class.getName(),
680                                    getRecentLayoutSetBranchIdKey(layoutSetId)));
681            }
682    
683            public String getSchedulerGroupName(String destinationName, long groupId) {
684                    return destinationName.concat(StringPool.SLASH).concat(
685                            String.valueOf(groupId));
686            }
687    
688            public Map<String, String[]> getStagingParameters() {
689                    Map<String, String[]> parameterMap =
690                            new LinkedHashMap<String, String[]>();
691    
692                    parameterMap.put(
693                            PortletDataHandlerKeys.CATEGORIES,
694                            new String[] {Boolean.TRUE.toString()});
695                    parameterMap.put(
696                            PortletDataHandlerKeys.DATA_STRATEGY,
697                            new String[] {
698                                    PortletDataHandlerKeys.DATA_STRATEGY_MIRROR_OVERWRITE});
699                    parameterMap.put(
700                            PortletDataHandlerKeys.DELETE_MISSING_LAYOUTS,
701                            new String[] {Boolean.TRUE.toString()});
702                    parameterMap.put(
703                            PortletDataHandlerKeys.DELETE_PORTLET_DATA,
704                            new String[] {Boolean.FALSE.toString()});
705                    parameterMap.put(
706                            PortletDataHandlerKeys.IGNORE_LAST_PUBLISH_DATE,
707                            new String[] {Boolean.TRUE.toString()});
708                    parameterMap.put(
709                            PortletDataHandlerKeys.LAYOUT_SET_PROTOTYPE_LINK_ENABLED,
710                            new String[] {Boolean.FALSE.toString()});
711                    parameterMap.put(
712                            PortletDataHandlerKeys.LAYOUT_SET_SETTINGS,
713                            new String[] {Boolean.FALSE.toString()});
714                    parameterMap.put(
715                            PortletDataHandlerKeys.LOGO,
716                            new String[] {Boolean.FALSE.toString()});
717                    parameterMap.put(
718                            PortletDataHandlerKeys.PERMISSIONS,
719                            new String[] {Boolean.TRUE.toString()});
720                    parameterMap.put(
721                            PortletDataHandlerKeys.PORTLET_DATA,
722                            new String[] {Boolean.TRUE.toString()});
723                    parameterMap.put(
724                            PortletDataHandlerKeys.PORTLET_DATA_ALL,
725                            new String[] {Boolean.TRUE.toString()});
726                    parameterMap.put(
727                            PortletDataHandlerKeys.PORTLET_SETUP,
728                            new String[] {Boolean.TRUE.toString()});
729                    parameterMap.put(
730                            PortletDataHandlerKeys.PORTLET_USER_PREFERENCES,
731                            new String[] {Boolean.TRUE.toString()});
732                    parameterMap.put(
733                            PortletDataHandlerKeys.THEME,
734                            new String[] {Boolean.FALSE.toString()});
735                    parameterMap.put(
736                            PortletDataHandlerKeys.THEME_REFERENCE,
737                            new String[] {Boolean.TRUE.toString()});
738                    parameterMap.put(
739                            PortletDataHandlerKeys.UPDATE_LAST_PUBLISH_DATE,
740                            new String[] {Boolean.TRUE.toString()});
741                    parameterMap.put(
742                            PortletDataHandlerKeys.USER_ID_STRATEGY,
743                            new String[] {UserIdStrategy.CURRENT_USER_ID});
744    
745                    return parameterMap;
746            }
747    
748            public Map<String, String[]> getStagingParameters(
749                    PortletRequest portletRequest) {
750    
751                    Map<String, String[]> parameterMap =
752                            new LinkedHashMap<String, String[]>(
753                                    portletRequest.getParameterMap());
754    
755                    if (!parameterMap.containsKey(PortletDataHandlerKeys.DATA_STRATEGY)) {
756                            parameterMap.put(
757                                    PortletDataHandlerKeys.DATA_STRATEGY,
758                                    new String[] {
759                                            PortletDataHandlerKeys.DATA_STRATEGY_MIRROR_OVERWRITE});
760                    }
761    
762                    /*if (!parameterMap.containsKey(
763                                    PortletDataHandlerKeys.DELETE_MISSING_LAYOUTS)) {
764    
765                            parameterMap.put(
766                                    PortletDataHandlerKeys.DELETE_MISSING_LAYOUTS,
767                                    new String[] {Boolean.TRUE.toString()});
768                    }*/
769    
770                    if (!parameterMap.containsKey(
771                                    PortletDataHandlerKeys.DELETE_PORTLET_DATA)) {
772    
773                            parameterMap.put(
774                                    PortletDataHandlerKeys.DELETE_PORTLET_DATA,
775                                    new String[] {Boolean.FALSE.toString()});
776                    }
777    
778                    if (!parameterMap.containsKey(
779                                    PortletDataHandlerKeys.LAYOUT_SET_PROTOTYPE_LINK_ENABLED)) {
780    
781                            parameterMap.put(
782                                    PortletDataHandlerKeys.LAYOUT_SET_PROTOTYPE_LINK_ENABLED,
783                                    new String[] {Boolean.FALSE.toString()});
784                    }
785    
786                    if (!parameterMap.containsKey(
787                                    PortletDataHandlerKeys.LAYOUT_SET_SETTINGS)) {
788    
789                            parameterMap.put(
790                                    PortletDataHandlerKeys.LAYOUT_SET_SETTINGS,
791                                    new String[] {Boolean.FALSE.toString()});
792                    }
793    
794                    if (!parameterMap.containsKey(PortletDataHandlerKeys.LOGO)) {
795                            parameterMap.put(
796                                    PortletDataHandlerKeys.LOGO,
797                                    new String[] {Boolean.FALSE.toString()});
798                    }
799    
800                    if (!parameterMap.containsKey(PortletDataHandlerKeys.PORTLET_DATA)) {
801                            parameterMap.put(
802                                    PortletDataHandlerKeys.PORTLET_DATA,
803                                    new String[] {Boolean.FALSE.toString()});
804                    }
805    
806                    if (!parameterMap.containsKey(
807                                    PortletDataHandlerKeys.PORTLET_DATA_ALL)) {
808    
809                            parameterMap.put(
810                                    PortletDataHandlerKeys.PORTLET_DATA_ALL,
811                                    new String[] {Boolean.FALSE.toString()});
812                    }
813    
814                    if (!parameterMap.containsKey(PortletDataHandlerKeys.PORTLET_SETUP)) {
815                            parameterMap.put(
816                                    PortletDataHandlerKeys.PORTLET_SETUP,
817                                    new String[] {Boolean.TRUE.toString()});
818                    }
819    
820                    if (!parameterMap.containsKey(
821                                    PortletDataHandlerKeys.PORTLET_USER_PREFERENCES)) {
822    
823                            parameterMap.put(
824                                    PortletDataHandlerKeys.PORTLET_USER_PREFERENCES,
825                                    new String[] {Boolean.TRUE.toString()});
826                    }
827    
828                    if (!parameterMap.containsKey(PortletDataHandlerKeys.THEME)) {
829                            parameterMap.put(
830                                    PortletDataHandlerKeys.THEME,
831                                    new String[] {Boolean.FALSE.toString()});
832                    }
833    
834                    if (!parameterMap.containsKey(PortletDataHandlerKeys.THEME_REFERENCE)) {
835                            parameterMap.put(
836                                    PortletDataHandlerKeys.THEME_REFERENCE,
837                                    new String[] {Boolean.FALSE.toString()});
838                    }
839    
840                    if (!parameterMap.containsKey(
841                                    PortletDataHandlerKeys.UPDATE_LAST_PUBLISH_DATE)) {
842    
843                            parameterMap.put(
844                                    PortletDataHandlerKeys.UPDATE_LAST_PUBLISH_DATE,
845                                    new String[] {Boolean.TRUE.toString()});
846                    }
847    
848                    if (!parameterMap.containsKey(
849                                    PortletDataHandlerKeys.USER_ID_STRATEGY)) {
850    
851                            parameterMap.put(
852                                    PortletDataHandlerKeys.USER_ID_STRATEGY,
853                                    new String[] {UserIdStrategy.CURRENT_USER_ID});
854                    }
855    
856                    return parameterMap;
857            }
858    
859            public WorkflowTask getWorkflowTask(
860                            long userId, LayoutRevision layoutRevision)
861                    throws PortalException, SystemException {
862    
863                    WorkflowInstanceLink workflowInstanceLink =
864                            WorkflowInstanceLinkLocalServiceUtil.fetchWorkflowInstanceLink(
865                                    layoutRevision.getCompanyId(), layoutRevision.getGroupId(),
866                                    LayoutRevision.class.getName(),
867                                    layoutRevision.getLayoutRevisionId());
868    
869                    if (workflowInstanceLink == null) {
870                            return null;
871                    }
872    
873                    List<WorkflowTask> workflowTasks =
874                            WorkflowTaskManagerUtil.getWorkflowTasksByWorkflowInstance(
875                                    layoutRevision.getCompanyId(), userId,
876                                    workflowInstanceLink.getWorkflowInstanceId(), false, 0, 1,
877                                    null);
878    
879                    if (!workflowTasks.isEmpty()) {
880                            return workflowTasks.get(0);
881                    }
882    
883                    return null;
884            }
885    
886            public boolean hasWorkflowTask(long userId, LayoutRevision layoutRevision)
887                    throws PortalException, SystemException {
888    
889                    WorkflowTask workflowTask = getWorkflowTask(userId, layoutRevision);
890    
891                    if (workflowTask != null) {
892                            return true;
893                    }
894    
895                    return false;
896            }
897    
898            public boolean isIncomplete(Layout layout, long layoutSetBranchId) {
899                    LayoutRevision layoutRevision = LayoutStagingUtil.getLayoutRevision(
900                            layout);
901    
902                    if (layoutRevision == null) {
903                            try {
904                                    layoutRevision =
905                                            LayoutRevisionLocalServiceUtil.getLayoutRevision(
906                                                    layoutSetBranchId, layout.getPlid(), true);
907    
908                                    return false;
909                            }
910                            catch (Exception e) {
911                            }
912                    }
913    
914                    try {
915                            layoutRevision = LayoutRevisionLocalServiceUtil.getLayoutRevision(
916                                    layoutSetBranchId, layout.getPlid(), false);
917                    }
918                    catch (Exception e) {
919                    }
920    
921                    if ((layoutRevision == null) ||
922                            (layoutRevision.getStatus() ==
923                                    WorkflowConstants.STATUS_INCOMPLETE)) {
924    
925                            return true;
926                    }
927    
928                    return false;
929            }
930    
931            public void publishLayout(
932                            long userId, long plid, long liveGroupId, boolean includeChildren)
933                    throws Exception {
934    
935                    Map<String, String[]> parameterMap = getStagingParameters();
936    
937                    parameterMap.put(
938                            PortletDataHandlerKeys.DELETE_MISSING_LAYOUTS,
939                            new String[] {Boolean.FALSE.toString()});
940    
941                    Layout layout = LayoutLocalServiceUtil.getLayout(plid);
942    
943                    List<Layout> layouts = new ArrayList<Layout>();
944    
945                    layouts.add(layout);
946    
947                    layouts.addAll(getMissingParentLayouts(layout, liveGroupId));
948    
949                    if (includeChildren) {
950                            layouts.addAll(layout.getAllChildren());
951                    }
952    
953                    long[] layoutIds = getLayoutIds(layouts);
954    
955                    publishLayouts(
956                            userId, layout.getGroupId(), liveGroupId, layout.isPrivateLayout(),
957                            layoutIds, parameterMap, null, null);
958            }
959    
960            public void publishLayouts(
961                            long userId, long sourceGroupId, long targetGroupId,
962                            boolean privateLayout, long[] layoutIds,
963                            Map<String, String[]> parameterMap, Date startDate, Date endDate)
964                    throws Exception {
965    
966                    lockGroup(userId, targetGroupId);
967    
968                    parameterMap.put(
969                            PortletDataHandlerKeys.PERFORM_DIRECT_BINARY_IMPORT,
970                            new String[] {Boolean.TRUE.toString()});
971    
972                    File file = LayoutLocalServiceUtil.exportLayoutsAsFile(
973                            sourceGroupId, privateLayout, layoutIds, parameterMap, startDate,
974                            endDate);
975    
976                    try {
977                            LayoutLocalServiceUtil.importLayouts(
978                                    userId, targetGroupId, privateLayout, parameterMap, file);
979                    }
980                    finally {
981                            file.delete();
982    
983                            unlockGroup(targetGroupId);
984                    }
985            }
986    
987            public void publishLayouts(
988                            long userId, long sourceGroupId, long targetGroupId,
989                            boolean privateLayout, Map<Long, Boolean> layoutIdMap,
990                            Map<String, String[]> parameterMap, Date startDate, Date endDate)
991                    throws Exception {
992    
993                    List<Layout> layouts = new ArrayList<Layout>();
994    
995                    for (Map.Entry<Long, Boolean> entry : layoutIdMap.entrySet()) {
996                            long plid = GetterUtil.getLong(String.valueOf(entry.getKey()));
997                            boolean includeChildren = entry.getValue();
998    
999                            Layout layout = LayoutLocalServiceUtil.getLayout(plid);
1000    
1001                            if (!layouts.contains(layout)) {
1002                                    layouts.add(layout);
1003                            }
1004    
1005                            List<Layout> parentLayouts = getMissingParentLayouts(
1006                                    layout, targetGroupId);
1007    
1008                            for (Layout parentLayout : parentLayouts) {
1009                                    if (!layouts.contains(parentLayout)) {
1010                                            layouts.add(parentLayout);
1011                                    }
1012                            }
1013    
1014                            if (includeChildren) {
1015                                    for (Layout childLayout : layout.getAllChildren()) {
1016                                            if (!layouts.contains(childLayout)) {
1017                                                    layouts.add(childLayout);
1018                                            }
1019                                    }
1020                            }
1021                    }
1022    
1023                    long[] layoutIds = getLayoutIds(layouts);
1024    
1025                    publishLayouts(
1026                            userId, sourceGroupId, targetGroupId, privateLayout, layoutIds,
1027                            parameterMap, startDate, endDate);
1028            }
1029    
1030            public void publishLayouts(
1031                            long userId, long sourceGroupId, long targetGroupId,
1032                            boolean privateLayout, Map<String, String[]> parameterMap,
1033                            Date startDate, Date endDate)
1034                    throws Exception {
1035    
1036                    publishLayouts(
1037                            userId, sourceGroupId, targetGroupId, privateLayout, (long[])null,
1038                            parameterMap, startDate, endDate);
1039            }
1040    
1041            public void publishToLive(PortletRequest portletRequest) throws Exception {
1042                    long groupId = ParamUtil.getLong(portletRequest, "groupId");
1043    
1044                    Group liveGroup = GroupLocalServiceUtil.getGroup(groupId);
1045    
1046                    Map<String, String[]> parameterMap = getStagingParameters(
1047                            portletRequest);
1048    
1049                    if (liveGroup.isStaged()) {
1050                            if (liveGroup.isStagedRemotely()) {
1051                                    publishToRemote(portletRequest);
1052                            }
1053                            else {
1054                                    Group stagingGroup = liveGroup.getStagingGroup();
1055    
1056                                    publishLayouts(
1057                                            portletRequest, stagingGroup.getGroupId(), groupId,
1058                                            parameterMap, false);
1059                            }
1060                    }
1061            }
1062    
1063            public void publishToLive(PortletRequest portletRequest, Portlet portlet)
1064                    throws Exception {
1065    
1066                    long plid = ParamUtil.getLong(portletRequest, "plid");
1067    
1068                    Layout sourceLayout = LayoutLocalServiceUtil.getLayout(plid);
1069    
1070                    Group stagingGroup = null;
1071                    Group liveGroup = null;
1072    
1073                    Layout targetLayout = null;
1074    
1075                    long scopeGroupId = PortalUtil.getScopeGroupId(portletRequest);
1076    
1077                    if (sourceLayout.hasScopeGroup() &&
1078                            (sourceLayout.getScopeGroup().getGroupId() == scopeGroupId)) {
1079    
1080                            stagingGroup = sourceLayout.getScopeGroup();
1081                            liveGroup = stagingGroup.getLiveGroup();
1082    
1083                            targetLayout = LayoutLocalServiceUtil.getLayout(
1084                                    liveGroup.getClassPK());
1085                    }
1086                    else {
1087                            stagingGroup = sourceLayout.getGroup();
1088                            liveGroup = stagingGroup.getLiveGroup();
1089    
1090                            targetLayout = LayoutLocalServiceUtil.getLayoutByUuidAndGroupId(
1091                                    sourceLayout.getUuid(), liveGroup.getGroupId());
1092                    }
1093    
1094                    copyPortlet(
1095                            portletRequest, stagingGroup.getGroupId(), liveGroup.getGroupId(),
1096                            sourceLayout.getPlid(), targetLayout.getPlid(),
1097                            portlet.getPortletId());
1098            }
1099    
1100            public void publishToRemote(PortletRequest portletRequest)
1101                    throws Exception {
1102    
1103                    publishToRemote(portletRequest, false);
1104            }
1105    
1106            public void scheduleCopyFromLive(PortletRequest portletRequest)
1107                    throws Exception {
1108    
1109                    long stagingGroupId = ParamUtil.getLong(
1110                            portletRequest, "stagingGroupId");
1111    
1112                    Group stagingGroup = GroupLocalServiceUtil.getGroup(stagingGroupId);
1113    
1114                    long liveGroupId = stagingGroup.getLiveGroupId();
1115    
1116                    Map<String, String[]> parameterMap = getStagingParameters(
1117                            portletRequest);
1118    
1119                    publishLayouts(
1120                            portletRequest, liveGroupId, stagingGroupId, parameterMap, true);
1121            }
1122    
1123            public void schedulePublishToLive(PortletRequest portletRequest)
1124                    throws Exception {
1125    
1126                    long stagingGroupId = ParamUtil.getLong(
1127                            portletRequest, "stagingGroupId");
1128    
1129                    Group stagingGroup = GroupLocalServiceUtil.getGroup(stagingGroupId);
1130    
1131                    long liveGroupId = stagingGroup.getLiveGroupId();
1132    
1133                    Map<String, String[]> parameterMap = getStagingParameters(
1134                            portletRequest);
1135    
1136                    publishLayouts(
1137                            portletRequest, stagingGroupId, liveGroupId, parameterMap, true);
1138            }
1139    
1140            public void schedulePublishToRemote(PortletRequest portletRequest)
1141                    throws Exception {
1142    
1143                    publishToRemote(portletRequest, true);
1144            }
1145    
1146            public void setRecentLayoutBranchId(
1147                    HttpServletRequest request, long layoutSetBranchId, long plid,
1148                    long layoutBranchId)
1149                    throws SystemException {
1150    
1151                    PortalPreferences portalPreferences =
1152                            PortletPreferencesFactoryUtil.getPortalPreferences(request);
1153    
1154                    setRecentLayoutBranchId(
1155                            portalPreferences, layoutSetBranchId, plid, layoutBranchId);
1156            }
1157    
1158            public void setRecentLayoutBranchId(
1159                    User user, long layoutSetBranchId, long plid, long layoutBranchId)
1160                    throws SystemException {
1161    
1162                    PortalPreferences portalPreferences = getPortalPreferences(user);
1163    
1164                    setRecentLayoutBranchId(
1165                            portalPreferences, layoutSetBranchId, plid, layoutBranchId);
1166            }
1167    
1168            public void setRecentLayoutRevisionId(
1169                            HttpServletRequest request, long layoutSetBranchId, long plid,
1170                            long layoutRevisionId)
1171                    throws SystemException {
1172    
1173                    PortalPreferences portalPreferences =
1174                            PortletPreferencesFactoryUtil.getPortalPreferences(request);
1175    
1176                    setRecentLayoutRevisionId(
1177                            portalPreferences, layoutSetBranchId, plid, layoutRevisionId);
1178            }
1179    
1180            public void setRecentLayoutRevisionId(
1181                            User user, long layoutSetBranchId, long plid, long layoutRevisionId)
1182                    throws SystemException {
1183    
1184                    PortalPreferences portalPreferences = getPortalPreferences(user);
1185    
1186                    setRecentLayoutRevisionId(
1187                            portalPreferences, layoutSetBranchId, plid, layoutRevisionId);
1188            }
1189    
1190            public void setRecentLayoutSetBranchId(
1191                    HttpServletRequest request, long layoutSetId, long layoutSetBranchId) {
1192    
1193                    SessionClicks.put(
1194                            request, Staging.class.getName(),
1195                            getRecentLayoutSetBranchIdKey(layoutSetId),
1196                            String.valueOf(layoutSetBranchId));
1197            }
1198    
1199            public void setRecentLayoutSetBranchId(
1200                            User user, long layoutSetId, long layoutSetBranchId)
1201                    throws SystemException {
1202    
1203                    PortalPreferences portalPreferences = getPortalPreferences(user);
1204    
1205                    portalPreferences.setValue(
1206                            Staging.class.getName(), getRecentLayoutSetBranchIdKey(layoutSetId),
1207                            String.valueOf(layoutSetBranchId));
1208            }
1209    
1210            public void unscheduleCopyFromLive(PortletRequest portletRequest)
1211                    throws Exception {
1212    
1213                    long stagingGroupId = ParamUtil.getLong(
1214                            portletRequest, "stagingGroupId");
1215    
1216                    String jobName = ParamUtil.getString(portletRequest, "jobName");
1217                    String groupName = getSchedulerGroupName(
1218                            DestinationNames.LAYOUTS_LOCAL_PUBLISHER, stagingGroupId);
1219    
1220                    LayoutServiceUtil.unschedulePublishToLive(
1221                            stagingGroupId, jobName, groupName);
1222            }
1223    
1224            public void unschedulePublishToLive(PortletRequest portletRequest)
1225                    throws Exception {
1226    
1227                    long stagingGroupId = ParamUtil.getLong(
1228                            portletRequest, "stagingGroupId");
1229    
1230                    Group stagingGroup = GroupLocalServiceUtil.getGroup(stagingGroupId);
1231    
1232                    long liveGroupId = stagingGroup.getLiveGroupId();
1233    
1234                    String jobName = ParamUtil.getString(portletRequest, "jobName");
1235                    String groupName = getSchedulerGroupName(
1236                            DestinationNames.LAYOUTS_LOCAL_PUBLISHER, liveGroupId);
1237    
1238                    LayoutServiceUtil.unschedulePublishToLive(
1239                            liveGroupId, jobName, groupName);
1240            }
1241    
1242            public void unschedulePublishToRemote(PortletRequest portletRequest)
1243                    throws Exception {
1244    
1245                    long groupId = ParamUtil.getLong(portletRequest, "groupId");
1246    
1247                    String jobName = ParamUtil.getString(portletRequest, "jobName");
1248                    String groupName = getSchedulerGroupName(
1249                            DestinationNames.LAYOUTS_REMOTE_PUBLISHER, groupId);
1250    
1251                    LayoutServiceUtil.unschedulePublishToRemote(
1252                            groupId, jobName, groupName);
1253            }
1254    
1255            public void updateLastImportSettings(
1256                            Element layoutElement, Layout layout,
1257                            PortletDataContext portletDataContext)
1258                    throws Exception {
1259    
1260                    Map<String, String[]> parameterMap =
1261                            portletDataContext.getParameterMap();
1262    
1263                    String cmd = MapUtil.getString(parameterMap, "cmd");
1264    
1265                    if (!cmd.equals("publish_to_live")) {
1266                            return;
1267                    }
1268    
1269                    UnicodeProperties typeSettingsProperties =
1270                            layout.getTypeSettingsProperties();
1271    
1272                    typeSettingsProperties.setProperty(
1273                            "last-import-date", String.valueOf(System.currentTimeMillis()));
1274    
1275                    String layoutRevisionId = GetterUtil.getString(
1276                            layoutElement.attributeValue("layout-revision-id"));
1277    
1278                    typeSettingsProperties.setProperty(
1279                            "last-import-layout-revision-id", layoutRevisionId);
1280    
1281                    String layoutSetBranchId = MapUtil.getString(
1282                            parameterMap, "layoutSetBranchId");
1283    
1284                    typeSettingsProperties.setProperty(
1285                            "last-import-layout-set-branch-id", layoutSetBranchId);
1286    
1287                    String layoutSetBranchName = MapUtil.getString(
1288                            parameterMap, "layoutSetBranchName");
1289    
1290                    typeSettingsProperties.setProperty(
1291                            "last-import-layout-set-branch-name", layoutSetBranchName);
1292    
1293                    String lastImportUserName = MapUtil.getString(
1294                            parameterMap, "lastImportUserName");
1295    
1296                    typeSettingsProperties.setProperty(
1297                            "last-import-user-name", lastImportUserName);
1298    
1299                    String lastImportUserUuid = MapUtil.getString(
1300                            parameterMap, "lastImportUserUuid");
1301    
1302                    typeSettingsProperties.setProperty(
1303                            "last-import-user-uuid", lastImportUserUuid);
1304    
1305                    String layoutBranchId = GetterUtil.getString(
1306                            layoutElement.attributeValue("layout-branch-id"));
1307    
1308                    typeSettingsProperties.setProperty(
1309                            "last-import-layout-branch-id", layoutBranchId);
1310    
1311                    String layoutBranchName = GetterUtil.getString(
1312                            layoutElement.attributeValue("layout-branch-name"));
1313    
1314                    typeSettingsProperties.setProperty(
1315                            "last-import-layout-branch-name", layoutBranchName);
1316    
1317                    layout.setTypeSettingsProperties(typeSettingsProperties);
1318            }
1319    
1320            public void updateStaging(PortletRequest portletRequest, Group liveGroup)
1321                    throws Exception {
1322    
1323                    ThemeDisplay themeDisplay = (ThemeDisplay)portletRequest.getAttribute(
1324                            WebKeys.THEME_DISPLAY);
1325    
1326                    PermissionChecker permissionChecker =
1327                            themeDisplay.getPermissionChecker();
1328    
1329                    long userId = permissionChecker.getUserId();
1330    
1331                    Group scopeGroup = themeDisplay.getScopeGroup();
1332    
1333                    if (!GroupPermissionUtil.contains(
1334                                    permissionChecker, liveGroup.getGroupId(),
1335                                    ActionKeys.MANAGE_STAGING)) {
1336    
1337                            return;
1338                    }
1339    
1340                    int stagingType = getStagingType(portletRequest, liveGroup);
1341    
1342                    boolean branchingPublic = getBoolean(
1343                            portletRequest, liveGroup, "branchingPublic");
1344                    boolean branchingPrivate = getBoolean(
1345                            portletRequest, liveGroup, "branchingPrivate");
1346    
1347                    ServiceContext serviceContext =
1348                            ServiceContextThreadLocal.getServiceContext();
1349    
1350                    if (stagingType == StagingConstants.TYPE_NOT_STAGED) {
1351                            if (liveGroup.hasStagingGroup() || liveGroup.isStagedRemotely()) {
1352                                    disableStaging(portletRequest, liveGroup, serviceContext);
1353                            }
1354                    }
1355                    else if (stagingType == StagingConstants.TYPE_LOCAL_STAGING) {
1356                            enableLocalStaging(
1357                                    userId, scopeGroup, liveGroup, branchingPublic,
1358                                    branchingPrivate, serviceContext);
1359                    }
1360                    else if (stagingType == StagingConstants.TYPE_REMOTE_STAGING) {
1361                            String remoteAddress = getString(
1362                                    portletRequest, liveGroup, "remoteAddress");
1363    
1364                            remoteAddress = stripProtocolFromRemoteAddress(remoteAddress);
1365    
1366                            int remotePort = getInteger(
1367                                    portletRequest, liveGroup, "remotePort");
1368                            String remotePathContext = getString(
1369                                    portletRequest, liveGroup, "remotePathContext");
1370                            boolean secureConnection = getBoolean(
1371                                    portletRequest, liveGroup, "secureConnection");
1372                            long remoteGroupId = getLong(
1373                                    portletRequest, liveGroup, "remoteGroupId");
1374    
1375                            enableRemoteStaging(
1376                                    userId, scopeGroup, liveGroup, branchingPublic,
1377                                    branchingPrivate, remoteAddress, remotePort, remotePathContext,
1378                                    secureConnection, remoteGroupId, serviceContext);
1379                    }
1380            }
1381    
1382            protected void checkDefaultLayoutSetBranches(
1383                            long userId, Group liveGroup, boolean branchingPublic,
1384                            boolean branchingPrivate, boolean remote,
1385                            ServiceContext serviceContext)
1386                    throws Exception {
1387    
1388                    long targetGroupId = 0;
1389    
1390                    if (remote) {
1391                            targetGroupId = liveGroup.getGroupId();
1392                    }
1393                    else {
1394                            Group stagingGroup = liveGroup.getStagingGroup();
1395    
1396                            if (stagingGroup == null) {
1397                                    return;
1398                            }
1399    
1400                            targetGroupId = stagingGroup.getGroupId();
1401                    }
1402    
1403                    if (branchingPublic) {
1404                            Locale locale = LocaleUtil.getDefault();
1405    
1406                            String description = LanguageUtil.format(
1407                                    locale,
1408                                    LayoutSetBranchConstants.MASTER_BRANCH_DESCRIPTION_PUBLIC,
1409                                    liveGroup.getDescriptiveName());
1410    
1411                            try {
1412                                    LayoutSetBranch layoutSetBranch =
1413                                            LayoutSetBranchLocalServiceUtil.addLayoutSetBranch(
1414                                                    userId, targetGroupId, false,
1415                                                    LayoutSetBranchConstants.MASTER_BRANCH_NAME,
1416                                                    description, true,
1417                                                    LayoutSetBranchConstants.ALL_BRANCHES, serviceContext);
1418    
1419                                    List<LayoutRevision> layoutRevisions =
1420                                            LayoutRevisionLocalServiceUtil.getLayoutRevisions(
1421                                                    layoutSetBranch.getLayoutSetBranchId(), false);
1422    
1423                                    for (LayoutRevision layoutRevision : layoutRevisions) {
1424                                            LayoutRevisionLocalServiceUtil.updateStatus(
1425                                                    userId, layoutRevision.getLayoutRevisionId(),
1426                                                    WorkflowConstants.STATUS_APPROVED, serviceContext);
1427                                    }
1428                            }
1429                            catch (LayoutSetBranchNameException lsbne) {
1430                            }
1431                    }
1432    
1433                    if (branchingPrivate) {
1434                            Locale locale = LocaleUtil.getDefault();
1435    
1436                            String description = LanguageUtil.format(
1437                                    locale,
1438                                    LayoutSetBranchConstants.MASTER_BRANCH_DESCRIPTION_PRIVATE,
1439                                    liveGroup.getDescriptiveName());
1440    
1441                            try {
1442                                    LayoutSetBranch layoutSetBranch =
1443                                            LayoutSetBranchLocalServiceUtil.addLayoutSetBranch(
1444                                                    userId, targetGroupId, true,
1445                                                    LayoutSetBranchConstants.MASTER_BRANCH_NAME,
1446                                                    description, true,
1447                                                    LayoutSetBranchConstants.ALL_BRANCHES, serviceContext);
1448    
1449                                    List<LayoutRevision> layoutRevisions =
1450                                            LayoutRevisionLocalServiceUtil.getLayoutRevisions(
1451                                                    layoutSetBranch.getLayoutSetBranchId(), false);
1452    
1453                                    for (LayoutRevision layoutRevision : layoutRevisions) {
1454                                            LayoutRevisionLocalServiceUtil.updateStatus(
1455                                                    userId, layoutRevision.getLayoutRevisionId(),
1456                                                    WorkflowConstants.STATUS_APPROVED, serviceContext);
1457                                    }
1458                            }
1459                            catch (LayoutSetBranchNameException lsbne) {
1460                            }
1461                    }
1462            }
1463    
1464            protected void deleteRecentLayoutRevisionId(
1465                    PortalPreferences portalPreferences, long layoutSetBranchId,
1466                    long plid) {
1467    
1468                    portalPreferences.setValue(
1469                            Staging.class.getName(),
1470                            getRecentLayoutRevisionIdKey(layoutSetBranchId, plid), null);
1471            }
1472    
1473            protected boolean getBoolean(
1474                    PortletRequest portletRequest, Group group, String param) {
1475    
1476                    return ParamUtil.getBoolean(
1477                            portletRequest, param,
1478                            GetterUtil.getBoolean(group.getTypeSettingsProperty(param)));
1479            }
1480    
1481            protected Calendar getDate(
1482                            PortletRequest portletRequest, String paramPrefix,
1483                            boolean timeZoneSensitive)
1484                    throws Exception {
1485    
1486                    ThemeDisplay themeDisplay = (ThemeDisplay)portletRequest.getAttribute(
1487                            WebKeys.THEME_DISPLAY);
1488    
1489                    int dateMonth = ParamUtil.getInteger(
1490                            portletRequest, paramPrefix + "Month");
1491                    int dateDay = ParamUtil.getInteger(portletRequest, paramPrefix + "Day");
1492                    int dateYear = ParamUtil.getInteger(
1493                            portletRequest, paramPrefix + "Year");
1494                    int dateHour = ParamUtil.getInteger(
1495                            portletRequest, paramPrefix + "Hour");
1496                    int dateMinute = ParamUtil.getInteger(
1497                            portletRequest, paramPrefix + "Minute");
1498                    int dateAmPm = ParamUtil.getInteger(
1499                            portletRequest, paramPrefix + "AmPm");
1500    
1501                    if (dateAmPm == Calendar.PM) {
1502                            dateHour += 12;
1503                    }
1504    
1505                    Locale locale = null;
1506                    TimeZone timeZone = null;
1507    
1508                    if (timeZoneSensitive) {
1509                            locale = themeDisplay.getLocale();
1510                            timeZone = themeDisplay.getTimeZone();
1511                    }
1512                    else {
1513                            locale = LocaleUtil.getDefault();
1514                            timeZone = TimeZoneUtil.getDefault();
1515                    }
1516    
1517                    Calendar cal = CalendarFactoryUtil.getCalendar(timeZone, locale);
1518    
1519                    cal.set(Calendar.MONTH, dateMonth);
1520                    cal.set(Calendar.DATE, dateDay);
1521                    cal.set(Calendar.YEAR, dateYear);
1522                    cal.set(Calendar.HOUR_OF_DAY, dateHour);
1523                    cal.set(Calendar.MINUTE, dateMinute);
1524                    cal.set(Calendar.SECOND, 0);
1525                    cal.set(Calendar.MILLISECOND, 0);
1526    
1527                    return cal;
1528            }
1529    
1530            protected int getInteger(
1531                    PortletRequest portletRequest, Group group, String param) {
1532    
1533                    return ParamUtil.getInteger(
1534                            portletRequest, param,
1535                            GetterUtil.getInteger(group.getTypeSettingsProperty(param)));
1536            }
1537    
1538            protected long[] getLayoutIds(List<Layout> layouts) {
1539                    long[] layoutIds = new long[layouts.size()];
1540    
1541                    for (int i = 0; i < layouts.size(); i++) {
1542                            Layout layout = layouts.get(i);
1543    
1544                            layoutIds[i] = layout.getLayoutId();
1545                    }
1546    
1547                    return layoutIds;
1548            }
1549    
1550            protected long getLong(
1551                    PortletRequest portletRequest, Group group, String param) {
1552    
1553                    return ParamUtil.getLong(
1554                            portletRequest, param,
1555                            GetterUtil.getLong(group.getTypeSettingsProperty(param)));
1556            }
1557    
1558            protected PortalPreferences getPortalPreferences(User user)
1559                    throws SystemException {
1560    
1561                    boolean signedIn = !user.isDefaultUser();
1562    
1563                    PortalPreferences portalPreferences =
1564                            PortletPreferencesFactoryUtil.getPortalPreferences(
1565                                    user.getCompanyId(), user.getUserId(), signedIn);
1566    
1567                    return portalPreferences;
1568            }
1569    
1570            protected long getRecentLayoutBranchId(
1571                    PortalPreferences portalPreferences, long layoutSetBranchId,
1572                    long plid) {
1573    
1574                    return GetterUtil.getLong(
1575                            portalPreferences.getValue(
1576                                    Staging.class.getName(),
1577                                    getRecentLayoutBranchIdKey(layoutSetBranchId, plid)));
1578            }
1579    
1580            protected String getRecentLayoutBranchIdKey(
1581                    long layoutSetBranchId, long plid) {
1582    
1583                    StringBundler sb = new StringBundler(4);
1584    
1585                    sb.append("layoutBranchId-");
1586                    sb.append(layoutSetBranchId);
1587                    sb.append(StringPool.DASH);
1588                    sb.append(plid);
1589    
1590                    return sb.toString();
1591            }
1592    
1593            protected long getRecentLayoutRevisionId(
1594                            PortalPreferences portalPreferences, long layoutSetBranchId,
1595                            long plid)
1596                    throws PortalException, SystemException {
1597    
1598                    long layoutRevisionId = GetterUtil.getLong(
1599                            portalPreferences.getValue(
1600                                    Staging.class.getName(),
1601                                    getRecentLayoutRevisionIdKey(layoutSetBranchId, plid)));
1602    
1603                    if (layoutRevisionId > 0) {
1604                            return layoutRevisionId;
1605                    }
1606    
1607                    long layoutBranchId = getRecentLayoutBranchId(
1608                            portalPreferences, layoutSetBranchId, plid);
1609    
1610                    if (layoutBranchId > 0) {
1611                            try {
1612                                    LayoutBranchLocalServiceUtil.getLayoutBranch(layoutBranchId);
1613                            }
1614                            catch (NoSuchLayoutBranchException nslbe) {
1615                                    LayoutBranch layoutBranch =
1616                                            LayoutBranchLocalServiceUtil.getMasterLayoutBranch(
1617                                                    layoutSetBranchId, plid);
1618    
1619                                    layoutBranchId = layoutBranch.getLayoutBranchId();
1620                            }
1621                    }
1622    
1623                    if (layoutBranchId > 0) {
1624                            try {
1625                                    LayoutRevision layoutRevision =
1626                                            LayoutRevisionLocalServiceUtil.getLayoutRevision(
1627                                                    layoutSetBranchId, layoutBranchId, plid);
1628    
1629                                    if (layoutRevision != null) {
1630                                            layoutRevisionId = layoutRevision.getLayoutRevisionId();
1631                                    }
1632                            }
1633                            catch (NoSuchLayoutRevisionException nslre) {
1634                            }
1635                    }
1636    
1637                    return layoutRevisionId;
1638            }
1639    
1640            protected String getRecentLayoutRevisionIdKey(
1641                    long layoutSetBranchId, long plid) {
1642    
1643                    StringBundler sb = new StringBundler(4);
1644    
1645                    sb.append("layoutRevisionId-");
1646                    sb.append(layoutSetBranchId);
1647                    sb.append(StringPool.DASH);
1648                    sb.append(plid);
1649    
1650                    return sb.toString();
1651            }
1652    
1653            protected String getRecentLayoutSetBranchIdKey(long layoutSetId) {
1654                    return "layoutSetBranchId_" + layoutSetId;
1655            }
1656    
1657            protected int getStagingType(
1658                    PortletRequest portletRequest, Group liveGroup) {
1659    
1660                    String stagingType = portletRequest.getParameter("stagingType");
1661    
1662                    if (stagingType != null) {
1663                            return GetterUtil.getInteger(stagingType);
1664                    }
1665    
1666                    if (liveGroup.isStagedRemotely()) {
1667                            return StagingConstants.TYPE_REMOTE_STAGING;
1668                    }
1669    
1670                    if (liveGroup.hasStagingGroup()) {
1671                            return StagingConstants.TYPE_LOCAL_STAGING;
1672                    }
1673    
1674                    return StagingConstants.TYPE_NOT_STAGED;
1675            }
1676    
1677            protected String getString(
1678                    PortletRequest portletRequest, Group group, String param) {
1679    
1680                    return ParamUtil.getString(
1681                            portletRequest, param,
1682                            GetterUtil.getString(group.getTypeSettingsProperty(param)));
1683            }
1684    
1685            protected void lockGroup(long userId, long groupId) throws Exception {
1686                    if (!PropsValues.STAGING_LOCK_ENABLED) {
1687                            return;
1688                    }
1689    
1690                    if (LockLocalServiceUtil.isLocked(Staging.class.getName(), groupId)) {
1691                            Lock lock = LockLocalServiceUtil.getLock(
1692                                    Staging.class.getName(), groupId);
1693    
1694                            throw new DuplicateLockException(lock);
1695                    }
1696    
1697                    LockLocalServiceUtil.lock(
1698                            userId, Staging.class.getName(), String.valueOf(groupId),
1699                            StagingImpl.class.getName(), false,
1700                            StagingConstants.LOCK_EXPIRATION_TIME);
1701            }
1702    
1703            protected void publishLayouts(
1704                            PortletRequest portletRequest, long sourceGroupId,
1705                            long targetGroupId, Map<String, String[]> parameterMap,
1706                            boolean schedule)
1707                    throws Exception {
1708    
1709                    ThemeDisplay themeDisplay = (ThemeDisplay)portletRequest.getAttribute(
1710                            WebKeys.THEME_DISPLAY);
1711    
1712                    String tabs1 = ParamUtil.getString(portletRequest, "tabs1");
1713    
1714                    boolean privateLayout = true;
1715    
1716                    if (tabs1.equals("public-pages")) {
1717                            privateLayout = false;
1718                    }
1719    
1720                    String scope = ParamUtil.getString(portletRequest, "scope");
1721    
1722                    Map<Long, Boolean> layoutIdMap = new LinkedHashMap<Long, Boolean>();
1723    
1724                    if (scope.equals("selected-pages")) {
1725                            long[] rowIds = ParamUtil.getLongValues(portletRequest, "rowIds");
1726    
1727                            for (long selPlid : rowIds) {
1728                                    boolean delete = ParamUtil.getBoolean(
1729                                            portletRequest, "delete_" + selPlid);
1730                                    boolean includeChildren = ParamUtil.getBoolean(
1731                                            portletRequest, "includeChildren_" + selPlid);
1732    
1733                                    if (!delete && includeChildren) {
1734                                            layoutIdMap.put(selPlid, true);
1735                                    }
1736                                    else {
1737                                            layoutIdMap.put(selPlid, false);
1738                                    }
1739                            }
1740                    }
1741    
1742                    String range = ParamUtil.getString(portletRequest, "range");
1743    
1744                    Date startDate = null;
1745                    Date endDate = null;
1746    
1747                    if (range.equals("dateRange")) {
1748                            startDate = getDate(portletRequest, "startDate", true).getTime();
1749    
1750                            endDate = getDate(portletRequest, "endDate", true).getTime();
1751                    }
1752                    else if (range.equals("fromLastPublishDate")) {
1753                            LayoutSet layoutSet = LayoutSetLocalServiceUtil.getLayoutSet(
1754                                    sourceGroupId, privateLayout);
1755    
1756                            long lastPublishDate = GetterUtil.getLong(
1757                                    layoutSet.getSettingsProperty("last-publish-date"));
1758    
1759                            if (lastPublishDate > 0) {
1760                                    endDate = new Date();
1761    
1762                                    startDate = new Date(lastPublishDate);
1763                            }
1764                    }
1765                    else if (range.equals("last")) {
1766                            int rangeLast = ParamUtil.getInteger(portletRequest, "last");
1767    
1768                            Date now = new Date();
1769    
1770                            startDate = new Date(now.getTime() - (rangeLast * Time.HOUR));
1771    
1772                            endDate = now;
1773                    }
1774    
1775                    if (schedule) {
1776                            String groupName = getSchedulerGroupName(
1777                                    DestinationNames.LAYOUTS_LOCAL_PUBLISHER, targetGroupId);
1778    
1779                            int recurrenceType = ParamUtil.getInteger(
1780                                    portletRequest, "recurrenceType");
1781    
1782                            Calendar startCal = getDate(
1783                                    portletRequest, "schedulerStartDate", true);
1784    
1785                            String cronText = SchedulerEngineHelperUtil.getCronText(
1786                                    portletRequest, startCal, true, recurrenceType);
1787    
1788                            Date schedulerEndDate = null;
1789    
1790                            int endDateType = ParamUtil.getInteger(
1791                                    portletRequest, "endDateType");
1792    
1793                            if (endDateType == 1) {
1794                                    Calendar endCal = getDate(
1795                                            portletRequest, "schedulerEndDate", true);
1796    
1797                                    schedulerEndDate = endCal.getTime();
1798                            }
1799    
1800                            String description = ParamUtil.getString(
1801                                    portletRequest, "description");
1802    
1803                            LayoutServiceUtil.schedulePublishToLive(
1804                                    sourceGroupId, targetGroupId, privateLayout, layoutIdMap,
1805                                    parameterMap, scope, startDate, endDate, groupName, cronText,
1806                                    startCal.getTime(), schedulerEndDate, description);
1807                    }
1808                    else {
1809                            MessageStatus messageStatus = new MessageStatus();
1810    
1811                            messageStatus.startTimer();
1812    
1813                            String command =
1814                                    LayoutsLocalPublisherRequest.COMMAND_SELECTED_PAGES;
1815    
1816                            try {
1817                                    if (scope.equals("all-pages")) {
1818                                            command = LayoutsLocalPublisherRequest.COMMAND_ALL_PAGES;
1819    
1820                                            publishLayouts(
1821                                                    themeDisplay.getUserId(), sourceGroupId, targetGroupId,
1822                                                    privateLayout, parameterMap, startDate, endDate);
1823                                    }
1824                                    else {
1825                                            publishLayouts(
1826                                                    themeDisplay.getUserId(), sourceGroupId, targetGroupId,
1827                                                    privateLayout, layoutIdMap, parameterMap, startDate,
1828                                                    endDate);
1829                                    }
1830                            }
1831                            catch (Exception e) {
1832                                    messageStatus.setException(e);
1833    
1834                                    throw e;
1835                            }
1836                            finally {
1837                                    messageStatus.stopTimer();
1838    
1839                                    LayoutsLocalPublisherRequest publisherRequest =
1840                                            new LayoutsLocalPublisherRequest(
1841                                                    command, themeDisplay.getUserId(), sourceGroupId,
1842                                                    targetGroupId, privateLayout, layoutIdMap, parameterMap,
1843                                                    startDate, endDate);
1844    
1845                                    messageStatus.setPayload(publisherRequest);
1846    
1847                                    MessageBusUtil.sendMessage(
1848                                            DestinationNames.MESSAGE_BUS_MESSAGE_STATUS, messageStatus);
1849                            }
1850                    }
1851            }
1852    
1853            protected void publishToRemote(
1854                            PortletRequest portletRequest, boolean schedule)
1855                    throws Exception {
1856    
1857                    ThemeDisplay themeDisplay = (ThemeDisplay)portletRequest.getAttribute(
1858                            WebKeys.THEME_DISPLAY);
1859    
1860                    String tabs1 = ParamUtil.getString(portletRequest, "tabs1");
1861    
1862                    long groupId = ParamUtil.getLong(portletRequest, "groupId");
1863    
1864                    boolean privateLayout = true;
1865    
1866                    if (tabs1.equals("public-pages")) {
1867                            privateLayout = false;
1868                    }
1869    
1870                    String scope = ParamUtil.getString(portletRequest, "scope");
1871    
1872                    if (Validator.isNull(scope)) {
1873                            scope = "all-pages";
1874                    }
1875    
1876                    Map<Long, Boolean> layoutIdMap = null;
1877    
1878                    if (scope.equals("selected-pages")) {
1879                            layoutIdMap = new LinkedHashMap<Long, Boolean>();
1880    
1881                            long[] rowIds = ParamUtil.getLongValues(portletRequest, "rowIds");
1882    
1883                            for (long selPlid : rowIds) {
1884                                    boolean delete = ParamUtil.getBoolean(
1885                                            portletRequest, "delete_" + selPlid);
1886                                    boolean includeChildren = ParamUtil.getBoolean(
1887                                            portletRequest, "includeChildren_" + selPlid);
1888    
1889                                    if (!delete && includeChildren) {
1890                                            layoutIdMap.put(selPlid, true);
1891                                    }
1892                                    else {
1893                                            layoutIdMap.put(selPlid, false);
1894                                    }
1895                            }
1896                    }
1897    
1898                    Map<String, String[]> parameterMap = getStagingParameters(
1899                            portletRequest);
1900    
1901                    parameterMap.put(
1902                            PortletDataHandlerKeys.PUBLISH_TO_REMOTE,
1903                            new String[] {Boolean.TRUE.toString()});
1904    
1905                    Group group = GroupLocalServiceUtil.getGroup(groupId);
1906    
1907                    UnicodeProperties groupTypeSettingsProperties =
1908                            group.getTypeSettingsProperties();
1909    
1910                    String remoteAddress = ParamUtil.getString(
1911                            portletRequest, "remoteAddress",
1912                            groupTypeSettingsProperties.getProperty("remoteAddress"));
1913    
1914                    remoteAddress = stripProtocolFromRemoteAddress(remoteAddress);
1915    
1916                    int remotePort = ParamUtil.getInteger(
1917                            portletRequest, "remotePort",
1918                            GetterUtil.getInteger(
1919                                    groupTypeSettingsProperties.getProperty("remotePort")));
1920                    String remotePathContext = ParamUtil.getString(
1921                            portletRequest, "remotePathContext",
1922                            groupTypeSettingsProperties.getProperty("remotePathContext"));
1923                    boolean secureConnection = ParamUtil.getBoolean(
1924                            portletRequest, "secureConnection",
1925                            GetterUtil.getBoolean(
1926                                    groupTypeSettingsProperties.getProperty("secureConnection")));
1927                    long remoteGroupId = ParamUtil.getLong(
1928                            portletRequest, "remoteGroupId",
1929                            GetterUtil.getLong(
1930                                    groupTypeSettingsProperties.getProperty("remoteGroupId")));
1931                    boolean remotePrivateLayout = ParamUtil.getBoolean(
1932                            portletRequest, "remotePrivateLayout");
1933    
1934                    validate(
1935                            remoteAddress, remotePort, remotePathContext, secureConnection,
1936                            remoteGroupId);
1937    
1938                    if (group.isCompany()) {
1939                            updateGroupTypeSettingsProperties(
1940                                    group, remoteAddress, remotePort, remotePathContext,
1941                                    secureConnection, remoteGroupId);
1942                    }
1943    
1944                    String range = ParamUtil.getString(portletRequest, "range");
1945    
1946                    Date startDate = null;
1947                    Date endDate = null;
1948    
1949                    if (range.equals("dateRange")) {
1950                            startDate = getDate(portletRequest, "startDate", true).getTime();
1951    
1952                            endDate = getDate(portletRequest, "endDate", true).getTime();
1953                    }
1954                    else if (range.equals("fromLastPublishDate")) {
1955                            LayoutSet layoutSet = LayoutSetLocalServiceUtil.getLayoutSet(
1956                                    groupId, privateLayout);
1957    
1958                            long lastPublishDate = GetterUtil.getLong(
1959                                    layoutSet.getSettingsProperty("last-publish-date"));
1960    
1961                            if (lastPublishDate > 0) {
1962                                    endDate = new Date();
1963    
1964                                    startDate = new Date(lastPublishDate);
1965                            }
1966                    }
1967                    else if (range.equals("last")) {
1968                            int rangeLast = ParamUtil.getInteger(portletRequest, "last");
1969    
1970                            Date now = new Date();
1971    
1972                            startDate = new Date(now.getTime() - (rangeLast * Time.HOUR));
1973    
1974                            endDate = now;
1975                    }
1976    
1977                    if (schedule) {
1978                            String groupName = getSchedulerGroupName(
1979                                    DestinationNames.LAYOUTS_REMOTE_PUBLISHER, groupId);
1980    
1981                            int recurrenceType = ParamUtil.getInteger(
1982                                    portletRequest, "recurrenceType");
1983    
1984                            Calendar startCal = getDate(
1985                                    portletRequest, "schedulerStartDate", true);
1986    
1987                            String cronText = SchedulerEngineHelperUtil.getCronText(
1988                                    portletRequest, startCal, true, recurrenceType);
1989    
1990                            Date schedulerEndDate = null;
1991    
1992                            int endDateType = ParamUtil.getInteger(
1993                                    portletRequest, "endDateType");
1994    
1995                            if (endDateType == 1) {
1996                                    Calendar endCal = getDate(
1997                                            portletRequest, "schedulerEndDate", true);
1998    
1999                                    schedulerEndDate = endCal.getTime();
2000                            }
2001    
2002                            String description = ParamUtil.getString(
2003                                    portletRequest, "description");
2004    
2005                            LayoutServiceUtil.schedulePublishToRemote(
2006                                    groupId, privateLayout, layoutIdMap, parameterMap,
2007                                    remoteAddress, remotePort, remotePathContext, secureConnection,
2008                                    remoteGroupId, remotePrivateLayout, startDate, endDate,
2009                                    groupName, cronText, startCal.getTime(), schedulerEndDate,
2010                                    description);
2011                    }
2012                    else {
2013                            MessageStatus messageStatus = new MessageStatus();
2014    
2015                            messageStatus.startTimer();
2016    
2017                            try {
2018                                    copyRemoteLayouts(
2019                                            groupId, privateLayout, layoutIdMap, parameterMap,
2020                                            remoteAddress, remotePort, remotePathContext,
2021                                            secureConnection, remoteGroupId, remotePrivateLayout,
2022                                            startDate, endDate);
2023                            }
2024                            catch (Exception e) {
2025                                    messageStatus.setException(e);
2026    
2027                                    throw e;
2028                            }
2029                            finally {
2030                                    messageStatus.stopTimer();
2031    
2032                                    LayoutsRemotePublisherRequest publisherRequest =
2033                                            new LayoutsRemotePublisherRequest(
2034                                                    themeDisplay.getUserId(), groupId, privateLayout,
2035                                                    layoutIdMap, parameterMap, remoteAddress, remotePort,
2036                                                    remotePathContext, secureConnection, remoteGroupId,
2037                                                    remotePrivateLayout, startDate, endDate);
2038    
2039                                    messageStatus.setPayload(publisherRequest);
2040    
2041                                    MessageBusUtil.sendMessage(
2042                                            DestinationNames.MESSAGE_BUS_MESSAGE_STATUS, messageStatus);
2043                            }
2044                    }
2045            }
2046    
2047            protected void setCommonStagingOptions(
2048                            Group liveGroup, UnicodeProperties typeSettingsProperties,
2049                            ServiceContext serviceContext)
2050                    throws Exception {
2051    
2052                    LayoutExporter.updateLastPublishDate(
2053                            liveGroup.getPrivateLayoutSet(), 0);
2054                    LayoutExporter.updateLastPublishDate(liveGroup.getPublicLayoutSet(), 0);
2055    
2056                    Set<String> parameterNames = serviceContext.getAttributes().keySet();
2057    
2058                    for (String parameterName : parameterNames) {
2059                            if (parameterName.startsWith(StagingConstants.STAGED_PORTLET) &&
2060                                    !parameterName.endsWith("Checkbox")) {
2061    
2062                                    boolean staged = ParamUtil.getBoolean(
2063                                            serviceContext, parameterName);
2064    
2065                                    typeSettingsProperties.setProperty(
2066                                            parameterName, String.valueOf(staged));
2067                            }
2068                    }
2069            }
2070    
2071            protected void setRecentLayoutBranchId(
2072                    PortalPreferences portalPreferences, long layoutSetBranchId, long plid,
2073                    long layoutBranchId) {
2074    
2075                    portalPreferences.setValue(
2076                            Staging.class.getName(),
2077                            getRecentLayoutBranchIdKey(layoutSetBranchId, plid),
2078                            String.valueOf(layoutBranchId));
2079            }
2080    
2081            protected void setRecentLayoutRevisionId(
2082                            PortalPreferences portalPreferences, long layoutSetBranchId,
2083                            long plid, long layoutRevisionId)
2084                    throws SystemException {
2085    
2086                    long layoutBranchId = 0;
2087    
2088                    try {
2089                            LayoutRevision layoutRevision =
2090                                    LayoutRevisionLocalServiceUtil.getLayoutRevision(
2091                                            layoutRevisionId);
2092    
2093                            layoutBranchId = layoutRevision.getLayoutBranchId();
2094    
2095                            LayoutRevision lastLayoutRevision =
2096                                    LayoutRevisionLocalServiceUtil.getLayoutRevision(
2097                                            layoutSetBranchId, layoutBranchId, plid);
2098    
2099                            if (lastLayoutRevision.getLayoutRevisionId() == layoutRevisionId) {
2100                                    deleteRecentLayoutRevisionId(
2101                                            portalPreferences, layoutSetBranchId, plid);
2102                            }
2103                            else {
2104                                    portalPreferences.setValue(
2105                                            Staging.class.getName(),
2106                                            getRecentLayoutRevisionIdKey(layoutSetBranchId, plid),
2107                                            String.valueOf(layoutRevisionId));
2108                            }
2109                    }
2110                    catch (PortalException pe) {
2111                    }
2112    
2113                    portalPreferences.setValue(
2114                            Staging.class.getName(),
2115                            getRecentLayoutBranchIdKey(layoutSetBranchId, plid),
2116                            String.valueOf(layoutBranchId));
2117            }
2118    
2119            protected String stripProtocolFromRemoteAddress(String remoteAddress) {
2120                    if (remoteAddress.startsWith(Http.HTTP_WITH_SLASH)) {
2121                            remoteAddress = remoteAddress.substring(
2122                                    Http.HTTP_WITH_SLASH.length());
2123                    }
2124                    else if (remoteAddress.startsWith(Http.HTTPS_WITH_SLASH)) {
2125                            remoteAddress = remoteAddress.substring(
2126                                    Http.HTTPS_WITH_SLASH.length());
2127                    }
2128    
2129                    return remoteAddress;
2130            }
2131    
2132            protected void unlockGroup(long groupId) throws SystemException {
2133                    if (!PropsValues.STAGING_LOCK_ENABLED) {
2134                            return;
2135                    }
2136    
2137                    LockLocalServiceUtil.unlock(Staging.class.getName(), groupId);
2138            }
2139    
2140            protected void updateGroupTypeSettingsProperties(
2141                            Group group, String remoteAddress, int remotePort,
2142                            String remotePathContext, boolean secureConnection,
2143                            long remoteGroupId)
2144                    throws Exception {
2145    
2146                    UnicodeProperties typeSettingsProperties =
2147                            group.getTypeSettingsProperties();
2148    
2149                    typeSettingsProperties.setProperty("remoteAddress", remoteAddress);
2150                    typeSettingsProperties.setProperty(
2151                            "remoteGroupId", String.valueOf(remoteGroupId));
2152                    typeSettingsProperties.setProperty(
2153                            "remotePathContext", remotePathContext);
2154                    typeSettingsProperties.setProperty(
2155                            "remotePort", String.valueOf(remotePort));
2156                    typeSettingsProperties.setProperty(
2157                            "secureConnection", String.valueOf(secureConnection));
2158    
2159                    group.setTypeSettingsProperties(typeSettingsProperties);
2160    
2161                    GroupLocalServiceUtil.updateGroup(group);
2162            }
2163    
2164            protected void validate(
2165                            String remoteAddress, int remotePort, String remotePathContext,
2166                            boolean secureConnection, long remoteGroupId)
2167                    throws Exception {
2168    
2169                    RemoteOptionsException roe = null;
2170    
2171                    if (!Validator.isDomain(remoteAddress) &&
2172                            !Validator.isIPAddress(remoteAddress)) {
2173    
2174                            roe = new RemoteOptionsException(
2175                                    RemoteOptionsException.REMOTE_ADDRESS);
2176    
2177                            roe.setRemoteAddress(remoteAddress);
2178    
2179                            throw roe;
2180                    }
2181    
2182                    if ((remotePort < 1) || (remotePort > 65535)) {
2183                            roe = new RemoteOptionsException(
2184                                    RemoteOptionsException.REMOTE_PORT);
2185    
2186                            roe.setRemotePort(remotePort);
2187    
2188                            throw roe;
2189                    }
2190    
2191                    if (Validator.isNotNull(remotePathContext) &&
2192                            (!remotePathContext.startsWith(StringPool.FORWARD_SLASH) ||
2193                             remotePathContext.endsWith(StringPool.FORWARD_SLASH))) {
2194    
2195                            roe = new RemoteOptionsException(
2196                                    RemoteOptionsException.REMOTE_PATH_CONTEXT);
2197    
2198                            roe.setRemotePathContext(remotePathContext);
2199    
2200                            throw roe;
2201                    }
2202    
2203                    if (remoteGroupId <= 0) {
2204                            roe = new RemoteOptionsException(
2205                                    RemoteOptionsException.REMOTE_GROUP_ID);
2206    
2207                            roe.setRemoteGroupId(remoteGroupId);
2208    
2209                            throw roe;
2210                    }
2211    
2212                    PermissionChecker permissionChecker =
2213                            PermissionThreadLocal.getPermissionChecker();
2214    
2215                    User user = permissionChecker.getUser();
2216    
2217                    String url = buildRemoteURL(
2218                            remoteAddress, remotePort, remotePathContext, secureConnection,
2219                            GroupConstants.DEFAULT_LIVE_GROUP_ID, false);
2220    
2221                    HttpPrincipal httpPrincipal = new HttpPrincipal(
2222                            url, user.getEmailAddress(), user.getPassword(),
2223                            user.getPasswordEncrypted());
2224    
2225                    // Ping remote host and verify that the group exists
2226    
2227                    try {
2228                            GroupServiceHttp.getGroup(httpPrincipal, remoteGroupId);
2229                    }
2230                    catch (NoSuchGroupException nsge) {
2231                            RemoteExportException ree = new RemoteExportException(
2232                                    RemoteExportException.NO_GROUP);
2233    
2234                            ree.setGroupId(remoteGroupId);
2235    
2236                            throw ree;
2237                    }
2238                    catch (PrincipalException pe) {
2239                            RemoteExportException ree = new RemoteExportException(
2240                                    RemoteExportException.NO_PERMISSIONS);
2241    
2242                            ree.setGroupId(remoteGroupId);
2243    
2244                            throw ree;
2245                    }
2246                    catch (SystemException se) {
2247                            RemoteExportException ree = new RemoteExportException(
2248                                    RemoteExportException.BAD_CONNECTION);
2249    
2250                            ree.setURL(url);
2251    
2252                            throw ree;
2253                    }
2254    
2255            }
2256    
2257    }