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