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