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.verify;
016    
017    import com.liferay.portal.kernel.bean.PortalBeanLocatorUtil;
018    import com.liferay.portal.kernel.dao.jdbc.DataAccess;
019    import com.liferay.portal.kernel.log.Log;
020    import com.liferay.portal.kernel.log.LogFactoryUtil;
021    import com.liferay.portal.kernel.util.StringBundler;
022    import com.liferay.portal.kernel.util.StringPool;
023    import com.liferay.portal.verify.model.VerifiableGroupedModel;
024    
025    import java.sql.Connection;
026    import java.sql.PreparedStatement;
027    import java.sql.ResultSet;
028    
029    import java.util.ArrayList;
030    import java.util.Collection;
031    import java.util.List;
032    import java.util.Map;
033    
034    /**
035     * @author Shinn Lok
036     */
037    public class VerifyGroupedModel extends VerifyProcess {
038    
039            public void verify(VerifiableGroupedModel ... verifiableGroupedModels)
040                    throws Exception {
041    
042                    List<String> unverifiedTableNames = new ArrayList<String>();
043    
044                    for (VerifiableGroupedModel verifiableGroupedModel :
045                                    verifiableGroupedModels) {
046    
047                            unverifiedTableNames.add(verifiableGroupedModel.getTableName());
048                    }
049    
050                    while (!unverifiedTableNames.isEmpty()) {
051                            int count = unverifiedTableNames.size();
052    
053                            for (VerifiableGroupedModel verifiableGroupedModel :
054                                            verifiableGroupedModels) {
055    
056                                    if (unverifiedTableNames.contains(
057                                                    verifiableGroupedModel.getRelatedTableName()) ||
058                                            !unverifiedTableNames.contains(
059                                                    verifiableGroupedModel.getTableName())) {
060    
061                                            continue;
062                                    }
063    
064                                    verifyGroupedModel(verifiableGroupedModel);
065    
066                                    unverifiedTableNames.remove(
067                                            verifiableGroupedModel.getTableName());
068                            }
069    
070                            if (unverifiedTableNames.size() == count) {
071                                    throw new VerifyException(
072                                            "Circular dependency detected " + unverifiedTableNames);
073                            }
074                    }
075            }
076    
077            @Override
078            protected void doVerify() throws Exception {
079                    Map<String, VerifiableGroupedModel> verifiableGroupedModelsMap =
080                            PortalBeanLocatorUtil.locate(VerifiableGroupedModel.class);
081    
082                    Collection<VerifiableGroupedModel> verifiableGroupedModels =
083                            verifiableGroupedModelsMap.values();
084    
085                    verify(
086                            verifiableGroupedModels.toArray(
087                                    new VerifiableGroupedModel[verifiableGroupedModels.size()]));
088            }
089    
090            protected long getGroupId(
091                            String tableName, String primaryKeColumnName, long primKey)
092                    throws Exception {
093    
094                    Connection con = null;
095                    PreparedStatement ps = null;
096                    ResultSet rs = null;
097    
098                    try {
099                            con = DataAccess.getUpgradeOptimizedConnection();
100    
101                            ps = con.prepareStatement(
102                                    "select groupId from " + tableName + " where " +
103                                            primaryKeColumnName + " = ?");
104    
105                            ps.setLong(1, primKey);
106    
107                            rs = ps.executeQuery();
108    
109                            if (rs.next()) {
110                                    return rs.getLong("groupId");
111                            }
112    
113                            if (_log.isDebugEnabled()) {
114                                    _log.debug("Unable to find " + tableName + " " + primKey);
115                            }
116    
117                            return 0;
118                    }
119                    finally {
120                            DataAccess.cleanUp(con, ps, rs);
121                    }
122            }
123    
124            protected void verifyGroupedModel(
125                            VerifiableGroupedModel verifiableGroupedModel)
126                    throws Exception {
127    
128                    Connection con = null;
129                    PreparedStatement ps = null;
130                    ResultSet rs = null;
131    
132                    try {
133                            con = DataAccess.getUpgradeOptimizedConnection();
134    
135                            StringBundler sb = new StringBundler(7);
136    
137                            sb.append("select ");
138                            sb.append(verifiableGroupedModel.getPrimaryKeyColumnName());
139                            sb.append(StringPool.COMMA_AND_SPACE);
140                            sb.append(verifiableGroupedModel.getRelatedPrimaryKeyColumnName());
141                            sb.append(" from ");
142                            sb.append(verifiableGroupedModel.getTableName());
143                            sb.append(" where groupId is null");
144    
145                            ps = con.prepareStatement(sb.toString());
146    
147                            rs = ps.executeQuery();
148    
149                            while (rs.next()) {
150                                    long primKey = rs.getLong(
151                                            verifiableGroupedModel.getPrimaryKeyColumnName());
152                                    long relatedPrimKey = rs.getLong(
153                                            verifiableGroupedModel.getRelatedPrimaryKeyColumnName());
154    
155                                    long groupId = getGroupId(
156                                            verifiableGroupedModel.getRelatedTableName(),
157                                            verifiableGroupedModel.getRelatedPrimaryKeyColumnName(),
158                                            relatedPrimKey);
159    
160                                    if (groupId <= 0) {
161                                            continue;
162                                    }
163    
164                                    sb = new StringBundler(8);
165    
166                                    sb.append("update ");
167                                    sb.append(verifiableGroupedModel.getTableName());
168                                    sb.append(" set groupId = ");
169                                    sb.append(groupId);
170                                    sb.append(" where ");
171                                    sb.append(verifiableGroupedModel.getPrimaryKeyColumnName());
172                                    sb.append(" = ");
173                                    sb.append(primKey);
174    
175                                    runSQL(sb.toString());
176                            }
177                    }
178                    finally {
179                            DataAccess.cleanUp(con, ps, rs);
180                    }
181            }
182    
183            private static final Log _log = LogFactoryUtil.getLog(
184                    VerifyGroupedModel.class);
185    
186    }