001    /**
002     * Copyright (c) 2000-2013 Liferay, Inc. All rights reserved.
003     *
004     * This library is free software; you can redistribute it and/or modify it under
005     * the terms of the GNU Lesser General Public License as published by the Free
006     * Software Foundation; either version 2.1 of the License, or (at your option)
007     * any later version.
008     *
009     * This library is distributed in the hope that it will be useful, but WITHOUT
010     * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
011     * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
012     * details.
013     */
014    
015    package com.liferay.portal.service.impl;
016    
017    import com.liferay.portal.NoSuchGroupException;
018    import com.liferay.portal.RemoteExportException;
019    import com.liferay.portal.kernel.dao.orm.QueryUtil;
020    import com.liferay.portal.kernel.exception.PortalException;
021    import com.liferay.portal.kernel.exception.SystemException;
022    import com.liferay.portal.kernel.io.unsync.UnsyncByteArrayInputStream;
023    import com.liferay.portal.kernel.language.LanguageUtil;
024    import com.liferay.portal.kernel.lar.ExportImportThreadLocal;
025    import com.liferay.portal.kernel.lar.MissingReferences;
026    import com.liferay.portal.kernel.log.Log;
027    import com.liferay.portal.kernel.log.LogFactoryUtil;
028    import com.liferay.portal.kernel.repository.model.FileEntry;
029    import com.liferay.portal.kernel.repository.model.Folder;
030    import com.liferay.portal.kernel.staging.LayoutStagingUtil;
031    import com.liferay.portal.kernel.staging.StagingConstants;
032    import com.liferay.portal.kernel.staging.StagingUtil;
033    import com.liferay.portal.kernel.util.ContentTypes;
034    import com.liferay.portal.kernel.util.FileUtil;
035    import com.liferay.portal.kernel.util.GetterUtil;
036    import com.liferay.portal.kernel.util.LocaleUtil;
037    import com.liferay.portal.kernel.util.ParamUtil;
038    import com.liferay.portal.kernel.util.PropsKeys;
039    import com.liferay.portal.kernel.util.StreamUtil;
040    import com.liferay.portal.kernel.util.UnicodeProperties;
041    import com.liferay.portal.kernel.util.Validator;
042    import com.liferay.portal.kernel.workflow.WorkflowConstants;
043    import com.liferay.portal.model.Group;
044    import com.liferay.portal.model.GroupConstants;
045    import com.liferay.portal.model.Layout;
046    import com.liferay.portal.model.LayoutRevision;
047    import com.liferay.portal.model.LayoutSet;
048    import com.liferay.portal.model.LayoutSetBranch;
049    import com.liferay.portal.model.LayoutSetBranchConstants;
050    import com.liferay.portal.model.LayoutStagingHandler;
051    import com.liferay.portal.model.Repository;
052    import com.liferay.portal.model.User;
053    import com.liferay.portal.portletfilerepository.PortletFileRepositoryUtil;
054    import com.liferay.portal.security.auth.HttpPrincipal;
055    import com.liferay.portal.security.auth.PrincipalException;
056    import com.liferay.portal.security.auth.RemoteAuthException;
057    import com.liferay.portal.security.permission.PermissionChecker;
058    import com.liferay.portal.security.permission.PermissionThreadLocal;
059    import com.liferay.portal.service.ServiceContext;
060    import com.liferay.portal.service.base.StagingLocalServiceBaseImpl;
061    import com.liferay.portal.service.http.GroupServiceHttp;
062    import com.liferay.portal.util.PortalUtil;
063    import com.liferay.portal.util.PortletKeys;
064    import com.liferay.portlet.documentlibrary.NoSuchFileEntryException;
065    import com.liferay.portlet.documentlibrary.NoSuchFolderException;
066    import com.liferay.portlet.documentlibrary.model.DLFolderConstants;
067    import com.liferay.portlet.documentlibrary.util.comparator.RepositoryModelNameComparator;
068    
069    import java.io.File;
070    import java.io.FileOutputStream;
071    import java.io.IOException;
072    import java.io.InputStream;
073    
074    import java.util.Date;
075    import java.util.HashMap;
076    import java.util.HashSet;
077    import java.util.List;
078    import java.util.Map;
079    import java.util.Set;
080    
081    import javax.portlet.PortletRequest;
082    
083    /**
084     * @author Michael C. Han
085     * @author Mate Thurzo
086     * @author Vilmos Papp
087     */
088    public class StagingLocalServiceImpl extends StagingLocalServiceBaseImpl {
089    
090            @Override
091            public void checkDefaultLayoutSetBranches(
092                            long userId, Group liveGroup, boolean branchingPublic,
093                            boolean branchingPrivate, boolean remote,
094                            ServiceContext serviceContext)
095                    throws PortalException, SystemException {
096    
097                    long targetGroupId = 0;
098    
099                    if (remote) {
100                            targetGroupId = liveGroup.getGroupId();
101                    }
102                    else {
103                            Group stagingGroup = liveGroup.getStagingGroup();
104    
105                            if (stagingGroup == null) {
106                                    return;
107                            }
108    
109                            targetGroupId = stagingGroup.getGroupId();
110                    }
111    
112                    LayoutSetBranch layoutSetBranch =
113                            layoutSetBranchLocalService.fetchLayoutSetBranch(
114                                    targetGroupId, false,
115                                    LayoutSetBranchConstants.MASTER_BRANCH_NAME);
116    
117                    if (branchingPublic && (layoutSetBranch == null)) {
118                            addDefaultLayoutSetBranch(
119                                    userId, targetGroupId, liveGroup.getDescriptiveName(), false,
120                                    serviceContext);
121                    }
122                    else if (!branchingPublic && (layoutSetBranch != null)) {
123                            deleteLayoutSetBranches(targetGroupId, false);
124                    }
125                    else if (layoutSetBranch != null) {
126                            clearLastPublishDate(targetGroupId, false);
127                    }
128    
129                    layoutSetBranch = layoutSetBranchLocalService.fetchLayoutSetBranch(
130                            targetGroupId, true, LayoutSetBranchConstants.MASTER_BRANCH_NAME);
131    
132                    if (branchingPrivate && (layoutSetBranch == null)) {
133                            addDefaultLayoutSetBranch(
134                                    userId, targetGroupId, liveGroup.getDescriptiveName(), true,
135                                    serviceContext);
136                    }
137                    else if (!branchingPrivate && (layoutSetBranch != null)) {
138                            deleteLayoutSetBranches(targetGroupId, true);
139                    }
140                    else if (layoutSetBranch != null) {
141                            clearLastPublishDate(targetGroupId, false);
142                    }
143            }
144    
145            @Override
146            public void cleanUpStagingRequest(long stagingRequestId)
147                    throws PortalException, SystemException {
148    
149                    try {
150                            PortletFileRepositoryUtil.deleteFolder(stagingRequestId);
151                    }
152                    catch (NoSuchFolderException nsfe) {
153                            if (_log.isDebugEnabled()) {
154                                    _log.debug(
155                                            "Unable to clean up staging request " + stagingRequestId,
156                                            nsfe);
157                            }
158                    }
159            }
160    
161            @Override
162            public long createStagingRequest(long userId, long groupId, String checksum)
163                    throws PortalException, SystemException {
164    
165                    ServiceContext serviceContext = new ServiceContext();
166    
167                    Repository repository = PortletFileRepositoryUtil.addPortletRepository(
168                            groupId, PortletKeys.SITES_ADMIN, serviceContext);
169    
170                    Folder folder = PortletFileRepositoryUtil.addPortletFolder(
171                            userId, repository.getRepositoryId(),
172                            DLFolderConstants.DEFAULT_PARENT_FOLDER_ID, checksum,
173                            serviceContext);
174    
175                    return folder.getFolderId();
176            }
177    
178            @Override
179            public void disableStaging(Group liveGroup, ServiceContext serviceContext)
180                    throws PortalException, SystemException {
181    
182                    disableStaging((PortletRequest)null, liveGroup, serviceContext);
183            }
184    
185            @Override
186            public void disableStaging(
187                            PortletRequest portletRequest, Group liveGroup,
188                            ServiceContext serviceContext)
189                    throws PortalException, SystemException {
190    
191                    UnicodeProperties typeSettingsProperties =
192                            liveGroup.getTypeSettingsProperties();
193    
194                    boolean stagedRemotely = GetterUtil.getBoolean(
195                            typeSettingsProperties.getProperty("stagedRemotely"));
196    
197                    if (stagedRemotely) {
198                            String remoteURL = StagingUtil.buildRemoteURL(
199                                    typeSettingsProperties);
200    
201                            long remoteGroupId = GetterUtil.getLong(
202                                    typeSettingsProperties.getProperty("remoteGroupId"));
203    
204                            disableRemoteStaging(remoteURL, remoteGroupId);
205                    }
206    
207                    typeSettingsProperties.remove("branchingPrivate");
208                    typeSettingsProperties.remove("branchingPublic");
209                    typeSettingsProperties.remove("remoteAddress");
210                    typeSettingsProperties.remove("remoteGroupId");
211                    typeSettingsProperties.remove("remotePathContext");
212                    typeSettingsProperties.remove("remotePort");
213                    typeSettingsProperties.remove("secureConnection");
214                    typeSettingsProperties.remove("staged");
215                    typeSettingsProperties.remove("stagedRemotely");
216    
217                    Set<String> keys = new HashSet<String>();
218    
219                    for (String key : typeSettingsProperties.keySet()) {
220                            if (key.startsWith(StagingConstants.STAGED_PORTLET)) {
221                                    keys.add(key);
222                            }
223                    }
224    
225                    for (String key : keys) {
226                            typeSettingsProperties.remove(key);
227                    }
228    
229                    StagingUtil.deleteLastImportSettings(liveGroup, true);
230                    StagingUtil.deleteLastImportSettings(liveGroup, false);
231    
232                    checkDefaultLayoutSetBranches(
233                            serviceContext.getUserId(), liveGroup, false, false, stagedRemotely,
234                            serviceContext);
235    
236                    if (liveGroup.hasStagingGroup()) {
237                            Group stagingGroup = liveGroup.getStagingGroup();
238    
239                            groupLocalService.deleteGroup(stagingGroup.getGroupId());
240    
241                            liveGroup.clearStagingGroup();
242                    }
243    
244                    groupLocalService.updateGroup(
245                            liveGroup.getGroupId(), typeSettingsProperties.toString());
246            }
247    
248            @Override
249            public void enableLocalStaging(
250                            long userId, Group liveGroup, boolean branchingPublic,
251                            boolean branchingPrivate, ServiceContext serviceContext)
252                    throws PortalException, SystemException {
253    
254                    if (liveGroup.isStagedRemotely()) {
255                            disableStaging(liveGroup, serviceContext);
256                    }
257    
258                    UnicodeProperties typeSettingsProperties =
259                            liveGroup.getTypeSettingsProperties();
260    
261                    typeSettingsProperties.setProperty(
262                            "branchingPrivate", String.valueOf(branchingPrivate));
263                    typeSettingsProperties.setProperty(
264                            "branchingPublic", String.valueOf(branchingPublic));
265                    typeSettingsProperties.setProperty("staged", Boolean.TRUE.toString());
266                    typeSettingsProperties.setProperty(
267                            "stagedRemotely", String.valueOf(false));
268    
269                    setCommonStagingOptions(
270                            liveGroup, typeSettingsProperties, serviceContext);
271    
272                    groupLocalService.updateGroup(
273                            liveGroup.getGroupId(), typeSettingsProperties.toString());
274    
275                    if (!liveGroup.hasStagingGroup()) {
276                            serviceContext.setAttribute("staging", String.valueOf(true));
277    
278                            Group stagingGroup = addStagingGroup(
279                                    userId, liveGroup, serviceContext);
280    
281                            Map<String, String[]> parameterMap =
282                                    StagingUtil.getStagingParameters();
283    
284                            if (liveGroup.hasPrivateLayouts()) {
285                                    StagingUtil.publishLayouts(
286                                            userId, liveGroup.getGroupId(), stagingGroup.getGroupId(),
287                                            true, parameterMap, null, null);
288                            }
289    
290                            if (liveGroup.hasPublicLayouts() ||
291                                    !liveGroup.hasPrivateLayouts()) {
292    
293                                    StagingUtil.publishLayouts(
294                                            userId, liveGroup.getGroupId(), stagingGroup.getGroupId(),
295                                            false, parameterMap, null, null);
296                            }
297                    }
298    
299                    checkDefaultLayoutSetBranches(
300                            userId, liveGroup, branchingPublic, branchingPrivate, false,
301                            serviceContext);
302            }
303    
304            @Override
305            public void enableRemoteStaging(
306                            long userId, Group liveGroup, boolean branchingPublic,
307                            boolean branchingPrivate, String remoteAddress, int remotePort,
308                            String remotePathContext, boolean secureConnection,
309                            long remoteGroupId, ServiceContext serviceContext)
310                    throws PortalException, SystemException {
311    
312                    StagingUtil.validateRemote(
313                            remoteAddress, remotePort, remotePathContext, secureConnection,
314                            remoteGroupId);
315    
316                    if (liveGroup.hasStagingGroup()) {
317                            disableStaging(liveGroup, serviceContext);
318                    }
319    
320                    String remoteURL = StagingUtil.buildRemoteURL(
321                            remoteAddress, remotePort, remotePathContext, secureConnection,
322                            GroupConstants.DEFAULT_LIVE_GROUP_ID, false);
323    
324                    UnicodeProperties typeSettingsProperties =
325                            liveGroup.getTypeSettingsProperties();
326    
327                    boolean stagedRemotely = GetterUtil.getBoolean(
328                            typeSettingsProperties.getProperty("stagedRemotely"));
329    
330                    if (stagedRemotely) {
331                            long oldRemoteGroupId = GetterUtil.getLong(
332                                    typeSettingsProperties.getProperty("remoteGroupId"));
333    
334                            String oldRemoteURL = StagingUtil.buildRemoteURL(
335                                    typeSettingsProperties);
336    
337                            if (!remoteURL.equals(oldRemoteURL) ||
338                                    (remoteGroupId != oldRemoteGroupId)) {
339    
340                                    disableRemoteStaging(oldRemoteURL, oldRemoteGroupId);
341    
342                                    stagedRemotely = false;
343                            }
344                    }
345    
346                    if (!stagedRemotely) {
347                            enableRemoteStaging(remoteURL, remoteGroupId);
348                    }
349    
350                    typeSettingsProperties.setProperty(
351                            "branchingPrivate", String.valueOf(branchingPrivate));
352                    typeSettingsProperties.setProperty(
353                            "branchingPublic", String.valueOf(branchingPublic));
354                    typeSettingsProperties.setProperty("remoteAddress", remoteAddress);
355                    typeSettingsProperties.setProperty(
356                            "remoteGroupId", String.valueOf(remoteGroupId));
357                    typeSettingsProperties.setProperty(
358                            "remotePathContext", remotePathContext);
359                    typeSettingsProperties.setProperty(
360                            "remotePort", String.valueOf(remotePort));
361                    typeSettingsProperties.setProperty(
362                            "secureConnection", String.valueOf(secureConnection));
363                    typeSettingsProperties.setProperty("staged", Boolean.TRUE.toString());
364                    typeSettingsProperties.setProperty(
365                            "stagedRemotely", Boolean.TRUE.toString());
366    
367                    setCommonStagingOptions(
368                            liveGroup, typeSettingsProperties, serviceContext);
369    
370                    groupLocalService.updateGroup(
371                            liveGroup.getGroupId(), typeSettingsProperties.toString());
372    
373                    updateStagedPortlets(remoteURL, remoteGroupId, typeSettingsProperties);
374    
375                    checkDefaultLayoutSetBranches(
376                            userId, liveGroup, branchingPublic, branchingPrivate, true,
377                            serviceContext);
378            }
379    
380            @Override
381            public void publishStagingRequest(
382                            long userId, long stagingRequestId, boolean privateLayout,
383                            Map<String, String[]> parameterMap)
384                    throws PortalException, SystemException {
385    
386                    try {
387                            ExportImportThreadLocal.setLayoutImportInProcess(true);
388    
389                            Folder folder = PortletFileRepositoryUtil.getPortletFolder(
390                                    stagingRequestId);
391    
392                            FileEntry stagingRequestFileEntry = getStagingRequestFileEntry(
393                                    userId, stagingRequestId, folder);
394    
395                            layoutLocalService.importLayouts(
396                                    userId, folder.getGroupId(), privateLayout, parameterMap,
397                                    stagingRequestFileEntry.getContentStream());
398                    }
399                    finally {
400                            ExportImportThreadLocal.setLayoutImportInProcess(false);
401                    }
402            }
403    
404            @Override
405            public void updateStagingRequest(
406                            long userId, long stagingRequestId, String fileName, byte[] bytes)
407                    throws PortalException, SystemException {
408    
409                    Folder folder = PortletFileRepositoryUtil.getPortletFolder(
410                            stagingRequestId);
411    
412                    PortletFileRepositoryUtil.addPortletFileEntry(
413                            folder.getGroupId(), userId, Group.class.getName(),
414                            folder.getGroupId(), PortletKeys.SITES_ADMIN, folder.getFolderId(),
415                            new UnsyncByteArrayInputStream(bytes), fileName,
416                            ContentTypes.APPLICATION_ZIP, false);
417            }
418    
419            @Override
420            public MissingReferences validateStagingRequest(
421                            long userId, long stagingRequestId, boolean privateLayout,
422                            Map<String, String[]> parameterMap)
423                    throws PortalException, SystemException {
424    
425                    try {
426                            ExportImportThreadLocal.setLayoutValidationInProcess(true);
427    
428                            Folder folder = PortletFileRepositoryUtil.getPortletFolder(
429                                    stagingRequestId);
430    
431                            FileEntry fileEntry = getStagingRequestFileEntry(
432                                    userId, stagingRequestId, folder);
433    
434                            return layoutLocalService.validateImportLayoutsFile(
435                                    userId, folder.getGroupId(), privateLayout, parameterMap,
436                                    fileEntry.getContentStream());
437                    }
438                    finally {
439                            ExportImportThreadLocal.setLayoutValidationInProcess(false);
440                    }
441            }
442    
443            protected void addDefaultLayoutSetBranch(
444                            long userId, long groupId, String groupName, boolean privateLayout,
445                            ServiceContext serviceContext)
446                    throws PortalException, SystemException {
447    
448                    String masterBranchDescription =
449                            LayoutSetBranchConstants.MASTER_BRANCH_DESCRIPTION_PUBLIC;
450    
451                    if (privateLayout) {
452                            masterBranchDescription =
453                                    LayoutSetBranchConstants.MASTER_BRANCH_DESCRIPTION_PRIVATE;
454                    }
455    
456                    String description = LanguageUtil.format(
457                            PortalUtil.getSiteDefaultLocale(groupId), masterBranchDescription,
458                            groupName, false);
459    
460                    try {
461                            serviceContext.setWorkflowAction(WorkflowConstants.STATUS_APPROVED);
462    
463                            LayoutSetBranch layoutSetBranch =
464                                    layoutSetBranchLocalService.addLayoutSetBranch(
465                                            userId, groupId, privateLayout,
466                                            LayoutSetBranchConstants.MASTER_BRANCH_NAME, description,
467                                            true, LayoutSetBranchConstants.ALL_BRANCHES,
468                                            serviceContext);
469    
470                            List<LayoutRevision> layoutRevisions =
471                                    layoutRevisionLocalService.getLayoutRevisions(
472                                            layoutSetBranch.getLayoutSetBranchId(), false);
473    
474                            for (LayoutRevision layoutRevision : layoutRevisions) {
475                                    layoutRevisionLocalService.updateStatus(
476                                            userId, layoutRevision.getLayoutRevisionId(),
477                                            WorkflowConstants.STATUS_APPROVED, serviceContext);
478                            }
479                    }
480                    catch (PortalException pe) {
481                            if (_log.isWarnEnabled()) {
482                                    _log.warn(
483                                            "Unable to create master branch for " +
484                                                    (privateLayout ? "private" : "public") + " layouts",
485                                            pe);
486                            }
487                    }
488            }
489    
490            protected Group addStagingGroup(
491                            long userId, Group liveGroup, ServiceContext serviceContext)
492                    throws PortalException, SystemException {
493    
494                    long parentGroupId = GroupConstants.DEFAULT_PARENT_GROUP_ID;
495    
496                    if (liveGroup.getParentGroupId() !=
497                                    GroupConstants.DEFAULT_PARENT_GROUP_ID) {
498    
499                            Group parentGroup = liveGroup.getParentGroup();
500    
501                            if (parentGroup.hasStagingGroup()) {
502                                    parentGroup = parentGroup.getStagingGroup();
503                            }
504    
505                            parentGroupId = parentGroup.getGroupId();
506                    }
507    
508                    Group stagingGroup = groupLocalService.addGroup(
509                            userId, parentGroupId, liveGroup.getClassName(),
510                            liveGroup.getClassPK(), liveGroup.getGroupId(),
511                            liveGroup.getDescriptiveName(), liveGroup.getDescription(),
512                            liveGroup.getType(), liveGroup.isManualMembership(),
513                            liveGroup.getMembershipRestriction(), liveGroup.getFriendlyURL(),
514                            false, liveGroup.isActive(), serviceContext);
515    
516                    if (LanguageUtil.isInheritLocales(liveGroup.getGroupId())) {
517                            return stagingGroup;
518                    }
519    
520                    UnicodeProperties liveTypeSettingsProperties =
521                            liveGroup.getTypeSettingsProperties();
522    
523                    UnicodeProperties stagingTypeSettingsProperties =
524                            stagingGroup.getTypeSettingsProperties();
525    
526                    stagingTypeSettingsProperties.setProperty(
527                            PropsKeys.LOCALES,
528                            liveTypeSettingsProperties.getProperty(PropsKeys.LOCALES));
529                    stagingTypeSettingsProperties.setProperty(
530                            "inheritLocales", Boolean.FALSE.toString());
531                    stagingTypeSettingsProperties.setProperty(
532                            "languageId",
533                            liveTypeSettingsProperties.getProperty(
534                                    "languageId",
535                                    LocaleUtil.toLanguageId(LocaleUtil.getDefault())));
536    
537                    return groupLocalService.updateGroup(
538                            stagingGroup.getGroupId(),
539                            stagingTypeSettingsProperties.toString());
540            }
541    
542            protected void clearLastPublishDate(long groupId, boolean privateLayout)
543                    throws PortalException, SystemException {
544    
545                    LayoutSet layoutSet = layoutSetLocalService.getLayoutSet(
546                            groupId, privateLayout);
547    
548                    UnicodeProperties settingsProperties =
549                            layoutSet.getSettingsProperties();
550    
551                    settingsProperties.remove("last-publish-date");
552    
553                    layoutSetLocalService.updateSettings(
554                            groupId, privateLayout, settingsProperties.toString());
555            }
556    
557            protected void deleteLayoutSetBranches(long groupId, boolean privateLayout)
558                    throws PortalException, SystemException {
559    
560                    // Find the latest layout revision for all the published layouts
561    
562                    Map<Long, LayoutRevision> layoutRevisions =
563                            new HashMap<Long, LayoutRevision>();
564    
565                    List<LayoutSetBranch> layoutSetBranches =
566                            layoutSetBranchLocalService.getLayoutSetBranches(
567                                    groupId, privateLayout);
568    
569                    for (LayoutSetBranch layoutSetBranch : layoutSetBranches) {
570                            String lastPublishDateString = layoutSetBranch.getSettingsProperty(
571                                    "last-publish-date");
572    
573                            if (Validator.isNull(lastPublishDateString)) {
574                                    continue;
575                            }
576    
577                            Date lastPublishDate = new Date(
578                                    GetterUtil.getLong(lastPublishDateString));
579    
580                            List<LayoutRevision> headLayoutRevisions =
581                                    layoutRevisionLocalService.getLayoutRevisions(
582                                            layoutSetBranch.getLayoutSetBranchId(), true);
583    
584                            for (LayoutRevision headLayoutRevision : headLayoutRevisions) {
585                                    LayoutRevision layoutRevision = layoutRevisions.get(
586                                            headLayoutRevision.getPlid());
587    
588                                    if (layoutRevision == null) {
589                                            layoutRevisions.put(
590                                                    headLayoutRevision.getPlid(), headLayoutRevision);
591    
592                                            continue;
593                                    }
594    
595                                    Date statusDate = headLayoutRevision.getStatusDate();
596    
597                                    if (statusDate.after(layoutRevision.getStatusDate()) &&
598                                            lastPublishDate.after(statusDate)) {
599    
600                                            layoutRevisions.put(
601                                                    headLayoutRevision.getPlid(), headLayoutRevision);
602                                    }
603                            }
604                    }
605    
606                    // Update all layouts based on their latest published revision
607    
608                    for (LayoutRevision layoutRevision : layoutRevisions.values()) {
609                            updateLayoutWithLayoutRevision(layoutRevision);
610                    }
611    
612                    layoutSetBranchLocalService.deleteLayoutSetBranches(
613                            groupId, privateLayout, true);
614            }
615    
616            protected void disableRemoteStaging(String remoteURL, long remoteGroupId)
617                    throws PortalException {
618    
619                    PermissionChecker permissionChecker =
620                            PermissionThreadLocal.getPermissionChecker();
621    
622                    User user = permissionChecker.getUser();
623    
624                    HttpPrincipal httpPrincipal = new HttpPrincipal(
625                            remoteURL, user.getScreenName(), user.getPassword(),
626                            user.getPasswordEncrypted());
627    
628                    try {
629                            GroupServiceHttp.disableStaging(httpPrincipal, remoteGroupId);
630                    }
631                    catch (NoSuchGroupException nsge) {
632                            if (_log.isWarnEnabled()) {
633                                    _log.warn("Remote live group was already deleted", nsge);
634                            }
635                    }
636                    catch (PrincipalException pe) {
637                            RemoteExportException ree = new RemoteExportException(
638                                    RemoteExportException.NO_PERMISSIONS);
639    
640                            ree.setGroupId(remoteGroupId);
641    
642                            throw ree;
643                    }
644                    catch (RemoteAuthException rae) {
645                            rae.setURL(remoteURL);
646    
647                            throw rae;
648                    }
649                    catch (SystemException se) {
650                            RemoteExportException ree = new RemoteExportException(
651                                    RemoteExportException.BAD_CONNECTION);
652    
653                            ree.setURL(remoteURL);
654    
655                            throw ree;
656                    }
657            }
658    
659            protected void enableRemoteStaging(String remoteURL, long remoteGroupId)
660                    throws PortalException {
661    
662                    PermissionChecker permissionChecker =
663                            PermissionThreadLocal.getPermissionChecker();
664    
665                    User user = permissionChecker.getUser();
666    
667                    HttpPrincipal httpPrincipal = new HttpPrincipal(
668                            remoteURL, user.getScreenName(), user.getPassword(),
669                            user.getPasswordEncrypted());
670    
671                    try {
672                            GroupServiceHttp.enableStaging(httpPrincipal, remoteGroupId);
673                    }
674                    catch (NoSuchGroupException nsge) {
675                            RemoteExportException ree = new RemoteExportException(
676                                    RemoteExportException.NO_GROUP);
677    
678                            ree.setGroupId(remoteGroupId);
679    
680                            throw ree;
681                    }
682                    catch (PrincipalException pe) {
683                            RemoteExportException ree = new RemoteExportException(
684                                    RemoteExportException.NO_PERMISSIONS);
685    
686                            ree.setGroupId(remoteGroupId);
687    
688                            throw ree;
689                    }
690                    catch (RemoteAuthException rae) {
691                            rae.setURL(remoteURL);
692    
693                            throw rae;
694                    }
695                    catch (SystemException se) {
696                            RemoteExportException ree = new RemoteExportException(
697                                    RemoteExportException.BAD_CONNECTION);
698    
699                            ree.setURL(remoteURL);
700    
701                            throw ree;
702                    }
703            }
704    
705            protected FileEntry fetchStagingRequestFileEntry(
706                            long stagingRequestId, Folder folder)
707                    throws PortalException, SystemException {
708    
709                    try {
710                            return PortletFileRepositoryUtil.getPortletFileEntry(
711                                    folder.getGroupId(), folder.getFolderId(),
712                                    getAssembledFileName(stagingRequestId));
713                    }
714                    catch (NoSuchFileEntryException nsfe) {
715                            return null;
716                    }
717            }
718    
719            protected String getAssembledFileName(long stagingRequestId) {
720                    return _ASSEMBLED_LAR_PREFIX + String.valueOf(stagingRequestId) +
721                            ".lar";
722            }
723    
724            protected FileEntry getStagingRequestFileEntry(
725                            long userId, long stagingRequestId, Folder folder)
726                    throws PortalException, SystemException {
727    
728                    FileEntry stagingRequestFileEntry = fetchStagingRequestFileEntry(
729                            stagingRequestId, folder);
730    
731                    if (stagingRequestFileEntry != null) {
732                            return stagingRequestFileEntry;
733                    }
734    
735                    FileOutputStream fileOutputStream = null;
736    
737                    File tempFile = null;
738    
739                    try {
740                            tempFile = FileUtil.createTempFile("lar");
741    
742                            fileOutputStream = new FileOutputStream(tempFile);
743    
744                            List<FileEntry> fileEntries =
745                                    PortletFileRepositoryUtil.getPortletFileEntries(
746                                            folder.getGroupId(), folder.getFolderId(),
747                                            WorkflowConstants.STATUS_ANY, QueryUtil.ALL_POS,
748                                            QueryUtil.ALL_POS, new RepositoryModelNameComparator(true));
749    
750                            for (FileEntry fileEntry : fileEntries) {
751                                    InputStream inputStream = fileEntry.getContentStream();
752    
753                                    try {
754                                            StreamUtil.transfer(inputStream, fileOutputStream, false);
755                                    }
756                                    finally {
757                                            StreamUtil.cleanUp(inputStream);
758    
759                                            PortletFileRepositoryUtil.deletePortletFileEntry(
760                                                    fileEntry.getFileEntryId());
761                                    }
762                            }
763    
764                            String checksum = FileUtil.getMD5Checksum(tempFile);
765    
766                            if (!checksum.equals(folder.getName())) {
767                                    throw new SystemException("Invalid checksum for LAR file");
768                            }
769    
770                            PortletFileRepositoryUtil.addPortletFileEntry(
771                                    folder.getGroupId(), userId, Group.class.getName(),
772                                    folder.getGroupId(), PortletKeys.SITES_ADMIN,
773                                    folder.getFolderId(), tempFile,
774                                    getAssembledFileName(stagingRequestId),
775                                    ContentTypes.APPLICATION_ZIP, false);
776    
777                            stagingRequestFileEntry = fetchStagingRequestFileEntry(
778                                    stagingRequestId, folder);
779    
780                            if (stagingRequestFileEntry == null) {
781                                    throw new SystemException("Unable to assemble LAR file");
782                            }
783    
784                            return stagingRequestFileEntry;
785                    }
786                    catch (IOException ioe) {
787                            throw new SystemException("Unable to reassemble LAR file", ioe);
788                    }
789                    finally {
790                            StreamUtil.cleanUp(fileOutputStream);
791    
792                            FileUtil.delete(tempFile);
793                    }
794            }
795    
796            protected void setCommonStagingOptions(
797                    Group liveGroup, UnicodeProperties typeSettingsProperties,
798                    ServiceContext serviceContext) {
799    
800                    if (liveGroup.getRemoteStagingGroupCount() > 0) {
801                            return;
802                    }
803    
804                    Set<String> parameterNames = serviceContext.getAttributes().keySet();
805    
806                    for (String parameterName : parameterNames) {
807                            if (parameterName.startsWith(StagingConstants.STAGED_PORTLET) &&
808                                    !parameterName.endsWith("Checkbox")) {
809    
810                                    boolean staged = ParamUtil.getBoolean(
811                                            serviceContext, parameterName);
812    
813                                    typeSettingsProperties.setProperty(
814                                            parameterName, String.valueOf(staged));
815                            }
816                    }
817            }
818    
819            protected Layout updateLayoutWithLayoutRevision(
820                            LayoutRevision layoutRevision)
821                    throws SystemException {
822    
823                    Layout layout = layoutLocalService.fetchLayout(
824                            layoutRevision.getPlid());
825    
826                    LayoutStagingHandler layoutStagingHandler =
827                            LayoutStagingUtil.getLayoutStagingHandler(layout);
828    
829                    layout = layoutStagingHandler.getLayout();
830    
831                    layout.setUserId(layoutRevision.getUserId());
832                    layout.setUserName(layoutRevision.getUserName());
833                    layout.setCreateDate(layoutRevision.getCreateDate());
834                    layout.setModifiedDate(layoutRevision.getModifiedDate());
835                    layout.setPrivateLayout(layoutRevision.getPrivateLayout());
836                    layout.setName(layoutRevision.getName());
837                    layout.setTitle(layoutRevision.getTitle());
838                    layout.setDescription(layoutRevision.getDescription());
839                    layout.setKeywords(layoutRevision.getKeywords());
840                    layout.setRobots(layoutRevision.getRobots());
841                    layout.setTypeSettings(layoutRevision.getTypeSettings());
842                    layout.setIconImageId(layoutRevision.getIconImageId());
843                    layout.setThemeId(layoutRevision.getThemeId());
844                    layout.setColorSchemeId(layoutRevision.getColorSchemeId());
845                    layout.setWapThemeId(layoutRevision.getWapThemeId());
846                    layout.setWapColorSchemeId(layoutRevision.getWapColorSchemeId());
847                    layout.setCss(layoutRevision.getCss());
848    
849                    return layoutLocalService.updateLayout(layout);
850            }
851    
852            protected void updateStagedPortlets(
853                            String remoteURL, long remoteGroupId,
854                            UnicodeProperties typeSettingsProperties)
855                    throws PortalException {
856    
857                    PermissionChecker permissionChecker =
858                            PermissionThreadLocal.getPermissionChecker();
859    
860                    User user = permissionChecker.getUser();
861    
862                    HttpPrincipal httpPrincipal = new HttpPrincipal(
863                            remoteURL, user.getScreenName(), user.getPassword(),
864                            user.getPasswordEncrypted());
865    
866                    Map<String, String> stagedPortletIds = new HashMap<String, String>();
867    
868                    for (String key : typeSettingsProperties.keySet()) {
869                            if (key.startsWith(StagingConstants.STAGED_PORTLET)) {
870                                    stagedPortletIds.put(
871                                            key, typeSettingsProperties.getProperty(key));
872                            }
873                    }
874    
875                    try {
876                            GroupServiceHttp.updateStagedPortlets(
877                                    httpPrincipal, remoteGroupId, stagedPortletIds);
878                    }
879                    catch (NoSuchGroupException nsge) {
880                            RemoteExportException ree = new RemoteExportException(
881                                    RemoteExportException.NO_GROUP);
882    
883                            ree.setGroupId(remoteGroupId);
884    
885                            throw ree;
886                    }
887                    catch (PrincipalException pe) {
888                            RemoteExportException ree = new RemoteExportException(
889                                    RemoteExportException.NO_PERMISSIONS);
890    
891                            ree.setGroupId(remoteGroupId);
892    
893                            throw ree;
894                    }
895                    catch (RemoteAuthException rae) {
896                            rae.setURL(remoteURL);
897    
898                            throw rae;
899                    }
900                    catch (SystemException se) {
901                            RemoteExportException ree = new RemoteExportException(
902                                    RemoteExportException.BAD_CONNECTION);
903    
904                            ree.setURL(remoteURL);
905    
906                            throw ree;
907                    }
908            }
909    
910            private static final String _ASSEMBLED_LAR_PREFIX = "assembled_";
911    
912            private static Log _log = LogFactoryUtil.getLog(
913                    StagingLocalServiceImpl.class);
914    
915    }