001    /**
002     * Copyright (c) 2000-2013 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.v5_2_0;
016    
017    import com.liferay.portal.kernel.dao.jdbc.DataAccess;
018    import com.liferay.portal.kernel.upgrade.UpgradeProcess;
019    import com.liferay.portal.kernel.util.GetterUtil;
020    import com.liferay.portal.kernel.util.StringBundler;
021    import com.liferay.portal.kernel.util.StringPool;
022    import com.liferay.portal.kernel.util.StringUtil;
023    import com.liferay.portal.kernel.util.UnicodeProperties;
024    import com.liferay.portal.kernel.util.Validator;
025    import com.liferay.portal.model.LayoutTypePortletConstants;
026    import com.liferay.portal.model.PortletConstants;
027    import com.liferay.portal.model.ResourceConstants;
028    import com.liferay.portal.service.permission.PortletPermissionUtil;
029    
030    import java.sql.Connection;
031    import java.sql.PreparedStatement;
032    import java.sql.ResultSet;
033    
034    /**
035     * @author Brian Wing Shun Chan
036     */
037    public class UpgradePortletId extends UpgradeProcess {
038    
039            @Override
040            protected void doUpgrade() throws Exception {
041    
042                    // This is only tested to work on instanceable portlets
043    
044                    try {
045                            runSQL("create index IX_5F076332 on Resource_ (primKey)");
046                    }
047                    catch (Exception e) {
048                    }
049    
050                    try {
051                            runSQL(
052                                    "create index IX_8E6DA3A1 on PortletPreferences (portletId)");
053                    }
054                    catch (Exception e) {
055                    }
056    
057                    String[][] portletIdsArray = getPortletIdsArray();
058    
059                    for (int i = 0; i < portletIdsArray.length; i++) {
060                            String[] portletIds = portletIdsArray[i];
061    
062                            String oldRootPortletId = portletIds[0];
063                            String newRootPortletId = portletIds[1];
064    
065                            updatePortlet(oldRootPortletId, newRootPortletId);
066                            updateLayouts(oldRootPortletId, newRootPortletId, false);
067                            updateResource(oldRootPortletId, newRootPortletId);
068                            updateResourceCode(oldRootPortletId, newRootPortletId);
069                    }
070            }
071    
072            protected String[][] getPortletIdsArray() {
073                    return new String[][] {
074                            new String[] {
075                                    "109", "1_WAR_webformportlet"
076                            },
077                            new String[] {
078                                    "google_adsense_portlet_WAR_googleadsenseportlet",
079                                    "1_WAR_googleadsenseportlet"
080                            },
081                            new String[] {
082                                    "google_gadget_portlet_WAR_googlegadgetportlet",
083                                    "1_WAR_googlegadgetportlet"
084                            },
085                            new String[] {
086                                    "google_maps_portlet_WAR_googlemapsportlet",
087                                    "1_WAR_googlemapsportlet"
088                            }
089                    };
090            }
091    
092            protected void updateInstanceablePortletPreferences(
093                            String oldRootPortletId, String newRootPortletId)
094                    throws Exception {
095    
096                    Connection con = null;
097                    PreparedStatement ps = null;
098                    ResultSet rs = null;
099    
100                    try {
101                            con = DataAccess.getUpgradeOptimizedConnection();
102    
103                            StringBundler sb = new StringBundler(8);
104    
105                            sb.append("select portletPreferencesId, portletId from ");
106                            sb.append("PortletPreferences where portletId = '");
107                            sb.append(oldRootPortletId);
108                            sb.append("' OR portletId like '");
109                            sb.append(oldRootPortletId);
110                            sb.append("_INSTANCE_%' OR portletId like '");
111                            sb.append(oldRootPortletId);
112                            sb.append("_USER_%_INSTANCE_%'");
113    
114                            ps = con.prepareStatement(sb.toString());
115    
116                            rs = ps.executeQuery();
117    
118                            while (rs.next()) {
119                                    long portletPreferencesId = rs.getLong("portletPreferencesId");
120                                    String portletId = rs.getString("portletId");
121    
122                                    String newPortletId = StringUtil.replace(
123                                            portletId, oldRootPortletId, newRootPortletId);
124    
125                                    updatePortletPreference(portletPreferencesId, newPortletId);
126                            }
127                    }
128                    finally {
129                            DataAccess.cleanUp(con, ps, rs);
130                    }
131            }
132    
133            protected void updateLayout(long plid, String typeSettings)
134                    throws Exception {
135    
136                    Connection con = null;
137                    PreparedStatement ps = null;
138    
139                    try {
140                            con = DataAccess.getUpgradeOptimizedConnection();
141    
142                            ps = con.prepareStatement(
143                                    "update Layout set typeSettings = ? where plid = " + plid);
144    
145                            ps.setString(1, typeSettings);
146    
147                            ps.executeUpdate();
148                    }
149                    finally {
150                            DataAccess.cleanUp(con, ps);
151                    }
152            }
153    
154            protected void updateLayout(
155                            long plid, String oldPortletId, String newPortletId)
156                    throws Exception {
157    
158                    Connection con = null;
159                    PreparedStatement ps = null;
160                    ResultSet rs = null;
161    
162                    try {
163                            con = DataAccess.getUpgradeOptimizedConnection();
164    
165                            ps = con.prepareStatement(
166                                    "select typeSettings from Layout where plid = " + plid);
167    
168                            rs = ps.executeQuery();
169    
170                            while (rs.next()) {
171                                    String typeSettings = rs.getString("typeSettings");
172    
173                                    String newTypeSettings = StringUtil.replace(
174                                            typeSettings, oldPortletId, newPortletId);
175    
176                                    updateLayout(plid, newTypeSettings);
177                            }
178                    }
179                    finally {
180                            DataAccess.cleanUp(con, ps, rs);
181                    }
182            }
183    
184            protected void updateLayouts(
185                            String oldRootPortletId, String newRootPortletId,
186                            boolean exactMatch)
187                    throws Exception {
188    
189                    Connection con = null;
190                    PreparedStatement ps = null;
191                    ResultSet rs = null;
192    
193                    try {
194                            con = DataAccess.getUpgradeOptimizedConnection();
195    
196                            StringBundler sb = new StringBundler(14);
197    
198                            sb.append("select plid, typeSettings from Layout where ");
199                            sb.append("typeSettings like '%=");
200                            sb.append(oldRootPortletId);
201                            sb.append(",%' OR typeSettings like '%,");
202                            sb.append(oldRootPortletId);
203                            sb.append(",%' OR typeSettings like '%=");
204                            sb.append(oldRootPortletId);
205                            sb.append("_INSTANCE_%' OR typeSettings like '%,");
206                            sb.append(oldRootPortletId);
207                            sb.append("_INSTANCE_%' OR typeSettings like '%=");
208                            sb.append(oldRootPortletId);
209                            sb.append("_USER_%' OR typeSettings like '%,");
210                            sb.append(oldRootPortletId);
211                            sb.append("_USER_%'");
212    
213                            ps = con.prepareStatement(sb.toString());
214    
215                            rs = ps.executeQuery();
216    
217                            while (rs.next()) {
218                                    long plid = rs.getLong("plid");
219                                    String typeSettings = rs.getString("typeSettings");
220    
221                                    String newTypeSettings = getNewTypeSettings(
222                                            typeSettings, oldRootPortletId, newRootPortletId,
223                                            exactMatch);
224    
225                                    updateLayout(plid, newTypeSettings);
226                            }
227                    }
228                    finally {
229                            DataAccess.cleanUp(con, ps, rs);
230                    }
231            }
232    
233            protected void updatePortlet(
234                            String oldRootPortletId, String newRootPortletId)
235                    throws Exception {
236    
237                    runSQL(
238                            "update Portlet set portletId = '" + newRootPortletId +
239                                    "' where portletId = '" + oldRootPortletId + "'");
240    
241                    runSQL(
242                            "update ResourceAction set name = '" + newRootPortletId +
243                                    "' where name = '" + oldRootPortletId + "'");
244    
245                    updateResourcePermission(oldRootPortletId, newRootPortletId);
246    
247                    updateInstanceablePortletPreferences(
248                            oldRootPortletId, newRootPortletId);
249            }
250    
251            protected void updatePortletPreference(
252                            long portletPreferencesId, String portletId)
253                    throws Exception {
254    
255                    Connection con = null;
256                    PreparedStatement ps = null;
257    
258                    try {
259                            con = DataAccess.getUpgradeOptimizedConnection();
260    
261                            ps = con.prepareStatement(
262                                    "update PortletPreferences set portletId = ? where " +
263                                            "portletPreferencesId = " + portletPreferencesId);
264    
265                            ps.setString(1, portletId);
266    
267                            ps.executeUpdate();
268                    }
269                    finally {
270                            DataAccess.cleanUp(con, ps);
271                    }
272            }
273    
274            protected void updateResource(
275                            String oldRootPortletId, String newRootPortletId)
276                    throws Exception {
277    
278                    Connection con = null;
279                    PreparedStatement ps = null;
280                    ResultSet rs = null;
281    
282                    try {
283                            con = DataAccess.getUpgradeOptimizedConnection();
284    
285                            ps = con.prepareStatement(
286                                    "select primKey from Resource_ where primKey like ?");
287    
288                            ps.setString(
289                                    1,
290                                    "%" + PortletConstants.LAYOUT_SEPARATOR + oldRootPortletId +
291                                            "%");
292    
293                            rs = ps.executeQuery();
294    
295                            while (rs.next()) {
296                                    String oldPrimKey = rs.getString("primKey");
297    
298                                    int pos = oldPrimKey.indexOf(PortletConstants.LAYOUT_SEPARATOR);
299    
300                                    long plid = GetterUtil.getLong(oldPrimKey.substring(0, pos));
301    
302                                    String portletId = oldPrimKey.substring(
303                                            pos + PortletConstants.LAYOUT_SEPARATOR.length());
304    
305                                    String newPrimKey =
306                                            plid + PortletConstants.LAYOUT_SEPARATOR + newRootPortletId;
307    
308                                    String oldPortletId = oldRootPortletId;
309                                    String newPortletId = newRootPortletId;
310    
311                                    pos = portletId.indexOf(PortletConstants.INSTANCE_SEPARATOR);
312    
313                                    if (pos != -1) {
314                                            portletId = portletId.substring(0, pos);
315    
316                                            String instanceId = oldPrimKey.substring(
317                                                    pos + PortletConstants.INSTANCE_SEPARATOR.length());
318    
319                                            newPrimKey +=
320                                                    PortletConstants.INSTANCE_SEPARATOR + instanceId;
321    
322                                            oldPortletId +=
323                                                    PortletConstants.INSTANCE_SEPARATOR + instanceId;
324                                            newPortletId +=
325                                                    PortletConstants.INSTANCE_SEPARATOR + instanceId;
326                                    }
327    
328                                    if (!portletId.equals(oldRootPortletId)) {
329                                            continue;
330                                    }
331    
332                                    runSQL(
333                                            "update Resource_ set primKey = '" + newPrimKey +
334                                                    "' where primKey = '" + oldPrimKey + "'");
335    
336                                    updateLayout(plid, oldPortletId, newPortletId);
337    
338                                    runSQL(
339                                            "update PortletPreferences set portletId = '" +
340                                                    newPortletId + "' where portletId = '" + oldPortletId +
341                                                            "'");
342                            }
343                    }
344                    finally {
345                            DataAccess.cleanUp(con, ps, rs);
346                    }
347            }
348    
349            protected void updateResourceCode(
350                            String oldRootPortletId, String newRootPortletId)
351                    throws Exception {
352    
353                    runSQL(
354                            "update ResourceCode set name = '" + newRootPortletId +
355                                    "' where name = '" + oldRootPortletId + "'");
356            }
357    
358            protected void updateResourcePermission(
359                            long resourcePermissionId, String name, String primKey)
360                    throws Exception {
361    
362                    Connection con = null;
363                    PreparedStatement ps = null;
364    
365                    try {
366                            con = DataAccess.getUpgradeOptimizedConnection();
367    
368                            ps = con.prepareStatement(
369                                    "update ResourcePermission set name = ?, primKey = ? where " +
370                                            "resourcePermissionId = " + resourcePermissionId);
371    
372                            ps.setString(1, name);
373                            ps.setString(2, primKey);
374    
375                            ps.executeUpdate();
376                    }
377                    finally {
378                            DataAccess.cleanUp(con, ps);
379                    }
380            }
381    
382            protected void updateResourcePermission(
383                            String oldRootPortletId, String newRootPortletId)
384                    throws Exception {
385    
386                    Connection con = null;
387                    PreparedStatement ps = null;
388                    ResultSet rs = null;
389    
390                    try {
391                            con = DataAccess.getUpgradeOptimizedConnection();
392    
393                            ps = con.prepareStatement(
394                                    "select resourcePermissionId, name, scope, primKey from " +
395                                            "ResourcePermission where name = '" + oldRootPortletId +
396                                                    "'");
397    
398                            rs = ps.executeQuery();
399    
400                            while (rs.next()) {
401                                    long resourcePermissionId = rs.getLong("resourcePermissionId");
402                                    int scope = rs.getInt("scope");
403                                    String primKey = rs.getString("primKey");
404    
405                                    String newName = newRootPortletId;
406    
407                                    if (scope == ResourceConstants.SCOPE_INDIVIDUAL) {
408                                            int pos = primKey.indexOf(
409                                                    PortletConstants.LAYOUT_SEPARATOR);
410    
411                                            long plid = GetterUtil.getLong(primKey.substring(0, pos));
412    
413                                            String portletId = primKey.substring(
414                                                    pos + PortletConstants.LAYOUT_SEPARATOR.length());
415    
416                                            String instanceId = PortletConstants.getInstanceId(
417                                                    portletId);
418    
419                                            String newPortletId = newRootPortletId;
420    
421                                            if (Validator.isNotNull(instanceId)) {
422                                                    newPortletId +=
423                                                            PortletConstants.INSTANCE_SEPARATOR + instanceId;
424                                            }
425    
426                                            primKey = PortletPermissionUtil.getPrimaryKey(
427                                                    plid, newPortletId);
428                                    }
429    
430                                    updateResourcePermission(
431                                            resourcePermissionId, newName, primKey);
432                            }
433                    }
434                    finally {
435                            DataAccess.cleanUp(con, ps, rs);
436                    }
437            }
438    
439            private String getNewTypeSettings(
440                    String typeSettings, String oldRootPortletId, String newRootPortletId,
441                    boolean exactMatch) {
442    
443                    UnicodeProperties typeSettingsProperties = new UnicodeProperties(true);
444    
445                    typeSettingsProperties.fastLoad(typeSettings);
446    
447                    for (int i = 1; i <= 10; i++) {
448                            String column = LayoutTypePortletConstants.COLUMN_PREFIX + i;
449    
450                            if (!typeSettingsProperties.containsKey(column)) {
451                                    continue;
452                            }
453    
454                            String[] portletIds = StringUtil.split(
455                                    typeSettingsProperties.getProperty(column));
456    
457                            for (int j = 0; j < portletIds.length; j++) {
458                                    String portletId = portletIds[j];
459    
460                                    if (exactMatch) {
461                                            if (portletId.equals(oldRootPortletId)) {
462                                                    portletIds[j] = newRootPortletId;
463                                            }
464    
465                                            continue;
466                                    }
467    
468                                    String rootPortletId = PortletConstants.getRootPortletId(
469                                            portletId);
470    
471                                    if (!rootPortletId.equals(oldRootPortletId)) {
472                                            continue;
473                                    }
474    
475                                    String instanceId = PortletConstants.getInstanceId(portletId);
476    
477                                    portletIds[j] = newRootPortletId;
478    
479                                    if (Validator.isNotNull(instanceId)) {
480                                            portletIds[j] +=
481                                                    PortletConstants.INSTANCE_SEPARATOR + instanceId;
482                                    }
483                            }
484    
485                            typeSettingsProperties.setProperty(
486                                    column, StringUtil.merge(portletIds).concat(StringPool.COMMA));
487                    }
488    
489                    return typeSettingsProperties.toString();
490            }
491    
492    }