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