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