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.util;
016    
017    import com.liferay.portal.kernel.dao.jdbc.DataAccess;
018    import com.liferay.portal.kernel.log.Log;
019    import com.liferay.portal.kernel.log.LogFactoryUtil;
020    import com.liferay.portal.kernel.upgrade.UpgradeProcess;
021    import com.liferay.portal.kernel.util.StringUtil;
022    import com.liferay.portal.model.PortletConstants;
023    import com.liferay.portal.model.impl.LayoutTypePortletImpl;
024    
025    import java.sql.Connection;
026    import java.sql.PreparedStatement;
027    import java.sql.ResultSet;
028    
029    /**
030     * @author Brian Wing Shun Chan
031     */
032    public class UpgradePortletId extends UpgradeProcess {
033    
034            @Override
035            protected void doUpgrade() throws Exception {
036    
037                    // Rename instanceable portlet IDs. We expect the root form of the
038                    // portlet ID because we will rename all instances of the portlet ID.
039    
040                    String[][] renamePortletIdsArray = getRenamePortletIdsArray();
041    
042                    for (String[] renamePortletIds : renamePortletIdsArray) {
043                            String oldRootPortletId = renamePortletIds[0];
044                            String newRootPortletId = renamePortletIds[1];
045    
046                            updatePortlet(oldRootPortletId, newRootPortletId);
047                            updateLayouts(oldRootPortletId, newRootPortletId);
048                    }
049    
050                    // Rename uninstanceable portlet IDs to instanceable portlet IDs
051    
052                    String[] uninstanceablePortletIds = getUninstanceablePortletIds();
053    
054                    for (String portletId : uninstanceablePortletIds) {
055                            if (portletId.contains(PortletConstants.INSTANCE_SEPARATOR)) {
056                                    if (_log.isWarnEnabled()) {
057                                            _log.warn(
058                                                    "Portlet " + portletId + " is already instanceable");
059                                    }
060    
061                                    continue;
062                            }
063    
064                            String instanceId = LayoutTypePortletImpl.generateInstanceId();
065    
066                            String newPortletId = PortletConstants.assemblePortletId(
067                                    portletId, instanceId);
068    
069                            updateResourcePermission(portletId, newPortletId, false);
070                            updateInstanceablePortletPreferences(portletId, newPortletId);
071                            updateLayouts(portletId, newPortletId);
072                    }
073            }
074    
075            protected String[][] getRenamePortletIdsArray() {
076                    return new String[][] {
077                            new String[] {
078                                    "109", "1_WAR_webformportlet"
079                            },
080                            new String[] {
081                                    "google_adsense_portlet_WAR_googleadsenseportlet",
082                                    "1_WAR_googleadsenseportlet"
083                            },
084                            new String[] {
085                                    "google_gadget_portlet_WAR_googlegadgetportlet",
086                                    "1_WAR_googlegadgetportlet"
087                            },
088                            new String[] {
089                                    "google_maps_portlet_WAR_googlemapsportlet",
090                                    "1_WAR_googlemapsportlet"
091                            }
092                    };
093            }
094    
095            protected String[] getUninstanceablePortletIds() {
096                    return new String[0];
097            }
098    
099            protected void updateInstanceablePortletPreferences(
100                            String oldRootPortletId, String newRootPortletId)
101                    throws Exception {
102    
103                    Connection con = null;
104                    PreparedStatement ps = null;
105                    ResultSet rs = null;
106    
107                    try {
108                            con = DataAccess.getUpgradeOptimizedConnection();
109    
110                            ps = con.prepareStatement(
111                                    "select portletPreferencesId, portletId from " +
112                                            "PortletPreferences where portletId like '" +
113                                                    oldRootPortletId + "%'");
114    
115                            rs = ps.executeQuery();
116    
117                            while (rs.next()) {
118                                    long portletPreferencesId = rs.getLong("portletPreferencesId");
119                                    String portletId = rs.getString("portletId");
120    
121                                    String newPortletId = StringUtil.replace(
122                                            portletId, oldRootPortletId, newRootPortletId);
123    
124                                    updatePortletPreference(portletPreferencesId, newPortletId);
125                            }
126                    }
127                    finally {
128                            DataAccess.cleanUp(con, ps, rs);
129                    }
130            }
131    
132            protected void updateLayout(long plid, String typeSettings)
133                    throws Exception {
134    
135                    Connection con = null;
136                    PreparedStatement ps = null;
137    
138                    try {
139                            con = DataAccess.getUpgradeOptimizedConnection();
140    
141                            ps = con.prepareStatement(
142                                    "update Layout set typeSettings = ? where plid = " + plid);
143    
144                            ps.setString(1, typeSettings);
145    
146                            ps.executeUpdate();
147                    }
148                    finally {
149                            DataAccess.cleanUp(con, ps);
150                    }
151            }
152    
153            protected void updateLayout(
154                            long plid, String oldPortletId, String newPortletId)
155                    throws Exception {
156    
157                    Connection con = null;
158                    PreparedStatement ps = null;
159                    ResultSet rs = null;
160    
161                    try {
162                            con = DataAccess.getUpgradeOptimizedConnection();
163    
164                            ps = con.prepareStatement(
165                                    "select typeSettings from Layout where plid = " + plid);
166    
167                            rs = ps.executeQuery();
168    
169                            while (rs.next()) {
170                                    String typeSettings = rs.getString("typeSettings");
171    
172                                    String newTypeSettings = StringUtil.replace(
173                                            typeSettings, oldPortletId, newPortletId);
174    
175                                    updateLayout(plid, newTypeSettings);
176                            }
177                    }
178                    finally {
179                            DataAccess.cleanUp(con, ps, rs);
180                    }
181            }
182    
183            protected void updateLayouts(
184                            String oldRootPortletId, String newRootPortletId)
185                    throws Exception {
186    
187                    Connection con = null;
188                    PreparedStatement ps = null;
189                    ResultSet rs = null;
190    
191                    try {
192                            con = DataAccess.getUpgradeOptimizedConnection();
193    
194                            ps = con.prepareStatement(
195                                    "select plid, typeSettings from Layout where typeSettings " +
196                                            "like '%" + oldRootPortletId + "%'");
197    
198                            rs = ps.executeQuery();
199    
200                            while (rs.next()) {
201                                    long plid = rs.getLong("plid");
202                                    String typeSettings = rs.getString("typeSettings");
203    
204                                    String newTypeSettings = StringUtil.replace(
205                                            typeSettings, oldRootPortletId, newRootPortletId);
206    
207                                    updateLayout(plid, newTypeSettings);
208                            }
209                    }
210                    finally {
211                            DataAccess.cleanUp(con, ps, rs);
212                    }
213            }
214    
215            protected void updatePortlet(
216                            String oldRootPortletId, String newRootPortletId)
217                    throws Exception {
218    
219                    runSQL(
220                            "update Portlet set portletId = '" + newRootPortletId +
221                                    "' where portletId = '" + oldRootPortletId + "'");
222    
223                    runSQL(
224                            "update ResourceAction set name = '" + newRootPortletId +
225                                    "' where name = '" + oldRootPortletId + "'");
226    
227                    updateResourcePermission(oldRootPortletId, newRootPortletId, true);
228    
229                    updateInstanceablePortletPreferences(
230                            oldRootPortletId, newRootPortletId);
231            }
232    
233            protected void updatePortletPreference(
234                            long portletPreferencesId, String portletId)
235                    throws Exception {
236    
237                    Connection con = null;
238                    PreparedStatement ps = null;
239    
240                    try {
241                            con = DataAccess.getUpgradeOptimizedConnection();
242    
243                            ps = con.prepareStatement(
244                                    "update PortletPreferences set portletId = ? where " +
245                                            "portletPreferencesId = " + portletPreferencesId);
246    
247                            ps.setString(1, portletId);
248    
249                            ps.executeUpdate();
250                    }
251                    finally {
252                            DataAccess.cleanUp(con, ps);
253                    }
254            }
255    
256            protected void updateResourcePermission(
257                            long resourcePermissionId, String name, String primKey)
258                    throws Exception {
259    
260                    Connection con = null;
261                    PreparedStatement ps = null;
262    
263                    try {
264                            con = DataAccess.getUpgradeOptimizedConnection();
265    
266                            ps = con.prepareStatement(
267                                    "update ResourcePermission set name = ?, primKey = ? where " +
268                                            "resourcePermissionId = " + resourcePermissionId);
269    
270                            ps.setString(1, name);
271                            ps.setString(2, primKey);
272    
273                            ps.executeUpdate();
274                    }
275                    finally {
276                            DataAccess.cleanUp(con, ps);
277                    }
278            }
279    
280            protected void updateResourcePermission(
281                            String oldRootPortletId, String newRootPortletId,
282                            boolean updateName)
283                    throws Exception {
284    
285                    Connection con = null;
286                    PreparedStatement ps = null;
287                    ResultSet rs = null;
288    
289                    try {
290                            con = DataAccess.getUpgradeOptimizedConnection();
291    
292                            ps = con.prepareStatement(
293                                    "select resourcePermissionId, name, primKey from " +
294                                            "ResourcePermission where name = '" + oldRootPortletId +
295                                                    "'");
296    
297                            rs = ps.executeQuery();
298    
299                            while (rs.next()) {
300                                    long resourcePermissionId = rs.getLong("resourcePermissionId");
301                                    String name = rs.getString("name");
302                                    String primKey = rs.getString("primKey");
303    
304                                    String newName = name;
305    
306                                    if (updateName) {
307                                            newName = StringUtil.replace(
308                                                    name, oldRootPortletId, newRootPortletId);
309                                    }
310    
311                                    String newPrimKey = StringUtil.replace(
312                                            primKey, oldRootPortletId, newRootPortletId);
313    
314                                    updateResourcePermission(
315                                            resourcePermissionId, newName, newPrimKey);
316                            }
317                    }
318                    finally {
319                            DataAccess.cleanUp(con, ps, rs);
320                    }
321            }
322    
323            private static Log _log = LogFactoryUtil.getLog(UpgradePortletId.class);
324    
325    }