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                    finally {
137                            DataAccess.cleanUp(con, ps, rs);
138                    }
139    
140                    return layout;
141            }
142    
143            protected String getLayoutUuid(long plid, long layoutId) throws Exception {
144                    Object[] layout = getLayout(plid);
145    
146                    if (layout == null) {
147                            return null;
148                    }
149    
150                    String uuid = null;
151    
152                    Connection con = null;
153                    PreparedStatement ps = null;
154                    ResultSet rs = null;
155    
156                    try {
157                            con = DataAccess.getUpgradeOptimizedConnection();
158    
159                            ps = con.prepareStatement(
160                                    "select uuid_ from Layout where groupId = ? and " +
161                                            "privateLayout = ? and layoutId = ?");
162    
163                            long groupId = (Long)layout[0];
164                            boolean privateLayout = (Boolean)layout[2];
165    
166                            ps.setLong(1, groupId);
167                            ps.setBoolean(2, privateLayout);
168                            ps.setLong(3, layoutId);
169    
170                            rs = ps.executeQuery();
171    
172                            if (rs.next()) {
173                                    uuid = rs.getString("uuid_");
174                            }
175                    }
176                    finally {
177                            DataAccess.cleanUp(con, ps, rs);
178                    }
179    
180                    return uuid;
181            }
182    
183            protected String[] getPortletIds() {
184                    return new String[0];
185            }
186    
187            protected String getUpdatePortletPreferencesWhereClause() {
188                    String[] portletIds = getPortletIds();
189    
190                    if (portletIds.length == 0) {
191                            throw new IllegalArgumentException(
192                                    "Subclasses must override getPortletIds or " +
193                                            "getUpdatePortletPreferencesWhereClause");
194                    }
195    
196                    StringBundler sb = new StringBundler(portletIds.length * 5 - 1);
197    
198                    for (int i = 0; i < portletIds.length; i++) {
199                            String portletId = portletIds[i];
200    
201                            sb.append("portletId ");
202    
203                            if (portletId.contains(StringPool.PERCENT)) {
204                                    sb.append(" like '");
205                                    sb.append(portletId);
206                                    sb.append("'");
207                            }
208                            else {
209                                    sb.append(" = '");
210                                    sb.append(portletId);
211                                    sb.append("'");
212                            }
213    
214                            if ((i + 1) < portletIds.length) {
215                                    sb.append(" or ");
216                            }
217                    }
218    
219                    return sb.toString();
220            }
221    
222            protected void updatePortletPreferences() throws Exception {
223                    Connection con = null;
224                    PreparedStatement ps = null;
225                    ResultSet rs = null;
226    
227                    try {
228                            con = DataAccess.getUpgradeOptimizedConnection();
229    
230                            StringBundler sb = new StringBundler(4);
231    
232                            sb.append("select portletPreferencesId, ownerId, ownerType, ");
233                            sb.append("plid, portletId, preferences from PortletPreferences");
234    
235                            String whereClause = getUpdatePortletPreferencesWhereClause();
236    
237                            if (Validator.isNotNull(whereClause)) {
238                                    sb.append(" where ");
239                                    sb.append(whereClause);
240                            }
241    
242                            String sql = sb.toString();
243    
244                            ps = con.prepareStatement(sql);
245    
246                            rs = ps.executeQuery();
247    
248                            while (rs.next()) {
249                                    long portletPreferencesId = rs.getLong("portletPreferencesId");
250                                    long ownerId = rs.getLong("ownerId");
251                                    int ownerType = rs.getInt("ownerType");
252                                    long plid = rs.getLong("plid");
253                                    String portletId = rs.getString("portletId");
254                                    String preferences = GetterUtil.getString(
255                                            rs.getString("preferences"));
256    
257                                    long companyId = 0;
258    
259                                    if (ownerType == PortletKeys.PREFS_OWNER_TYPE_ARCHIVED) {
260                                            companyId = getCompanyId(
261                                                    "select companyId from PortletItem where " +
262                                                            "portletItemId = ?",
263                                                    ownerId);
264                                    }
265                                    else if (ownerType == PortletKeys.PREFS_OWNER_TYPE_COMPANY) {
266                                            companyId = ownerId;
267                                    }
268                                    else if (ownerType == PortletKeys.PREFS_OWNER_TYPE_GROUP) {
269                                            Object[] group = getGroup(ownerId);
270    
271                                            if (group != null) {
272                                                    companyId = (Long)group[1];
273                                            }
274                                    }
275                                    else if (ownerType == PortletKeys.PREFS_OWNER_TYPE_LAYOUT) {
276                                            Object[] layout = getLayout(plid);
277    
278                                            if (layout != null) {
279                                                    companyId = (Long)layout[1];
280                                            }
281                                    }
282                                    else if (ownerType ==
283                                                            PortletKeys.PREFS_OWNER_TYPE_ORGANIZATION) {
284    
285                                            companyId = getCompanyId(
286                                                    "select companyId from Organization_ where " +
287                                                            "organizationId = ?",
288                                                    ownerId);
289                                    }
290                                    else if (ownerType == PortletKeys.PREFS_OWNER_TYPE_USER) {
291                                            companyId = getCompanyId(
292                                                    "select companyId from User_ where userId = ?",
293                                                    ownerId);
294                                    }
295                                    else {
296                                            throw new UnsupportedOperationException(
297                                                    "Unsupported owner type " + ownerType);
298                                    }
299    
300                                    if (companyId > 0) {
301                                            String newPreferences = upgradePreferences(
302                                                    companyId, ownerId, ownerType, plid, portletId,
303                                                    preferences);
304    
305                                            if (!preferences.equals(newPreferences)) {
306                                                    updatePortletPreferences(
307                                                            portletPreferencesId, newPreferences);
308                                            }
309                                    }
310                                    else {
311                                            deletePortletPreferences(portletPreferencesId);
312                                    }
313                            }
314                    }
315                    finally {
316                            DataAccess.cleanUp(con, ps, rs);
317                    }
318            }
319    
320            protected void updatePortletPreferences(
321                            long portletPreferencesId, String preferences)
322                    throws Exception {
323    
324                    Connection con = null;
325                    PreparedStatement ps = null;
326    
327                    try {
328                            con = DataAccess.getUpgradeOptimizedConnection();
329    
330                            ps = con.prepareStatement(
331                                    "update PortletPreferences set preferences = ? where " +
332                                            "portletPreferencesId = " + portletPreferencesId);
333    
334                            ps.setString(1, preferences);
335    
336                            ps.executeUpdate();
337                    }
338                    finally {
339                            DataAccess.cleanUp(con, ps);
340                    }
341            }
342    
343            protected void upgradeMultiValuePreference(
344                            PortletPreferences portletPreferences, String key)
345                    throws ReadOnlyException {
346    
347                    String value = portletPreferences.getValue(key, StringPool.BLANK);
348    
349                    if (Validator.isNotNull(value)) {
350                            portletPreferences.setValues(key, StringUtil.split(value));
351                    }
352            }
353    
354            protected abstract String upgradePreferences(
355                            long companyId, long ownerId, int ownerType, long plid,
356                            String portletId, String xml)
357                    throws Exception;
358    
359    }