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.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.security.auth.FullNameGenerator;
025 import com.liferay.portal.security.auth.FullNameGeneratorFactory;
026 import com.liferay.portal.verify.model.VerifiableAuditedModel;
027
028 import java.sql.Connection;
029 import java.sql.PreparedStatement;
030 import java.sql.ResultSet;
031 import java.sql.Timestamp;
032
033 import java.util.ArrayList;
034 import java.util.Collection;
035 import java.util.List;
036 import java.util.Map;
037
038
042 public class VerifyAuditedModel extends VerifyProcess {
043
044 public void verify(VerifiableAuditedModel ... verifiableAuditedModels)
045 throws Exception {
046
047 List<String> unverifiedTableNames = new ArrayList<String>();
048
049 for (VerifiableAuditedModel verifiableAuditedModel :
050 verifiableAuditedModels) {
051
052 unverifiedTableNames.add(verifiableAuditedModel.getTableName());
053 }
054
055 List<VerifyAuditedModelRunnable> verifyAuditedModelRunnables =
056 new ArrayList<VerifyAuditedModelRunnable>(
057 unverifiedTableNames.size());
058
059 while (!unverifiedTableNames.isEmpty()) {
060 int count = unverifiedTableNames.size();
061
062 for (VerifiableAuditedModel verifiableAuditedModel :
063 verifiableAuditedModels) {
064
065 if (unverifiedTableNames.contains(
066 verifiableAuditedModel.getJoinByTableName()) ||
067 !unverifiedTableNames.contains(
068 verifiableAuditedModel.getTableName())) {
069
070 continue;
071 }
072
073 VerifyAuditedModelRunnable verifyAuditedModelRunnable =
074 new VerifyAuditedModelRunnable(verifiableAuditedModel);
075
076 verifyAuditedModelRunnables.add(verifyAuditedModelRunnable);
077
078 unverifiedTableNames.remove(
079 verifiableAuditedModel.getTableName());
080 }
081
082 if (unverifiedTableNames.size() == count) {
083 throw new VerifyException(
084 "Circular dependency detected " + unverifiedTableNames);
085 }
086 }
087
088 doVerify(verifyAuditedModelRunnables);
089 }
090
091 @Override
092 protected void doVerify() throws Exception {
093 Map<String, VerifiableAuditedModel> verifiableAuditedModelsMap =
094 PortalBeanLocatorUtil.locate(VerifiableAuditedModel.class);
095
096 Collection<VerifiableAuditedModel> verifiableAuditedModels =
097 verifiableAuditedModelsMap.values();
098
099 verify(
100 verifiableAuditedModels.toArray(
101 new VerifiableAuditedModel[verifiableAuditedModels.size()]));
102 }
103
104 protected Object[] getAuditedModelArray(
105 String tableName, String pkColumnName, long primKey)
106 throws Exception {
107
108 Connection con = null;
109 PreparedStatement ps = null;
110 ResultSet rs = null;
111
112 try {
113 con = DataAccess.getUpgradeOptimizedConnection();
114
115 ps = con.prepareStatement(
116 "select companyId, userId, createDate, modifiedDate from " +
117 tableName + " where " + pkColumnName + " = ?");
118
119 ps.setLong(1, primKey);
120
121 rs = ps.executeQuery();
122
123 if (rs.next()) {
124 long companyId = rs.getLong("companyId");
125 long userId = rs.getLong("userId");
126 Timestamp createDate = rs.getTimestamp("createDate");
127 Timestamp modifiedDate = rs.getTimestamp("modifiedDate");
128
129 return new Object[] {
130 companyId, userId, getUserName(userId), createDate,
131 modifiedDate
132 };
133 }
134
135 if (_log.isDebugEnabled()) {
136 _log.debug("Unable to find " + tableName + " " + primKey);
137 }
138
139 return null;
140 }
141 finally {
142 DataAccess.cleanUp(con, ps, rs);
143 }
144 }
145
146 protected Object[] getDefaultUserArray(Connection con, long companyId)
147 throws Exception {
148
149 PreparedStatement ps = null;
150 ResultSet rs = null;
151
152 try {
153 ps = con.prepareStatement(
154 "select userId, firstName, middleName, lastName from User_" +
155 " where companyId = ? and defaultUser = ?");
156
157 ps.setLong(1, companyId);
158 ps.setBoolean(2, true);
159
160 rs = ps.executeQuery();
161
162 if (rs.next()) {
163 long userId = rs.getLong("userId");
164 String firstName = rs.getString("firstName");
165 String middleName = rs.getString("middleName");
166 String lastName = rs.getString("lastName");
167
168 FullNameGenerator fullNameGenerator =
169 FullNameGeneratorFactory.getInstance();
170
171 String userName = fullNameGenerator.getFullName(
172 firstName, middleName, lastName);
173
174 Timestamp createDate = new Timestamp(
175 System.currentTimeMillis());
176
177 return new Object[] {
178 companyId, userId, userName, createDate, createDate
179 };
180 }
181
182 return null;
183 }
184 finally {
185 DataAccess.cleanUp(null, ps, rs);
186 }
187 }
188
189 protected String getUserName(long userId) throws Exception {
190 Connection con = null;
191 PreparedStatement ps = null;
192 ResultSet rs = null;
193
194 try {
195 con = DataAccess.getUpgradeOptimizedConnection();
196
197 ps = con.prepareStatement(
198 "select firstName, middleName, lastName from User_ where " +
199 "userId = ?");
200
201 ps.setLong(1, userId);
202
203 rs = ps.executeQuery();
204
205 if (rs.next()) {
206 String firstName = rs.getString("firstName");
207 String middleName = rs.getString("middleName");
208 String lastName = rs.getString("lastName");
209
210 FullNameGenerator fullNameGenerator =
211 FullNameGeneratorFactory.getInstance();
212
213 return fullNameGenerator.getFullName(
214 firstName, middleName, lastName);
215 }
216
217 return StringPool.BLANK;
218 }
219 finally {
220 DataAccess.cleanUp(con, ps, rs);
221 }
222 }
223
224 protected void verifyAuditedModel(
225 String tableName, String primaryKeyColumnName, long primKey,
226 Object[] auditedModelArray, boolean updateDates)
227 throws Exception {
228
229 Connection con = null;
230 PreparedStatement ps = null;
231
232 try {
233 con = DataAccess.getUpgradeOptimizedConnection();
234
235 long companyId = (Long)auditedModelArray[0];
236
237 if (auditedModelArray[2] == null) {
238 auditedModelArray = getDefaultUserArray(con, companyId);
239
240 if (auditedModelArray == null) {
241 return;
242 }
243 }
244
245 long userId = (Long)auditedModelArray[1];
246 String userName = (String)auditedModelArray[2];
247 Timestamp createDate = (Timestamp)auditedModelArray[3];
248 Timestamp modifiedDate = (Timestamp)auditedModelArray[4];
249
250 StringBundler sb = new StringBundler(7);
251
252 sb.append("update ");
253 sb.append(tableName);
254 sb.append(" set companyId = ?, userId = ?, userName = ?");
255
256 if (updateDates) {
257 sb.append(", createDate = ?, modifiedDate = ?");
258 }
259
260 sb.append(" where ");
261 sb.append(primaryKeyColumnName);
262 sb.append(" = ?");
263
264 ps = con.prepareStatement(sb.toString());
265
266 ps.setLong(1, companyId);
267 ps.setLong(2, userId);
268 ps.setString(3, userName);
269
270 if (updateDates) {
271 ps.setTimestamp(4, createDate);
272 ps.setTimestamp(5, modifiedDate);
273 ps.setLong(6, primKey);
274 }
275 else {
276 ps.setLong(4, primKey);
277 }
278
279 ps.executeUpdate();
280 }
281 catch (Exception e) {
282 if (_log.isWarnEnabled()) {
283 _log.warn("Unable to verify model " + tableName, e);
284 }
285 }
286 finally {
287 DataAccess.cleanUp(con, ps);
288 }
289 }
290
291 protected void verifyAuditedModel(
292 VerifiableAuditedModel verifiableAuditedModel)
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(verifiableAuditedModel.getPrimaryKeyColumnName());
306 sb.append(", companyId");
307
308 if (verifiableAuditedModel.getJoinByTableName() != null) {
309 sb.append(StringPool.COMMA_AND_SPACE);
310 sb.append(verifiableAuditedModel.getJoinByTableName());
311 }
312
313 sb.append(" from ");
314 sb.append(verifiableAuditedModel.getTableName());
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[] auditedModelArray = null;
322
323 long previousCompanyId = 0;
324
325 while (rs.next()) {
326 long companyId = rs.getLong("companyId");
327 long primKey = rs.getLong(
328 verifiableAuditedModel.getPrimaryKeyColumnName());
329
330 if (verifiableAuditedModel.getJoinByTableName() != null) {
331 long relatedPrimKey = rs.getLong(
332 verifiableAuditedModel.getJoinByTableName());
333
334 auditedModelArray = getAuditedModelArray(
335 verifiableAuditedModel.getRelatedModelName(),
336 verifiableAuditedModel.getRelatedPKColumnName(),
337 relatedPrimKey);
338 }
339 else if (previousCompanyId != companyId) {
340 auditedModelArray = getDefaultUserArray(con, companyId);
341
342 previousCompanyId = companyId;
343 }
344
345 if (auditedModelArray == null) {
346 continue;
347 }
348
349 verifyAuditedModel(
350 verifiableAuditedModel.getTableName(),
351 verifiableAuditedModel.getPrimaryKeyColumnName(), primKey,
352 auditedModelArray, verifiableAuditedModel.isUpdateDates());
353 }
354 }
355 finally {
356 DataAccess.cleanUp(con, ps, rs);
357 }
358 }
359
360 private static final Log _log = LogFactoryUtil.getLog(
361 VerifyAuditedModel.class);
362
363 private class VerifyAuditedModelRunnable extends ThrowableAwareRunnable {
364
365 public VerifyAuditedModelRunnable(
366 VerifiableAuditedModel verifiableAuditedModel) {
367
368 _verifiableAuditedModel = verifiableAuditedModel;
369 }
370
371 @Override
372 protected void doRun() throws Exception {
373 verifyAuditedModel(_verifiableAuditedModel);
374 }
375
376 private final VerifiableAuditedModel _verifiableAuditedModel;
377
378 }
379
380 }