/** * Copyright (c) 2000-present Liferay, Inc. All rights reserved. * * This library is free software; you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License as published by the Free * Software Foundation; either version 2.1 of the License, or (at your option) * any later version. * * This library is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more * details. */ package com.liferay.exportimport.controller; import static com.liferay.exportimport.kernel.lifecycle.ExportImportLifecycleConstants.EVENT_LAYOUT_EXPORT_FAILED; import static com.liferay.exportimport.kernel.lifecycle.ExportImportLifecycleConstants.EVENT_LAYOUT_EXPORT_STARTED; import static com.liferay.exportimport.kernel.lifecycle.ExportImportLifecycleConstants.EVENT_LAYOUT_EXPORT_SUCCEEDED; import static com.liferay.exportimport.kernel.lifecycle.ExportImportLifecycleConstants.PROCESS_FLAG_LAYOUT_EXPORT_IN_PROCESS; import static com.liferay.exportimport.kernel.lifecycle.ExportImportLifecycleConstants.PROCESS_FLAG_LAYOUT_STAGING_IN_PROCESS; import aQute.bnd.annotation.ProviderType; import com.liferay.exportimport.constants.ExportImportConstants; import com.liferay.exportimport.kernel.controller.ExportController; import com.liferay.exportimport.kernel.controller.ExportImportController; import com.liferay.exportimport.kernel.lar.ExportImportDateUtil; import com.liferay.exportimport.kernel.lar.ExportImportHelperUtil; import com.liferay.exportimport.kernel.lar.ExportImportThreadLocal; import com.liferay.exportimport.kernel.lar.PortletDataContext; import com.liferay.exportimport.kernel.lar.PortletDataContextFactoryUtil; import com.liferay.exportimport.kernel.lar.PortletDataHandlerKeys; import com.liferay.exportimport.kernel.lar.StagedModelDataHandlerUtil; import com.liferay.exportimport.kernel.lifecycle.ExportImportLifecycleManager; import com.liferay.exportimport.kernel.model.ExportImportConfiguration; import com.liferay.exportimport.kernel.staging.LayoutStagingUtil; import com.liferay.exportimport.lar.DeletionSystemEventExporter; import com.liferay.exportimport.lar.PermissionExporter; import com.liferay.portal.background.task.model.BackgroundTask; import com.liferay.portal.background.task.service.BackgroundTaskLocalService; import com.liferay.portal.kernel.backgroundtask.BackgroundTaskThreadLocal; import com.liferay.portal.kernel.language.LanguageUtil; import com.liferay.portal.kernel.log.Log; import com.liferay.portal.kernel.log.LogFactoryUtil; import com.liferay.portal.kernel.model.Group; import com.liferay.portal.kernel.model.Layout; import com.liferay.portal.kernel.model.LayoutPrototype; import com.liferay.portal.kernel.model.LayoutSet; import com.liferay.portal.kernel.model.LayoutSetPrototype; import com.liferay.portal.kernel.model.adapter.ModelAdapterUtil; import com.liferay.portal.kernel.service.GroupLocalService; import com.liferay.portal.kernel.service.ImageLocalService; import com.liferay.portal.kernel.service.LayoutLocalService; import com.liferay.portal.kernel.service.LayoutPrototypeLocalService; import com.liferay.portal.kernel.service.LayoutRevisionLocalService; import com.liferay.portal.kernel.service.LayoutSetBranchLocalService; import com.liferay.portal.kernel.service.LayoutSetLocalService; import com.liferay.portal.kernel.service.LayoutSetPrototypeLocalService; import com.liferay.portal.kernel.service.ServiceContext; import com.liferay.portal.kernel.service.ServiceContextThreadLocal; import com.liferay.portal.kernel.service.UserLocalService; import com.liferay.portal.kernel.util.DateRange; import com.liferay.portal.kernel.util.GetterUtil; import com.liferay.portal.kernel.util.LocaleUtil; import com.liferay.portal.kernel.util.MapUtil; import com.liferay.portal.kernel.util.ReleaseInfo; import com.liferay.portal.kernel.util.StringUtil; import com.liferay.portal.kernel.util.Time; import com.liferay.portal.kernel.util.Validator; import com.liferay.portal.kernel.xml.Document; import com.liferay.portal.kernel.xml.Element; import com.liferay.portal.kernel.xml.SAXReaderUtil; import com.liferay.portal.kernel.zip.ZipWriter; import com.liferay.site.model.adapter.StagedGroup; import java.io.File; import java.io.Serializable; import java.util.Map; import org.apache.commons.lang.time.StopWatch; import org.osgi.service.component.annotations.Component; import org.osgi.service.component.annotations.Reference; /** * @author Brian Wing Shun Chan * @author Joel Kozikowski * @author Charles May * @author Raymond Augé * @author Jorge Ferrer * @author Bruno Farache * @author Karthik Sudarshan * @author Zsigmond Rab * @author Douglas Wong * @author Mate Thurzo */ @Component( immediate = true, property = {"model.class.name=com.liferay.portal.kernel.model.Layout"}, service = {ExportImportController.class, LayoutExportController.class} ) @ProviderType public class LayoutExportController implements ExportController { @Override public File export(ExportImportConfiguration exportImportConfiguration) throws Exception { PortletDataContext portletDataContext = null; try { ExportImportThreadLocal.setLayoutExportInProcess(true); portletDataContext = getPortletDataContext( exportImportConfiguration); _exportImportLifecycleManager.fireExportImportLifecycleEvent( EVENT_LAYOUT_EXPORT_STARTED, getProcessFlag(), String.valueOf( exportImportConfiguration.getExportImportConfigurationId()), PortletDataContextFactoryUtil.clonePortletDataContext( portletDataContext)); File file = doExport(portletDataContext); ExportImportThreadLocal.setLayoutExportInProcess(false); _exportImportLifecycleManager.fireExportImportLifecycleEvent( EVENT_LAYOUT_EXPORT_SUCCEEDED, getProcessFlag(), String.valueOf( exportImportConfiguration.getExportImportConfigurationId()), PortletDataContextFactoryUtil.clonePortletDataContext( portletDataContext)); return file; } catch (Throwable t) { ExportImportThreadLocal.setLayoutExportInProcess(false); _exportImportLifecycleManager.fireExportImportLifecycleEvent( EVENT_LAYOUT_EXPORT_FAILED, getProcessFlag(), String.valueOf( exportImportConfiguration.getExportImportConfigurationId()), PortletDataContextFactoryUtil.clonePortletDataContext( portletDataContext), t); throw t; } } protected File doExport(PortletDataContext portletDataContext) throws Exception { Map<String, String[]> parameterMap = portletDataContext.getParameterMap(); boolean ignoreLastPublishDate = MapUtil.getBoolean( parameterMap, PortletDataHandlerKeys.IGNORE_LAST_PUBLISH_DATE); boolean permissions = MapUtil.getBoolean( parameterMap, PortletDataHandlerKeys.PERMISSIONS); if (_log.isDebugEnabled()) { _log.debug("Export permissions " + permissions); } long companyId = portletDataContext.getCompanyId(); long defaultUserId = _userLocalService.getDefaultUserId(companyId); ServiceContext serviceContext = ServiceContextThreadLocal.popServiceContext(); if (serviceContext == null) { serviceContext = new ServiceContext(); } serviceContext.setCompanyId(companyId); serviceContext.setSignedIn(true); if (BackgroundTaskThreadLocal.hasBackgroundTask()) { BackgroundTask backgroundTask = _backgroundTaskLocalService.getBackgroundTask( BackgroundTaskThreadLocal.getBackgroundTaskId()); serviceContext.setUserId(backgroundTask.getUserId()); } else { serviceContext.setUserId(defaultUserId); } serviceContext.setAttribute("exporting", Boolean.TRUE); long layoutSetBranchId = MapUtil.getLong( parameterMap, "layoutSetBranchId"); serviceContext.setAttribute("layoutSetBranchId", layoutSetBranchId); ServiceContextThreadLocal.pushServiceContext(serviceContext); if (ignoreLastPublishDate) { portletDataContext.setEndDate(null); portletDataContext.setStartDate(null); } StopWatch stopWatch = new StopWatch(); stopWatch.start(); Document document = SAXReaderUtil.createDocument(); Element rootElement = document.addElement("root"); portletDataContext.setExportDataRootElement(rootElement); Element headerElement = rootElement.addElement("header"); headerElement.addAttribute( "available-locales", StringUtil.merge( LanguageUtil.getAvailableLocales( portletDataContext.getScopeGroupId()))); headerElement.addAttribute( "build-number", String.valueOf(ReleaseInfo.getBuildNumber())); headerElement.addAttribute( "schema-version", ExportImportConstants.EXPORT_IMPORT_SCHEMA_VERSION); headerElement.addAttribute("export-date", Time.getRFC822()); if (portletDataContext.hasDateRange()) { headerElement.addAttribute( "start-date", String.valueOf(portletDataContext.getStartDate())); headerElement.addAttribute( "end-date", String.valueOf(portletDataContext.getEndDate())); } headerElement.addAttribute( "company-id", String.valueOf(portletDataContext.getCompanyId())); headerElement.addAttribute( "company-group-id", String.valueOf(portletDataContext.getCompanyGroupId())); headerElement.addAttribute( "group-id", String.valueOf(portletDataContext.getGroupId())); headerElement.addAttribute( "user-personal-site-group-id", String.valueOf(portletDataContext.getUserPersonalSiteGroupId())); headerElement.addAttribute( "private-layout", String.valueOf(portletDataContext.isPrivateLayout())); Group group = _groupLocalService.fetchGroup( portletDataContext.getGroupId()); String type = "layout-set"; if (group.isLayoutPrototype()) { type = "layout-prototype"; LayoutPrototype layoutPrototype = _layoutPrototypeLocalService.getLayoutPrototype( group.getClassPK()); headerElement.addAttribute("type-uuid", layoutPrototype.getUuid()); } else if (group.isLayoutSetPrototype()) { type = "layout-set-prototype"; LayoutSetPrototype layoutSetPrototype = _layoutSetPrototypeLocalService.getLayoutSetPrototype( group.getClassPK()); headerElement.addAttribute( "type-uuid", layoutSetPrototype.getUuid()); } headerElement.addAttribute("type", type); portletDataContext.setType(type); Element missingReferencesElement = rootElement.addElement( "missing-references"); portletDataContext.setMissingReferencesElement( missingReferencesElement); rootElement.addElement("site-portlets"); rootElement.addElement("site-services"); // Export the group LayoutSet layoutSet = _layoutSetLocalService.getLayoutSet( portletDataContext.getGroupId(), portletDataContext.isPrivateLayout()); String layoutSetPrototypeUuid = layoutSet.getLayoutSetPrototypeUuid(); if (!group.isStaged() && Validator.isNotNull(layoutSetPrototypeUuid)) { LayoutSetPrototype layoutSetPrototype = _layoutSetPrototypeLocalService. getLayoutSetPrototypeByUuidAndCompanyId( layoutSetPrototypeUuid, companyId); headerElement.addAttribute( "layout-set-prototype-uuid", layoutSetPrototypeUuid); headerElement.addAttribute( "layout-set-prototype-name", layoutSetPrototype.getName(LocaleUtil.getDefault())); } StagedGroup stagedGroup = ModelAdapterUtil.adapt( group, Group.class, StagedGroup.class); StagedModelDataHandlerUtil.exportStagedModel( portletDataContext, stagedGroup); // Export other models _portletExportController.exportAssetLinks(portletDataContext); _portletExportController.exportExpandoTables(portletDataContext); _portletExportController.exportLocks(portletDataContext); _deletionSystemEventExporter.exportDeletionSystemEvents( portletDataContext); if (permissions) { _permissionExporter.exportPortletDataPermissions( portletDataContext); } ExportImportHelperUtil.writeManifestSummary( document, portletDataContext.getManifestSummary()); if (_log.isInfoEnabled()) { _log.info("Exporting layouts takes " + stopWatch.getTime() + " ms"); } portletDataContext.addZipEntry( "/manifest.xml", document.formattedString()); ZipWriter zipWriter = portletDataContext.getZipWriter(); return zipWriter.getFile(); } /** * @deprecated As of 4.0.0 */ @Deprecated protected File doExport( PortletDataContext portletDataContext, long[] layoutIds) throws Exception { return doExport(portletDataContext); } /** * @deprecated As of 4.0.0 */ @Deprecated protected void exportLayout( PortletDataContext portletDataContext, long[] layoutIds, Layout layout) throws Exception { StagedModelDataHandlerUtil.exportStagedModel( portletDataContext, layout); } /** * @deprecated As of 4.0.0 */ @Deprecated protected void getLayoutPortlets( PortletDataContext portletDataContext, long[] layoutIds, Map<String, Object[]> portletIds, Layout layout) throws Exception { } protected PortletDataContext getPortletDataContext( ExportImportConfiguration exportImportConfiguration) throws Exception { Map<String, Serializable> settingsMap = exportImportConfiguration.getSettingsMap(); long sourceGroupId = MapUtil.getLong(settingsMap, "sourceGroupId"); Group group = _groupLocalService.getGroup(sourceGroupId); Map<String, String[]> parameterMap = (Map<String, String[]>)settingsMap.get("parameterMap"); DateRange dateRange = ExportImportDateUtil.getDateRange( exportImportConfiguration); ZipWriter zipWriter = ExportImportHelperUtil.getLayoutSetZipWriter( sourceGroupId); PortletDataContext portletDataContext = PortletDataContextFactoryUtil.createExportPortletDataContext( group.getCompanyId(), sourceGroupId, parameterMap, dateRange.getStartDate(), dateRange.getEndDate(), zipWriter); boolean privateLayout = MapUtil.getBoolean( settingsMap, "privateLayout"); long[] layoutIds = GetterUtil.getLongValues( settingsMap.get("layoutIds")); portletDataContext.setExportImportProcessId( String.valueOf( exportImportConfiguration.getExportImportConfigurationId())); portletDataContext.setPrivateLayout(privateLayout); portletDataContext.setLayoutIds(layoutIds); return portletDataContext; } protected int getProcessFlag() { if (ExportImportThreadLocal.isLayoutStagingInProcess()) { return PROCESS_FLAG_LAYOUT_STAGING_IN_PROCESS; } return PROCESS_FLAG_LAYOUT_EXPORT_IN_PROCESS; } /** * @deprecated As of 4.0.0 */ @Deprecated protected boolean prepareLayoutStagingHandler( PortletDataContext portletDataContext, Layout layout) { return LayoutStagingUtil.prepareLayoutStagingHandler( portletDataContext, layout); } /** * @deprecated As of 4.0.0 */ @Deprecated protected void setBackgroundTaskLocalService( BackgroundTaskLocalService backgroundTaskLocalService) { } /** * @deprecated As of 4.0.0 */ @Deprecated protected void setExportImportLifecycleManager( ExportImportLifecycleManager exportImportLifecycleManager) { } /** * @deprecated As of 4.0.0 */ @Deprecated protected void setGroupLocalService(GroupLocalService groupLocalService) { } /** * @deprecated As of 4.0.0 */ @Deprecated protected void setImageLocalService(ImageLocalService imageLocalService) { } /** * @deprecated As of 4.0.0 */ @Deprecated protected void setLayoutLocalService( LayoutLocalService layoutLocalService) { } /** * @deprecated As of 4.0.0 */ @Deprecated protected void setLayoutPrototypeLocalService( LayoutPrototypeLocalService layoutPrototypeLocalService) { _layoutPrototypeLocalService = layoutPrototypeLocalService; } /** * @deprecated As of 4.0.0 */ @Deprecated protected void setLayoutRevisionLocalService( LayoutRevisionLocalService layoutRevisionLocalService) { } /** * @deprecated As of 4.0.0 */ @Deprecated protected void setLayoutSetBranchLocalService( LayoutSetBranchLocalService layoutSetBranchLocalService) { } /** * @deprecated As of 4.0.0 */ @Deprecated protected void setLayoutSetLocalService( LayoutSetLocalService layoutSetLocalService) { } /** * @deprecated As of 4.0.0 */ @Deprecated protected void setLayoutSetPrototypeLocalService( LayoutSetPrototypeLocalService layoutSetPrototypeLocalService) { } /** * @deprecated As of 4.0.0 */ @Deprecated protected void setPortletExportController( PortletExportController portletExportController) { } /** * @deprecated As of 4.0.0 */ @Deprecated protected void setUserLocalService(UserLocalService userLocalService) { } private static final Log _log = LogFactoryUtil.getLog( LayoutExportController.class); @Reference private BackgroundTaskLocalService _backgroundTaskLocalService; private final DeletionSystemEventExporter _deletionSystemEventExporter = DeletionSystemEventExporter.getInstance(); @Reference private ExportImportLifecycleManager _exportImportLifecycleManager; @Reference private GroupLocalService _groupLocalService; @Reference private LayoutPrototypeLocalService _layoutPrototypeLocalService; @Reference private LayoutSetLocalService _layoutSetLocalService; @Reference private LayoutSetPrototypeLocalService _layoutSetPrototypeLocalService; private final PermissionExporter _permissionExporter = PermissionExporter.getInstance(); @Reference private PortletExportController _portletExportController; @Reference private UserLocalService _userLocalService; }