/** * 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_PORTLET_EXPORT_FAILED; import static com.liferay.exportimport.kernel.lifecycle.ExportImportLifecycleConstants.EVENT_PORTLET_EXPORT_STARTED; import static com.liferay.exportimport.kernel.lifecycle.ExportImportLifecycleConstants.EVENT_PORTLET_EXPORT_SUCCEEDED; import static com.liferay.exportimport.kernel.lifecycle.ExportImportLifecycleConstants.PROCESS_FLAG_PORTLET_EXPORT_IN_PROCESS; import static com.liferay.exportimport.kernel.lifecycle.ExportImportLifecycleConstants.PROCESS_FLAG_PORTLET_STAGING_IN_PROCESS; import aQute.bnd.annotation.ProviderType; import com.liferay.asset.kernel.model.AssetLink; import com.liferay.asset.kernel.model.adapter.StagedAssetLink; import com.liferay.asset.kernel.service.AssetEntryLocalService; import com.liferay.asset.kernel.service.AssetLinkLocalService; import com.liferay.expando.kernel.model.ExpandoColumn; import com.liferay.exportimport.kernel.controller.ExportController; import com.liferay.exportimport.kernel.controller.ExportImportController; import com.liferay.exportimport.kernel.exception.LayoutImportException; import com.liferay.exportimport.kernel.lar.ExportImportDateUtil; import com.liferay.exportimport.kernel.lar.ExportImportHelperUtil; import com.liferay.exportimport.kernel.lar.ExportImportPathUtil; import com.liferay.exportimport.kernel.lar.ExportImportProcessCallbackRegistryUtil; import com.liferay.exportimport.kernel.lar.ExportImportThreadLocal; import com.liferay.exportimport.kernel.lar.ManifestSummary; import com.liferay.exportimport.kernel.lar.PortletDataContext; import com.liferay.exportimport.kernel.lar.PortletDataContextFactoryUtil; import com.liferay.exportimport.kernel.lar.PortletDataHandler; import com.liferay.exportimport.kernel.lar.PortletDataHandlerKeys; import com.liferay.exportimport.kernel.lar.PortletDataHandlerStatusMessageSenderUtil; import com.liferay.exportimport.kernel.lifecycle.ExportImportLifecycleManager; import com.liferay.exportimport.kernel.model.ExportImportConfiguration; import com.liferay.exportimport.lar.DeletionSystemEventExporter; import com.liferay.exportimport.lar.PermissionExporter; import com.liferay.exportimport.portlet.data.handler.provider.PortletDataHandlerProvider; import com.liferay.exportimport.portlet.preferences.processor.Capability; import com.liferay.exportimport.portlet.preferences.processor.ExportImportPortletPreferencesProcessor; import com.liferay.exportimport.portlet.preferences.processor.ExportImportPortletPreferencesProcessorRegistryUtil; import com.liferay.petra.xml.DocUtil; import com.liferay.portal.kernel.backgroundtask.BackgroundTaskThreadLocal; import com.liferay.portal.kernel.dao.orm.ActionableDynamicQuery; import com.liferay.portal.kernel.exception.NoSuchPortletPreferencesException; import com.liferay.portal.kernel.exception.PortalException; import com.liferay.portal.kernel.exception.SystemException; import com.liferay.portal.kernel.language.LanguageUtil; import com.liferay.portal.kernel.lock.Lock; 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.LayoutConstants; import com.liferay.portal.kernel.model.LayoutTypePortlet; import com.liferay.portal.kernel.model.Portlet; import com.liferay.portal.kernel.model.PortletConstants; import com.liferay.portal.kernel.model.PortletItem; import com.liferay.portal.kernel.model.PortletPreferences; import com.liferay.portal.kernel.model.User; import com.liferay.portal.kernel.model.adapter.ModelAdapterUtil; import com.liferay.portal.kernel.portlet.PortletPreferencesFactoryUtil; import com.liferay.portal.kernel.service.GroupLocalService; import com.liferay.portal.kernel.service.LayoutLocalService; import com.liferay.portal.kernel.service.PortletItemLocalService; import com.liferay.portal.kernel.service.PortletLocalService; import com.liferay.portal.kernel.service.PortletPreferencesLocalService; 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.CharPool; import com.liferay.portal.kernel.util.DateRange; import com.liferay.portal.kernel.util.GetterUtil; import com.liferay.portal.kernel.util.ListUtil; import com.liferay.portal.kernel.util.MapUtil; import com.liferay.portal.kernel.util.Portal; import com.liferay.portal.kernel.util.PortletKeys; import com.liferay.portal.kernel.util.ReleaseInfo; import com.liferay.portal.kernel.util.StringBundler; import com.liferay.portal.kernel.util.StringPool; import com.liferay.portal.kernel.util.StringUtil; import com.liferay.portal.kernel.util.Time; import com.liferay.portal.kernel.util.UnicodeProperties; 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.Node; import com.liferay.portal.kernel.xml.SAXReaderUtil; import com.liferay.portal.kernel.zip.ZipWriter; import java.io.File; import java.io.IOException; import java.io.Serializable; import java.util.Date; import java.util.List; import java.util.Map; import java.util.concurrent.Callable; 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 Zsigmond Rab * @author Douglas Wong * @author Mate Thurzo */ @Component( immediate = true, property = {"model.class.name=com.liferay.portal.kernel.model.Portlet"}, service = {ExportImportController.class, PortletExportController.class} ) @ProviderType public class PortletExportController implements ExportController { @Override public File export(ExportImportConfiguration exportImportConfiguration) throws Exception { PortletDataContext portletDataContext = null; try { ExportImportThreadLocal.setPortletExportInProcess(true); portletDataContext = getPortletDataContext( exportImportConfiguration); _exportImportLifecycleManager.fireExportImportLifecycleEvent( EVENT_PORTLET_EXPORT_STARTED, getProcessFlag(), String.valueOf( exportImportConfiguration.getExportImportConfigurationId()), PortletDataContextFactoryUtil.clonePortletDataContext( portletDataContext)); File file = doExport(portletDataContext); ExportImportThreadLocal.setPortletExportInProcess(false); _exportImportLifecycleManager.fireExportImportLifecycleEvent( EVENT_PORTLET_EXPORT_SUCCEEDED, getProcessFlag(), String.valueOf( exportImportConfiguration.getExportImportConfigurationId()), PortletDataContextFactoryUtil.clonePortletDataContext( portletDataContext)); return file; } catch (Throwable t) { ExportImportThreadLocal.setPortletExportInProcess(false); _exportImportLifecycleManager.fireExportImportLifecycleEvent( EVENT_PORTLET_EXPORT_FAILED, getProcessFlag(), String.valueOf( exportImportConfiguration.getExportImportConfigurationId()), PortletDataContextFactoryUtil.clonePortletDataContext( portletDataContext), t); throw t; } } public void exportPortlet( PortletDataContext portletDataContext, long plid, Element parentElement, boolean exportPermissions, boolean exportPortletArchivedSetups, boolean exportPortletData, boolean exportPortletSetup, boolean exportPortletUserPreferences) throws Exception { long layoutId = LayoutConstants.DEFAULT_PARENT_LAYOUT_ID; Layout layout = _layoutLocalService.fetchLayout(plid); if (layout != null) { plid = layout.getPlid(); layoutId = layout.getLayoutId(); } Portlet portlet = _portletLocalService.getPortletById( portletDataContext.getCompanyId(), portletDataContext.getPortletId()); if ((portlet == null) || portlet.isUndeployedPortlet()) { if (_log.isDebugEnabled()) { _log.debug( "Do not export portlet " + portletDataContext.getPortletId() + " because the portlet is not deployed"); } return; } if (!portlet.isInstanceable() && !portlet.isPreferencesUniquePerLayout() && portletDataContext.hasNotUniquePerLayout( portletDataContext.getPortletId())) { return; } if (BackgroundTaskThreadLocal.hasBackgroundTask()) { PortletDataContext clonedPortletDataContext = PortletDataContextFactoryUtil.clonePortletDataContext( portletDataContext); ManifestSummary manifestSummary = clonedPortletDataContext.getManifestSummary(); manifestSummary.resetCounters(); PortletDataHandler portletDataHandler = portlet.getPortletDataHandlerInstance(); portletDataHandler.prepareManifestSummary(clonedPortletDataContext); PortletDataHandlerStatusMessageSenderUtil.sendStatusMessage( "portlet", portletDataContext.getPortletId(), manifestSummary); } Document document = SAXReaderUtil.createDocument(); Element portletElement = document.addElement("portlet"); portletElement.addAttribute( "portlet-id", portletDataContext.getPortletId()); portletElement.addAttribute( "root-portlet-id", portletDataContext.getRootPortletId()); portletElement.addAttribute("old-plid", String.valueOf(plid)); portletElement.addAttribute( "scope-group-id", String.valueOf(portletDataContext.getScopeGroupId())); portletElement.addAttribute( "scope-layout-type", portletDataContext.getScopeType()); portletElement.addAttribute( "scope-layout-uuid", portletDataContext.getScopeLayoutUuid()); portletElement.addAttribute( "private-layout", String.valueOf(portletDataContext.isPrivateLayout())); // Data if (exportPortletData) { javax.portlet.PortletPreferences jxPortletPreferences = null; if (ExportImportThreadLocal.isInitialLayoutStagingInProcess()) { if (layout != null) { Group liveGroup = layout.getGroup(); Group stagingGroup = liveGroup.getStagingGroup(); layout.setGroupId(stagingGroup.getGroupId()); jxPortletPreferences = PortletPreferencesFactoryUtil.getStrictPortletSetup( layout, portletDataContext.getPortletId()); layout.setGroupId(liveGroup.getGroupId()); } else { Group liveGroup = _groupLocalService.getGroup( portletDataContext.getGroupId()); Group stagingGroup = liveGroup.getStagingGroup(); jxPortletPreferences = PortletPreferencesFactoryUtil.getStrictPortletSetup( portletDataContext.getCompanyId(), stagingGroup.getGroupId(), portletDataContext.getPortletId()); } } else { if (layout != null) { jxPortletPreferences = PortletPreferencesFactoryUtil.getStrictPortletSetup( layout, portletDataContext.getPortletId()); } else { jxPortletPreferences = PortletPreferencesFactoryUtil.getStrictPortletSetup( portletDataContext.getCompanyId(), portletDataContext.getGroupId(), portletDataContext.getPortletId()); } } if (!portlet.isPreferencesUniquePerLayout()) { StringBundler sb = new StringBundler(5); sb.append(portletDataContext.getPortletId()); sb.append(StringPool.AT); sb.append(portletDataContext.getScopeType()); sb.append(StringPool.AT); sb.append(portletDataContext.getScopeLayoutUuid()); String dataKey = sb.toString(); if (!portletDataContext.hasNotUniquePerLayout(dataKey)) { portletDataContext.putNotUniquePerLayout(dataKey); exportPortletData( portletDataContext, portlet, layout, jxPortletPreferences, portletElement); } } else { exportPortletData( portletDataContext, portlet, layout, jxPortletPreferences, portletElement); } } // Portlet preferences if (exportPortletSetup) { // Company exportPortletPreferences( portletDataContext, portletDataContext.getCompanyId(), PortletKeys.PREFS_OWNER_TYPE_COMPANY, false, layout, plid, portlet.getRootPortletId(), portletElement); // Group exportPortletPreferences( portletDataContext, portletDataContext.getScopeGroupId(), PortletKeys.PREFS_OWNER_TYPE_GROUP, false, layout, PortletKeys.PREFS_PLID_SHARED, portlet.getRootPortletId(), portletElement); // Group embedded portlets exportPortletPreferences( portletDataContext, portletDataContext.getScopeGroupId(), PortletKeys.PREFS_OWNER_TYPE_LAYOUT, false, layout, PortletKeys.PREFS_PLID_SHARED, portlet.getPortletId(), portletElement); // Layout exportPortletPreferences( portletDataContext, PortletKeys.PREFS_OWNER_ID_DEFAULT, PortletKeys.PREFS_OWNER_TYPE_LAYOUT, false, layout, plid, portletDataContext.getPortletId(), portletElement); } // Portlet user preferences if (exportPortletUserPreferences) { List<PortletPreferences> portletPreferencesList = _portletPreferencesLocalService.getPortletPreferences( PortletKeys.PREFS_OWNER_TYPE_USER, plid, portletDataContext.getPortletId()); for (PortletPreferences portletPreferences : portletPreferencesList) { boolean defaultUser = false; if (portletPreferences.getOwnerId() == PortletKeys.PREFS_OWNER_ID_DEFAULT) { defaultUser = true; } exportPortletPreferences( portletDataContext, portletPreferences.getOwnerId(), PortletKeys.PREFS_OWNER_TYPE_USER, defaultUser, layout, plid, portletDataContext.getPortletId(), portletElement); } try { PortletPreferences groupPortletPreferences = _portletPreferencesLocalService.getPortletPreferences( portletDataContext.getScopeGroupId(), PortletKeys.PREFS_OWNER_TYPE_GROUP, PortletKeys.PREFS_PLID_SHARED, portlet.getRootPortletId()); exportPortletPreference( portletDataContext, portletDataContext.getScopeGroupId(), PortletKeys.PREFS_OWNER_TYPE_GROUP, false, groupPortletPreferences, portlet.getRootPortletId(), PortletKeys.PREFS_PLID_SHARED, portletElement); } catch (NoSuchPortletPreferencesException nsppe) { // LPS-52675 if (_log.isDebugEnabled()) { _log.debug(nsppe, nsppe); } } } // Archived setups if (exportPortletArchivedSetups) { List<PortletItem> portletItems = _portletItemLocalService.getPortletItems( portletDataContext.getGroupId(), portletDataContext.getRootPortletId(), PortletPreferences.class.getName()); for (PortletItem portletItem : portletItems) { exportPortletPreferences( portletDataContext, portletItem.getPortletItemId(), PortletKeys.PREFS_OWNER_TYPE_ARCHIVED, false, null, plid, portletItem.getPortletId(), portletElement); } } // Permissions if (exportPermissions) { _permissionExporter.exportPortletPermissions( portletDataContext, portletDataContext.getPortletId(), layout, portletElement); } // Zip StringBundler pathSB = new StringBundler(4); pathSB.append(ExportImportPathUtil.getPortletPath(portletDataContext)); pathSB.append(StringPool.SLASH); pathSB.append(plid); pathSB.append("/portlet.xml"); String path = pathSB.toString(); Element element = parentElement.addElement("portlet"); element.addAttribute("portlet-id", portletDataContext.getPortletId()); element.addAttribute("layout-id", String.valueOf(layoutId)); element.addAttribute("path", path); element.addAttribute("portlet-data", String.valueOf(exportPortletData)); PortletDataHandler portletDataHandler = portlet.getPortletDataHandlerInstance(); element.addAttribute( "schema-version", portletDataHandler.getSchemaVersion()); StringBundler configurationOptionsSB = new StringBundler(6); if (exportPortletSetup) { configurationOptionsSB.append("setup"); configurationOptionsSB.append(StringPool.COMMA); } if (exportPortletArchivedSetups) { configurationOptionsSB.append("archived-setups"); configurationOptionsSB.append(StringPool.COMMA); } if (exportPortletUserPreferences) { configurationOptionsSB.append("user-preferences"); configurationOptionsSB.append(StringPool.COMMA); } if (configurationOptionsSB.index() > 0) { configurationOptionsSB.setIndex(configurationOptionsSB.index() - 1); } element.addAttribute( "portlet-configuration", configurationOptionsSB.toString()); try { portletDataContext.addZipEntry(path, document.formattedString()); } catch (IOException ioe) { if (_log.isWarnEnabled()) { _log.warn(ioe.getMessage()); } } } public void exportPortletData( PortletDataContext portletDataContext, Portlet portlet, Layout layout, javax.portlet.PortletPreferences jxPortletPreferences, Element parentElement) throws Exception { if (portlet == null) { return; } PortletDataHandler portletDataHandler = portlet.getPortletDataHandlerInstance(); if ((portletDataHandler == null) || portletDataHandler.isDataPortletInstanceLevel()) { return; } Group group = _groupLocalService.getGroup( portletDataContext.getGroupId()); long plid = LayoutConstants.DEFAULT_PLID; if (layout != null) { group = layout.getGroup(); plid = layout.getPlid(); } if (group.isStagingGroup()) { group = group.getLiveGroup(); } String portletId = portlet.getPortletId(); if (ExportImportThreadLocal.isStagingInProcess() && !group.isStagedPortlet(portletId)) { if (_log.isDebugEnabled()) { _log.debug( "Not exporting data for " + portletId + " because it is configured not to be staged"); } return; } if (_log.isDebugEnabled()) { _log.debug("Exporting data for " + portletId); } StringBundler sb = new StringBundler(4); sb.append( ExportImportPathUtil.getPortletPath(portletDataContext, portletId)); sb.append(StringPool.SLASH); if (portlet.isPreferencesUniquePerLayout()) { sb.append(plid); } else { sb.append(portletDataContext.getScopeGroupId()); } sb.append("/portlet-data.xml"); String path = sb.toString(); if (portletDataContext.hasPrimaryKey(String.class, path)) { return; } Date originalStartDate = portletDataContext.getStartDate(); Date portletLastPublishDate = ExportImportDateUtil.getLastPublishDate( portletDataContext, jxPortletPreferences); portletDataContext.setStartDate(portletLastPublishDate); long groupId = portletDataContext.getGroupId(); portletDataContext.setGroupId(portletDataContext.getScopeGroupId()); portletDataContext.clearScopedPrimaryKeys(); String data = null; try { data = portletDataHandler.exportData( portletDataContext, portletId, jxPortletPreferences); } finally { portletDataContext.setGroupId(groupId); portletDataContext.setStartDate(originalStartDate); } if (Validator.isNull(data)) { if (_log.isDebugEnabled()) { _log.debug( "Not exporting data for " + portletId + " because null data was returned"); } return; } Element portletDataElement = parentElement.addElement("portlet-data"); portletDataElement.addAttribute("path", path); portletDataContext.addZipEntry(path, data); boolean updateLastPublishDate = MapUtil.getBoolean( portletDataContext.getParameterMap(), PortletDataHandlerKeys.UPDATE_LAST_PUBLISH_DATE); if (ExportImportThreadLocal.isStagingInProcess() && updateLastPublishDate) { DateRange adjustedDateRange = new DateRange( portletLastPublishDate, portletDataContext.getEndDate()); ExportImportProcessCallbackRegistryUtil.registerCallback( portletDataContext.getExportImportProcessId(), new UpdatePortletLastPublishDateCallable( adjustedDateRange, portletDataContext.getEndDate(), portletDataContext.getGroupId(), plid, portletId)); } } public void exportService( PortletDataContext portletDataContext, Element rootElement, boolean exportServiceSetup) throws Exception { if (!exportServiceSetup) { return; } PortletDataHandler portletDataHandler = _portletDataHandlerProvider.provide( portletDataContext.getPortletId()); if (portletDataHandler == null) { return; } String serviceName = portletDataHandler.getServiceName(); if (Validator.isNotNull(serviceName)) { // Company service exportServicePortletPreferences( portletDataContext, portletDataContext.getCompanyId(), PortletKeys.PREFS_OWNER_TYPE_COMPANY, serviceName, rootElement); // Group service exportServicePortletPreferences( portletDataContext, portletDataContext.getScopeGroupId(), PortletKeys.PREFS_OWNER_TYPE_GROUP, serviceName, rootElement); } } protected File doExport(PortletDataContext portletDataContext) throws Exception { boolean exportPermissions = MapUtil.getBoolean( portletDataContext.getParameterMap(), PortletDataHandlerKeys.PERMISSIONS); if (_log.isDebugEnabled()) { _log.debug("Export permissions " + exportPermissions); } StopWatch stopWatch = new StopWatch(); stopWatch.start(); Layout layout = _layoutLocalService.getLayout( portletDataContext.getPlid()); if (!layout.isTypeControlPanel() && !layout.isTypePanel() && !layout.isTypePortlet()) { StringBundler sb = new StringBundler(4); sb.append("Unable to export layout "); sb.append(layout.getPlid()); sb.append(" because it has an invalid type: "); sb.append(layout.getType()); throw new LayoutImportException(sb.toString()); } ServiceContext serviceContext = ServiceContextThreadLocal.getServiceContext(); if (serviceContext == null) { serviceContext = new ServiceContext(); serviceContext.setCompanyId(layout.getCompanyId()); serviceContext.setSignedIn(false); long defaultUserId = _userLocalService.getDefaultUserId( layout.getCompanyId()); serviceContext.setUserId(defaultUserId); ServiceContextThreadLocal.pushServiceContext(serviceContext); } long layoutSetBranchId = MapUtil.getLong( portletDataContext.getParameterMap(), "layoutSetBranchId"); serviceContext.setAttribute("layoutSetBranchId", layoutSetBranchId); long scopeGroupId = portletDataContext.getGroupId(); javax.portlet.PortletPreferences jxPortletPreferences = PortletPreferencesFactoryUtil.getLayoutPortletSetup( layout, portletDataContext.getPortletId()); String scopeType = GetterUtil.getString( jxPortletPreferences.getValue("lfrScopeType", null)); String scopeLayoutUuid = GetterUtil.getString( jxPortletPreferences.getValue("lfrScopeLayoutUuid", null)); if (Validator.isNotNull(scopeType)) { Group scopeGroup = null; if (scopeType.equals("company")) { scopeGroup = _groupLocalService.getCompanyGroup( layout.getCompanyId()); } else if (Validator.isNotNull(scopeLayoutUuid)) { scopeGroup = layout.getScopeGroup(); } if (scopeGroup != null) { scopeGroupId = scopeGroup.getGroupId(); } } portletDataContext.setScopeType(scopeType); portletDataContext.setScopeLayoutUuid(scopeLayoutUuid); 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( _portal.getSiteGroupId( portletDataContext.getScopeGroupId())))); headerElement.addAttribute( "build-number", String.valueOf(ReleaseInfo.getBuildNumber())); 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("type", portletDataContext.getType()); headerElement.addAttribute( "company-id", String.valueOf(portletDataContext.getCompanyId())); headerElement.addAttribute( "company-group-id", String.valueOf(portletDataContext.getCompanyGroupId())); headerElement.addAttribute("group-id", String.valueOf(scopeGroupId)); headerElement.addAttribute( "user-personal-site-group-id", String.valueOf(portletDataContext.getUserPersonalSiteGroupId())); headerElement.addAttribute( "private-layout", String.valueOf(layout.isPrivateLayout())); headerElement.addAttribute( "root-portlet-id", portletDataContext.getRootPortletId()); Element missingReferencesElement = rootElement.addElement( "missing-references"); portletDataContext.setMissingReferencesElement( missingReferencesElement); Map<String, Boolean> exportPortletControlsMap = ExportImportHelperUtil.getExportPortletControlsMap( layout.getCompanyId(), portletDataContext.getPortletId(), portletDataContext.getParameterMap()); exportPortlet( portletDataContext, layout.getPlid(), rootElement, exportPermissions, exportPortletControlsMap.get( PortletDataHandlerKeys.PORTLET_ARCHIVED_SETUPS), exportPortletControlsMap.get(PortletDataHandlerKeys.PORTLET_DATA), exportPortletControlsMap.get(PortletDataHandlerKeys.PORTLET_SETUP), exportPortletControlsMap.get( PortletDataHandlerKeys.PORTLET_USER_PREFERENCES)); exportService( portletDataContext, rootElement, exportPortletControlsMap.get(PortletDataHandlerKeys.PORTLET_SETUP)); exportAssetLinks(portletDataContext); exportExpandoTables(portletDataContext); exportLocks(portletDataContext); _deletionSystemEventExporter.exportDeletionSystemEvents( portletDataContext); if (exportPermissions) { _permissionExporter.exportPortletDataPermissions( portletDataContext); } ExportImportHelperUtil.writeManifestSummary( document, portletDataContext.getManifestSummary()); if (_log.isInfoEnabled()) { _log.info("Exporting portlet took " + stopWatch.getTime() + " ms"); } try { portletDataContext.addZipEntry( "/manifest.xml", document.formattedString()); } catch (IOException ioe) { throw new SystemException( "Unable to create the export LAR manifest file for portlet " + portletDataContext.getPortletId(), ioe); } ZipWriter zipWriter = portletDataContext.getZipWriter(); return zipWriter.getFile(); } protected void exportAssetLinks(PortletDataContext portletDataContext) throws Exception { Document document = SAXReaderUtil.createDocument(); Element rootElement = document.addElement("links"); Element exportDataRootElement = portletDataContext.getExportDataRootElement(); try { portletDataContext.setExportDataRootElement(rootElement); ActionableDynamicQuery linkActionableDynamicQuery = _assetLinkLocalService.getExportActionbleDynamicQuery( portletDataContext); linkActionableDynamicQuery.performActions(); for (long linkId : portletDataContext.getAssetLinkIds()) { AssetLink assetLink = _assetLinkLocalService.getAssetLink( linkId); StagedAssetLink stagedAssetLink = ModelAdapterUtil.adapt( assetLink, AssetLink.class, StagedAssetLink.class); portletDataContext.addClassedModel( portletDataContext.getExportDataElement(stagedAssetLink), ExportImportPathUtil.getModelPath(stagedAssetLink), stagedAssetLink); } } finally { portletDataContext.setExportDataRootElement(exportDataRootElement); } portletDataContext.addZipEntry( ExportImportPathUtil.getRootPath(portletDataContext) + "/links.xml", document.formattedString()); } protected void exportExpandoTables(PortletDataContext portletDataContext) throws Exception { Document document = SAXReaderUtil.createDocument(); Element rootElement = document.addElement("expando-tables"); Map<String, List<ExpandoColumn>> expandoColumnsMap = portletDataContext.getExpandoColumns(); for (Map.Entry<String, List<ExpandoColumn>> entry : expandoColumnsMap.entrySet()) { String className = entry.getKey(); Element expandoTableElement = rootElement.addElement( "expando-table"); expandoTableElement.addAttribute("class-name", className); List<ExpandoColumn> expandoColumns = entry.getValue(); for (ExpandoColumn expandoColumn : expandoColumns) { Element expandoColumnElement = expandoTableElement.addElement( "expando-column"); expandoColumnElement.addAttribute( "column-id", String.valueOf(expandoColumn.getColumnId())); expandoColumnElement.addAttribute( "name", expandoColumn.getName()); expandoColumnElement.addAttribute( "type", String.valueOf(expandoColumn.getType())); DocUtil.add( expandoColumnElement, "default-data", expandoColumn.getDefaultData()); Element typeSettingsElement = expandoColumnElement.addElement( "type-settings"); UnicodeProperties typeSettingsProperties = expandoColumn.getTypeSettingsProperties(); typeSettingsElement.addCDATA(typeSettingsProperties.toString()); } } portletDataContext.addZipEntry( ExportImportPathUtil.getRootPath(portletDataContext) + "/expando-tables.xml", document.formattedString()); } protected void exportLocks(PortletDataContext portletDataContext) throws Exception { Document document = SAXReaderUtil.createDocument(); Element rootElement = document.addElement("locks"); Map<String, Lock> locksMap = portletDataContext.getLocks(); for (Map.Entry<String, Lock> entry : locksMap.entrySet()) { Lock lock = entry.getValue(); String entryKey = entry.getKey(); int pos = entryKey.indexOf(CharPool.POUND); String className = entryKey.substring(0, pos); String key = entryKey.substring(pos + 1); String path = getLockPath(portletDataContext, className, key, lock); Element assetElement = rootElement.addElement("asset"); assetElement.addAttribute("path", path); assetElement.addAttribute("class-name", className); assetElement.addAttribute("key", key); portletDataContext.addZipEntry(path, lock); } portletDataContext.addZipEntry( ExportImportPathUtil.getRootPath(portletDataContext) + "/locks.xml", document.formattedString()); } /** * @deprecated As of 4.0.0 */ @Deprecated protected void exportPortlet( PortletDataContext portletDataContext, Layout layout, Element parentElement, boolean exportPermissions, boolean exportPortletArchivedSetups, boolean exportPortletData, boolean exportPortletSetup, boolean exportPortletUserPreferences) throws Exception { exportPortlet( portletDataContext, layout.getPlid(), parentElement, exportPermissions, exportPortletArchivedSetups, exportPortletData, exportPortletSetup, exportPortletUserPreferences); } protected void exportPortletPreference( PortletDataContext portletDataContext, long ownerId, int ownerType, boolean defaultUser, PortletPreferences portletPreferences, String portletId, long plid, Element parentElement) throws Exception { String preferencesXML = portletPreferences.getPreferences(); if (Validator.isNull(preferencesXML)) { preferencesXML = PortletConstants.DEFAULT_PREFERENCES; } javax.portlet.PortletPreferences jxPortletPreferences = PortletPreferencesFactoryUtil.fromDefaultXML(preferencesXML); Portlet portlet = _portletLocalService.getPortletById( portletDataContext.getCompanyId(), portletId); Element portletPreferencesElement = parentElement.addElement( "portlet-preferences"); if ((portlet != null) && (portlet.getPortletDataHandlerInstance() != null)) { Element exportDataRootElement = portletDataContext.getExportDataRootElement(); try { portletDataContext.clearScopedPrimaryKeys(); Element preferenceDataElement = portletPreferencesElement.addElement("preference-data"); portletDataContext.setExportDataRootElement( preferenceDataElement); ExportImportPortletPreferencesProcessor exportImportPortletPreferencesProcessor = ExportImportPortletPreferencesProcessorRegistryUtil. getExportImportPortletPreferencesProcessor( portlet.getRootPortletId()); if (exportImportPortletPreferencesProcessor != null) { List<Capability> exportCapabilities = exportImportPortletPreferencesProcessor. getExportCapabilities(); if (ListUtil.isNotEmpty(exportCapabilities)) { for (Capability exportCapability : exportCapabilities) { exportCapability.process( portletDataContext, jxPortletPreferences); } } exportImportPortletPreferencesProcessor. processExportPortletPreferences( portletDataContext, jxPortletPreferences); } else { PortletDataHandler portletDataHandler = portlet.getPortletDataHandlerInstance(); jxPortletPreferences = portletDataHandler.processExportPortletPreferences( portletDataContext, portletId, jxPortletPreferences); } } finally { portletDataContext.setExportDataRootElement( exportDataRootElement); } } Document document = SAXReaderUtil.read( PortletPreferencesFactoryUtil.toXML(jxPortletPreferences)); Element rootElement = document.getRootElement(); rootElement.addAttribute("owner-id", String.valueOf(ownerId)); rootElement.addAttribute("owner-type", String.valueOf(ownerType)); rootElement.addAttribute("default-user", String.valueOf(defaultUser)); rootElement.addAttribute("plid", String.valueOf(plid)); rootElement.addAttribute("portlet-id", portletId); if (ownerType == PortletKeys.PREFS_OWNER_TYPE_ARCHIVED) { PortletItem portletItem = _portletItemLocalService.getPortletItem( ownerId); rootElement.addAttribute( "archive-user-uuid", portletItem.getUserUuid()); rootElement.addAttribute("archive-name", portletItem.getName()); } else if (ownerType == PortletKeys.PREFS_OWNER_TYPE_USER) { User user = _userLocalService.fetchUserById(ownerId); if (user == null) { return; } rootElement.addAttribute("user-uuid", user.getUserUuid()); } List<Node> nodes = document.selectNodes( "/portlet-preferences/preference[name/text() = " + "'last-publish-date']"); for (Node node : nodes) { node.detach(); } String path = ExportImportPathUtil.getPortletPreferencesPath( portletDataContext, portletId, ownerId, ownerType, plid); portletPreferencesElement.addAttribute("path", path); portletDataContext.addZipEntry( path, document.formattedString(StringPool.TAB, false, false)); } protected void exportPortletPreferences( PortletDataContext portletDataContext, long ownerId, int ownerType, boolean defaultUser, Layout layout, long plid, String portletId, Element parentElement) throws Exception { PortletPreferences portletPreferences = null; try { portletPreferences = getPortletPreferences( ownerId, ownerType, plid, portletId); } catch (NoSuchPortletPreferencesException nsppe) { // LPS-52675 if (_log.isDebugEnabled()) { _log.debug(nsppe, nsppe); } return; } LayoutTypePortlet layoutTypePortlet = null; if (layout != null) { layoutTypePortlet = (LayoutTypePortlet)layout.getLayoutType(); } if ((layoutTypePortlet == null) || layoutTypePortlet.hasPortletId(portletId)) { exportPortletPreference( portletDataContext, ownerId, ownerType, defaultUser, portletPreferences, portletId, plid, parentElement); } } protected void exportServicePortletPreference( PortletDataContext portletDataContext, long ownerId, int ownerType, PortletPreferences portletPreferences, String serviceName, Element parentElement) throws Exception { String preferencesXML = portletPreferences.getPreferences(); if (Validator.isNull(preferencesXML)) { preferencesXML = PortletConstants.DEFAULT_PREFERENCES; } javax.portlet.PortletPreferences jxPortletPreferences = PortletPreferencesFactoryUtil.fromDefaultXML(preferencesXML); Document document = SAXReaderUtil.read( PortletPreferencesFactoryUtil.toXML(jxPortletPreferences)); Element rootElement = document.getRootElement(); rootElement.addAttribute("owner-id", String.valueOf(ownerId)); rootElement.addAttribute("owner-type", String.valueOf(ownerType)); rootElement.addAttribute("default-user", String.valueOf(false)); rootElement.addAttribute("service-name", serviceName); if (ownerType == PortletKeys.PREFS_OWNER_TYPE_ARCHIVED) { PortletItem portletItem = _portletItemLocalService.getPortletItem( ownerId); rootElement.addAttribute( "archive-user-uuid", portletItem.getUserUuid()); rootElement.addAttribute("archive-name", portletItem.getName()); } else if (ownerType == PortletKeys.PREFS_OWNER_TYPE_USER) { User user = _userLocalService.fetchUserById(ownerId); if (user == null) { return; } rootElement.addAttribute("user-uuid", user.getUserUuid()); } List<Node> nodes = document.selectNodes( "/portlet-preferences/preference[name/text() = " + "'last-publish-date']"); for (Node node : nodes) { node.detach(); } Element serviceElement = parentElement.addElement("service"); String path = ExportImportPathUtil.getServicePortletPreferencesPath( portletDataContext, serviceName, ownerId, ownerType); serviceElement.addAttribute("path", path); serviceElement.addAttribute("service-name", serviceName); portletDataContext.addZipEntry(path, document.formattedString()); } protected void exportServicePortletPreferences( PortletDataContext portletDataContext, long ownerId, int ownerType, String serviceName, Element parentElement) throws Exception { PortletPreferences portletPreferences = null; try { portletPreferences = getPortletPreferences( ownerId, ownerType, LayoutConstants.DEFAULT_PLID, serviceName); } catch (NoSuchPortletPreferencesException nsppe) { // LPS-52675 if (_log.isDebugEnabled()) { _log.debug(nsppe, nsppe); } return; } exportServicePortletPreference( portletDataContext, ownerId, ownerType, portletPreferences, serviceName, parentElement); } protected String getLockPath( PortletDataContext portletDataContext, String className, String key, Lock lock) { StringBundler sb = new StringBundler(8); sb.append(ExportImportPathUtil.getRootPath(portletDataContext)); sb.append("/locks/"); sb.append(_portal.getClassNameId(className)); sb.append(CharPool.FORWARD_SLASH); sb.append(key); sb.append(CharPool.FORWARD_SLASH); sb.append(lock.getLockId()); sb.append(".xml"); return sb.toString(); } protected PortletDataContext getPortletDataContext( ExportImportConfiguration exportImportConfiguration) throws PortalException { Map<String, Serializable> settingsMap = exportImportConfiguration.getSettingsMap(); long sourcePlid = MapUtil.getLong(settingsMap, "sourcePlid"); long sourceGroupId = MapUtil.getLong(settingsMap, "sourceGroupId"); String portletId = MapUtil.getString(settingsMap, "portletId"); Map<String, String[]> parameterMap = (Map<String, String[]>)settingsMap.get("parameterMap"); DateRange dateRange = ExportImportDateUtil.getDateRange( exportImportConfiguration); Layout layout = _layoutLocalService.getLayout(sourcePlid); ZipWriter zipWriter = ExportImportHelperUtil.getPortletZipWriter( portletId); PortletDataContext portletDataContext = PortletDataContextFactoryUtil.createExportPortletDataContext( layout.getCompanyId(), sourceGroupId, parameterMap, dateRange.getStartDate(), dateRange.getEndDate(), zipWriter); portletDataContext.setExportImportProcessId( String.valueOf( exportImportConfiguration.getExportImportConfigurationId())); portletDataContext.setOldPlid(sourcePlid); portletDataContext.setPlid(sourcePlid); portletDataContext.setPortletId(portletId); portletDataContext.setType("portlet"); return portletDataContext; } protected PortletPreferences getPortletPreferences( long ownerId, int ownerType, long plid, String portletId) throws PortalException { PortletPreferences portletPreferences = null; if ((ownerType == PortletKeys.PREFS_OWNER_TYPE_ARCHIVED) || (ownerType == PortletKeys.PREFS_OWNER_TYPE_COMPANY) || (ownerType == PortletKeys.PREFS_OWNER_TYPE_GROUP)) { portletPreferences = _portletPreferencesLocalService.getPortletPreferences( ownerId, ownerType, LayoutConstants.DEFAULT_PLID, portletId); } else { portletPreferences = _portletPreferencesLocalService.getPortletPreferences( ownerId, ownerType, plid, portletId); } return portletPreferences; } protected int getProcessFlag() { if (ExportImportThreadLocal.isPortletStagingInProcess()) { return PROCESS_FLAG_PORTLET_STAGING_IN_PROCESS; } return PROCESS_FLAG_PORTLET_EXPORT_IN_PROCESS; } @Reference(unbind = "-") protected void setAssetEntryLocalService( AssetEntryLocalService assetEntryLocalService) { _assetEntryLocalService = assetEntryLocalService; } @Reference(unbind = "-") protected void setAssetLinkLocalService( AssetLinkLocalService assetLinkLocalService) { _assetLinkLocalService = assetLinkLocalService; } @Reference(unbind = "-") protected void setExportImportLifecycleManager( ExportImportLifecycleManager exportImportLifecycleManager) { _exportImportLifecycleManager = exportImportLifecycleManager; } @Reference(unbind = "-") protected void setGroupLocalService(GroupLocalService groupLocalService) { _groupLocalService = groupLocalService; } @Reference(unbind = "-") protected void setLayoutLocalService( LayoutLocalService layoutLocalService) { _layoutLocalService = layoutLocalService; } @Reference(unbind = "-") protected void setPortletItemLocalService( PortletItemLocalService portletItemLocalService) { _portletItemLocalService = portletItemLocalService; } @Reference(unbind = "-") protected void setPortletLocalService( PortletLocalService portletLocalService) { _portletLocalService = portletLocalService; } @Reference(unbind = "-") protected void setPortletPreferencesLocalService( PortletPreferencesLocalService portletPreferencesLocalService) { _portletPreferencesLocalService = portletPreferencesLocalService; } @Reference(unbind = "-") protected void setUserLocalService(UserLocalService userLocalService) { _userLocalService = userLocalService; } private static final Log _log = LogFactoryUtil.getLog( PortletExportController.class); private AssetEntryLocalService _assetEntryLocalService; private AssetLinkLocalService _assetLinkLocalService; private final DeletionSystemEventExporter _deletionSystemEventExporter = DeletionSystemEventExporter.getInstance(); private ExportImportLifecycleManager _exportImportLifecycleManager; private GroupLocalService _groupLocalService; private LayoutLocalService _layoutLocalService; private final PermissionExporter _permissionExporter = PermissionExporter.getInstance(); @Reference private Portal _portal; @Reference private PortletDataHandlerProvider _portletDataHandlerProvider; private PortletItemLocalService _portletItemLocalService; private PortletLocalService _portletLocalService; private PortletPreferencesLocalService _portletPreferencesLocalService; private UserLocalService _userLocalService; private class UpdatePortletLastPublishDateCallable implements Callable<Void> { public UpdatePortletLastPublishDateCallable( DateRange dateRange, Date endDate, long groupId, long plid, String portletId) { _dateRange = dateRange; _endDate = endDate; _groupId = groupId; _plid = plid; _portletId = portletId; } @Override public Void call() throws PortalException { Group group = _groupLocalService.getGroup(_groupId); Layout layout = _layoutLocalService.fetchLayout(_plid); if (group.hasStagingGroup()) { group = group.getStagingGroup(); if (layout != null) { layout = _layoutLocalService.fetchLayoutByUuidAndGroupId( layout.getUuid(), group.getGroupId(), layout.isPrivateLayout()); } } javax.portlet.PortletPreferences jxPortletPreferences = null; if (layout == null) { jxPortletPreferences = PortletPreferencesFactoryUtil.getStrictPortletSetup( group.getCompanyId(), group.getGroupId(), _portletId); } else { jxPortletPreferences = PortletPreferencesFactoryUtil.getStrictPortletSetup( layout, _portletId); } ExportImportDateUtil.updateLastPublishDate( _portletId, jxPortletPreferences, _dateRange, _endDate); return null; } private final DateRange _dateRange; private final Date _endDate; private final long _groupId; private final long _plid; private final String _portletId; } }