001    /**
002     * Copyright (c) 2000-2013 Liferay, Inc. All rights reserved.
003     *
004     * This library is free software; you can redistribute it and/or modify it under
005     * the terms of the GNU Lesser General Public License as published by the Free
006     * Software Foundation; either version 2.1 of the License, or (at your option)
007     * any later version.
008     *
009     * This library is distributed in the hope that it will be useful, but WITHOUT
010     * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
011     * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
012     * details.
013     */
014    
015    package com.liferay.portal.verify;
016    
017    import com.liferay.portal.kernel.dao.jdbc.DataAccess;
018    import com.liferay.portal.kernel.log.Log;
019    import com.liferay.portal.kernel.log.LogFactoryUtil;
020    import com.liferay.portal.kernel.util.GetterUtil;
021    import com.liferay.portal.kernel.util.StringBundler;
022    import com.liferay.portal.kernel.util.StringPool;
023    import com.liferay.portal.security.auth.FullNameGenerator;
024    import com.liferay.portal.security.auth.FullNameGeneratorFactory;
025    
026    import java.sql.Connection;
027    import java.sql.PreparedStatement;
028    import java.sql.ResultSet;
029    import java.sql.Timestamp;
030    
031    import java.util.ArrayList;
032    import java.util.List;
033    
034    /**
035     * @author Michael C. Han
036     * @author Shinn Lok
037     */
038    public class VerifyAuditedModel extends VerifyProcess {
039    
040            @Override
041            protected void doVerify() throws Exception {
042                    List<String> pendingModels = new ArrayList<String>();
043    
044                    for (String[] model : _MODELS) {
045                            pendingModels.add(model[0]);
046                    }
047    
048                    while (!pendingModels.isEmpty()) {
049                            int count = pendingModels.size();
050    
051                            for (String[] model : _MODELS) {
052                                    if (pendingModels.contains(model[3]) ||
053                                            !pendingModels.contains(model[0])) {
054    
055                                            continue;
056                                    }
057    
058                                    verifyModel(
059                                            model[0], model[1], model[2], model[3], model[4],
060                                            GetterUtil.getBoolean(model[5]));
061    
062                                    pendingModels.remove(model[0]);
063                            }
064    
065                            if (pendingModels.size() == count) {
066                                    throw new VerifyException(
067                                            "Circular dependency detected " + pendingModels);
068                            }
069                    }
070            }
071    
072            protected Object[] getDefaultUserArray(Connection con, long companyId)
073                    throws Exception {
074    
075                    PreparedStatement ps = null;
076                    ResultSet rs = null;
077    
078                    try {
079                            ps = con.prepareStatement(
080                                    "select userId, firstName, middleName, lastName from User_" +
081                                            " where companyId = ? and defaultUser = ?");
082    
083                            ps.setLong(1, companyId);
084                            ps.setBoolean(2, true);
085    
086                            rs = ps.executeQuery();
087    
088                            if (rs.next()) {
089                                    long userId = rs.getLong("userId");
090                                    String firstName = rs.getString("firstName");
091                                    String middleName = rs.getString("middleName");
092                                    String lastName = rs.getString("lastName");
093    
094                                    FullNameGenerator fullNameGenerator =
095                                            FullNameGeneratorFactory.getInstance();
096    
097                                    String userName = fullNameGenerator.getFullName(
098                                            firstName, middleName, lastName);
099    
100                                    Timestamp createDate = new Timestamp(
101                                            System.currentTimeMillis());
102    
103                                    return new Object[] {
104                                            companyId, userId, userName, createDate, createDate
105                                    };
106                            }
107    
108                            return null;
109                    }
110                    finally {
111                            DataAccess.cleanUp(null, ps, rs);
112                    }
113            }
114    
115            protected Object[] getModelArray(
116                            String modelName, String pkColumnName, long primKey)
117                    throws Exception {
118    
119                    Connection con = null;
120                    PreparedStatement ps = null;
121                    ResultSet rs = null;
122    
123                    try {
124                            con = DataAccess.getUpgradeOptimizedConnection();
125    
126                            ps = con.prepareStatement(
127                                    "select companyId, userId, createDate, modifiedDate from " +
128                                            modelName + " where " + pkColumnName + " = ?");
129    
130                            ps.setLong(1, primKey);
131    
132                            rs = ps.executeQuery();
133    
134                            if (rs.next()) {
135                                    long companyId = rs.getLong("companyId");
136                                    long userId = rs.getLong("userId");
137                                    Timestamp createDate = rs.getTimestamp("createDate");
138                                    Timestamp modifiedDate = rs.getTimestamp("modifiedDate");
139    
140                                    return new Object[] {
141                                            companyId, userId, getUserName(userId), createDate,
142                                            modifiedDate
143                                    };
144                            }
145    
146                            if (_log.isDebugEnabled()) {
147                                    _log.debug(
148                                            "Unable to find " + modelName + StringPool.SPACE + primKey);
149                            }
150    
151                            return null;
152                    }
153                    finally {
154                            DataAccess.cleanUp(con, ps, rs);
155                    }
156            }
157    
158            protected String getUserName(long userId) throws Exception {
159                    Connection con = null;
160                    PreparedStatement ps = null;
161                    ResultSet rs = null;
162    
163                    try {
164                            con = DataAccess.getUpgradeOptimizedConnection();
165    
166                            ps = con.prepareStatement(
167                                    "select firstName, middleName, lastName from User_ where " +
168                                            "userId = ?");
169    
170                            ps.setLong(1, userId);
171    
172                            rs = ps.executeQuery();
173    
174                            if (rs.next()) {
175                                    String firstName = rs.getString("firstName");
176                                    String middleName = rs.getString("middleName");
177                                    String lastName = rs.getString("lastName");
178    
179                                    FullNameGenerator fullNameGenerator =
180                                            FullNameGeneratorFactory.getInstance();
181    
182                                    return fullNameGenerator.getFullName(
183                                            firstName, middleName, lastName);
184                            }
185    
186                            return StringPool.BLANK;
187                    }
188                    finally {
189                            DataAccess.cleanUp(con, ps, rs);
190                    }
191            }
192    
193            protected void verifyModel(
194                            String modelName, String pkColumnName, long primKey,
195                            Object[] modelArray, boolean updateDates)
196                    throws Exception {
197    
198                    Connection con = null;
199                    PreparedStatement ps = null;
200    
201                    try {
202                            con = DataAccess.getUpgradeOptimizedConnection();
203    
204                            long companyId = (Long)modelArray[0];
205    
206                            if (modelArray[2] == null) {
207                                    modelArray = getDefaultUserArray(con, companyId);
208    
209                                    if (modelArray == null) {
210                                            return;
211                                    }
212                            }
213    
214                            long userId = (Long)modelArray[1];
215                            String userName = (String)modelArray[2];
216                            Timestamp createDate = (Timestamp)modelArray[3];
217                            Timestamp modifiedDate = (Timestamp)modelArray[4];
218    
219                            StringBundler sb = new StringBundler(7);
220    
221                            sb.append("update ");
222                            sb.append(modelName);
223                            sb.append(" set companyId = ?, userId = ?, userName = ?");
224    
225                            if (updateDates) {
226                                    sb.append(", createDate = ?, modifiedDate = ?");
227                            }
228    
229                            sb.append(" where ");
230                            sb.append(pkColumnName);
231                            sb.append(" = ?");
232    
233                            ps = con.prepareStatement(sb.toString());
234    
235                            ps.setLong(1, companyId);
236                            ps.setLong(2, userId);
237                            ps.setString(3, userName);
238    
239                            if (updateDates) {
240                                    ps.setTimestamp(4, createDate);
241                                    ps.setTimestamp(5, modifiedDate);
242                                    ps.setLong(6, primKey);
243                            }
244                            else {
245                                    ps.setLong(4, primKey);
246                            }
247    
248                            ps.executeUpdate();
249                    }
250                    catch (Exception e) {
251                            if (_log.isWarnEnabled()) {
252                                    _log.warn("Unable to verify model " + modelName, e);
253                            }
254                    }
255                    finally {
256                            DataAccess.cleanUp(con, ps);
257                    }
258            }
259    
260            protected void verifyModel(
261                            String modelName, String pkColumnName, String joinByColumnName,
262                            String relatedModelName, String relatedPKColumnName,
263                            boolean updateDates)
264                    throws Exception {
265    
266                    Connection con = null;
267                    PreparedStatement ps = null;
268                    ResultSet rs = null;
269    
270                    try {
271                            con = DataAccess.getUpgradeOptimizedConnection();
272    
273                            StringBundler sb = new StringBundler(8);
274    
275                            sb.append("select ");
276                            sb.append(pkColumnName);
277                            sb.append(", companyId");
278    
279                            if (joinByColumnName != null) {
280                                    sb.append(StringPool.COMMA_AND_SPACE);
281                                    sb.append(joinByColumnName);
282                            }
283    
284                            sb.append(" from ");
285                            sb.append(modelName);
286                            sb.append(" where userName is null order by companyId");
287    
288                            ps = con.prepareStatement(sb.toString());
289    
290                            rs = ps.executeQuery();
291    
292                            Object[] modelArray = null;
293    
294                            long previousCompanyId = 0;
295    
296                            while (rs.next()) {
297                                    long companyId = rs.getLong("companyId");
298                                    long primKey = rs.getLong(pkColumnName);
299    
300                                    if (joinByColumnName != null) {
301                                            long relatedPrimKey = rs.getLong(joinByColumnName);
302    
303                                            modelArray = getModelArray(
304                                                    relatedModelName, relatedPKColumnName, relatedPrimKey);
305                                    }
306                                    else if (previousCompanyId != companyId) {
307                                            modelArray = getDefaultUserArray(con, companyId);
308    
309                                            previousCompanyId = companyId;
310                                    }
311    
312                                    if (modelArray == null) {
313                                            continue;
314                                    }
315    
316                                    verifyModel(
317                                            modelName, pkColumnName, primKey, modelArray, updateDates);
318                            }
319                    }
320                    finally {
321                            DataAccess.cleanUp(con, ps, rs);
322                    }
323            }
324    
325            private static final String[][] _MODELS = new String[][] {
326                    new String[] {
327                            "Layout", "plid", null, null, null, "false"
328                    },
329                    new String[] {
330                            "LayoutPrototype", "layoutPrototypeId", null, null, null, "true"
331                    },
332                    new String[] {
333                            "LayoutSetPrototype", "layoutSetPrototypeId", null, null, null,
334                            "false"
335                    },
336                    new String[] {
337                            "MBDiscussion", "discussionId", "threadId", "MBThread", "threadId",
338                            "true"
339                    },
340                    new String[] {
341                            "MBThread", "threadId", "rootMessageId", "MBMessage", "messageId",
342                            "true"
343                    },
344                    new String[] {
345                            "MBThreadFlag", "threadFlagId", "userId", "User_", "userId", "true",
346                    },
347                    new String[] {
348                            "Organization_", "organizationId", null, null, null, "true"
349                    },
350                    new String[] {
351                            "PollsChoice", "choiceId", "questionId", "PollsQuestion",
352                            "questionId", "true"
353                    },
354                    new String[] {
355                            "PollsVote", "voteId", "questionId", "PollsQuestion", "questionId",
356                            "true"
357                    },
358                    new String[] {
359                            "RepositoryEntry", "repositoryEntryId", "repositoryId",
360                            "Repository", "repositoryId", "true"
361                    },
362                    new String[] {
363                            "Role_", "roleId", null, null, null, "true"
364                    },
365                    new String[] {
366                            "UserGroup", "userGroupId", null, null, null, "true"
367                    }
368            };
369    
370            private static Log _log = LogFactoryUtil.getLog(VerifyAuditedModel.class);
371    
372    }