001
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.language.LanguageUtil;
021 import com.liferay.portal.kernel.log.Log;
022 import com.liferay.portal.kernel.log.LogFactoryUtil;
023 import com.liferay.portal.kernel.util.GetterUtil;
024 import com.liferay.portal.kernel.util.LocaleUtil;
025 import com.liferay.portal.kernel.util.StringBundler;
026 import com.liferay.portal.kernel.util.StringPool;
027 import com.liferay.portal.security.auth.FullNameGenerator;
028 import com.liferay.portal.security.auth.FullNameGeneratorFactory;
029
030 import java.sql.Connection;
031 import java.sql.PreparedStatement;
032 import java.sql.ResultSet;
033 import java.sql.Timestamp;
034
035 import java.util.ArrayList;
036 import java.util.List;
037
038
042 public class VerifyAuditedModel extends VerifyProcess {
043
044 @Override
045 protected void doVerify() throws Exception {
046 List<String> pendingModels = new ArrayList<String>();
047
048 for (String[] model : _MODELS) {
049 pendingModels.add(model[0]);
050 }
051
052 List<VerifyAuditedModelRunnable> verifyAuditedModelRunnables =
053 new ArrayList<VerifyAuditedModelRunnable>(_MODELS.length);
054
055 while (!pendingModels.isEmpty()) {
056 int count = pendingModels.size();
057
058 for (String[] model : _MODELS) {
059 if (pendingModels.contains(model[3]) ||
060 !pendingModels.contains(model[0])) {
061
062 continue;
063 }
064
065 VerifyAuditedModelRunnable verifyAuditedModelRunnable =
066 new VerifyAuditedModelRunnable(
067 ShardUtil.getCurrentShardName(), model[0], model[1],
068 model[2], model[3], model[4],
069 GetterUtil.getBoolean(model[5]),
070 GetterUtil.getBoolean(model[6]));
071
072 verifyAuditedModelRunnables.add(verifyAuditedModelRunnable);
073
074 pendingModels.remove(model[0]);
075 }
076
077 if (pendingModels.size() == count) {
078 throw new VerifyException(
079 "Circular dependency detected " + pendingModels);
080 }
081 }
082
083 doVerify(verifyAuditedModelRunnables);
084 }
085
086 protected Object[] getDefaultUserArray(Connection con, long companyId)
087 throws Exception {
088
089 PreparedStatement ps = null;
090 ResultSet rs = null;
091
092 try {
093 ps = con.prepareStatement(
094 "select userId, firstName, middleName, lastName from User_" +
095 " where companyId = ? and defaultUser = ?");
096
097 ps.setLong(1, companyId);
098 ps.setBoolean(2, true);
099
100 rs = ps.executeQuery();
101
102 if (rs.next()) {
103 long userId = rs.getLong("userId");
104 String firstName = rs.getString("firstName");
105 String middleName = rs.getString("middleName");
106 String lastName = rs.getString("lastName");
107
108 FullNameGenerator fullNameGenerator =
109 FullNameGeneratorFactory.getInstance();
110
111 String userName = fullNameGenerator.getFullName(
112 firstName, middleName, lastName);
113
114 Timestamp createDate = new Timestamp(
115 System.currentTimeMillis());
116
117 return new Object[] {
118 companyId, userId, userName, createDate, createDate
119 };
120 }
121
122 return null;
123 }
124 finally {
125 DataAccess.cleanUp(null, ps, rs);
126 }
127 }
128
129 protected Object[] getModelArray(
130 String modelName, String pkColumnName, long primKey,
131 boolean allowAnonymousUser, long previousUserId)
132 throws Exception {
133
134 Connection con = null;
135 PreparedStatement ps = null;
136 ResultSet rs = null;
137
138 try {
139 con = DataAccess.getUpgradeOptimizedConnection();
140
141 ps = con.prepareStatement(
142 "select companyId, userId, createDate, modifiedDate from " +
143 modelName + " where " + pkColumnName + " = ?");
144
145 ps.setLong(1, primKey);
146
147 rs = ps.executeQuery();
148
149 if (rs.next()) {
150 long companyId = rs.getLong("companyId");
151
152 long userId = 0;
153 String userName = null;
154
155 if (allowAnonymousUser) {
156 userId = previousUserId;
157
158 userName = LanguageUtil.format(
159 LocaleUtil.getSiteDefault(), "anonymous",
160 new Object[]{});
161 }
162 else {
163 userId = rs.getLong("userId");
164 userName = getUserName(userId);
165 }
166
167 Timestamp createDate = rs.getTimestamp("createDate");
168 Timestamp modifiedDate = rs.getTimestamp("modifiedDate");
169
170 return new Object[] {
171 companyId, userId, userName, createDate, modifiedDate
172 };
173 }
174
175 if (_log.isDebugEnabled()) {
176 _log.debug(
177 "Unable to find " + modelName + StringPool.SPACE + primKey);
178 }
179
180 return null;
181 }
182 finally {
183 DataAccess.cleanUp(con, ps, rs);
184 }
185 }
186
187 protected String getUserName(long userId) throws Exception {
188 Connection con = null;
189 PreparedStatement ps = null;
190 ResultSet rs = null;
191
192 try {
193 con = DataAccess.getUpgradeOptimizedConnection();
194
195 ps = con.prepareStatement(
196 "select firstName, middleName, lastName from User_ where " +
197 "userId = ?");
198
199 ps.setLong(1, userId);
200
201 rs = ps.executeQuery();
202
203 if (rs.next()) {
204 String firstName = rs.getString("firstName");
205 String middleName = rs.getString("middleName");
206 String lastName = rs.getString("lastName");
207
208 FullNameGenerator fullNameGenerator =
209 FullNameGeneratorFactory.getInstance();
210
211 return fullNameGenerator.getFullName(
212 firstName, middleName, lastName);
213 }
214
215 return StringPool.BLANK;
216 }
217 finally {
218 DataAccess.cleanUp(con, ps, rs);
219 }
220 }
221
222 protected void verifyModel(
223 String modelName, String pkColumnName, long primKey,
224 Object[] modelArray, boolean updateDates)
225 throws Exception {
226
227 Connection con = null;
228 PreparedStatement ps = null;
229
230 try {
231 con = DataAccess.getUpgradeOptimizedConnection();
232
233 long companyId = (Long)modelArray[0];
234
235 if (modelArray[2] == null) {
236 modelArray = getDefaultUserArray(con, companyId);
237
238 if (modelArray == null) {
239 return;
240 }
241 }
242
243 long userId = (Long)modelArray[1];
244 String userName = (String)modelArray[2];
245 Timestamp createDate = (Timestamp)modelArray[3];
246 Timestamp modifiedDate = (Timestamp)modelArray[4];
247
248 StringBundler sb = new StringBundler(7);
249
250 sb.append("update ");
251 sb.append(modelName);
252 sb.append(" set companyId = ?, userId = ?, userName = ?");
253
254 if (updateDates) {
255 sb.append(", createDate = ?, modifiedDate = ?");
256 }
257
258 sb.append(" where ");
259 sb.append(pkColumnName);
260 sb.append(" = ?");
261
262 ps = con.prepareStatement(sb.toString());
263
264 ps.setLong(1, companyId);
265 ps.setLong(2, userId);
266 ps.setString(3, userName);
267
268 if (updateDates) {
269 ps.setTimestamp(4, createDate);
270 ps.setTimestamp(5, modifiedDate);
271 ps.setLong(6, primKey);
272 }
273 else {
274 ps.setLong(4, primKey);
275 }
276
277 ps.executeUpdate();
278 }
279 catch (Exception e) {
280 if (_log.isWarnEnabled()) {
281 _log.warn("Unable to verify model " + modelName, e);
282 }
283 }
284 finally {
285 DataAccess.cleanUp(con, ps);
286 }
287 }
288
289 protected void verifyModel(
290 String modelName, String pkColumnName, String joinByColumnName,
291 String relatedModelName, String relatedPKColumnName,
292 boolean updateDates, boolean allowAnonymousUser)
293 throws Exception {
294
295 Connection con = null;
296 PreparedStatement ps = null;
297 ResultSet rs = null;
298
299 try {
300 con = DataAccess.getUpgradeOptimizedConnection();
301
302 StringBundler sb = new StringBundler(8);
303
304 sb.append("select ");
305 sb.append(pkColumnName);
306 sb.append(", companyId, userId");
307
308 if (joinByColumnName != null) {
309 sb.append(StringPool.COMMA_AND_SPACE);
310 sb.append(joinByColumnName);
311 }
312
313 sb.append(" from ");
314 sb.append(modelName);
315 sb.append(" where userName is null order by companyId");
316
317 ps = con.prepareStatement(sb.toString());
318
319 rs = ps.executeQuery();
320
321 Object[] modelArray = null;
322
323 long previousCompanyId = 0;
324
325 while (rs.next()) {
326 long companyId = rs.getLong("companyId");
327 long primKey = rs.getLong(pkColumnName);
328
329 if (joinByColumnName != null) {
330 long previousUserId = rs.getLong("userId");
331 long relatedPrimKey = rs.getLong(joinByColumnName);
332
333 modelArray = getModelArray(
334 relatedModelName, relatedPKColumnName, relatedPrimKey,
335 allowAnonymousUser, previousUserId);
336 }
337 else if (previousCompanyId != companyId) {
338 modelArray = getDefaultUserArray(con, companyId);
339
340 previousCompanyId = companyId;
341 }
342
343 if (modelArray == null) {
344 continue;
345 }
346
347 verifyModel(
348 modelName, pkColumnName, primKey, modelArray, updateDates);
349 }
350 }
351 finally {
352 DataAccess.cleanUp(con, ps, rs);
353 }
354 }
355
356 private static final String[][] _MODELS = new String[][] {
357 new String[] {
358 "Layout", "plid", null, null, null, "false", "false"
359 },
360 new String[] {
361 "LayoutPrototype", "layoutPrototypeId", null, null, null, "true",
362 "false"
363 },
364 new String[] {
365 "LayoutSetPrototype", "layoutSetPrototypeId", null, null, null,
366 "false", "false"
367 },
368 new String[] {
369 "MBDiscussion", "discussionId", "threadId", "MBThread", "threadId",
370 "true", "false"
371 },
372 new String[] {
373 "MBThread", "threadId", "rootMessageId", "MBMessage", "messageId",
374 "true", "false"
375 },
376 new String[] {
377 "MBThreadFlag", "threadFlagId", "userId", "User_", "userId", "true",
378 "false"
379 },
380 new String[] {
381 "Organization_", "organizationId", null, null, null, "true", "false"
382 },
383 new String[] {
384 "PollsChoice", "choiceId", "questionId", "PollsQuestion",
385 "questionId", "true", "false"
386 },
387 new String[] {
388 "PollsVote", "voteId", "questionId", "PollsQuestion", "questionId",
389 "true", "true"
390 },
391 new String[] {
392 "RepositoryEntry", "repositoryEntryId", "repositoryId",
393 "Repository", "repositoryId", "true", "false"
394 },
395 new String[] {
396 "Role_", "roleId", null, null, null, "true", "false"
397 },
398 new String[] {
399 "UserGroup", "userGroupId", null, null, null, "true", "false"
400 }
401 };
402
403 private static Log _log = LogFactoryUtil.getLog(VerifyAuditedModel.class);
404
405 private class VerifyAuditedModelRunnable extends ThrowableAwareRunnable {
406
407 private VerifyAuditedModelRunnable(
408 String shardName, String modelName, String pkColumnName,
409 String joinByColumnName, String relatedModelName,
410 String relatedPKColumnName, boolean updateDates,
411 boolean allowAnonymousUser) {
412
413 super(shardName);
414
415 _modelName = modelName;
416 _pkColumnName = pkColumnName;
417 _joinByColumnName = joinByColumnName;
418 _relatedModelName = relatedModelName;
419 _relatedPKColumnName = relatedPKColumnName;
420 _updateDates = updateDates;
421 _allowAnonymousUser = allowAnonymousUser;
422 }
423
424 @Override
425 protected void doRun() throws Exception {
426 verifyModel(
427 _modelName, _pkColumnName, _joinByColumnName, _relatedModelName,
428 _relatedPKColumnName, _updateDates, _allowAnonymousUser);
429 }
430
431 private final boolean _allowAnonymousUser;
432 private final String _joinByColumnName;
433 private final String _modelName;
434 private final String _pkColumnName;
435 private final String _relatedModelName;
436 private final String _relatedPKColumnName;
437 private final boolean _updateDates;
438
439 }
440
441 }