001    /**
002     * Copyright (c) 2000-present Liferay, Inc. All rights reserved.
003     *
004     * This library is free software; you can redistribute it and/or modify it under
005     * the terms of the GNU Lesser General Public License as published by the Free
006     * Software Foundation; either version 2.1 of the License, or (at your option)
007     * any later version.
008     *
009     * This library is distributed in the hope that it will be useful, but WITHOUT
010     * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
011     * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
012     * details.
013     */
014    
015    package com.liferay.portal.upgrade.util;
016    
017    import com.liferay.portal.kernel.dao.jdbc.AutoBatchPreparedStatementUtil;
018    import com.liferay.portal.kernel.log.Log;
019    import com.liferay.portal.kernel.log.LogFactoryUtil;
020    import com.liferay.portal.kernel.model.LayoutTypePortletConstants;
021    import com.liferay.portal.kernel.model.PortletConstants;
022    import com.liferay.portal.kernel.model.PortletInstance;
023    import com.liferay.portal.kernel.model.ResourceConstants;
024    import com.liferay.portal.kernel.service.permission.PortletPermissionUtil;
025    import com.liferay.portal.kernel.upgrade.UpgradeProcess;
026    import com.liferay.portal.kernel.util.GetterUtil;
027    import com.liferay.portal.kernel.util.LoggingTimer;
028    import com.liferay.portal.kernel.util.StringBundler;
029    import com.liferay.portal.kernel.util.StringPool;
030    import com.liferay.portal.kernel.util.StringUtil;
031    import com.liferay.portal.kernel.util.UnicodeProperties;
032    
033    import java.sql.PreparedStatement;
034    import java.sql.ResultSet;
035    import java.sql.SQLException;
036    
037    /**
038     * @author     Brian Wing Shun Chan
039     * @deprecated As of 7.0.0, replaced by {@link
040     *             com.liferay.portal.kernel.upgrade.BaseUpgradePortletId}
041     */
042    @Deprecated
043    public class UpgradePortletId extends UpgradeProcess {
044    
045            @Override
046            protected void doUpgrade() throws Exception {
047                    upgradeInstanceablePortletIds();
048                    upgradeUninstanceablePortletIds();
049            }
050    
051            protected String getNewTypeSettings(
052                    String typeSettings, String oldRootPortletId, String newRootPortletId,
053                    boolean exactMatch) {
054    
055                    UnicodeProperties typeSettingsProperties = new UnicodeProperties(true);
056    
057                    typeSettingsProperties.fastLoad(typeSettings);
058    
059                    for (int i = 1; i <= 10; i++) {
060                            String column = LayoutTypePortletConstants.COLUMN_PREFIX + i;
061    
062                            if (!typeSettingsProperties.containsKey(column)) {
063                                    continue;
064                            }
065    
066                            String[] portletIds = StringUtil.split(
067                                    typeSettingsProperties.getProperty(column));
068    
069                            for (int j = 0; j < portletIds.length; j++) {
070                                    String portletId = portletIds[j];
071    
072                                    if (exactMatch) {
073                                            if (portletId.equals(oldRootPortletId)) {
074                                                    portletIds[j] = newRootPortletId;
075                                            }
076    
077                                            continue;
078                                    }
079    
080                                    String rootPortletId = PortletConstants.getRootPortletId(
081                                            portletId);
082    
083                                    if (!rootPortletId.equals(oldRootPortletId)) {
084                                            continue;
085                                    }
086    
087                                    long userId = PortletConstants.getUserId(portletId);
088                                    String instanceId = PortletConstants.getInstanceId(portletId);
089    
090                                    portletIds[j] = PortletConstants.assemblePortletId(
091                                            newRootPortletId, userId, instanceId);
092                            }
093    
094                            typeSettingsProperties.setProperty(
095                                    column, StringUtil.merge(portletIds).concat(StringPool.COMMA));
096                    }
097    
098                    return typeSettingsProperties.toString();
099            }
100    
101            protected String[][] getRenamePortletIdsArray() {
102                    return new String[][] {
103                            new String[] {
104                                    "109", "1_WAR_webformportlet"
105                            },
106                            new String[] {
107                                    "google_adsense_portlet_WAR_googleadsenseportlet",
108                                    "1_WAR_googleadsenseportlet"
109                            },
110                            new String[] {
111                                    "google_gadget_portlet_WAR_googlegadgetportlet",
112                                    "1_WAR_googlegadgetportlet"
113                            },
114                            new String[] {
115                                    "google_maps_portlet_WAR_googlemapsportlet",
116                                    "1_WAR_googlemapsportlet"
117                            }
118                    };
119            }
120    
121            protected String getTypeSettingsCriteria(String portletId) {
122                    StringBundler sb = new StringBundler(21);
123    
124                    sb.append("typeSettings like '%=");
125                    sb.append(portletId);
126                    sb.append(",%' OR typeSettings like '%=");
127                    sb.append(portletId);
128                    sb.append("\n%' OR typeSettings like '%=");
129                    sb.append(portletId);
130                    sb.append("%' OR typeSettings like '%,");
131                    sb.append(portletId);
132                    sb.append(",%' OR typeSettings like '%,");
133                    sb.append(portletId);
134                    sb.append("\n%' OR typeSettings like '%,");
135                    sb.append(portletId);
136                    sb.append("%' OR typeSettings like '%=");
137                    sb.append(portletId);
138                    sb.append("_INSTANCE_%' OR typeSettings like '%,");
139                    sb.append(portletId);
140                    sb.append("_INSTANCE_%' OR typeSettings like '%=");
141                    sb.append(portletId);
142                    sb.append("_USER_%' OR typeSettings like '%,");
143                    sb.append(portletId);
144                    sb.append("_USER_%'");
145    
146                    return sb.toString();
147            }
148    
149            protected String[] getUninstanceablePortletIds() {
150                    return new String[0];
151            }
152    
153            protected void updateInstanceablePortletPreferences(
154                            String oldRootPortletId, String newRootPortletId)
155                    throws Exception {
156    
157                    StringBundler sb = new StringBundler(8);
158    
159                    sb.append("select portletPreferencesId, portletId from ");
160                    sb.append("PortletPreferences where portletId = '");
161                    sb.append(oldRootPortletId);
162                    sb.append("' OR portletId like '");
163                    sb.append(oldRootPortletId);
164                    sb.append("_INSTANCE_%' OR portletId like '");
165                    sb.append(oldRootPortletId);
166                    sb.append("_USER_%_INSTANCE_%'");
167    
168                    try (PreparedStatement ps1 = connection.prepareStatement(sb.toString());
169                            PreparedStatement ps2 =
170                                    AutoBatchPreparedStatementUtil.concurrentAutoBatch(
171                                            connection,
172                                            "update PortletPreferences set portletId = ? where " +
173                                                    "portletPreferencesId = ?");
174                            ResultSet rs = ps1.executeQuery()) {
175    
176                            while (rs.next()) {
177                                    long portletPreferencesId = rs.getLong("portletPreferencesId");
178                                    String portletId = rs.getString("portletId");
179    
180                                    String newPortletId = StringUtil.replace(
181                                            portletId, oldRootPortletId, newRootPortletId);
182    
183                                    ps2.setString(1, newPortletId);
184                                    ps2.setLong(2, portletPreferencesId);
185    
186                                    ps2.addBatch();
187                            }
188    
189                            ps2.executeBatch();
190                    }
191            }
192    
193            protected void updateLayout(long plid, String typeSettings)
194                    throws Exception {
195    
196                    try (PreparedStatement ps = connection.prepareStatement(
197                                    "update Layout set typeSettings = ? where plid = " + plid)) {
198    
199                            ps.setString(1, typeSettings);
200    
201                            ps.executeUpdate();
202                    }
203                    catch (SQLException sqle) {
204                            if (_log.isWarnEnabled()) {
205                                    _log.warn(sqle, sqle);
206                            }
207                    }
208            }
209    
210            protected void updateLayout(
211                            long plid, String oldPortletId, String newPortletId)
212                    throws Exception {
213    
214                    try (PreparedStatement ps = connection.prepareStatement(
215                                    "select typeSettings from Layout where plid = " + plid);
216                            ResultSet rs = ps.executeQuery()) {
217    
218                            while (rs.next()) {
219                                    String typeSettings = rs.getString("typeSettings");
220    
221                                    String newTypeSettings = StringUtil.replace(
222                                            typeSettings, oldPortletId, newPortletId);
223    
224                                    updateLayout(plid, newTypeSettings);
225                            }
226                    }
227                    catch (Exception e) {
228                            if (_log.isWarnEnabled()) {
229                                    _log.warn(e, e);
230                            }
231                    }
232            }
233    
234            protected void updateLayoutRevision(
235                            long layoutRevisionId, String typeSettings)
236                    throws Exception {
237    
238                    String sql =
239                            "update LayoutRevision set typeSettings = ? " +
240                                    "where layoutRevisionId = " + layoutRevisionId;
241    
242                    try (PreparedStatement ps = connection.prepareStatement(sql)) {
243                            ps.setString(1, typeSettings);
244    
245                            ps.executeUpdate();
246                    }
247                    catch (SQLException sqle) {
248                            if (_log.isWarnEnabled()) {
249                                    _log.warn(sqle, sqle);
250                            }
251                    }
252            }
253    
254            protected void updateLayoutRevisions(
255                            String oldRootPortletId, String newRootPortletId,
256                            boolean exactMatch)
257                    throws Exception {
258    
259                    String sql =
260                            "select layoutRevisionId, typeSettings from LayoutRevision where " +
261                                    getTypeSettingsCriteria(oldRootPortletId);
262    
263                    try (PreparedStatement ps = connection.prepareStatement(sql);
264                            ResultSet rs = ps.executeQuery()) {
265    
266                            while (rs.next()) {
267                                    long layoutRevisionId = rs.getLong("layoutRevisionId");
268                                    String typeSettings = rs.getString("typeSettings");
269    
270                                    String newTypeSettings = getNewTypeSettings(
271                                            typeSettings, oldRootPortletId, newRootPortletId,
272                                            exactMatch);
273    
274                                    updateLayoutRevision(layoutRevisionId, newTypeSettings);
275                            }
276                    }
277            }
278    
279            protected void updateLayouts(
280                            String oldRootPortletId, String newRootPortletId,
281                            boolean exactMatch)
282                    throws Exception {
283    
284                    String sql =
285                            "select plid, typeSettings from Layout where " +
286                                    getTypeSettingsCriteria(oldRootPortletId);
287    
288                    try (PreparedStatement ps = connection.prepareStatement(sql);
289                            ResultSet rs = ps.executeQuery()) {
290    
291                            while (rs.next()) {
292                                    long plid = rs.getLong("plid");
293                                    String typeSettings = rs.getString("typeSettings");
294    
295                                    String newTypeSettings = getNewTypeSettings(
296                                            typeSettings, oldRootPortletId, newRootPortletId,
297                                            exactMatch);
298    
299                                    updateLayout(plid, newTypeSettings);
300                            }
301                    }
302            }
303    
304            protected void updatePortlet(
305                            String oldRootPortletId, String newRootPortletId)
306                    throws Exception {
307    
308                    try {
309                            updatePortletId(oldRootPortletId, newRootPortletId);
310    
311                            updateResourceAction(oldRootPortletId, newRootPortletId);
312    
313                            updateResourcePermission(oldRootPortletId, newRootPortletId, true);
314    
315                            updateUserNotificationDelivery(oldRootPortletId, newRootPortletId);
316    
317                            updateUserNotificationEvent(oldRootPortletId, newRootPortletId);
318    
319                            updateInstanceablePortletPreferences(
320                                    oldRootPortletId, newRootPortletId);
321                    }
322                    catch (Exception e) {
323                            if (_log.isWarnEnabled()) {
324                                    _log.warn(e, e);
325                            }
326                    }
327            }
328    
329            protected void updatePortletId(
330                            String oldRootPortletId, String newRootPortletId)
331                    throws Exception {
332    
333                    runSQL(
334                            "update Portlet set portletId = '" + newRootPortletId +
335                                    "' where portletId = '" + oldRootPortletId + "'");
336            }
337    
338            protected void updateResourceAction(String oldName, String newName)
339                    throws Exception {
340    
341                    runSQL(
342                            "update ResourceAction set name = '" + newName +
343                                    "' where name = '" + oldName + "'");
344            }
345    
346            protected void updateResourcePermission(
347                            String oldRootPortletId, String newRootPortletId,
348                            boolean updateName)
349                    throws Exception {
350    
351                    try (PreparedStatement ps1 = connection.prepareStatement(
352                                    "select resourcePermissionId, name, scope, primKey from " +
353                                            "ResourcePermission where name = '" + oldRootPortletId +
354                                                    "'");
355                            PreparedStatement ps2 =
356                                    AutoBatchPreparedStatementUtil.concurrentAutoBatch(
357                                            connection,
358                                            "update ResourcePermission set name = ?, primKey = ? " +
359                                                    "where resourcePermissionId = ?");
360                            ResultSet rs = ps1.executeQuery()) {
361    
362                            while (rs.next()) {
363                                    long resourcePermissionId = rs.getLong("resourcePermissionId");
364                                    String name = rs.getString("name");
365                                    int scope = rs.getInt("scope");
366                                    String primKey = rs.getString("primKey");
367    
368                                    String newName = name;
369    
370                                    if (updateName) {
371                                            newName = newRootPortletId;
372                                    }
373    
374                                    if (scope == ResourceConstants.SCOPE_INDIVIDUAL) {
375                                            int pos = primKey.indexOf(
376                                                    PortletConstants.LAYOUT_SEPARATOR);
377    
378                                            if (pos != -1) {
379                                                    long plid = GetterUtil.getLong(
380                                                            primKey.substring(0, pos));
381    
382                                                    String portletId = primKey.substring(
383                                                            pos + PortletConstants.LAYOUT_SEPARATOR.length());
384    
385                                                    String instanceId = PortletConstants.getInstanceId(
386                                                            portletId);
387                                                    long userId = PortletConstants.getUserId(portletId);
388    
389                                                    String newPortletId =
390                                                            PortletConstants.assemblePortletId(
391                                                                    newRootPortletId, userId, instanceId);
392    
393                                                    primKey = PortletPermissionUtil.getPrimaryKey(
394                                                            plid, newPortletId);
395                                            }
396    
397                                            if (name.equals(primKey)) {
398                                                    primKey = newName;
399                                            }
400                                    }
401    
402                                    ps2.setString(1, newName);
403                                    ps2.setString(2, primKey);
404                                    ps2.setLong(3, resourcePermissionId);
405    
406                                    ps2.addBatch();
407                            }
408    
409                            ps2.executeBatch();
410                    }
411                    catch (SQLException sqle) {
412                            if (_log.isWarnEnabled()) {
413                                    _log.warn(sqle, sqle);
414                            }
415                    }
416            }
417    
418            protected void updateUserNotificationDelivery(
419                            String oldPortletId, String newPortletId)
420                    throws Exception {
421    
422                    runSQL(
423                            "update UserNotificationDelivery set portletId = '" + newPortletId +
424                                    "' where portletId = '" + oldPortletId +"'");
425            }
426    
427            protected void updateUserNotificationEvent(
428                            String oldPortletId, String newPortletId)
429                    throws Exception {
430    
431                    runSQL(
432                            "update UserNotificationEvent set type_ = '" + newPortletId +
433                                    "' where type_ = '" + oldPortletId + "'");
434            }
435    
436            protected void upgradeInstanceablePortletIds() throws Exception {
437    
438                    // Rename instanceable portlet IDs. We expect the root form of the
439                    // portlet ID because we will rename all instances of the portlet ID.
440    
441                    try (LoggingTimer loggingTimer = new LoggingTimer()) {
442                            String[][] renamePortletIdsArray = getRenamePortletIdsArray();
443    
444                            for (String[] renamePortletIds : renamePortletIdsArray) {
445                                    String oldRootPortletId = renamePortletIds[0];
446                                    String newRootPortletId = renamePortletIds[1];
447    
448                                    updatePortlet(oldRootPortletId, newRootPortletId);
449                                    updateLayoutRevisions(
450                                            oldRootPortletId, newRootPortletId, false);
451                                    updateLayouts(oldRootPortletId, newRootPortletId, false);
452                            }
453                    }
454            }
455    
456            protected void upgradeUninstanceablePortletIds() throws Exception {
457    
458                    // Rename uninstanceable portlet IDs to instanceable portlet IDs
459    
460                    try (LoggingTimer loggingTimer = new LoggingTimer()) {
461                            String[] uninstanceablePortletIds = getUninstanceablePortletIds();
462    
463                            for (String portletId : uninstanceablePortletIds) {
464                                    PortletInstance portletInstance =
465                                            PortletInstance.fromPortletInstanceKey(portletId);
466    
467                                    if (portletInstance.hasInstanceId()) {
468                                            if (_log.isWarnEnabled()) {
469                                                    _log.warn(
470                                                            "Portlet " + portletId +
471                                                                    " is already instanceable");
472                                            }
473    
474                                            continue;
475                                    }
476    
477                                    PortletInstance newPortletInstance = new PortletInstance(
478                                            portletId);
479    
480                                    String newPortletInstanceKey =
481                                            newPortletInstance.getPortletInstanceKey();
482    
483                                    updateInstanceablePortletPreferences(
484                                            portletId, newPortletInstanceKey);
485                                    updateResourcePermission(
486                                            portletId, newPortletInstanceKey, false);
487                                    updateLayoutRevisions(portletId, newPortletInstanceKey, true);
488                                    updateLayouts(portletId, newPortletInstanceKey, true);
489                            }
490                    }
491            }
492    
493            private static final Log _log = LogFactoryUtil.getLog(
494                    UpgradePortletId.class);
495    
496    }