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.upgrade.v6_2_0;
016    
017    import com.liferay.portal.kernel.model.LayoutTypePortletConstants;
018    import com.liferay.portal.kernel.model.PortletConstants;
019    import com.liferay.portal.kernel.model.PortletPreferences;
020    import com.liferay.portal.kernel.portlet.PortletPreferencesFactoryUtil;
021    import com.liferay.portal.kernel.upgrade.UpgradeProcess;
022    import com.liferay.portal.kernel.util.GetterUtil;
023    import com.liferay.portal.kernel.util.LoggingTimer;
024    import com.liferay.portal.kernel.util.PortletKeys;
025    import com.liferay.portal.kernel.util.StringPool;
026    import com.liferay.portal.kernel.util.StringUtil;
027    import com.liferay.portal.model.impl.PortletPreferencesImpl;
028    import com.liferay.portlet.PortalPreferencesImpl;
029    import com.liferay.portlet.PortalPreferencesWrapper;
030    
031    import java.sql.PreparedStatement;
032    import java.sql.ResultSet;
033    
034    import java.util.ArrayList;
035    import java.util.List;
036    
037    /**
038     * @author Raymond Aug??
039     */
040    public class UpgradeCustomizablePortlets extends UpgradeProcess {
041    
042            public static String namespacePlid(long plid) {
043                    return "com.liferay.portal.model.CustomizedPages".concat(
044                            String.valueOf(plid));
045            }
046    
047            @Override
048            protected void doUpgrade() throws Exception {
049                    upgradeCustomizablePreferences();
050            }
051    
052            protected PortalPreferencesWrapper getPortalPreferencesInstance(
053                    long ownerId, int ownerType, String xml) {
054    
055                    PortalPreferencesImpl portalPreferencesImpl =
056                            (PortalPreferencesImpl)PortletPreferencesFactoryUtil.fromXML(
057                                    ownerId, ownerType, xml);
058    
059                    return new PortalPreferencesWrapper(portalPreferencesImpl);
060            }
061    
062            protected PortletPreferences getPortletPreferences(
063                            long ownerId, int ownerType, long plid, String portletId)
064                    throws Exception {
065    
066                    try (PreparedStatement ps = connection.prepareStatement(
067                                    "select portletPreferencesId, ownerId, ownerType, plid, " +
068                                            "portletId, preferences from PortletPreferences where " +
069                                                    "ownerId = ?, ownerType = ?, plid = ?, portletId = " +
070                                                            "?")) {
071    
072                            ps.setLong(1, ownerId);
073                            ps.setInt(2, ownerType);
074                            ps.setLong(3, plid);
075                            ps.setString(4, portletId);
076    
077                            try (ResultSet rs = ps.executeQuery()) {
078                                    if (!rs.next()) {
079                                            return null;
080                                    }
081    
082                                    PortletPreferences portletPreferences =
083                                            new PortletPreferencesImpl();
084    
085                                    portletPreferences.setPortletPreferencesId(
086                                            rs.getLong("portletPreferencesId"));
087                                    portletPreferences.setOwnerId(rs.getLong("ownerId"));
088                                    portletPreferences.setOwnerType(rs.getInt("ownerType"));
089                                    portletPreferences.setPlid(rs.getLong("plid"));
090                                    portletPreferences.setPortletId(rs.getString("portletId"));
091                                    portletPreferences.setPreferences(rs.getString("preferences"));
092    
093                                    return portletPreferences;
094                            }
095                    }
096            }
097    
098            protected void upgradeCustomizablePreferences() throws Exception {
099                    try (LoggingTimer loggingTimer = new LoggingTimer();
100                            PreparedStatement ps = connection.prepareStatement(
101                                    "select ownerId, ownerType, preferences from " +
102                                            "PortalPreferences where preferences like " +
103                                                    "'%com.liferay.portal.model.CustomizedPages%'");
104                            ResultSet rs = ps.executeQuery()) {
105    
106                            while (rs.next()) {
107                                    long ownerId = rs.getLong("ownerId");
108                                    int ownerType = rs.getInt("ownerType");
109                                    String preferences = rs.getString("preferences");
110    
111                                    PortalPreferencesWrapper portalPreferencesWrapper =
112                                            getPortalPreferencesInstance(
113                                                    ownerId, ownerType, preferences);
114    
115                                    upgradeCustomizablePreferences(
116                                            portalPreferencesWrapper, ownerId, ownerType, preferences);
117    
118                                    portalPreferencesWrapper.store();
119                            }
120                    }
121            }
122    
123            protected void upgradeCustomizablePreferences(
124                            PortalPreferencesWrapper portalPreferencesWrapper, long ownerId,
125                            int ownerType, String preferences)
126                    throws Exception {
127    
128                    PortalPreferencesImpl portalPreferencesImpl =
129                            portalPreferencesWrapper.getPortalPreferencesImpl();
130    
131                    int x = preferences.indexOf(_PREFIX);
132                    int y = -1;
133    
134                    if (x != -1) {
135                            x += _PREFIX.length();
136                            y = preferences.indexOf(_SUFFIX, x);
137                    }
138                    else {
139                            return;
140                    }
141    
142                    while (x != -1) {
143    
144                            // <name>com.liferay.portal.model.CustomizedPages10415#column-1
145                            // </name>
146    
147                            String[] parts = StringUtil.split(
148                                    preferences.substring(x, y), StringPool.POUND);
149    
150                            long plid = GetterUtil.getLong(parts[0]);
151                            String key = GetterUtil.getString(parts[1]);
152    
153                            if (key.startsWith(LayoutTypePortletConstants.COLUMN_PREFIX)) {
154                                    String value = portalPreferencesImpl.getValue(
155                                            namespacePlid(plid), key);
156    
157                                    List<String> newPortletIds = new ArrayList<>();
158    
159                                    try (PreparedStatement ps = connection.prepareStatement(
160                                                    "update PortletPreferences set ownerId = ?, " +
161                                                            "ownerType = ?, plid = ?, portletId = ? where " +
162                                                            "ownerId = ? and ownerType = ? and plid = ? and " +
163                                                            "portletId = ?")) {
164    
165                                            for (String customPortletId : StringUtil.split(value)) {
166                                                    String newPortletId = null;
167    
168                                                    if (!PortletConstants.hasInstanceId(customPortletId)) {
169                                                            newPortletIds.add(customPortletId);
170                                                    }
171                                                    else {
172                                                            String instanceId = PortletConstants.getInstanceId(
173                                                                    customPortletId);
174    
175                                                            newPortletId = PortletConstants.assemblePortletId(
176                                                                    customPortletId, ownerId, instanceId);
177    
178                                                            ps.setLong(1, ownerId);
179                                                            ps.setInt(2, PortletKeys.PREFS_OWNER_TYPE_USER);
180                                                            ps.setLong(3, plid);
181                                                            ps.setString(4, newPortletId);
182                                                            ps.setLong(5, 0L);
183                                                            ps.setInt(6, PortletKeys.PREFS_OWNER_TYPE_LAYOUT);
184                                                            ps.setLong(7, plid);
185                                                            ps.setString(8, newPortletId);
186    
187                                                            newPortletIds.add(newPortletId);
188    
189                                                            ps.addBatch();
190                                                    }
191                                            }
192    
193                                            ps.executeBatch();
194                                    }
195    
196                                    value = StringUtil.merge(newPortletIds);
197    
198                                    portalPreferencesImpl.setValue(namespacePlid(plid), key, value);
199                            }
200    
201                            x = preferences.indexOf(_PREFIX, y);
202                            y = -1;
203    
204                            if (x != -1) {
205                                    x += _PREFIX.length();
206                                    y = preferences.indexOf(_SUFFIX, x);
207                            }
208                    }
209            }
210    
211            private static final String _PREFIX =
212                    "<name>com.liferay.portal.model.CustomizedPages";
213    
214            private static final String _SUFFIX = "</name>";
215    
216    }