001
014
015 package com.liferay.portal.verify;
016
017 import com.liferay.portal.kernel.concurrent.ThrowableAwareRunnable;
018 import com.liferay.portal.kernel.dao.db.BaseDBProcess;
019 import com.liferay.portal.kernel.dao.jdbc.DataAccess;
020 import com.liferay.portal.kernel.exception.BulkException;
021 import com.liferay.portal.kernel.log.Log;
022 import com.liferay.portal.kernel.log.LogFactoryUtil;
023 import com.liferay.portal.kernel.util.ClassLoaderUtil;
024 import com.liferay.portal.kernel.util.ClassUtil;
025 import com.liferay.portal.kernel.util.StringUtil;
026 import com.liferay.portal.model.ReleaseConstants;
027 import com.liferay.portal.util.PropsValues;
028
029 import java.sql.Connection;
030 import java.sql.PreparedStatement;
031 import java.sql.ResultSet;
032
033 import java.util.ArrayList;
034 import java.util.Collection;
035 import java.util.HashSet;
036 import java.util.List;
037 import java.util.Set;
038 import java.util.concurrent.Callable;
039 import java.util.concurrent.ExecutorService;
040 import java.util.concurrent.Executors;
041 import java.util.concurrent.Future;
042 import java.util.regex.Matcher;
043 import java.util.regex.Pattern;
044
045
055 public abstract class VerifyProcess extends BaseDBProcess {
056
057 public static final int ALWAYS = -1;
058
059 public static final int NEVER = 0;
060
061 public static final int ONCE = 1;
062
063 public void verify() throws VerifyException {
064 long start = System.currentTimeMillis();
065
066 if (_log.isInfoEnabled()) {
067 _log.info("Verifying " + ClassUtil.getClassName(this));
068 }
069
070 try (Connection con = DataAccess.getUpgradeOptimizedConnection()) {
071 connection = con;
072
073 doVerify();
074 }
075 catch (Exception e) {
076 throw new VerifyException(e);
077 }
078 finally {
079 connection = null;
080
081 if (_log.isInfoEnabled()) {
082 _log.info(
083 "Completed verification process " +
084 ClassUtil.getClassName(this) + " in " +
085 (System.currentTimeMillis() - start) + "ms");
086 }
087 }
088 }
089
090 public void verify(VerifyProcess verifyProcess) throws VerifyException {
091 verifyProcess.verify();
092 }
093
094 protected void doVerify() throws Exception {
095 }
096
097 protected void doVerify(
098 Collection<? extends ThrowableAwareRunnable>
099 throwableAwareRunnables)
100 throws Exception {
101
102 if (throwableAwareRunnables.size() <
103 PropsValues.VERIFY_PROCESS_CONCURRENCY_THRESHOLD) {
104
105 for (ThrowableAwareRunnable throwableAwareRunnable :
106 throwableAwareRunnables) {
107
108 throwableAwareRunnable.run();
109 }
110 }
111 else {
112 ExecutorService executorService = Executors.newFixedThreadPool(
113 throwableAwareRunnables.size());
114
115 List<Callable<Object>> jobs = new ArrayList<>(
116 throwableAwareRunnables.size());
117
118 for (Runnable runnable : throwableAwareRunnables) {
119 jobs.add(Executors.callable(runnable));
120 }
121
122 try {
123 List<Future<Object>> futures = executorService.invokeAll(jobs);
124
125 for (Future<Object> future : futures) {
126 future.get();
127 }
128 }
129 finally {
130 executorService.shutdown();
131 }
132 }
133
134 List<Throwable> throwables = new ArrayList<>();
135
136 for (ThrowableAwareRunnable throwableAwareRunnable :
137 throwableAwareRunnables) {
138
139 if (throwableAwareRunnable.hasException()) {
140 throwables.add(throwableAwareRunnable.getThrowable());
141 }
142 }
143
144 if (!throwables.isEmpty()) {
145 throw new BulkException(
146 "Verification error: " + getClass().getName(), throwables);
147 }
148 }
149
150
156 protected int getBuildNumber() throws Exception {
157 PreparedStatement ps = null;
158 ResultSet rs = null;
159
160 try {
161 ps = connection.prepareStatement(
162 "select buildNumber from Release_ where servletContextName " +
163 "= ?");
164
165 ps.setString(1, ReleaseConstants.DEFAULT_SERVLET_CONTEXT_NAME);
166
167 rs = ps.executeQuery();
168
169 rs.next();
170
171 return rs.getInt(1);
172 }
173 finally {
174 DataAccess.cleanUp(ps, rs);
175 }
176 }
177
178 protected Set<String> getPortalTableNames() throws Exception {
179 if (_portalTableNames != null) {
180 return _portalTableNames;
181 }
182
183 ClassLoader classLoader = ClassLoaderUtil.getContextClassLoader();
184
185 String sql = StringUtil.read(
186 classLoader,
187 "com/liferay/portal/tools/sql/dependencies/portal-tables.sql");
188
189 Matcher matcher = _createTablePattern.matcher(sql);
190
191 Set<String> tableNames = new HashSet<>();
192
193 while (matcher.find()) {
194 String match = matcher.group(1);
195
196 tableNames.add(StringUtil.toLowerCase(match));
197 }
198
199 _portalTableNames = tableNames;
200
201 return tableNames;
202 }
203
204 protected boolean isPortalTableName(String tableName) throws Exception {
205 Set<String> portalTableNames = getPortalTableNames();
206
207 return portalTableNames.contains(StringUtil.toLowerCase(tableName));
208 }
209
210 private static final Log _log = LogFactoryUtil.getLog(VerifyProcess.class);
211
212 private final Pattern _createTablePattern = Pattern.compile(
213 "create table (\\S*) \\(");
214 private Set<String> _portalTableNames;
215
216 }