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