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_0_2;
016    
017    import com.liferay.portal.kernel.upgrade.UpgradeProcess;
018    import com.liferay.portal.kernel.util.CharPool;
019    import com.liferay.portal.kernel.util.LoggingTimer;
020    import com.liferay.portal.kernel.util.PortletKeys;
021    import com.liferay.portal.kernel.util.StringUtil;
022    
023    import java.sql.PreparedStatement;
024    import java.sql.ResultSet;
025    
026    import java.util.regex.Matcher;
027    import java.util.regex.Pattern;
028    
029    /**
030     * @author Wesley Gong
031     * @author Bijan Vakili
032     * @author Douglas Wong
033     * @author Brian Wing Shun Chan
034     */
035    public class UpgradeNestedPortlets extends UpgradeProcess {
036    
037            @Override
038            protected void doUpgrade() throws Exception {
039                    updateLayouts();
040            }
041    
042            protected void updateLayout(long plid, String typeSettings)
043                    throws Exception {
044    
045                    try (PreparedStatement ps = connection.prepareStatement(
046                                    "update Layout set typeSettings = ? where plid = " + plid)) {
047    
048                            ps.setString(1, typeSettings);
049    
050                            ps.executeUpdate();
051                    }
052            }
053    
054            protected void updateLayouts() throws Exception {
055                    try (LoggingTimer loggingTimer = new LoggingTimer();
056                            PreparedStatement ps = connection.prepareStatement(_GET_LAYOUT);
057                            ResultSet rs = ps.executeQuery()) {
058    
059                            while (rs.next()) {
060                                    long plid = rs.getLong("plid");
061                                    String typeSettings = rs.getString("typeSettings");
062    
063                                    String newTypeSettings = typeSettings;
064    
065                                    Matcher matcher = _pattern.matcher(typeSettings);
066    
067                                    while (matcher.find()) {
068                                            String nestedColumnIds = matcher.group();
069    
070                                            int underlineCount = StringUtil.count(
071                                                    nestedColumnIds, CharPool.UNDERLINE);
072    
073                                            if (underlineCount == _UNDERLINE_COUNT) {
074                                                    String newNestedColumnIds =
075                                                            "_" + matcher.group(1) + "_" + matcher.group(2);
076    
077                                                    newTypeSettings = StringUtil.replace(
078                                                            newTypeSettings, nestedColumnIds,
079                                                            newNestedColumnIds);
080                                            }
081                                    }
082    
083                                    if (!newTypeSettings.equals(typeSettings)) {
084                                            updateLayout(plid, newTypeSettings);
085                                    }
086                            }
087                    }
088            }
089    
090            private static final String _GET_LAYOUT =
091                    "select plid, typeSettings from Layout where typeSettings like " +
092                            "'%nested-column-ids=" + PortletKeys.NESTED_PORTLETS +
093                                    UpgradeNestedPortlets._INSTANCE_SEPARATOR + "%'";
094    
095            private static final String _INSTANCE_SEPARATOR = "_INSTANCE_";
096    
097            private static final int _UNDERLINE_COUNT = StringUtil.count(
098                    _INSTANCE_SEPARATOR, CharPool.UNDERLINE) + 1;
099    
100            private static final Pattern _pattern = Pattern.compile(
101                    "(" + PortletKeys.NESTED_PORTLETS + _INSTANCE_SEPARATOR +
102                            "[^_,\\s=]+_)([^_,\\s=]+)");
103    
104    }