/**
* 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;
}