001    /**
002     * Copyright (c) 2000-2013 Liferay, Inc. All rights reserved.
003     *
004     * The contents of this file are subject to the terms of the Liferay Enterprise
005     * Subscription License ("License"). You may not use this file except in
006     * compliance with the License. You can obtain a copy of the License by
007     * contacting Liferay, Inc. See the License for the specific language governing
008     * permissions and limitations under the License, including but not limited to
009     * distribution rights of the Software.
010     *
011     *
012     *
013     */
014    
015    package com.liferay.portal.verify;
016    
017    import com.liferay.portal.kernel.concurrent.ThrowableAwareRunnable;
018    import com.liferay.portal.kernel.dao.jdbc.DataAccess;
019    import com.liferay.portal.kernel.dao.shard.ShardUtil;
020    import com.liferay.portal.kernel.log.Log;
021    import com.liferay.portal.kernel.log.LogFactoryUtil;
022    import com.liferay.portal.kernel.util.StringPool;
023    
024    import java.sql.Connection;
025    import java.sql.PreparedStatement;
026    import java.sql.ResultSet;
027    
028    import java.util.ArrayList;
029    import java.util.List;
030    
031    /**
032     * @author Shinn Lok
033     */
034    public class VerifyGroupId extends VerifyProcess {
035    
036            @Override
037            protected void doVerify() throws Exception {
038                    List<String> pendingModels = new ArrayList<String>();
039    
040                    for (String[] model : _MODELS) {
041                            pendingModels.add(model[0]);
042                    }
043    
044                    List<VerifiableGroupedModelRunnable> verifiableGroupedModelRunnables =
045                            new ArrayList<VerifiableGroupedModelRunnable>(_MODELS.length);
046    
047                    while (!pendingModels.isEmpty()) {
048                            int count = pendingModels.size();
049    
050                            for (String[] model : _MODELS) {
051                                    if (pendingModels.contains(model[2]) ||
052                                            !pendingModels.contains(model[0])) {
053    
054                                            continue;
055                                    }
056    
057                                    VerifiableGroupedModelRunnable verifyAuditedModelRunnable =
058                                            new VerifiableGroupedModelRunnable(
059                                                    ShardUtil.getCurrentShardName(), model[0], model[1],
060                                                    model[2], model[3]);
061    
062                                    verifiableGroupedModelRunnables.add(verifyAuditedModelRunnable);
063    
064                                    verifyModel(model[0], model[1], model[2], model[3]);
065    
066                                    pendingModels.remove(model[0]);
067                            }
068    
069                            if (pendingModels.size() == count) {
070                                    throw new VerifyException(
071                                            "Circular dependency detected " + pendingModels);
072                            }
073                    }
074    
075                    doVerify(verifiableGroupedModelRunnables);
076            }
077    
078            protected long getGroupId(
079                            String modelName, String pkColumnName, long primKey)
080                    throws Exception {
081    
082                    Connection con = null;
083                    PreparedStatement ps = null;
084                    ResultSet rs = null;
085    
086                    try {
087                            con = DataAccess.getUpgradeOptimizedConnection();
088    
089                            ps = con.prepareStatement(
090                                    "select groupId from " + modelName + " where " + pkColumnName +
091                                            " = ?");
092    
093                            ps.setLong(1, primKey);
094    
095                            rs = ps.executeQuery();
096    
097                            if (rs.next()) {
098                                    return rs.getLong("groupId");
099                            }
100    
101                            if (_log.isDebugEnabled()) {
102                                    _log.debug(
103                                            "Unable to find " + modelName + StringPool.SPACE + primKey);
104                            }
105    
106                            return 0;
107                    }
108                    finally {
109                            DataAccess.cleanUp(con, ps, rs);
110                    }
111            }
112    
113            protected void verifyModel(
114                            String modelName, String pkColumnName, String relatedModelName,
115                            String relatedPKColumnName)
116                    throws Exception {
117    
118                    Connection con = null;
119                    PreparedStatement ps = null;
120                    ResultSet rs = null;
121    
122                    try {
123                            con = DataAccess.getUpgradeOptimizedConnection();
124    
125                            ps = con.prepareStatement(
126                                    "select " + pkColumnName + StringPool.COMMA_AND_SPACE +
127                                            relatedPKColumnName + " from " + modelName + " where " +
128                                                    "groupId is null");
129    
130                            rs = ps.executeQuery();
131    
132                            while (rs.next()) {
133                                    long primKey = rs.getLong(pkColumnName);
134                                    long relatedPrimKey = rs.getLong(relatedPKColumnName);
135    
136                                    long groupId = getGroupId(
137                                            relatedModelName, relatedPKColumnName, relatedPrimKey);
138    
139                                    if (groupId <= 0) {
140                                            continue;
141                                    }
142    
143                                    runSQL(
144                                            "update " + modelName + " set groupId = " + groupId +
145                                                    " where " + pkColumnName + " = " + primKey);
146                            }
147                    }
148                    finally {
149                            DataAccess.cleanUp(con, ps, rs);
150                    }
151            }
152    
153            private static final String[][] _MODELS = new String[][] {
154                    new String[] {
155                            "MBDiscussion", "discussionId", "MBThread", "threadId"
156                    },
157                    new String[] {
158                            "MBThreadFlag", "threadFlagId", "MBThread", "threadId"
159                    },
160                    new String[] {
161                            "PollsChoice", "choiceId", "PollsQuestion", "questionId"
162                    },
163                    new String[] {
164                            "PollsVote", "voteId", "PollsQuestion", "questionId"
165                    }
166            };
167    
168            private class VerifiableGroupedModelRunnable
169                    extends ThrowableAwareRunnable {
170    
171                    private VerifiableGroupedModelRunnable(
172                            String shardName, String modelName, String pkColumnName,
173                            String relatedModelName, String relatedPKColumnName) {
174    
175                            super(shardName);
176    
177                            _modelName = modelName;
178                            _pkColumnName = pkColumnName;
179                            _relatedModelName = relatedModelName;
180                            _relatedPKColumnName = relatedPKColumnName;
181                    }
182    
183                    @Override
184                    protected void doRun() throws Exception {
185                            verifyModel(
186                                    _modelName, _pkColumnName, _relatedModelName,
187                                    _relatedPKColumnName);
188                    }
189    
190                    private final String _modelName;
191                    private final String _pkColumnName;
192                    private final String _relatedModelName;
193                    private final String _relatedPKColumnName;
194    
195            }
196    
197            private static Log _log = LogFactoryUtil.getLog(VerifyGroupId.class);
198    
199    }