/**
* 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.layout.admin.web.internal.exportimport.data.handler;
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.EVENT_PORTLET_IMPORT_FAILED;
import static com.liferay.exportimport.kernel.lifecycle.ExportImportLifecycleConstants.EVENT_PORTLET_IMPORT_STARTED;
import static com.liferay.exportimport.kernel.lifecycle.ExportImportLifecycleConstants.EVENT_PORTLET_IMPORT_SUCCEEDED;
import com.liferay.counter.kernel.service.CounterLocalService;
import com.liferay.exportimport.controller.PortletExportController;
import com.liferay.exportimport.controller.PortletImportController;
import com.liferay.exportimport.data.handler.base.BaseStagedModelDataHandler;
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.PortletDataContext;
import com.liferay.exportimport.kernel.lar.PortletDataContextFactoryUtil;
import com.liferay.exportimport.kernel.lar.PortletDataException;
import com.liferay.exportimport.kernel.lar.PortletDataHandlerKeys;
import com.liferay.exportimport.kernel.lar.PortletDataHandlerStatusMessageSenderUtil;
import com.liferay.exportimport.kernel.lar.StagedModelDataHandler;
import com.liferay.exportimport.kernel.lar.StagedModelDataHandlerUtil;
import com.liferay.exportimport.kernel.lar.StagedModelModifiedDateComparator;
import com.liferay.exportimport.kernel.lifecycle.ExportImportLifecycleManager;
import com.liferay.exportimport.kernel.staging.LayoutStagingUtil;
import com.liferay.exportimport.kernel.staging.StagingUtil;
import com.liferay.exportimport.lar.LayoutCache;
import com.liferay.exportimport.lar.PermissionImporter;
import com.liferay.portal.kernel.backgroundtask.BackgroundTaskThreadLocal;
import com.liferay.portal.kernel.dao.orm.QueryUtil;
import com.liferay.portal.kernel.exception.NoSuchLayoutException;
import com.liferay.portal.kernel.exception.PortalException;
import com.liferay.portal.kernel.exception.SystemException;
import com.liferay.portal.kernel.json.JSONFactoryUtil;
import com.liferay.portal.kernel.json.JSONObject;
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.Image;
import com.liferay.portal.kernel.model.Layout;
import com.liferay.portal.kernel.model.LayoutBranch;
import com.liferay.portal.kernel.model.LayoutConstants;
import com.liferay.portal.kernel.model.LayoutFriendlyURL;
import com.liferay.portal.kernel.model.LayoutPrototype;
import com.liferay.portal.kernel.model.LayoutRevision;
import com.liferay.portal.kernel.model.LayoutSet;
import com.liferay.portal.kernel.model.LayoutStagingHandler;
import com.liferay.portal.kernel.model.LayoutTemplate;
import com.liferay.portal.kernel.model.LayoutTypePortlet;
import com.liferay.portal.kernel.model.LayoutTypePortletConstants;
import com.liferay.portal.kernel.model.Portlet;
import com.liferay.portal.kernel.model.adapter.StagedTheme;
import com.liferay.portal.kernel.service.GroupLocalService;
import com.liferay.portal.kernel.service.ImageLocalService;
import com.liferay.portal.kernel.service.LayoutFriendlyURLLocalService;
import com.liferay.portal.kernel.service.LayoutLocalService;
import com.liferay.portal.kernel.service.LayoutPrototypeLocalService;
import com.liferay.portal.kernel.service.LayoutSetLocalService;
import com.liferay.portal.kernel.service.LayoutTemplateLocalService;
import com.liferay.portal.kernel.service.PortletLocalService;
import com.liferay.portal.kernel.service.ResourceLocalService;
import com.liferay.portal.kernel.service.ServiceContext;
import com.liferay.portal.kernel.service.ServiceContextThreadLocal;
import com.liferay.portal.kernel.service.permission.PortletPermissionUtil;
import com.liferay.portal.kernel.settings.PortletInstanceSettingsLocator;
import com.liferay.portal.kernel.settings.Settings;
import com.liferay.portal.kernel.settings.SettingsFactoryUtil;
import com.liferay.portal.kernel.transaction.Propagation;
import com.liferay.portal.kernel.transaction.TransactionConfig;
import com.liferay.portal.kernel.transaction.TransactionInvokerUtil;
import com.liferay.portal.kernel.util.ArrayUtil;
import com.liferay.portal.kernel.util.CharPool;
import com.liferay.portal.kernel.util.Constants;
import com.liferay.portal.kernel.util.GetterUtil;
import com.liferay.portal.kernel.util.ListUtil;
import com.liferay.portal.kernel.util.LocaleUtil;
import com.liferay.portal.kernel.util.MapUtil;
import com.liferay.portal.kernel.util.ReflectionUtil;
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.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.SAXReaderUtil;
import com.liferay.portal.model.adapter.impl.StagedThemeImpl;
import com.liferay.portal.service.impl.LayoutLocalServiceHelper;
import com.liferay.portal.util.PropsValues;
import com.liferay.sites.kernel.util.SitesUtil;
import java.io.IOException;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.Callable;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Reference;
/**
* @author Mate Thurzo
*/
@Component(immediate = true, service = StagedModelDataHandler.class)
public class LayoutStagedModelDataHandler
extends BaseStagedModelDataHandler<Layout> {
public static final String[] CLASS_NAMES = {Layout.class.getName()};
@Override
public void deleteStagedModel(Layout layout) {
_layoutLocalService.deleteLayout(layout);
}
@Override
public void deleteStagedModel(
String uuid, long groupId, String className, String extraData)
throws PortalException {
JSONObject extraDataJSONObject = JSONFactoryUtil.createJSONObject(
extraData);
boolean privateLayout = extraDataJSONObject.getBoolean("privateLayout");
Layout layout = _layoutLocalService.fetchLayoutByUuidAndGroupId(
uuid, groupId, privateLayout);
if (layout != null) {
deleteStagedModel(layout);
}
}
@Override
public List<Layout> fetchStagedModelsByUuidAndCompanyId(
String uuid, long companyId) {
return _layoutLocalService.getLayoutsByUuidAndCompanyId(
uuid, companyId, QueryUtil.ALL_POS, QueryUtil.ALL_POS,
new StagedModelModifiedDateComparator<Layout>());
}
@Override
public String[] getClassNames() {
return CLASS_NAMES;
}
@Override
public String getDisplayName(Layout layout) {
return layout.getNameCurrentValue();
}
@Override
public Map<String, String> getReferenceAttributes(
PortletDataContext portletDataContext, Layout layout) {
Map<String, String> referenceAttributes = new HashMap<>();
referenceAttributes.put(
"layout-id", String.valueOf(layout.getLayoutId()));
referenceAttributes.put(
"private-layout", String.valueOf(layout.isPrivateLayout()));
return referenceAttributes;
}
@Override
public boolean validateReference(
PortletDataContext portletDataContext, Element referenceElement) {
validateMissingGroupReference(portletDataContext, referenceElement);
String uuid = referenceElement.attributeValue("uuid");
Map<Long, Long> groupIds =
(Map<Long, Long>)portletDataContext.getNewPrimaryKeysMap(
Group.class);
long groupId = GetterUtil.getLong(
referenceElement.attributeValue("group-id"));
groupId = MapUtil.getLong(groupIds, groupId);
boolean privateLayout = GetterUtil.getBoolean(
referenceElement.attributeValue("private-layout"));
Layout existingLayout = fetchMissingReference(
uuid, groupId, privateLayout);
if (existingLayout == null) {
return false;
}
return true;
}
protected String[] appendPortletIds(
String[] portletIds, String[] newPortletIds, String portletsMergeMode) {
for (String portletId : newPortletIds) {
if (ArrayUtil.contains(portletIds, portletId)) {
continue;
}
if (portletsMergeMode.equals(
PortletDataHandlerKeys.PORTLETS_MERGE_MODE_ADD_TO_BOTTOM)) {
portletIds = ArrayUtil.append(portletIds, portletId);
}
else {
portletIds = ArrayUtil.append(
new String[] {portletId}, portletIds);
}
}
return portletIds;
}
protected void deleteMissingLayoutFriendlyURLs(
PortletDataContext portletDataContext, Layout layout) {
Map<Long, Long> layoutFriendlyURLIds =
(Map<Long, Long>)portletDataContext.getNewPrimaryKeysMap(
LayoutFriendlyURL.class);
List<LayoutFriendlyURL> layoutFriendlyURLs =
_layoutFriendlyURLLocalService.getLayoutFriendlyURLs(
layout.getPlid());
for (LayoutFriendlyURL layoutFriendlyURL : layoutFriendlyURLs) {
if (!layoutFriendlyURLIds.containsValue(
layoutFriendlyURL.getLayoutFriendlyURLId())) {
_layoutFriendlyURLLocalService.deleteLayoutFriendlyURL(
layoutFriendlyURL);
}
}
}
@Override
protected void doExportStagedModel(
PortletDataContext portletDataContext, Layout layout)
throws Exception {
if (Objects.equals(
layout.getType(), LayoutConstants.TYPE_SHARED_PORTLET)) {
return;
}
Element layoutElement = portletDataContext.getExportDataElement(layout);
populateElementLayoutMetadata(layoutElement, layout);
layoutElement.addAttribute(Constants.ACTION, Constants.ADD);
portletDataContext.setPlid(layout.getPlid());
long parentLayoutId = layout.getParentLayoutId();
if (parentLayoutId != LayoutConstants.DEFAULT_PARENT_LAYOUT_ID) {
Layout parentLayout = _layoutLocalService.fetchLayout(
layout.getGroupId(), layout.isPrivateLayout(), parentLayoutId);
if (parentLayout != null) {
StagedModelDataHandlerUtil.exportReferenceStagedModel(
portletDataContext, layout, parentLayout,
PortletDataContext.REFERENCE_TYPE_PARENT);
layoutElement.addAttribute(
"parent-layout-uuid", parentLayout.getUuid());
}
}
List<LayoutFriendlyURL> layoutFriendlyURLs =
_layoutFriendlyURLLocalService.getLayoutFriendlyURLs(
layout.getPlid());
for (LayoutFriendlyURL layoutFriendlyURL : layoutFriendlyURLs) {
StagedModelDataHandlerUtil.exportReferenceStagedModel(
portletDataContext, layout, layoutFriendlyURL,
PortletDataContext.REFERENCE_TYPE_DEPENDENCY);
}
if (layout.isIconImage()) {
exportLayoutIconImage(portletDataContext, layout, layoutElement);
}
if (Objects.equals(
layout.getType(), LayoutConstants.TYPE_LINK_TO_LAYOUT)) {
exportLinkedLayout(portletDataContext, layout, layoutElement);
}
else if (Objects.equals(
layout.getType(), LayoutConstants.TYPE_PORTLET)) {
exportLayoutPortlets(portletDataContext, layout, layoutElement);
}
fixExportTypeSettings(layout);
exportTheme(portletDataContext, layout);
// Page versioning
LayoutStagingHandler layoutStagingHandler =
LayoutStagingUtil.getLayoutStagingHandler(layout);
if (layoutStagingHandler != null) {
layout = layoutStagingHandler.getLayout();
}
portletDataContext.addClassedModel(
layoutElement, ExportImportPathUtil.getModelPath(layout), layout);
}
@Override
protected void doImportMissingReference(
PortletDataContext portletDataContext, Element referenceElement)
throws PortletDataException {
importMissingGroupReference(portletDataContext, referenceElement);
String uuid = referenceElement.attributeValue("uuid");
Map<Long, Long> groupIds =
(Map<Long, Long>)portletDataContext.getNewPrimaryKeysMap(
Group.class);
long groupId = GetterUtil.getLong(
referenceElement.attributeValue("group-id"));
groupId = MapUtil.getLong(groupIds, groupId);
boolean privateLayout = GetterUtil.getBoolean(
referenceElement.attributeValue("private-layout"));
Layout existingLayout = null;
existingLayout = fetchMissingReference(uuid, groupId, privateLayout);
Map<Long, Layout> layouts =
(Map<Long, Layout>)portletDataContext.getNewPrimaryKeysMap(
Layout.class + ".layout");
long layoutId = GetterUtil.getLong(
referenceElement.attributeValue("layout-id"));
layouts.put(layoutId, existingLayout);
Map<Long, Long> layoutPlids =
(Map<Long, Long>)portletDataContext.getNewPrimaryKeysMap(
Layout.class);
long plid = GetterUtil.getLong(
referenceElement.attributeValue("class-pk"));
layoutPlids.put(plid, existingLayout.getPlid());
}
@Override
protected void doImportStagedModel(
PortletDataContext portletDataContext, Layout layout)
throws Exception {
final long groupId = portletDataContext.getGroupId();
long userId = portletDataContext.getUserId(layout.getUserUuid());
Element layoutElement =
portletDataContext.getImportDataStagedModelElement(layout);
long layoutId = GetterUtil.getLong(
layoutElement.attributeValue("layout-id"));
long oldLayoutId = layoutId;
final boolean privateLayout = portletDataContext.isPrivateLayout();
Map<Long, Layout> layouts =
(Map<Long, Layout>)portletDataContext.getNewPrimaryKeysMap(
Layout.class + ".layout");
Layout existingLayout = null;
Layout importedLayout = null;
String friendlyURL = layout.getFriendlyURL();
String layoutsImportMode = MapUtil.getString(
portletDataContext.getParameterMap(),
PortletDataHandlerKeys.LAYOUTS_IMPORT_MODE,
PortletDataHandlerKeys.LAYOUTS_IMPORT_MODE_MERGE_BY_LAYOUT_UUID);
if (layoutsImportMode.equals(
PortletDataHandlerKeys.LAYOUTS_IMPORT_MODE_ADD_AS_NEW)) {
layoutId = _layoutLocalService.getNextLayoutId(
groupId, privateLayout);
friendlyURL = StringPool.SLASH + layoutId;
}
else if (layoutsImportMode.equals(
PortletDataHandlerKeys.
LAYOUTS_IMPORT_MODE_MERGE_BY_LAYOUT_NAME)) {
Locale locale = LocaleUtil.getSiteDefault();
String localizedName = layout.getName(locale);
List<Layout> previousLayouts = _layoutLocalService.getLayouts(
groupId, privateLayout);
for (Layout curLayout : previousLayouts) {
if (localizedName.equals(curLayout.getName(locale)) ||
friendlyURL.equals(curLayout.getFriendlyURL())) {
existingLayout = curLayout;
break;
}
}
if (existingLayout == null) {
layoutId = _layoutLocalService.getNextLayoutId(
groupId, privateLayout);
friendlyURL = getFriendlyURL(friendlyURL, layoutId);
}
}
else if (layoutsImportMode.equals(
PortletDataHandlerKeys.
LAYOUTS_IMPORT_MODE_CREATED_FROM_PROTOTYPE)) {
existingLayout = _layoutLocalService.fetchLayoutByUuidAndGroupId(
layout.getUuid(), groupId, privateLayout);
if (SitesUtil.isLayoutModifiedSinceLastMerge(existingLayout)) {
layouts.put(oldLayoutId, existingLayout);
return;
}
LayoutFriendlyURL layoutFriendlyURL =
_layoutFriendlyURLLocalService.fetchFirstLayoutFriendlyURL(
groupId, privateLayout, friendlyURL);
if ((layoutFriendlyURL != null) && (existingLayout == null)) {
Layout mergeFailFriendlyURLLayout =
_layoutLocalService.getLayout(layoutFriendlyURL.getPlid());
SitesUtil.addMergeFailFriendlyURLLayout(
mergeFailFriendlyURLLayout);
if (!_log.isWarnEnabled()) {
return;
}
StringBundler sb = new StringBundler(6);
sb.append("Layout with layout ID ");
sb.append(layout.getLayoutId());
sb.append(" cannot be propagated because the friendly URL ");
sb.append("conflicts with the friendly URL of layout with ");
sb.append("layout ID ");
sb.append(mergeFailFriendlyURLLayout.getLayoutId());
_log.warn(sb.toString());
return;
}
}
else {
// The default behavior of import mode is
// PortletDataHandlerKeys.LAYOUTS_IMPORT_MODE_MERGE_BY_LAYOUT_UUID
existingLayout = _layoutLocalService.fetchLayoutByUuidAndGroupId(
layout.getUuid(), groupId, privateLayout);
if (existingLayout == null) {
existingLayout = _layoutLocalService.fetchLayoutByFriendlyURL(
groupId, privateLayout, friendlyURL);
}
if (existingLayout == null) {
layoutId = _layoutLocalService.getNextLayoutId(
groupId, privateLayout);
friendlyURL = getFriendlyURL(friendlyURL, layoutId);
}
}
if (_log.isDebugEnabled()) {
StringBundler sb = new StringBundler(7);
sb.append("Layout with {groupId=");
sb.append(groupId);
sb.append(",privateLayout=");
sb.append(privateLayout);
sb.append(",layoutId=");
sb.append(layoutId);
if (existingLayout == null) {
sb.append("} does not exist");
_log.debug(sb.toString());
}
else {
sb.append("} exists");
_log.debug(sb.toString());
}
}
if (existingLayout == null) {
long plid = _counterLocalService.increment();
importedLayout = _layoutLocalService.createLayout(plid);
if (layoutsImportMode.equals(
PortletDataHandlerKeys.
LAYOUTS_IMPORT_MODE_CREATED_FROM_PROTOTYPE)) {
importedLayout.setSourcePrototypeLayoutUuid(layout.getUuid());
layoutId = _layoutLocalService.getNextLayoutId(
groupId, privateLayout);
friendlyURL = getFriendlyURL(friendlyURL, layoutId);
}
else {
importedLayout.setCreateDate(layout.getCreateDate());
importedLayout.setModifiedDate(layout.getModifiedDate());
importedLayout.setLayoutPrototypeUuid(
layout.getLayoutPrototypeUuid());
importedLayout.setLayoutPrototypeLinkEnabled(
layout.isLayoutPrototypeLinkEnabled());
importedLayout.setSourcePrototypeLayoutUuid(
layout.getSourcePrototypeLayoutUuid());
}
importedLayout.setUuid(layout.getUuid());
importedLayout.setGroupId(groupId);
importedLayout.setUserId(userId);
importedLayout.setPrivateLayout(privateLayout);
importedLayout.setLayoutId(layoutId);
initNewLayoutPermissions(
portletDataContext.getCompanyId(), groupId, userId, layout,
importedLayout, privateLayout);
LayoutSet layoutSet = _layoutSetLocalService.getLayoutSet(
groupId, privateLayout);
importedLayout.setLayoutSet(layoutSet);
}
else {
importedLayout = existingLayout;
}
portletDataContext.setPlid(importedLayout.getPlid());
portletDataContext.setOldPlid(layout.getPlid());
long parentLayoutId = layout.getParentLayoutId();
String parentLayoutUuid = GetterUtil.getString(
layoutElement.attributeValue("parent-layout-uuid"));
Element parentLayoutElement =
portletDataContext.getReferenceDataElement(
layout, Layout.class, layout.getGroupId(), parentLayoutUuid);
if ((parentLayoutId != LayoutConstants.DEFAULT_PARENT_LAYOUT_ID) &&
(parentLayoutElement != null)) {
StagedModelDataHandlerUtil.importStagedModel(
portletDataContext, parentLayoutElement);
Layout importedParentLayout = layouts.get(parentLayoutId);
parentLayoutId = importedParentLayout.getLayoutId();
}
if (_log.isDebugEnabled()) {
StringBundler sb = new StringBundler(4);
sb.append("Importing layout with layout ID ");
sb.append(layoutId);
sb.append(" and parent layout ID ");
sb.append(parentLayoutId);
_log.debug(sb.toString());
}
importedLayout.setCompanyId(portletDataContext.getCompanyId());
if (layout.getLayoutPrototypeUuid() != null) {
importedLayout.setModifiedDate(new Date());
}
importedLayout.setParentLayoutId(parentLayoutId);
importedLayout.setName(layout.getName());
importedLayout.setTitle(layout.getTitle());
importedLayout.setDescription(layout.getDescription());
importedLayout.setKeywords(layout.getKeywords());
importedLayout.setRobots(layout.getRobots());
importedLayout.setType(layout.getType());
String portletsMergeMode = MapUtil.getString(
portletDataContext.getParameterMap(),
PortletDataHandlerKeys.PORTLETS_MERGE_MODE,
PortletDataHandlerKeys.PORTLETS_MERGE_MODE_REPLACE);
if (Objects.equals(layout.getType(), LayoutConstants.TYPE_PORTLET) &&
Validator.isNotNull(layout.getTypeSettings()) &&
!portletsMergeMode.equals(
PortletDataHandlerKeys.PORTLETS_MERGE_MODE_REPLACE)) {
mergePortlets(
importedLayout, layout.getTypeSettings(), portletsMergeMode);
}
else if (Objects.equals(
layout.getType(), LayoutConstants.TYPE_LINK_TO_LAYOUT)) {
importLinkedLayout(
portletDataContext, layout, importedLayout, layoutElement);
updateTypeSettings(importedLayout, layout);
}
else {
updateTypeSettings(importedLayout, layout);
}
importedLayout.setHidden(layout.isHidden());
importedLayout.setFriendlyURL(
getUniqueFriendlyURL(
portletDataContext, importedLayout, friendlyURL));
if (layout.getIconImageId() > 0) {
importLayoutIconImage(
portletDataContext, importedLayout, layoutElement);
}
else if (importedLayout.getIconImageId() > 0) {
_imageLocalService.deleteImage(importedLayout.getIconImageId());
}
if (existingLayout == null) {
try {
final long finalParentLayoutId = parentLayoutId;
int priority = TransactionInvokerUtil.invoke(
_transactionConfig,
new Callable<Integer>() {
@Override
public Integer call() throws Exception {
return _layoutLocalServiceHelper.getNextPriority(
groupId, privateLayout, finalParentLayoutId,
null, -1);
}
});
importedLayout.setPriority(priority);
}
catch (Throwable t) {
ReflectionUtil.throwException(t);
}
}
importedLayout.setLayoutPrototypeUuid(layout.getLayoutPrototypeUuid());
importedLayout.setLayoutPrototypeLinkEnabled(
layout.isLayoutPrototypeLinkEnabled());
ServiceContext serviceContext = portletDataContext.createServiceContext(
layout);
importedLayout.setExpandoBridgeAttributes(serviceContext);
StagingUtil.updateLastImportSettings(
layoutElement, importedLayout, portletDataContext);
fixImportTypeSettings(importedLayout);
importTheme(portletDataContext, layout, importedLayout);
_layoutLocalService.updateLayout(importedLayout);
_layoutSetLocalService.updatePageCount(groupId, privateLayout);
Map<Long, Long> layoutPlids =
(Map<Long, Long>)portletDataContext.getNewPrimaryKeysMap(
Layout.class);
layoutPlids.put(layout.getPlid(), importedLayout.getPlid());
layouts.put(oldLayoutId, importedLayout);
if (Objects.equals(layout.getType(), LayoutConstants.TYPE_PORTLET) &&
Validator.isNotNull(layout.getTypeSettings())) {
importLayoutPortlets(
portletDataContext, importedLayout, layoutElement);
}
importAssets(portletDataContext, layout, importedLayout);
importLayoutFriendlyURLs(portletDataContext, layout, importedLayout);
portletDataContext.importClassedModel(layout, importedLayout);
}
protected void exportLayoutIconImage(
PortletDataContext portletDataContext, Layout layout,
Element layoutElement)
throws Exception {
Image image = _imageLocalService.getImage(layout.getIconImageId());
if ((image != null) && (image.getTextObj() != null)) {
String iconPath = ExportImportPathUtil.getModelPath(
portletDataContext.getScopeGroupId(), Image.class.getName(),
image.getImageId());
Element iconImagePathElement = layoutElement.addElement(
"icon-image-path");
iconImagePathElement.addText(iconPath);
portletDataContext.addZipEntry(iconPath, image.getTextObj());
}
else {
if (_log.isWarnEnabled()) {
StringBundler sb = new StringBundler(4);
sb.append("Unable to export icon image ");
sb.append(layout.getIconImageId());
sb.append(" to layout ");
sb.append(layout.getLayoutId());
_log.warn(sb.toString());
}
layout.setIconImageId(0);
}
}
protected void exportLayoutPortlets(
PortletDataContext portletDataContext, Layout layout,
Element layoutElement)
throws Exception {
Map<String, String[]> parameterMap =
portletDataContext.getParameterMap();
boolean permissions = MapUtil.getBoolean(
parameterMap, PortletDataHandlerKeys.PERMISSIONS);
Element portletsElement = layoutElement.addElement("portlets");
long previousScopeGroupId = portletDataContext.getScopeGroupId();
Map<String, Object[]> portletIds = getPortletids(
portletDataContext, layout);
for (Map.Entry<String, Object[]> portletIdsEntry :
portletIds.entrySet()) {
String portletId = (String)portletIdsEntry.getValue()[0];
long scopeGroupId = (Long)portletIdsEntry.getValue()[1];
String scopeType = (String)portletIdsEntry.getValue()[2];
String scopeLayoutUuid = (String)portletIdsEntry.getValue()[3];
portletDataContext.setPlid(layout.getPlid());
portletDataContext.setOldPlid(layout.getPlid());
portletDataContext.setPortletId(portletId);
portletDataContext.setScopeGroupId(scopeGroupId);
portletDataContext.setScopeType(scopeType);
portletDataContext.setScopeLayoutUuid(scopeLayoutUuid);
Map<String, Boolean> exportPortletControlsMap =
ExportImportHelperUtil.getExportPortletControlsMap(
layout.getCompanyId(), portletId, parameterMap,
portletDataContext.getType());
try {
_exportImportLifecycleManager.fireExportImportLifecycleEvent(
EVENT_PORTLET_EXPORT_STARTED, getProcessFlag(),
portletDataContext.getExportImportProcessId(),
PortletDataContextFactoryUtil.clonePortletDataContext(
portletDataContext));
_portletExportController.exportPortlet(
portletDataContext, layout.getPlid(), portletsElement,
permissions,
exportPortletControlsMap.get(
PortletDataHandlerKeys.PORTLET_ARCHIVED_SETUPS),
exportPortletControlsMap.get(
PortletDataHandlerKeys.PORTLET_DATA),
exportPortletControlsMap.get(
PortletDataHandlerKeys.PORTLET_SETUP),
exportPortletControlsMap.get(
PortletDataHandlerKeys.PORTLET_USER_PREFERENCES));
_exportImportLifecycleManager.fireExportImportLifecycleEvent(
EVENT_PORTLET_EXPORT_SUCCEEDED, getProcessFlag(),
portletDataContext.getExportImportProcessId(),
PortletDataContextFactoryUtil.clonePortletDataContext(
portletDataContext));
}
catch (Throwable t) {
_exportImportLifecycleManager.fireExportImportLifecycleEvent(
EVENT_PORTLET_EXPORT_FAILED, getProcessFlag(),
portletDataContext.getExportImportProcessId(),
PortletDataContextFactoryUtil.clonePortletDataContext(
portletDataContext),
t);
throw t;
}
}
portletDataContext.setScopeGroupId(previousScopeGroupId);
}
protected void exportLinkedLayout(
PortletDataContext portletDataContext, Layout layout,
Element layoutElement)
throws Exception {
UnicodeProperties typeSettingsProperties =
layout.getTypeSettingsProperties();
long linkToLayoutId = GetterUtil.getLong(
typeSettingsProperties.getProperty(
"linkToLayoutId", StringPool.BLANK));
if (linkToLayoutId > 0) {
try {
Layout linkedToLayout = _layoutLocalService.getLayout(
portletDataContext.getScopeGroupId(),
layout.isPrivateLayout(), linkToLayoutId);
StagedModelDataHandlerUtil.exportReferenceStagedModel(
portletDataContext, layout, linkedToLayout,
PortletDataContext.REFERENCE_TYPE_STRONG);
layoutElement.addAttribute(
"linked-to-layout-uuid", linkedToLayout.getUuid());
}
catch (NoSuchLayoutException nsle) {
// LPS-52675
if (_log.isDebugEnabled()) {
_log.debug(nsle, nsle);
}
}
}
}
protected void exportTheme(
PortletDataContext portletDataContext, Layout layout)
throws Exception {
boolean exportThemeSettings = MapUtil.getBoolean(
portletDataContext.getParameterMap(),
PortletDataHandlerKeys.THEME_REFERENCE);
if (_log.isDebugEnabled()) {
_log.debug("Export theme settings " + exportThemeSettings);
}
if (exportThemeSettings &&
!portletDataContext.isPerformDirectBinaryImport() &&
!layout.isInheritLookAndFeel()) {
StagedTheme stagedTheme = new StagedThemeImpl(layout.getTheme());
Element layoutElement = portletDataContext.getExportDataElement(
layout);
portletDataContext.addReferenceElement(
layout, layoutElement, stagedTheme,
PortletDataContext.REFERENCE_TYPE_DEPENDENCY, true);
}
}
protected Object[] extractFriendlyURLInfo(Layout layout) {
if (!Objects.equals(layout.getType(), LayoutConstants.TYPE_URL)) {
return null;
}
UnicodeProperties typeSettings = layout.getTypeSettingsProperties();
String url = GetterUtil.getString(typeSettings.getProperty("url"));
String friendlyURLPrivateGroupPath =
PropsValues.LAYOUT_FRIENDLY_URL_PRIVATE_GROUP_SERVLET_MAPPING;
String friendlyURLPrivateUserPath =
PropsValues.LAYOUT_FRIENDLY_URL_PRIVATE_USER_SERVLET_MAPPING;
String friendlyURLPublicPath =
PropsValues.LAYOUT_FRIENDLY_URL_PUBLIC_SERVLET_MAPPING;
if (!url.startsWith(friendlyURLPrivateGroupPath) &&
!url.startsWith(friendlyURLPrivateUserPath) &&
!url.startsWith(friendlyURLPublicPath)) {
return null;
}
int x = url.indexOf(CharPool.SLASH, 1);
if (x == -1) {
return null;
}
int y = url.indexOf(CharPool.SLASH, x + 1);
if (y == -1) {
return null;
}
return new Object[] {url.substring(x, y), url, x, y};
}
protected Layout fetchMissingReference(
String uuid, long groupId, boolean privateLayout) {
// Try to fetch the existing layout from the importing group
Layout layout = _layoutLocalService.fetchLayoutByUuidAndGroupId(
uuid, groupId, privateLayout);
if (layout != null) {
return layout;
}
try {
// Try to fetch the existing layout from the parent sites
Group originalGroup = _groupLocalService.getGroup(groupId);
Group group = originalGroup.getParentGroup();
while (group != null) {
layout = _layoutLocalService.fetchLayoutByUuidAndGroupId(
uuid, group.getGroupId(), privateLayout);
if (layout != null) {
break;
}
group = group.getParentGroup();
}
if (layout == null) {
List<Layout> layouts = fetchStagedModelsByUuidAndCompanyId(
uuid, originalGroup.getCompanyId());
if (ListUtil.isEmpty(layouts)) {
return null;
}
layout = layouts.get(0);
}
return layout;
}
catch (Exception e) {
if (_log.isDebugEnabled()) {
_log.debug(e, e);
}
else if (_log.isWarnEnabled()) {
_log.warn(
"Unable to fetch missing reference layout from group " +
groupId);
}
return null;
}
}
protected void fixExportTypeSettings(Layout layout) throws Exception {
Object[] friendlyURLInfo = extractFriendlyURLInfo(layout);
if (friendlyURLInfo == null) {
return;
}
String friendlyURL = (String)friendlyURLInfo[0];
Group group = layout.getGroup();
String groupFriendlyURL = group.getFriendlyURL();
if (!friendlyURL.equals(groupFriendlyURL)) {
return;
}
UnicodeProperties typeSettings = layout.getTypeSettingsProperties();
String url = (String)friendlyURLInfo[1];
int x = (Integer)friendlyURLInfo[2];
int y = (Integer)friendlyURLInfo[3];
typeSettings.setProperty(
"url",
url.substring(0, x) + _SAME_GROUP_FRIENDLY_URL + url.substring(y));
}
protected void fixImportTypeSettings(Layout layout) throws Exception {
Object[] friendlyURLInfo = extractFriendlyURLInfo(layout);
if (friendlyURLInfo == null) {
return;
}
String friendlyURL = (String)friendlyURLInfo[0];
if (!friendlyURL.equals(_SAME_GROUP_FRIENDLY_URL)) {
return;
}
Group group = layout.getGroup();
UnicodeProperties typeSettings = layout.getTypeSettingsProperties();
String url = (String)friendlyURLInfo[1];
int x = (Integer)friendlyURLInfo[2];
int y = (Integer)friendlyURLInfo[3];
typeSettings.setProperty(
"url",
url.substring(0, x) + group.getFriendlyURL() + url.substring(y));
}
protected String getFriendlyURL(String friendlyURL, long layoutId) {
if (!Validator.isNumber(friendlyURL.substring(1))) {
return friendlyURL;
}
return StringPool.SLASH + layoutId;
}
protected Map<String, Object[]> getPortletids(
PortletDataContext portletDataContext, Layout layout)
throws Exception {
if (!LayoutStagingUtil.prepareLayoutStagingHandler(
portletDataContext, layout) ||
!layout.isSupportsEmbeddedPortlets()) {
// Only portlet type layouts support page scoping
return Collections.emptyMap();
}
Map<String, Object[]> portletIds = new HashMap<>();
LayoutTypePortlet layoutTypePortlet =
(LayoutTypePortlet)layout.getLayoutType();
// The getAllPortlets method returns all effective nonsystem portlets
// for any layout type, including embedded portlets, or in the case of
// panel type layout, selected portlets
for (Portlet portlet : layoutTypePortlet.getAllPortlets(false)) {
String portletId = portlet.getPortletId();
Settings portletInstanceSettings = SettingsFactoryUtil.getSettings(
new PortletInstanceSettingsLocator(layout, portletId));
String scopeType = portletInstanceSettings.getValue(
"lfrScopeType", null);
String scopeLayoutUuid = portletInstanceSettings.getValue(
"lfrScopeLayoutUuid", null);
long scopeGroupId = portletDataContext.getScopeGroupId();
if (Validator.isNotNull(scopeType)) {
Group scopeGroup = null;
if (scopeType.equals("company")) {
scopeGroup = _groupLocalService.getCompanyGroup(
layout.getCompanyId());
}
else if (scopeType.equals("layout")) {
Layout scopeLayout = null;
scopeLayout =
_layoutLocalService.fetchLayoutByUuidAndGroupId(
scopeLayoutUuid, portletDataContext.getGroupId(),
portletDataContext.isPrivateLayout());
if (scopeLayout == null) {
continue;
}
scopeGroup = scopeLayout.getScopeGroup();
}
else {
throw new IllegalArgumentException(
"Scope type " + scopeType + " is invalid");
}
if (scopeGroup != null) {
scopeGroupId = scopeGroup.getGroupId();
}
}
String key = PortletPermissionUtil.getPrimaryKey(
layout.getPlid(), portletId);
portletIds.put(
key,
new Object[] {
portletId, scopeGroupId, scopeType, scopeLayoutUuid
});
}
return portletIds;
}
protected String getUniqueFriendlyURL(
PortletDataContext portletDataContext, Layout existingLayout,
String friendlyURL) {
for (int i = 1;; i++) {
Layout duplicateFriendlyURLLayout =
_layoutLocalService.fetchLayoutByFriendlyURL(
portletDataContext.getGroupId(),
portletDataContext.isPrivateLayout(), friendlyURL);
if ((duplicateFriendlyURLLayout == null) ||
(duplicateFriendlyURLLayout.getPlid() ==
existingLayout.getPlid())) {
break;
}
friendlyURL = friendlyURL + i;
}
return friendlyURL;
}
protected void importAssets(
PortletDataContext portletDataContext, Layout layout,
Layout importedLayout)
throws Exception {
long userId = portletDataContext.getUserId(layout.getUserUuid());
long[] assetCategoryIds = portletDataContext.getAssetCategoryIds(
Layout.class, layout.getPlid());
String[] assetTagNames = portletDataContext.getAssetTagNames(
Layout.class, layout.getPlid());
_layoutLocalService.updateAsset(
userId, importedLayout, assetCategoryIds, assetTagNames);
}
protected void importLayoutFriendlyURLs(
PortletDataContext portletDataContext, Layout layout,
Layout importedLayout)
throws Exception {
List<Element> layoutFriendlyURLElements =
portletDataContext.getReferenceDataElements(
layout, LayoutFriendlyURL.class);
for (Element layoutFriendlyURLElement : layoutFriendlyURLElements) {
String layoutFriendlyURLPath =
layoutFriendlyURLElement.attributeValue("path");
LayoutFriendlyURL layoutFriendlyURL =
(LayoutFriendlyURL)portletDataContext.getZipEntryAsObject(
layoutFriendlyURLPath);
StagedModelDataHandlerUtil.importStagedModel(
portletDataContext, layoutFriendlyURL);
}
deleteMissingLayoutFriendlyURLs(portletDataContext, importedLayout);
}
protected void importLayoutIconImage(
PortletDataContext portletDataContext, Layout importedLayout,
Element layoutElement)
throws Exception {
String iconImagePath = layoutElement.elementText("icon-image-path");
byte[] iconBytes = portletDataContext.getZipEntryAsByteArray(
iconImagePath);
if (ArrayUtil.isNotEmpty(iconBytes)) {
if (importedLayout.getIconImageId() == 0) {
long iconImageId = _counterLocalService.increment();
importedLayout.setIconImageId(iconImageId);
}
_imageLocalService.updateImage(
importedLayout.getIconImageId(), iconBytes);
}
}
protected void importLayoutPortlets(
PortletDataContext portletDataContext, Layout layout,
Element layoutElement)
throws Exception {
boolean layoutSetPrototypeLinkEnabled = MapUtil.getBoolean(
portletDataContext.getParameterMap(),
PortletDataHandlerKeys.LAYOUT_SET_PROTOTYPE_LINK_ENABLED);
if (layoutSetPrototypeLinkEnabled &&
Validator.isNotNull(
portletDataContext.getLayoutSetPrototypeUuid()) &&
SitesUtil.isLayoutModifiedSinceLastMerge(layout)) {
return;
}
Map<String, String[]> parameterMap =
portletDataContext.getParameterMap();
boolean permissions = MapUtil.getBoolean(
parameterMap, PortletDataHandlerKeys.PERMISSIONS);
ServiceContext serviceContext =
ServiceContextThreadLocal.getServiceContext();
LayoutCache layoutCache = new LayoutCache();
Element portletsElement = layoutElement.element("portlets");
for (Element portletElement : portletsElement.elements()) {
String portletPath = portletElement.attributeValue("path");
String portletId = portletElement.attributeValue("portlet-id");
long oldPlid = GetterUtil.getLong(
portletElement.attributeValue("old-plid"));
Portlet portlet = _portletLocalService.getPortletById(
portletDataContext.getCompanyId(), portletId);
if (!portlet.isActive() || portlet.isUndeployedPortlet()) {
continue;
}
portletDataContext.setPlid(layout.getPlid());
portletDataContext.setOldPlid(oldPlid);
portletDataContext.setPortletId(portletId);
if (BackgroundTaskThreadLocal.hasBackgroundTask()) {
PortletDataHandlerStatusMessageSenderUtil.sendStatusMessage(
"portlet", portletId,
portletDataContext.getManifestSummary());
}
Document portletDocument = SAXReaderUtil.read(
portletDataContext.getZipEntryAsString(portletPath));
portletElement = portletDocument.getRootElement();
// The order of the import is important. You must always import the
// portlet preferences first, then the portlet data, then the
// portlet permissions. The import of the portlet data assumes that
// portlet preferences already exist.
setPortletScope(portletDataContext, portletElement);
long portletPreferencesGroupId = portletDataContext.getGroupId();
Element portletDataElement = portletElement.element("portlet-data");
Map<String, Boolean> importPortletControlsMap =
ExportImportHelperUtil.getImportPortletControlsMap(
portletDataContext.getCompanyId(), portletId, parameterMap,
portletDataElement,
portletDataContext.getManifestSummary());
if (layout != null) {
portletPreferencesGroupId = layout.getGroupId();
}
try {
_exportImportLifecycleManager.fireExportImportLifecycleEvent(
EVENT_PORTLET_IMPORT_STARTED, getProcessFlag(),
portletDataContext.getExportImportProcessId(),
PortletDataContextFactoryUtil.clonePortletDataContext(
portletDataContext));
// Portlet preferences
_portletImportController.importPortletPreferences(
portletDataContext, portletDataContext.getCompanyId(),
portletPreferencesGroupId, layout, portletElement, false,
importPortletControlsMap.get(
PortletDataHandlerKeys.PORTLET_ARCHIVED_SETUPS),
importPortletControlsMap.get(
PortletDataHandlerKeys.PORTLET_DATA),
importPortletControlsMap.get(
PortletDataHandlerKeys.PORTLET_SETUP),
importPortletControlsMap.get(
PortletDataHandlerKeys.PORTLET_USER_PREFERENCES));
// Portlet data
if (importPortletControlsMap.get(
PortletDataHandlerKeys.PORTLET_DATA)) {
_portletImportController.importPortletData(
portletDataContext, portletDataElement);
}
_exportImportLifecycleManager.fireExportImportLifecycleEvent(
EVENT_PORTLET_IMPORT_SUCCEEDED, getProcessFlag(),
portletDataContext.getExportImportProcessId(),
PortletDataContextFactoryUtil.clonePortletDataContext(
portletDataContext));
}
catch (Throwable t) {
_exportImportLifecycleManager.fireExportImportLifecycleEvent(
EVENT_PORTLET_IMPORT_FAILED, getProcessFlag(),
portletDataContext.getExportImportProcessId(),
PortletDataContextFactoryUtil.clonePortletDataContext(
portletDataContext),
t);
throw t;
}
finally {
_portletImportController.resetPortletScope(
portletDataContext, portletPreferencesGroupId);
}
// Portlet permissions
if (permissions) {
_permissionImporter.importPortletPermissions(
layoutCache, portletDataContext.getCompanyId(),
portletDataContext.getGroupId(), serviceContext.getUserId(),
layout, portletElement, portletId);
}
// Archived setups
_portletImportController.importPortletPreferences(
portletDataContext, portletDataContext.getCompanyId(),
portletDataContext.getGroupId(), null, portletElement, false,
importPortletControlsMap.get(
PortletDataHandlerKeys.PORTLET_ARCHIVED_SETUPS),
importPortletControlsMap.get(
PortletDataHandlerKeys.PORTLET_DATA),
importPortletControlsMap.get(
PortletDataHandlerKeys.PORTLET_SETUP),
importPortletControlsMap.get(
PortletDataHandlerKeys.PORTLET_USER_PREFERENCES));
}
}
protected void importLinkedLayout(
PortletDataContext portletDataContext, Layout layout,
Layout importedLayout, Element layoutElement)
throws Exception {
UnicodeProperties typeSettingsProperties =
layout.getTypeSettingsProperties();
long linkToLayoutId = GetterUtil.getLong(
typeSettingsProperties.getProperty(
"linkToLayoutId", StringPool.BLANK));
String linkedToLayoutUuid = layoutElement.attributeValue(
"linked-to-layout-uuid");
if (Validator.isNull(linkedToLayoutUuid) || (linkToLayoutId <= 0)) {
return;
}
ExportImportProcessCallbackRegistryUtil.registerCallback(
portletDataContext.getExportImportProcessId(),
new ImportLinkedLayoutCallable(
portletDataContext.getScopeGroupId(),
portletDataContext.isPrivateLayout(), importedLayout.getUuid(),
linkedToLayoutUuid));
}
@Override
protected void importReferenceStagedModels(
PortletDataContext portletDataContext, Layout layout) {
}
protected void importTheme(
PortletDataContext portletDataContext, Layout layout,
Layout importedLayout)
throws Exception {
boolean importThemeSettings = MapUtil.getBoolean(
portletDataContext.getParameterMap(),
PortletDataHandlerKeys.THEME_REFERENCE);
if (_log.isDebugEnabled()) {
_log.debug("Import theme settings " + importThemeSettings);
}
if (importThemeSettings) {
importedLayout.setColorSchemeId(layout.getColorSchemeId());
importedLayout.setCss(layout.getCss());
importedLayout.setThemeId(layout.getThemeId());
}
else {
importedLayout.setColorSchemeId(StringPool.BLANK);
importedLayout.setCss(StringPool.BLANK);
importedLayout.setThemeId(StringPool.BLANK);
}
}
protected void initNewLayoutPermissions(
long companyId, long groupId, long userId, Layout layout,
Layout importedLayout, boolean privateLayout)
throws Exception {
boolean addGroupPermissions = true;
Group group = importedLayout.getGroup();
if (privateLayout && group.isUser()) {
addGroupPermissions = false;
}
boolean addGuestPermissions = false;
if (!privateLayout ||
Objects.equals(
layout.getType(), LayoutConstants.TYPE_CONTROL_PANEL)) {
addGuestPermissions = true;
}
_resourceLocalService.addResources(
companyId, groupId, userId, Layout.class.getName(),
importedLayout.getPlid(), false, addGroupPermissions,
addGuestPermissions);
}
protected void mergePortlets(
Layout layout, String newTypeSettings, String portletsMergeMode) {
try {
UnicodeProperties previousTypeSettingsProperties =
layout.getTypeSettingsProperties();
LayoutTypePortlet previousLayoutType =
(LayoutTypePortlet)layout.getLayoutType();
LayoutTemplate previousLayoutTemplate =
previousLayoutType.getLayoutTemplate();
List<String> previousColumns = previousLayoutTemplate.getColumns();
UnicodeProperties newTypeSettingsProperties = new UnicodeProperties(
true);
newTypeSettingsProperties.load(newTypeSettings);
String layoutTemplateId = newTypeSettingsProperties.getProperty(
LayoutTypePortletConstants.LAYOUT_TEMPLATE_ID);
previousTypeSettingsProperties.setProperty(
LayoutTypePortletConstants.LAYOUT_TEMPLATE_ID,
layoutTemplateId);
String nestedColumnIds = newTypeSettingsProperties.getProperty(
LayoutTypePortletConstants.NESTED_COLUMN_IDS);
if (Validator.isNotNull(nestedColumnIds)) {
previousTypeSettingsProperties.setProperty(
LayoutTypePortletConstants.NESTED_COLUMN_IDS,
nestedColumnIds);
String[] nestedColumnIdsArray = StringUtil.split(
nestedColumnIds);
for (String nestedColumnId : nestedColumnIdsArray) {
String nestedColumnValue =
newTypeSettingsProperties.getProperty(nestedColumnId);
previousTypeSettingsProperties.setProperty(
nestedColumnId, nestedColumnValue);
}
}
LayoutTemplate newLayoutTemplate =
_layoutTemplateLocalService.getLayoutTemplate(
layoutTemplateId, false, null);
String[] newPortletIds = new String[0];
for (String columnId : newLayoutTemplate.getColumns()) {
String columnValue = newTypeSettingsProperties.getProperty(
columnId);
String[] portletIds = StringUtil.split(columnValue);
if (!previousColumns.contains(columnId)) {
newPortletIds = ArrayUtil.append(newPortletIds, portletIds);
}
else {
String[] previousPortletIds = StringUtil.split(
previousTypeSettingsProperties.getProperty(columnId));
portletIds = appendPortletIds(
previousPortletIds, portletIds, portletsMergeMode);
previousTypeSettingsProperties.setProperty(
columnId, StringUtil.merge(portletIds));
}
}
// Add portlets in non-existent column to the first column
String columnId = previousColumns.get(0);
String[] portletIds = StringUtil.split(
previousTypeSettingsProperties.getProperty(columnId));
appendPortletIds(portletIds, newPortletIds, portletsMergeMode);
previousTypeSettingsProperties.setProperty(
columnId, StringUtil.merge(portletIds));
layout.setTypeSettings(previousTypeSettingsProperties.toString());
}
catch (IOException ioe) {
layout.setTypeSettings(newTypeSettings);
}
}
protected void populateElementLayoutMetadata(
Element layoutElement, Layout layout)
throws Exception {
LayoutStagingHandler layoutStagingHandler =
LayoutStagingUtil.getLayoutStagingHandler(layout);
if (layoutStagingHandler != null) {
LayoutRevision layoutRevision =
layoutStagingHandler.getLayoutRevision();
if (layoutRevision != null) {
layoutElement.addAttribute(
"layout-revision-id",
String.valueOf(layoutRevision.getLayoutRevisionId()));
layoutElement.addAttribute(
"layout-branch-id",
String.valueOf(layoutRevision.getLayoutBranchId()));
LayoutBranch layoutBranch = layoutRevision.getLayoutBranch();
layoutElement.addAttribute(
"layout-branch-name",
String.valueOf(layoutBranch.getName()));
}
}
layoutElement.addAttribute("layout-uuid", layout.getUuid());
layoutElement.addAttribute(
"layout-id", String.valueOf(layout.getLayoutId()));
layoutElement.addAttribute(
"layout-priority", String.valueOf(layout.getPriority()));
String layoutPrototypeUuid = layout.getLayoutPrototypeUuid();
if (Validator.isNotNull(layoutPrototypeUuid)) {
LayoutPrototype layoutPrototype =
_layoutPrototypeLocalService.
getLayoutPrototypeByUuidAndCompanyId(
layoutPrototypeUuid, layout.getCompanyId());
layoutElement.addAttribute(
"layout-prototype-uuid", layoutPrototypeUuid);
layoutElement.addAttribute(
"layout-prototype-name",
layoutPrototype.getName(LocaleUtil.getDefault()));
}
}
@Reference(unbind = "-")
protected void setCounterLocalService(
CounterLocalService counterLocalService) {
_counterLocalService = counterLocalService;
}
@Reference(unbind = "-")
protected void setExportImportLifecycleManager(
ExportImportLifecycleManager exportImportLifecycleManager) {
_exportImportLifecycleManager = exportImportLifecycleManager;
}
@Reference(unbind = "-")
protected void setGroupLocalService(GroupLocalService groupLocalService) {
_groupLocalService = groupLocalService;
}
@Reference(unbind = "-")
protected void setImageLocalService(ImageLocalService imageLocalService) {
_imageLocalService = imageLocalService;
}
@Reference(unbind = "-")
protected void setLayoutFriendlyURLLocalService(
LayoutFriendlyURLLocalService layoutFriendlyURLLocalService) {
_layoutFriendlyURLLocalService = layoutFriendlyURLLocalService;
}
@Reference(unbind = "-")
protected void setLayoutLocalService(
LayoutLocalService layoutLocalService) {
_layoutLocalService = layoutLocalService;
}
@Reference(unbind = "-")
protected void setLayoutLocalServiceHelper(
LayoutLocalServiceHelper layoutLocalServiceHelper) {
_layoutLocalServiceHelper = layoutLocalServiceHelper;
}
@Reference(unbind = "-")
protected void setLayoutPrototypeLocalService(
LayoutPrototypeLocalService layoutPrototypeLocalService) {
_layoutPrototypeLocalService = layoutPrototypeLocalService;
}
@Reference(unbind = "-")
protected void setLayoutSetLocalService(
LayoutSetLocalService layoutSetLocalService) {
_layoutSetLocalService = layoutSetLocalService;
}
@Reference(unbind = "-")
protected void setLayoutTemplateLocalService(
LayoutTemplateLocalService layoutTemplateLocalService) {
_layoutTemplateLocalService = layoutTemplateLocalService;
}
@Reference(unbind = "-")
protected void setPortletExportController(
PortletExportController portletExportController) {
_portletExportController = portletExportController;
}
@Reference(unbind = "-")
protected void setPortletImportController(
PortletImportController portletImportController) {
_portletImportController = portletImportController;
}
@Reference(unbind = "-")
protected void setPortletLocalService(
PortletLocalService portletLocalService) {
_portletLocalService = portletLocalService;
}
protected void setPortletScope(
PortletDataContext portletDataContext, Element portletElement) {
// Portlet data scope
String scopeLayoutUuid = GetterUtil.getString(
portletElement.attributeValue("scope-layout-uuid"));
String scopeLayoutType = GetterUtil.getString(
portletElement.attributeValue("scope-layout-type"));
portletDataContext.setScopeLayoutUuid(scopeLayoutUuid);
portletDataContext.setScopeType(scopeLayoutType);
// Layout scope
try {
Group scopeGroup = null;
if (scopeLayoutType.equals("company")) {
scopeGroup = _groupLocalService.getCompanyGroup(
portletDataContext.getCompanyId());
}
else if (Validator.isNotNull(scopeLayoutUuid)) {
Layout scopeLayout =
_layoutLocalService.getLayoutByUuidAndGroupId(
scopeLayoutUuid, portletDataContext.getGroupId(),
portletDataContext.isPrivateLayout());
scopeGroup = _groupLocalService.checkScopeGroup(
scopeLayout, portletDataContext.getUserId(null));
Group group = scopeLayout.getGroup();
if (group.isStaged() && !group.isStagedRemotely()) {
try {
boolean privateLayout = GetterUtil.getBoolean(
portletElement.attributeValue("private-layout"));
Layout oldLayout =
_layoutLocalService.getLayoutByUuidAndGroupId(
scopeLayoutUuid,
portletDataContext.getSourceGroupId(),
privateLayout);
Group oldScopeGroup = oldLayout.getScopeGroup();
if (group.isStagingGroup()) {
scopeGroup.setLiveGroupId(
oldScopeGroup.getGroupId());
_groupLocalService.updateGroup(scopeGroup);
}
else {
oldScopeGroup.setLiveGroupId(
scopeGroup.getGroupId());
_groupLocalService.updateGroup(oldScopeGroup);
}
}
catch (NoSuchLayoutException nsle) {
if (_log.isWarnEnabled()) {
_log.warn(nsle);
}
}
}
}
if (scopeGroup != null) {
portletDataContext.setScopeGroupId(scopeGroup.getGroupId());
Map<Long, Long> groupIds =
(Map<Long, Long>)portletDataContext.getNewPrimaryKeysMap(
Group.class);
long oldScopeGroupId = GetterUtil.getLong(
portletElement.attributeValue("scope-group-id"));
groupIds.put(oldScopeGroupId, scopeGroup.getGroupId());
}
}
catch (PortalException pe) {
// LPS-52675
if (_log.isDebugEnabled()) {
_log.debug(pe, pe);
}
}
catch (Exception e) {
_log.error(e, e);
}
}
@Reference(unbind = "-")
protected void setResourceLocalService(
ResourceLocalService resourceLocalService) {
_resourceLocalService = resourceLocalService;
}
protected void updateTypeSettings(Layout importedLayout, Layout layout)
throws PortalException {
long groupId = layout.getGroupId();
try {
LayoutTypePortlet importedLayoutType =
(LayoutTypePortlet)importedLayout.getLayoutType();
List<String> importedPortletIds =
importedLayoutType.getPortletIds();
layout.setGroupId(importedLayout.getGroupId());
LayoutTypePortlet layoutTypePortlet =
(LayoutTypePortlet)layout.getLayoutType();
importedPortletIds.removeAll(layoutTypePortlet.getPortletIds());
if (!importedPortletIds.isEmpty()) {
_portletLocalService.deletePortlets(
importedLayout.getCompanyId(),
importedPortletIds.toArray(
new String[importedPortletIds.size()]),
importedLayout.getPlid());
}
importedLayout.setTypeSettingsProperties(
layoutTypePortlet.getTypeSettingsProperties());
}
finally {
layout.setGroupId(groupId);
}
}
private static final String _SAME_GROUP_FRIENDLY_URL =
"/[$SAME_GROUP_FRIENDLY_URL$]";
private static final Log _log = LogFactoryUtil.getLog(
LayoutStagedModelDataHandler.class);
private static final TransactionConfig _transactionConfig =
TransactionConfig.Factory.create(
Propagation.SUPPORTS,
new Class<?>[] {PortalException.class, SystemException.class});
private CounterLocalService _counterLocalService;
private ExportImportLifecycleManager _exportImportLifecycleManager;
private GroupLocalService _groupLocalService;
private ImageLocalService _imageLocalService;
private LayoutFriendlyURLLocalService _layoutFriendlyURLLocalService;
private LayoutLocalService _layoutLocalService;
private LayoutLocalServiceHelper _layoutLocalServiceHelper;
private LayoutPrototypeLocalService _layoutPrototypeLocalService;
private LayoutSetLocalService _layoutSetLocalService;
private LayoutTemplateLocalService _layoutTemplateLocalService;
private final PermissionImporter _permissionImporter =
PermissionImporter.getInstance();
private PortletExportController _portletExportController;
private PortletImportController _portletImportController;
private PortletLocalService _portletLocalService;
private ResourceLocalService _resourceLocalService;
private class ImportLinkedLayoutCallable implements Callable<Void> {
public ImportLinkedLayoutCallable(
long groupId, boolean privateLayout, String layoutUuid,
String linkedToLayoutUuid) {
_groupId = groupId;
_privateLayout = privateLayout;
_layoutUuid = layoutUuid;
_linkedToLayoutUuid = linkedToLayoutUuid;
}
@Override
public Void call() throws Exception {
Layout layout = _layoutLocalService.fetchLayoutByUuidAndGroupId(
_layoutUuid, _groupId, _privateLayout);
if (layout == null) {
return null;
}
Layout linkedToLayout =
_layoutLocalService.fetchLayoutByUuidAndGroupId(
_linkedToLayoutUuid, _groupId, _privateLayout);
if (linkedToLayout == null) {
if (_log.isWarnEnabled()) {
StringBundler sb = new StringBundler(6);
sb.append("Unable to link layout with friendly URL ");
sb.append(layout.getFriendlyURL());
sb.append(" and layout ID ");
sb.append(layout.getLayoutId());
sb.append(" to layout with layout UUID ");
sb.append(_linkedToLayoutUuid);
_log.warn(sb.toString());
}
return null;
}
UnicodeProperties typeSettingsProperties =
layout.getTypeSettingsProperties();
typeSettingsProperties.setProperty(
"privateLayout",
String.valueOf(linkedToLayout.isPrivateLayout()));
typeSettingsProperties.setProperty(
"linkToLayoutId", String.valueOf(linkedToLayout.getLayoutId()));
layout.setTypeSettingsProperties(typeSettingsProperties);
_layoutLocalService.updateLayout(layout);
return null;
}
private final long _groupId;
private final String _layoutUuid;
private final String _linkedToLayoutUuid;
private final boolean _privateLayout;
}
}