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