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.kernel.upgrade;
016    
017    import com.liferay.portal.kernel.dao.jdbc.AutoBatchPreparedStatementUtil;
018    import com.liferay.portal.kernel.dao.jdbc.DataAccess;
019    import com.liferay.portal.kernel.util.GetterUtil;
020    import com.liferay.portal.kernel.util.LoggingTimer;
021    import com.liferay.portal.kernel.util.PortletKeys;
022    import com.liferay.portal.kernel.util.StringBundler;
023    import com.liferay.portal.kernel.util.StringPool;
024    import com.liferay.portal.kernel.util.StringUtil;
025    import com.liferay.portal.kernel.util.Validator;
026    
027    import java.sql.PreparedStatement;
028    import java.sql.ResultSet;
029    
030    import javax.portlet.PortletPreferences;
031    import javax.portlet.ReadOnlyException;
032    
033    /**
034     * @author Jorge Ferrer
035     * @author Brian Wing Shun Chan
036     */
037    public abstract class BaseUpgradePortletPreferences extends UpgradeProcess {
038    
039            /**
040             * @deprecated As of 7.0.0, with no direct replacement
041             */
042            @Deprecated
043            protected void deletePortletPreferences(long portletPreferencesId)
044                    throws Exception {
045    
046                    runSQL(
047                            "delete from PortletPreferences where portletPreferencesId = " +
048                                    portletPreferencesId);
049            }
050    
051            @Override
052            protected void doUpgrade() throws Exception {
053                    updatePortletPreferences();
054            }
055    
056            protected long getCompanyId(String sql, long primaryKey) throws Exception {
057                    long companyId = 0;
058    
059                    PreparedStatement ps = null;
060                    ResultSet rs = null;
061    
062                    try {
063                            ps = connection.prepareStatement(sql);
064    
065                            ps.setLong(1, primaryKey);
066    
067                            rs = ps.executeQuery();
068    
069                            while (rs.next()) {
070                                    companyId = rs.getLong("companyId");
071                            }
072                    }
073                    finally {
074                            DataAccess.cleanUp(ps, rs);
075                    }
076    
077                    return companyId;
078            }
079    
080            protected Object[] getGroup(long groupId) throws Exception {
081                    Object[] group = null;
082    
083                    PreparedStatement ps = null;
084                    ResultSet rs = null;
085    
086                    try {
087                            ps = connection.prepareStatement(
088                                    "select companyId from Group_ where groupId = ?");
089    
090                            ps.setLong(1, groupId);
091    
092                            rs = ps.executeQuery();
093    
094                            while (rs.next()) {
095                                    long companyId = rs.getLong("companyId");
096    
097                                    group = new Object[] {groupId, companyId};
098                            }
099                    }
100                    finally {
101                            DataAccess.cleanUp(ps, rs);
102                    }
103    
104                    return group;
105            }
106    
107            protected Object[] getLayout(long plid) throws Exception {
108                    Object[] layout = null;
109    
110                    PreparedStatement ps = null;
111                    ResultSet rs = null;
112    
113                    try {
114                            ps = connection.prepareStatement(
115                                    "select groupId, companyId, privateLayout, layoutId from " +
116                                            "Layout where plid = ?");
117    
118                            ps.setLong(1, plid);
119    
120                            rs = ps.executeQuery();
121    
122                            while (rs.next()) {
123                                    long groupId = rs.getLong("groupId");
124                                    long companyId = rs.getLong("companyId");
125                                    boolean privateLayout = rs.getBoolean("privateLayout");
126                                    long layoutId = rs.getLong("layoutId");
127    
128                                    layout =
129                                            new Object[] {groupId, companyId, privateLayout, layoutId};
130                            }
131                    }
132                    finally {
133                            DataAccess.cleanUp(ps, rs);
134                    }
135    
136                    return layout;
137            }
138    
139            protected String getLayoutUuid(long plid, long layoutId) throws Exception {
140                    Object[] layout = getLayout(plid);
141    
142                    if (layout == null) {
143                            return null;
144                    }
145    
146                    String uuid = null;
147    
148                    PreparedStatement ps = null;
149                    ResultSet rs = null;
150    
151                    try {
152                            ps = connection.prepareStatement(
153                                    "select uuid_ from Layout where groupId = ? and " +
154                                            "privateLayout = ? and layoutId = ?");
155    
156                            long groupId = (Long)layout[0];
157                            boolean privateLayout = (Boolean)layout[2];
158    
159                            ps.setLong(1, groupId);
160                            ps.setBoolean(2, privateLayout);
161                            ps.setLong(3, layoutId);
162    
163                            rs = ps.executeQuery();
164    
165                            if (rs.next()) {
166                                    uuid = rs.getString("uuid_");
167                            }
168                    }
169                    finally {
170                            DataAccess.cleanUp(ps, rs);
171                    }
172    
173                    return uuid;
174            }
175    
176            protected String[] getPortletIds() {
177                    return new String[0];
178            }
179    
180            protected String getUpdatePortletPreferencesWhereClause() {
181                    String[] portletIds = getPortletIds();
182    
183                    if (portletIds.length == 0) {
184                            throw new IllegalArgumentException(
185                                    "Subclasses must override getPortletIds or " +
186                                            "getUpdatePortletPreferencesWhereClause");
187                    }
188    
189                    StringBundler sb = new StringBundler(portletIds.length * 5 - 1);
190    
191                    for (int i = 0; i < portletIds.length; i++) {
192                            String portletId = portletIds[i];
193    
194                            sb.append("portletId ");
195    
196                            if (portletId.contains(StringPool.PERCENT)) {
197                                    sb.append(" like '");
198                                    sb.append(portletId);
199                                    sb.append("'");
200                            }
201                            else {
202                                    sb.append(" = '");
203                                    sb.append(portletId);
204                                    sb.append("'");
205                            }
206    
207                            if ((i + 1) < portletIds.length) {
208                                    sb.append(" or ");
209                            }
210                    }
211    
212                    return sb.toString();
213            }
214    
215            protected void updatePortletPreferences() throws Exception {
216                    try (LoggingTimer loggingTimer = new LoggingTimer()) {
217                            StringBundler sb = new StringBundler(4);
218    
219                            sb.append("select portletPreferencesId, ownerId, ownerType, ");
220                            sb.append("plid, portletId, preferences from PortletPreferences");
221    
222                            String whereClause = getUpdatePortletPreferencesWhereClause();
223    
224                            if (Validator.isNotNull(whereClause)) {
225                                    sb.append(" where ");
226                                    sb.append(whereClause);
227                            }
228    
229                            try (PreparedStatement ps1 = connection.prepareStatement(
230                                            sb.toString());
231                                    PreparedStatement ps2 =
232                                            AutoBatchPreparedStatementUtil.concurrentAutoBatch(
233                                                    connection,
234                                                    "update PortletPreferences set preferences = ? where " +
235                                                            "portletPreferencesId = ?");
236                                    PreparedStatement ps3 =
237                                            AutoBatchPreparedStatementUtil.concurrentAutoBatch(
238                                                    connection,
239                                                    "delete from PortletPreferences where " +
240                                                            "portletPreferencesId = ?");
241                                    ResultSet rs = ps1.executeQuery()) {
242    
243                                    while (rs.next()) {
244                                            long portletPreferencesId = rs.getLong(
245                                                    "portletPreferencesId");
246                                            long ownerId = rs.getLong("ownerId");
247                                            int ownerType = rs.getInt("ownerType");
248                                            long plid = rs.getLong("plid");
249                                            String portletId = rs.getString("portletId");
250                                            String preferences = GetterUtil.getString(
251                                                    rs.getString("preferences"));
252    
253                                            long companyId = 0;
254    
255                                            if (ownerType == PortletKeys.PREFS_OWNER_TYPE_ARCHIVED) {
256                                                    companyId = getCompanyId(
257                                                            "select companyId from PortletItem where " +
258                                                                    "portletItemId = ?",
259                                                            ownerId);
260                                            }
261                                            else if (ownerType ==
262                                                                    PortletKeys.PREFS_OWNER_TYPE_COMPANY) {
263    
264                                                    companyId = ownerId;
265                                            }
266                                            else if (ownerType == PortletKeys.PREFS_OWNER_TYPE_GROUP) {
267                                                    Object[] group = getGroup(ownerId);
268    
269                                                    if (group != null) {
270                                                            companyId = (Long)group[1];
271                                                    }
272                                            }
273                                            else if (ownerType == PortletKeys.PREFS_OWNER_TYPE_LAYOUT) {
274                                                    Object[] layout = getLayout(plid);
275    
276                                                    if (layout != null) {
277                                                            companyId = (Long)layout[1];
278                                                    }
279                                            }
280                                            else if (ownerType ==
281                                                                    PortletKeys.PREFS_OWNER_TYPE_ORGANIZATION) {
282    
283                                                    companyId = getCompanyId(
284                                                            "select companyId from Organization_ where " +
285                                                                    "organizationId = ?",
286                                                            ownerId);
287                                            }
288                                            else if (ownerType == PortletKeys.PREFS_OWNER_TYPE_USER) {
289                                                    companyId = getCompanyId(
290                                                            "select companyId from User_ where userId = ?",
291                                                            ownerId);
292                                            }
293                                            else {
294                                                    throw new UnsupportedOperationException(
295                                                            "Unsupported owner type " + ownerType);
296                                            }
297    
298                                            if (companyId > 0) {
299                                                    String newPreferences = upgradePreferences(
300                                                            companyId, ownerId, ownerType, plid, portletId,
301                                                            preferences);
302    
303                                                    if (!preferences.equals(newPreferences)) {
304                                                            ps2.setString(1, newPreferences);
305                                                            ps2.setLong(2, portletPreferencesId);
306    
307                                                            ps2.addBatch();
308                                                    }
309                                            }
310                                            else {
311                                                    ps3.setLong(1, portletPreferencesId);
312    
313                                                    ps3.addBatch();
314                                            }
315    
316                                            ps2.executeBatch();
317    
318                                            ps3.executeBatch();
319                                    }
320                            }
321                    }
322            }
323    
324            @Deprecated
325            protected void updatePortletPreferences(
326                            long portletPreferencesId, String preferences)
327                    throws Exception {
328    
329                    PreparedStatement ps = null;
330    
331                    try {
332                            ps = connection.prepareStatement(
333                                    "update PortletPreferences set preferences = ? where " +
334                                            "portletPreferencesId = " + portletPreferencesId);
335    
336                            ps.setString(1, preferences);
337    
338                            ps.executeUpdate();
339                    }
340                    finally {
341                            DataAccess.cleanUp(ps);
342                    }
343            }
344    
345            protected void upgradeMultiValuePreference(
346                            PortletPreferences portletPreferences, String key)
347                    throws ReadOnlyException {
348    
349                    String value = portletPreferences.getValue(key, StringPool.BLANK);
350    
351                    if (Validator.isNotNull(value)) {
352                            portletPreferences.setValues(key, StringUtil.split(value));
353                    }
354            }
355    
356            protected abstract String upgradePreferences(
357                            long companyId, long ownerId, int ownerType, long plid,
358                            String portletId, String xml)
359                    throws Exception;
360    
361    }