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