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