/**
* 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.kernel.lar;
import com.liferay.portal.kernel.log.Log;
import com.liferay.portal.kernel.log.LogFactoryUtil;
import com.liferay.portal.kernel.model.Portlet;
import com.liferay.portal.kernel.plugin.Version;
import com.liferay.portal.kernel.service.PortletPreferencesLocalServiceUtil;
import com.liferay.portal.kernel.util.ArrayUtil;
import com.liferay.portal.kernel.util.GetterUtil;
import com.liferay.portal.kernel.util.PortletKeys;
import com.liferay.portal.kernel.util.StringPool;
import com.liferay.portal.kernel.util.Time;
import com.liferay.portal.kernel.util.Validator;
import com.liferay.portal.kernel.xml.Document;
import com.liferay.portal.kernel.xml.DocumentException;
import com.liferay.portal.kernel.xml.Element;
import com.liferay.portal.kernel.xml.SAXReaderUtil;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import javax.portlet.PortletPreferences;
/**
* @author Brian Wing Shun Chan
*/
public abstract class BasePortletDataHandler implements PortletDataHandler {
@Override
public PortletPreferences addDefaultData(
PortletDataContext portletDataContext, String portletId,
PortletPreferences portletPreferences)
throws PortletDataException {
long startTime = 0;
if (_log.isInfoEnabled()) {
_log.info("Adding default data to portlet " + portletId);
startTime = System.currentTimeMillis();
}
try {
return doAddDefaultData(
portletDataContext, portletId, portletPreferences);
}
catch (PortletDataException pde) {
throw pde;
}
catch (Exception e) {
throw new PortletDataException(e);
}
finally {
if (_log.isInfoEnabled()) {
long duration = System.currentTimeMillis() - startTime;
_log.info(
"Added default data to portlet in " +
Time.getDuration(duration));
}
}
}
@Override
public PortletPreferences deleteData(
PortletDataContext portletDataContext, String portletId,
PortletPreferences portletPreferences)
throws PortletDataException {
long startTime = 0;
if (_log.isInfoEnabled()) {
_log.info("Deleting portlet " + portletId);
startTime = System.currentTimeMillis();
}
try {
return doDeleteData(
portletDataContext, portletId, portletPreferences);
}
catch (Exception e) {
throw _handleException(
e, PortletDataException.DELETE_PORTLET_DATA, portletId);
}
finally {
if (_log.isInfoEnabled()) {
long duration = System.currentTimeMillis() - startTime;
_log.info("Deleted portlet in " + Time.getDuration(duration));
}
}
}
@Override
public String exportData(
PortletDataContext portletDataContext, String portletId,
PortletPreferences portletPreferences)
throws PortletDataException {
long startTime = 0;
if (_log.isInfoEnabled()) {
_log.info("Exporting portlet " + portletId);
startTime = System.currentTimeMillis();
}
Element rootElement = null;
try {
rootElement = portletDataContext.getExportDataRootElement();
portletDataContext.addDeletionSystemEventStagedModelTypes(
getDeletionSystemEventStagedModelTypes());
for (PortletDataHandlerControl portletDataHandlerControl :
getExportControls()) {
addUncheckedModelAdditionCount(
portletDataContext, portletDataHandlerControl);
}
return doExportData(
portletDataContext, portletId, portletPreferences);
}
catch (Exception e) {
throw _handleException(
e, PortletDataException.EXPORT_PORTLET_DATA, portletId);
}
finally {
portletDataContext.setExportDataRootElement(rootElement);
if (_log.isInfoEnabled()) {
long duration = System.currentTimeMillis() - startTime;
_log.info("Exported portlet in " + Time.getDuration(duration));
}
}
}
@Override
public DataLevel getDataLevel() {
return _dataLevel;
}
@Override
public String[] getDataPortletPreferences() {
return _dataPortletPreferences;
}
@Override
public StagedModelType[] getDeletionSystemEventStagedModelTypes() {
return _deletionSystemEventStagedModelTypes;
}
@Override
public PortletDataHandlerControl[] getExportConfigurationControls(
long companyId, long groupId, Portlet portlet,
boolean privateLayout)
throws Exception {
return getExportConfigurationControls(
companyId, groupId, portlet, -1, privateLayout);
}
@Override
public PortletDataHandlerControl[] getExportConfigurationControls(
long companyId, long groupId, Portlet portlet, long plid,
boolean privateLayout)
throws Exception {
List<PortletDataHandlerBoolean> configurationControls =
new ArrayList<>();
// Setup
if ((PortletPreferencesLocalServiceUtil.getPortletPreferencesCount(
PortletKeys.PREFS_OWNER_ID_DEFAULT,
PortletKeys.PREFS_OWNER_TYPE_LAYOUT, plid, portlet, false) >
0) ||
(PortletPreferencesLocalServiceUtil.getPortletPreferencesCount(
groupId, PortletKeys.PREFS_OWNER_TYPE_GROUP,
portlet.getRootPortletId(), false) > 0) ||
(PortletPreferencesLocalServiceUtil.getPortletPreferencesCount(
companyId, PortletKeys.PREFS_OWNER_TYPE_COMPANY,
portlet.getRootPortletId(), false) > 0)) {
PortletDataHandlerControl[] portletDataHandlerControls = null;
if (isDisplayPortlet()) {
portletDataHandlerControls = getExportControls();
}
configurationControls.add(
new PortletDataHandlerBoolean(
null, PortletDataHandlerKeys.PORTLET_SETUP, "setup", true,
false, portletDataHandlerControls, null, null));
}
// Archived setups
if (PortletPreferencesLocalServiceUtil.getPortletPreferencesCount(
-1, PortletKeys.PREFS_OWNER_TYPE_ARCHIVED,
portlet.getRootPortletId(), false) > 0) {
configurationControls.add(
new PortletDataHandlerBoolean(
null, PortletDataHandlerKeys.PORTLET_ARCHIVED_SETUPS,
"configuration-templates", true, false, null, null, null));
}
// User preferences
if ((PortletPreferencesLocalServiceUtil.getPortletPreferencesCount(
-1, PortletKeys.PREFS_OWNER_TYPE_USER, plid, portlet, false) >
0) ||
(PortletPreferencesLocalServiceUtil.getPortletPreferencesCount(
groupId, PortletKeys.PREFS_OWNER_TYPE_USER,
PortletKeys.PREFS_PLID_SHARED, portlet, false) > 0)) {
configurationControls.add(
new PortletDataHandlerBoolean(
null, PortletDataHandlerKeys.PORTLET_USER_PREFERENCES,
"user-preferences", true, false, null, null, null));
}
return configurationControls.toArray(
new PortletDataHandlerBoolean[configurationControls.size()]);
}
@Override
public PortletDataHandlerControl[] getExportControls() {
return _exportControls;
}
@Override
public PortletDataHandlerControl[] getExportMetadataControls() {
return _exportMetadataControls;
}
@Override
public long getExportModelCount(ManifestSummary manifestSummary) {
return getExportModelCount(manifestSummary, getExportControls());
}
@Override
public PortletDataHandlerControl[] getImportConfigurationControls(
Portlet portlet, ManifestSummary manifestSummary) {
String[] configurationPortletOptions =
manifestSummary.getConfigurationPortletOptions(
portlet.getRootPortletId());
return getImportConfigurationControls(configurationPortletOptions);
}
@Override
public PortletDataHandlerControl[] getImportConfigurationControls(
String[] configurationPortletOptions) {
List<PortletDataHandlerBoolean> configurationControls =
new ArrayList<>();
// Setup
if (ArrayUtil.contains(configurationPortletOptions, "setup")) {
PortletDataHandlerControl[] portletDataHandlerControls = null;
if (isDisplayPortlet()) {
portletDataHandlerControls = getExportControls();
}
configurationControls.add(
new PortletDataHandlerBoolean(
null, PortletDataHandlerKeys.PORTLET_SETUP, "setup", true,
false, portletDataHandlerControls, null, null));
}
// Archived setups
if (ArrayUtil.contains(
configurationPortletOptions, "archived-setups")) {
configurationControls.add(
new PortletDataHandlerBoolean(
null, PortletDataHandlerKeys.PORTLET_ARCHIVED_SETUPS,
"configuration-templates", true, false, null, null, null));
}
// User preferences
if (ArrayUtil.contains(
configurationPortletOptions, "user-preferences")) {
configurationControls.add(
new PortletDataHandlerBoolean(
null, PortletDataHandlerKeys.PORTLET_USER_PREFERENCES,
"user-preferences", true, false, null, null, null));
}
return configurationControls.toArray(
new PortletDataHandlerBoolean[configurationControls.size()]);
}
@Override
public PortletDataHandlerControl[] getImportControls() {
return _importControls;
}
@Override
public PortletDataHandlerControl[] getImportMetadataControls() {
return _importMetadataControls;
}
@Override
public String getPortletId() {
return _portletId;
}
@Override
public int getRank() {
return _rank;
}
@Override
public String getSchemaVersion() {
return "1.0.0";
}
@Override
public String getServiceName() {
return null;
}
@Override
public PortletPreferences importData(
PortletDataContext portletDataContext, String portletId,
PortletPreferences portletPreferences, String data)
throws PortletDataException {
long startTime = 0;
if (_log.isInfoEnabled()) {
_log.info("Importing portlet " + portletId);
startTime = System.currentTimeMillis();
}
long sourceGroupId = portletDataContext.getSourceGroupId();
Element rootElement = null;
try {
if (Validator.isXml(data)) {
rootElement = portletDataContext.getImportDataRootElement();
addImportDataRootElement(portletDataContext, data);
}
return doImportData(
portletDataContext, portletId, portletPreferences, data);
}
catch (Exception e) {
throw _handleException(
e, PortletDataException.IMPORT_PORTLET_DATA, portletId);
}
finally {
portletDataContext.setImportDataRootElement(rootElement);
portletDataContext.setSourceGroupId(sourceGroupId);
if (_log.isInfoEnabled()) {
long duration = System.currentTimeMillis() - startTime;
_log.info("Imported portlet in " + Time.getDuration(duration));
}
}
}
@Override
public boolean isDataAlwaysStaged() {
return _dataAlwaysStaged;
}
@Override
public boolean isDataLocalized() {
return _dataLocalized;
}
@Override
public boolean isDataPortalLevel() {
return _dataLevel.equals(DataLevel.PORTAL);
}
@Override
public boolean isDataPortletInstanceLevel() {
return _dataLevel.equals(DataLevel.PORTLET_INSTANCE);
}
@Override
public boolean isDataSiteLevel() {
return _dataLevel.equals(DataLevel.SITE);
}
@Override
public boolean isDisplayPortlet() {
if (isDataPortletInstanceLevel() &&
!ArrayUtil.isEmpty(getDataPortletPreferences())) {
return true;
}
return false;
}
@Override
public boolean isPublishToLiveByDefault() {
return _publishToLiveByDefault;
}
@Override
public boolean isRollbackOnException() {
// For now, we are going to throw an exception if one portlet data
// handler has an exception to ensure that the transaction is rolled
// back for data integrity. We may decide that this is not the best
// behavior in the future because a bad plugin could prevent deletion of
// groups.
return true;
}
@Override
public void prepareManifestSummary(PortletDataContext portletDataContext)
throws PortletDataException {
prepareManifestSummary(portletDataContext, null);
}
@Override
public void prepareManifestSummary(
PortletDataContext portletDataContext,
PortletPreferences portletPreferences)
throws PortletDataException {
try {
doPrepareManifestSummary(portletDataContext, portletPreferences);
}
catch (Exception e) {
throw _handleException(
e, PortletDataException.PREPARE_MANIFEST_SUMMARY,
portletDataContext.getPortletId());
}
}
/**
* @deprecated As of 7.0.0
*/
@Deprecated
@Override
public PortletPreferences processExportPortletPreferences(
PortletDataContext portletDataContext, String portletId,
PortletPreferences portletPreferences)
throws PortletDataException {
try {
return doProcessExportPortletPreferences(
portletDataContext, portletId, portletPreferences);
}
catch (PortletDataException pde) {
throw pde;
}
catch (Exception e) {
throw new PortletDataException(e);
}
}
/**
* @deprecated As of 7.0.0
*/
@Deprecated
@Override
public PortletPreferences processImportPortletPreferences(
PortletDataContext portletDataContext, String portletId,
PortletPreferences portletPreferences)
throws PortletDataException {
try {
return doProcessImportPortletPreferences(
portletDataContext, portletId, portletPreferences);
}
catch (PortletDataException pde) {
throw pde;
}
catch (Exception e) {
throw new PortletDataException(e);
}
}
@Override
public void setPortletId(String portletId) {
_portletId = portletId;
}
@Override
public void setRank(int rank) {
_rank = rank;
}
@Override
public boolean validateSchemaVersion(String schemaVersion) {
try {
return doValidateSchemaVersion(schemaVersion);
}
catch (Exception e) {
return false;
}
}
protected Element addExportDataRootElement(
PortletDataContext portletDataContext) {
Document document = SAXReaderUtil.createDocument();
Class<?> clazz = getClass();
Element rootElement = document.addElement(clazz.getSimpleName());
portletDataContext.setExportDataRootElement(rootElement);
return rootElement;
}
protected Element addImportDataRootElement(
PortletDataContext portletDataContext, String data)
throws DocumentException {
Document document = SAXReaderUtil.read(data);
Element rootElement = document.getRootElement();
portletDataContext.setImportDataRootElement(rootElement);
long groupId = GetterUtil.getLong(
rootElement.attributeValue("group-id"));
if (groupId != 0) {
portletDataContext.setSourceGroupId(groupId);
}
return rootElement;
}
protected void addUncheckedModelAdditionCount(
PortletDataContext portletDataContext,
PortletDataHandlerControl portletDataHandlerControl) {
if (!(portletDataHandlerControl instanceof PortletDataHandlerBoolean)) {
return;
}
PortletDataHandlerBoolean portletDataHandlerBoolean =
(PortletDataHandlerBoolean)portletDataHandlerControl;
PortletDataHandlerControl[] childPortletDataHandlerControls =
portletDataHandlerBoolean.getChildren();
if (childPortletDataHandlerControls != null) {
for (PortletDataHandlerControl childPortletDataHandlerControl :
childPortletDataHandlerControls) {
addUncheckedModelAdditionCount(
portletDataContext, childPortletDataHandlerControl);
}
}
if (Validator.isNull(portletDataHandlerControl.getClassName())) {
return;
}
boolean checkedControl = GetterUtil.getBoolean(
portletDataContext.getBooleanParameter(
portletDataHandlerControl.getNamespace(),
portletDataHandlerControl.getControlName(), false));
if (!checkedControl) {
ManifestSummary manifestSummary =
portletDataContext.getManifestSummary();
StagedModelType stagedModelType = new StagedModelType(
portletDataHandlerControl.getClassName(),
portletDataHandlerBoolean.getReferrerClassName());
String manifestSummaryKey = ManifestSummary.getManifestSummaryKey(
stagedModelType);
manifestSummary.addModelAdditionCount(manifestSummaryKey, 0);
}
}
protected PortletPreferences doAddDefaultData(
PortletDataContext portletDataContext, String portletId,
PortletPreferences portletPreferences)
throws Exception {
return portletPreferences;
}
protected PortletPreferences doDeleteData(
PortletDataContext portletDataContext, String portletId,
PortletPreferences portletPreferences)
throws Exception {
return portletPreferences;
}
protected String doExportData(
PortletDataContext portletDataContext, String portletId,
PortletPreferences portletPreferences)
throws Exception {
return null;
}
protected PortletPreferences doImportData(
PortletDataContext portletDataContext, String portletId,
PortletPreferences portletPreferences, String data)
throws Exception {
return null;
}
protected void doPrepareManifestSummary(
PortletDataContext portletDataContext,
PortletPreferences portletPreferences)
throws Exception {
}
protected PortletPreferences doProcessExportPortletPreferences(
PortletDataContext portletDataContext, String portletId,
PortletPreferences portletPreferences)
throws Exception {
return portletPreferences;
}
protected PortletPreferences doProcessImportPortletPreferences(
PortletDataContext portletDataContext, String portletId,
PortletPreferences portletPreferences)
throws Exception {
return portletPreferences;
}
protected boolean doValidateSchemaVersion(String schemaVersion)
throws Exception {
// Major version has to be identical
Version currentVersion = Version.getInstance(getSchemaVersion());
Version importedVersion = Version.getInstance(schemaVersion);
if (!Objects.equals(
currentVersion.getMajor(), importedVersion.getMajor())) {
return false;
}
// Imported minor version should be less than or equal to the current
// minor version
int currentMinorVersion = GetterUtil.getInteger(
currentVersion.getMinor(), -1);
int importedMinorVersion = GetterUtil.getInteger(
importedVersion.getMinor(), -1);
if (((currentMinorVersion == -1) && (importedMinorVersion == -1)) ||
(currentMinorVersion < importedMinorVersion)) {
return false;
}
// Import should be compatible with all minor versions if previous
// validations pass
return true;
}
protected String getExportDataRootElementString(Element rootElement) {
if (rootElement == null) {
return StringPool.BLANK;
}
try {
Document document = rootElement.getDocument();
return document.formattedString();
}
catch (IOException ioe) {
return StringPool.BLANK;
}
}
protected long getExportModelCount(
ManifestSummary manifestSummary,
PortletDataHandlerControl[] portletDataHandlerControls) {
long totalModelCount = -1;
for (PortletDataHandlerControl portletDataHandlerControl :
portletDataHandlerControls) {
StagedModelType stagedModelType = new StagedModelType(
portletDataHandlerControl.getClassName(),
portletDataHandlerControl.getReferrerClassName());
long modelAdditionCount = manifestSummary.getModelAdditionCount(
stagedModelType);
if (portletDataHandlerControl instanceof
PortletDataHandlerBoolean) {
PortletDataHandlerBoolean portletDataHandlerBoolean =
(PortletDataHandlerBoolean)portletDataHandlerControl;
PortletDataHandlerControl[] childPortletDataHandlerControls =
portletDataHandlerBoolean.getChildren();
if (childPortletDataHandlerControls != null) {
long childModelCount = getExportModelCount(
manifestSummary, childPortletDataHandlerControls);
if (childModelCount != -1) {
if (modelAdditionCount == -1) {
modelAdditionCount = childModelCount;
}
else {
modelAdditionCount += childModelCount;
}
}
}
}
if (modelAdditionCount == -1) {
continue;
}
if (totalModelCount == -1) {
totalModelCount = modelAdditionCount;
}
else {
totalModelCount += modelAdditionCount;
}
}
return totalModelCount;
}
protected void setDataAlwaysStaged(boolean dataAlwaysStaged) {
_dataAlwaysStaged = dataAlwaysStaged;
}
protected void setDataLevel(DataLevel dataLevel) {
_dataLevel = dataLevel;
}
protected void setDataLocalized(boolean dataLocalized) {
_dataLocalized = dataLocalized;
}
protected void setDataPortletPreferences(String... dataPortletPreferences) {
_dataPortletPreferences = dataPortletPreferences;
}
protected void setDeletionSystemEventStagedModelTypes(
StagedModelType... deletionSystemEventStagedModelTypes) {
_deletionSystemEventStagedModelTypes =
deletionSystemEventStagedModelTypes;
}
protected void setExportControls(
PortletDataHandlerControl... exportControls) {
_exportControls = exportControls;
setImportControls(exportControls);
}
protected void setExportMetadataControls(
PortletDataHandlerControl... exportMetadataControls) {
_exportMetadataControls = exportMetadataControls;
setImportMetadataControls(exportMetadataControls);
}
protected void setImportControls(
PortletDataHandlerControl... importControls) {
_importControls = importControls;
}
protected void setImportMetadataControls(
PortletDataHandlerControl... importMetadataControls) {
_importMetadataControls = importMetadataControls;
}
protected void setPublishToLiveByDefault(boolean publishToLiveByDefault) {
_publishToLiveByDefault = publishToLiveByDefault;
}
/**
* @deprecated As of 7.0.0
*/
@Deprecated
protected void setSupportsDataStrategyCopyAsNew(
boolean supportsDataStrategyCopyAsNew) {
}
private PortletDataException _handleException(
Exception e, int type, String portletId) {
PortletDataException pde = null;
if (e instanceof PortletDataException) {
pde = (PortletDataException)e;
}
else {
pde = new PortletDataException(e.getMessage(), e);
}
if (Validator.isNull(pde.getPortletId())) {
pde.setPortletId(portletId);
}
if (pde.getType() != PortletDataException.DEFAULT) {
return pde;
}
pde.setType(type);
return pde;
}
private static final Log _log = LogFactoryUtil.getLog(
BasePortletDataHandler.class);
private boolean _dataAlwaysStaged;
private DataLevel _dataLevel = DataLevel.SITE;
private boolean _dataLocalized;
private String[] _dataPortletPreferences = StringPool.EMPTY_ARRAY;
private StagedModelType[] _deletionSystemEventStagedModelTypes =
new StagedModelType[0];
private PortletDataHandlerControl[] _exportControls =
new PortletDataHandlerControl[0];
private PortletDataHandlerControl[] _exportMetadataControls =
new PortletDataHandlerControl[0];
private PortletDataHandlerControl[] _importControls =
new PortletDataHandlerControl[0];
private PortletDataHandlerControl[] _importMetadataControls =
new PortletDataHandlerControl[0];
private String _portletId;
private boolean _publishToLiveByDefault;
private int _rank = 100;
}