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