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                    Connection con = null;
104                    PreparedStatement ps = null;
105                    ResultSet rs = null;
106    
107                    try {
108                            con = DataAccess.getUpgradeOptimizedConnection();
109    
110                            ps = con.prepareStatement(
111                                    "select groupId from " + tableName + " where " +
112                                            primaryKeColumnName + " = ?");
113    
114                            ps.setLong(1, primKey);
115    
116                            rs = ps.executeQuery();
117    
118                            if (rs.next()) {
119                                    return rs.getLong("groupId");
120                            }
121    
122                            if (_log.isDebugEnabled()) {
123                                    _log.debug("Unable to find " + tableName + " " + primKey);
124                            }
125    
126                            return 0;
127                    }
128                    finally {
129                            DataAccess.cleanUp(con, ps, rs);
130                    }
131            }
132    
133            protected void verifyGroupedModel(
134                            VerifiableGroupedModel verifiableGroupedModel)
135                    throws Exception {
136    
137                    Connection con = null;
138                    PreparedStatement ps = null;
139                    ResultSet rs = null;
140    
141                    try {
142                            con = DataAccess.getUpgradeOptimizedConnection();
143    
144                            StringBundler sb = new StringBundler(7);
145    
146                            sb.append("select ");
147                            sb.append(verifiableGroupedModel.getPrimaryKeyColumnName());
148                            sb.append(StringPool.COMMA_AND_SPACE);
149                            sb.append(verifiableGroupedModel.getRelatedPrimaryKeyColumnName());
150                            sb.append(" from ");
151                            sb.append(verifiableGroupedModel.getTableName());
152                            sb.append(" where groupId is null");
153    
154                            ps = con.prepareStatement(sb.toString());
155    
156                            rs = ps.executeQuery();
157    
158                            while (rs.next()) {
159                                    long primKey = rs.getLong(
160                                            verifiableGroupedModel.getPrimaryKeyColumnName());
161                                    long relatedPrimKey = rs.getLong(
162                                            verifiableGroupedModel.getRelatedPrimaryKeyColumnName());
163    
164                                    long groupId = getGroupId(
165                                            verifiableGroupedModel.getRelatedTableName(),
166                                            verifiableGroupedModel.getRelatedPrimaryKeyColumnName(),
167                                            relatedPrimKey);
168    
169                                    if (groupId <= 0) {
170                                            continue;
171                                    }
172    
173                                    sb = new StringBundler(8);
174    
175                                    sb.append("update ");
176                                    sb.append(verifiableGroupedModel.getTableName());
177                                    sb.append(" set groupId = ");
178                                    sb.append(groupId);
179                                    sb.append(" where ");
180                                    sb.append(verifiableGroupedModel.getPrimaryKeyColumnName());
181                                    sb.append(" = ");
182                                    sb.append(primKey);
183    
184                                    runSQL(sb.toString());
185                            }
186                    }
187                    finally {
188                            DataAccess.cleanUp(con, ps, rs);
189                    }
190            }
191    
192            private static final Log _log = LogFactoryUtil.getLog(
193                    VerifyGroupedModel.class);
194    
195            private class VerifiableGroupedModelRunnable
196                    extends ThrowableAwareRunnable {
197    
198                    public VerifiableGroupedModelRunnable(
199                            VerifiableGroupedModel verifiableGroupedModel) {
200    
201                            _verifiableGroupedModel = verifiableGroupedModel;
202                    }
203    
204                    @Override
205                    protected void doRun() throws Exception {
206                            verifyGroupedModel(_verifiableGroupedModel);
207                    }
208    
209                    private final VerifiableGroupedModel _verifiableGroupedModel;
210    
211            }
212    
213    }