com.liferay.portal.kernel.upgrade.BaseUpgradePortletId.java Source code

Java tutorial

Introduction

Here is the source code for com.liferay.portal.kernel.upgrade.BaseUpgradePortletId.java

Source

/**
 * 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.portal.kernel.upgrade;

import com.liferay.exportimport.kernel.staging.StagingConstants;
import com.liferay.layout.admin.kernel.model.LayoutTypePortletConstants;
import com.liferay.petra.string.StringBundler;
import com.liferay.portal.kernel.dao.jdbc.AutoBatchPreparedStatementUtil;
import com.liferay.portal.kernel.log.Log;
import com.liferay.portal.kernel.log.LogFactoryUtil;
import com.liferay.portal.kernel.portlet.PortletIdCodec;
import com.liferay.portal.kernel.util.LoggingTimer;
import com.liferay.portal.kernel.util.StringUtil;
import com.liferay.portal.kernel.util.UnicodeProperties;

import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * @author Brian Wing Shun Chan
 */
public abstract class BaseUpgradePortletId extends UpgradeProcess {

    @Override
    protected void doUpgrade() throws Exception {
        upgradeInstanceablePortletIds();
        upgradeUninstanceablePortletIds();
    }

    protected String getNewTypeSettings(String typeSettings, String oldPropertyId, String newPropertyId) {

        UnicodeProperties typeSettingsProperties = new UnicodeProperties(true);

        typeSettingsProperties.fastLoad(typeSettings);

        String value = typeSettingsProperties.remove(oldPropertyId);

        if (value != null) {
            typeSettingsProperties.setProperty(newPropertyId, value);
        }

        return typeSettingsProperties.toString();
    }

    protected String getNewTypeSettings(String typeSettings, String oldRootPortletId, String newRootPortletId,
            boolean exactMatch) {

        UnicodeProperties typeSettingsProperties = new UnicodeProperties(true);

        typeSettingsProperties.fastLoad(typeSettings);

        for (Map.Entry<String, String> entry : typeSettingsProperties.entrySet()) {

            String typeSettingId = entry.getKey();

            if (!LayoutTypePortletConstants.hasPortletIds(typeSettingId)) {
                continue;
            }

            String[] portletIds = StringUtil.split(entry.getValue());

            for (int j = 0; j < portletIds.length; j++) {
                String portletId = portletIds[j];

                if (exactMatch) {
                    if (portletId.equals(oldRootPortletId)) {
                        portletIds[j] = newRootPortletId;
                    }

                    continue;
                }

                String rootPortletId = PortletIdCodec.decodePortletName(portletId);

                if (!rootPortletId.equals(oldRootPortletId)) {
                    continue;
                }

                long userId = PortletIdCodec.decodeUserId(portletId);
                String instanceId = PortletIdCodec.decodeInstanceId(portletId);

                portletIds[j] = PortletIdCodec.encode(newRootPortletId, userId, instanceId);
            }

            String portletIdsString = StringUtil.merge(portletIds);

            typeSettingsProperties.setProperty(typeSettingId, portletIdsString);
        }

        return typeSettingsProperties.toString();
    }

    protected String[][] getRenamePortletIdsArray() {
        return new String[0][0];
    }

    protected String getTypeSettingsCriteria(String portletId) {
        StringBundler sb = new StringBundler(21);

        sb.append("typeSettings like '%=");
        sb.append(portletId);
        sb.append(",%' OR typeSettings like '%=");
        sb.append(portletId);
        sb.append("\n%' OR typeSettings like '%=");
        sb.append(portletId);
        sb.append("%' OR typeSettings like '%,");
        sb.append(portletId);
        sb.append(",%' OR typeSettings like '%,");
        sb.append(portletId);
        sb.append("\n%' OR typeSettings like '%,");
        sb.append(portletId);
        sb.append("%' OR typeSettings like '%=");
        sb.append(portletId);
        sb.append("_INSTANCE_%' OR typeSettings like '%,");
        sb.append(portletId);
        sb.append("_INSTANCE_%' OR typeSettings like '%=");
        sb.append(portletId);
        sb.append("_USER_%' OR typeSettings like '%,");
        sb.append(portletId);
        sb.append("_USER_%'");

        return sb.toString();
    }

    protected String[] getUninstanceablePortletIds() {
        return new String[0];
    }

    /**
     * @deprecated As of Mueller (7.2.x), with no direct replacement
     */
    @Deprecated
    protected void updateGroup(long groupId, String typeSettings) throws Exception {

        String sql = "update Group_ set typeSettings = ? where groupId = " + groupId;

        try (PreparedStatement ps = connection.prepareStatement(sql)) {
            ps.setString(1, typeSettings);

            ps.executeUpdate();
        } catch (SQLException sqle) {
            if (_log.isWarnEnabled()) {
                _log.warn(sqle, sqle);
            }
        }
    }

    protected void updateGroup(String oldRootPortletId, String newRootPortletId) throws Exception {

        String oldStagedPortletId = _getStagedPortletId(oldRootPortletId);

        String sql1 = StringBundler.concat("select groupId, typeSettings from Group_ where typeSettings like ",
                "'%", oldStagedPortletId, "%'");

        String sql2 = "update Group_ set typeSettings = ? where groupId = ?";

        try (PreparedStatement ps1 = connection.prepareStatement(sql1);
                PreparedStatement ps2 = AutoBatchPreparedStatementUtil.concurrentAutoBatch(connection, sql2);
                ResultSet rs = ps1.executeQuery()) {

            while (rs.next()) {
                long groupId = rs.getLong("groupId");

                String typeSettings = rs.getString("typeSettings");

                String newTypeSettings = getNewTypeSettings(typeSettings, oldStagedPortletId,
                        _getStagedPortletId(newRootPortletId));

                ps2.setString(1, newTypeSettings);

                ps2.setLong(2, groupId);

                ps2.addBatch();
            }

            ps2.executeBatch();
        }
    }

    protected void updateInstanceablePortletPreferences(String oldRootPortletId, String newRootPortletId)
            throws Exception {

        runSQL(StringBundler.concat("update PortletPreferences set portletId = '", newRootPortletId,
                "' where portletId = '", oldRootPortletId, "'"));

        if (!newRootPortletId.contains("_INSTANCE_")) {
            runSQL(StringBundler.concat("update PortletPreferences set portletId = replace(", "portletId, '",
                    oldRootPortletId, "_INSTANCE_', '", newRootPortletId, "_INSTANCE_') where portletId like '",
                    oldRootPortletId, "_INSTANCE_%'"));
        }

        runSQL(StringBundler.concat("update PortletPreferences set portletId = replace(portletId, ", "'",
                oldRootPortletId, "_USER_', '", newRootPortletId, "_USER_') where portletId like '",
                oldRootPortletId, "_USER_%'"));
    }

    protected void updateLayout(long plid, String typeSettings) throws Exception {

        try (PreparedStatement ps = connection
                .prepareStatement("update Layout set typeSettings = ? where plid = " + plid)) {

            ps.setString(1, typeSettings);

            ps.executeUpdate();
        } catch (SQLException sqle) {
            if (_log.isWarnEnabled()) {
                _log.warn(sqle, sqle);
            }
        }
    }

    protected void updateLayout(long plid, String oldPortletId, String newPortletId) throws Exception {

        try (PreparedStatement ps = connection
                .prepareStatement("select typeSettings from Layout where plid = " + plid);
                ResultSet rs = ps.executeQuery()) {

            while (rs.next()) {
                String typeSettings = rs.getString("typeSettings");

                String newTypeSettings = StringUtil.replace(typeSettings, oldPortletId, newPortletId);

                updateLayout(plid, newTypeSettings);
            }
        } catch (Exception e) {
            if (_log.isWarnEnabled()) {
                _log.warn(e, e);
            }
        }
    }

    protected void updateLayoutRevision(long layoutRevisionId, String typeSettings) throws Exception {

        String sql = "update LayoutRevision set typeSettings = ? where " + "layoutRevisionId = " + layoutRevisionId;

        try (PreparedStatement ps = connection.prepareStatement(sql)) {
            ps.setString(1, typeSettings);

            ps.executeUpdate();
        } catch (SQLException sqle) {
            if (_log.isWarnEnabled()) {
                _log.warn(sqle, sqle);
            }
        }
    }

    protected void updateLayoutRevisions(String oldRootPortletId, String newRootPortletId, boolean exactMatch)
            throws Exception {

        String sql1 = "select layoutRevisionId, typeSettings from LayoutRevision where "
                + getTypeSettingsCriteria(oldRootPortletId);
        String sql2 = "update LayoutRevision set typeSettings = ? where " + "layoutRevisionId = ?";

        try (PreparedStatement ps1 = connection.prepareStatement(sql1);
                PreparedStatement ps2 = AutoBatchPreparedStatementUtil.concurrentAutoBatch(connection, sql2);
                ResultSet rs = ps1.executeQuery()) {

            while (rs.next()) {
                long layoutRevisionId = rs.getLong("layoutRevisionId");

                String typeSettings = rs.getString("typeSettings");

                String newTypeSettings = getNewTypeSettings(typeSettings, oldRootPortletId, newRootPortletId,
                        exactMatch);

                ps2.setString(1, newTypeSettings);

                ps2.setLong(2, layoutRevisionId);

                ps2.addBatch();
            }

            ps2.executeBatch();
        }
    }

    protected void updateLayouts(String oldRootPortletId, String newRootPortletId, boolean exactMatch)
            throws Exception {

        String sql1 = "select plid, typeSettings from Layout where " + getTypeSettingsCriteria(oldRootPortletId);
        String sql2 = "update Layout set typeSettings = ? where plid = ?";

        try (PreparedStatement ps1 = connection.prepareStatement(sql1);
                PreparedStatement ps2 = AutoBatchPreparedStatementUtil.concurrentAutoBatch(connection, sql2);
                ResultSet rs = ps1.executeQuery()) {

            while (rs.next()) {
                long plid = rs.getLong("plid");

                String typeSettings = rs.getString("typeSettings");

                String newTypeSettings = getNewTypeSettings(typeSettings, oldRootPortletId, newRootPortletId,
                        exactMatch);

                ps2.setString(1, newTypeSettings);

                ps2.setLong(2, plid);

                ps2.addBatch();
            }

            ps2.executeBatch();
        }
    }

    protected void updatePortlet(String oldRootPortletId, String newRootPortletId) throws Exception {

        try {
            updatePortletId(oldRootPortletId, newRootPortletId);

            updateResourceAction(oldRootPortletId, newRootPortletId);

            updateResourcePermission(oldRootPortletId, newRootPortletId, true);

            updateUserNotificationDelivery(oldRootPortletId, newRootPortletId);

            updateUserNotificationEvent(oldRootPortletId, newRootPortletId);

            updateInstanceablePortletPreferences(oldRootPortletId, newRootPortletId);
        } catch (Exception e) {
            if (_log.isWarnEnabled()) {
                _log.warn(e, e);
            }
        }
    }

    protected void updatePortletId(String oldRootPortletId, String newRootPortletId) throws Exception {

        runSQL(StringBundler.concat("update Portlet set portletId = '", newRootPortletId, "' where portletId = '",
                oldRootPortletId, "'"));
    }

    protected void updateResourceAction(String oldName, String newName) throws Exception {

        List<String> actionIds = new ArrayList<>();

        try (PreparedStatement ps = connection
                .prepareStatement("select actionId from ResourceAction where name = '" + newName + "'");
                ResultSet rs = ps.executeQuery()) {

            while (rs.next()) {
                actionIds.add(rs.getString("actionId"));
            }
        }

        if (actionIds.isEmpty()) {
            runSQL(StringBundler.concat("update ResourceAction set name = '", newName, "' where name = '", oldName,
                    "'"));
        } else {
            StringBundler sb = new StringBundler(5 + 3 * actionIds.size());

            sb.append("update ResourceAction set name = '");
            sb.append(newName);
            sb.append("' where name = '");
            sb.append(oldName);
            sb.append("' and actionId not in (");

            for (int i = 0; i < actionIds.size(); i++) {
                sb.append("'");
                sb.append(actionIds.get(i));

                if (i == (actionIds.size() - 1)) {
                    sb.append("')");
                } else {
                    sb.append("', ");
                }
            }

            runSQL(sb.toString());

            runSQL("delete from ResourceAction where name = '" + oldName + "'");
        }
    }

    protected void updateResourcePermission(String oldRootPortletId, String newRootPortletId, boolean updateName)
            throws Exception {

        runSQL(StringBundler.concat("update ResourcePermission set primKey = replace(primKey, ", "'_LAYOUT_",
                oldRootPortletId, "', '_LAYOUT_", newRootPortletId, "') where name = '", oldRootPortletId,
                "' and primKey like '%_LAYOUT_", oldRootPortletId, "'"));

        if (!newRootPortletId.contains("_INSTANCE_")) {
            runSQL(StringBundler.concat("update ResourcePermission set primKey = replace(", "primKey, '_LAYOUT_",
                    oldRootPortletId, "_INSTANCE_', ", "'_LAYOUT_", newRootPortletId, "_INSTANCE_') where name = ",
                    "'", oldRootPortletId, "' and primKey like '%_LAYOUT_", oldRootPortletId, "_INSTANCE_%'"));
        }

        if (updateName) {
            runSQL(StringBundler.concat("update ResourcePermission set primKey = '", newRootPortletId,
                    "' where name = '", oldRootPortletId, "' and primKey = '", oldRootPortletId, "'"));

            runSQL(StringBundler.concat("update ResourcePermission set name = '", newRootPortletId,
                    "' where name = '", oldRootPortletId, "'"));
        }
    }

    protected void updateUserNotificationDelivery(String oldPortletId, String newPortletId) throws Exception {

        runSQL(StringBundler.concat("update UserNotificationDelivery set portletId = '", newPortletId,
                "' where portletId = '", oldPortletId, "'"));
    }

    protected void updateUserNotificationEvent(String oldPortletId, String newPortletId) throws Exception {

        runSQL(StringBundler.concat("update UserNotificationEvent set type_ = '", newPortletId, "' where type_ = '",
                oldPortletId, "'"));
    }

    protected void upgradeInstanceablePortletIds() throws Exception {

        // Rename instanceable portlet IDs. We expect the root form of the
        // portlet ID because we will rename all instances of the portlet ID.

        try (LoggingTimer loggingTimer = new LoggingTimer()) {
            String[][] renamePortletIdsArray = getRenamePortletIdsArray();

            for (String[] renamePortletIds : renamePortletIdsArray) {
                String oldRootPortletId = renamePortletIds[0];
                String newRootPortletId = renamePortletIds[1];

                updateGroup(oldRootPortletId, newRootPortletId);
                updatePortlet(oldRootPortletId, newRootPortletId);
                updateLayoutRevisions(oldRootPortletId, newRootPortletId, false);
                updateLayouts(oldRootPortletId, newRootPortletId, false);
            }
        }
    }

    protected void upgradeUninstanceablePortletIds() throws Exception {

        // Rename uninstanceable portlet IDs to instanceable portlet IDs

        try (LoggingTimer loggingTimer = new LoggingTimer()) {
            String[] uninstanceablePortletIds = getUninstanceablePortletIds();

            for (String portletId : uninstanceablePortletIds) {
                if (PortletIdCodec.hasInstanceId(portletId)) {
                    if (_log.isWarnEnabled()) {
                        _log.warn("Portlet " + portletId + " is already instanceable");
                    }

                    continue;
                }

                PortletIdCodec.validatePortletName(portletId);

                String newPortletInstanceKey = PortletIdCodec.encode(portletId);

                updateInstanceablePortletPreferences(portletId, newPortletInstanceKey);
                updateResourcePermission(portletId, newPortletInstanceKey, false);
                updateLayoutRevisions(portletId, newPortletInstanceKey, true);
                updateLayouts(portletId, newPortletInstanceKey, true);
            }
        }
    }

    private String _getStagedPortletId(String portletId) {
        String key = portletId;

        if (key.startsWith(StagingConstants.STAGED_PORTLET)) {
            return key;
        }

        return StagingConstants.STAGED_PORTLET.concat(portletId);
    }

    private static final Log _log = LogFactoryUtil.getLog(BaseUpgradePortletId.class);

}