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