001
014
015 package com.liferay.portal.service.impl;
016
017 import com.liferay.portal.events.StartupHelperUtil;
018 import com.liferay.portal.kernel.dao.db.DB;
019 import com.liferay.portal.kernel.dao.db.DBManagerUtil;
020 import com.liferay.portal.kernel.dao.jdbc.DataAccess;
021 import com.liferay.portal.kernel.exception.NoSuchReleaseException;
022 import com.liferay.portal.kernel.exception.PortalException;
023 import com.liferay.portal.kernel.exception.SystemException;
024 import com.liferay.portal.kernel.log.Log;
025 import com.liferay.portal.kernel.log.LogFactoryUtil;
026 import com.liferay.portal.kernel.model.Release;
027 import com.liferay.portal.kernel.model.ReleaseConstants;
028 import com.liferay.portal.kernel.upgrade.OlderVersionException;
029 import com.liferay.portal.kernel.upgrade.UpgradeProcess;
030 import com.liferay.portal.kernel.upgrade.util.UpgradeProcessUtil;
031 import com.liferay.portal.kernel.util.GetterUtil;
032 import com.liferay.portal.kernel.util.PropsKeys;
033 import com.liferay.portal.kernel.util.StringBundler;
034 import com.liferay.portal.kernel.util.StringUtil;
035 import com.liferay.portal.kernel.util.Validator;
036 import com.liferay.portal.service.base.ReleaseLocalServiceBaseImpl;
037 import com.liferay.portal.util.PropsUtil;
038 import com.liferay.portal.util.PropsValues;
039
040 import java.sql.Connection;
041 import java.sql.PreparedStatement;
042 import java.sql.ResultSet;
043
044 import java.util.Date;
045 import java.util.List;
046 import java.util.Properties;
047
048
051 public class ReleaseLocalServiceImpl extends ReleaseLocalServiceBaseImpl {
052
053 @Override
054 public Release addRelease(String servletContextName, int buildNumber) {
055 Release release = null;
056
057 if (servletContextName.equals(
058 ReleaseConstants.DEFAULT_SERVLET_CONTEXT_NAME)) {
059
060 release = releasePersistence.create(ReleaseConstants.DEFAULT_ID);
061 }
062 else {
063 long releaseId = counterLocalService.increment();
064
065 release = releasePersistence.create(releaseId);
066 }
067
068 Date now = new Date();
069
070 release.setCreateDate(now);
071 release.setModifiedDate(now);
072 release.setServletContextName(servletContextName);
073 release.setBuildNumber(buildNumber);
074
075 if (servletContextName.equals(
076 ReleaseConstants.DEFAULT_SERVLET_CONTEXT_NAME)) {
077
078 release.setTestString(ReleaseConstants.TEST_STRING);
079 }
080
081 releasePersistence.update(release);
082
083 return release;
084 }
085
086 @Override
087 public Release addRelease(String servletContextName, String schemaVersion) {
088 Release release = null;
089
090 if (servletContextName.equals(
091 ReleaseConstants.DEFAULT_SERVLET_CONTEXT_NAME)) {
092
093 release = releasePersistence.create(ReleaseConstants.DEFAULT_ID);
094 }
095
096 else {
097 long releaseId = counterLocalService.increment();
098
099 release = releasePersistence.create(releaseId);
100 }
101
102 Date now = new Date();
103
104 release.setCreateDate(now);
105 release.setModifiedDate(now);
106 release.setServletContextName(servletContextName);
107 release.setSchemaVersion(schemaVersion);
108
109 if (servletContextName.equals(
110 ReleaseConstants.DEFAULT_SERVLET_CONTEXT_NAME)) {
111
112 release.setTestString(ReleaseConstants.TEST_STRING);
113 }
114
115 releasePersistence.update(release);
116
117 return release;
118 }
119
120 @Override
121 public void createTablesAndPopulate() {
122 try {
123 if (_log.isInfoEnabled()) {
124 _log.info("Create tables and populate with default data");
125 }
126
127 DB db = DBManagerUtil.getDB();
128
129 db.runSQLTemplate("portal-tables.sql", false);
130 db.runSQLTemplate("portal-data-common.sql", false);
131 db.runSQLTemplate("portal-data-counter.sql", false);
132 db.runSQLTemplate("portal-data-release.sql", false);
133 db.runSQLTemplate("indexes.sql", false);
134 db.runSQLTemplate("sequences.sql", false);
135
136 StartupHelperUtil.setDbNew(true);
137 }
138 catch (Exception e) {
139 _log.error(e, e);
140
141 throw new SystemException(e);
142 }
143 }
144
145 @Override
146 public Release fetchRelease(String servletContextName) {
147 if (Validator.isNull(servletContextName)) {
148 throw new IllegalArgumentException("Servlet context name is null");
149 }
150
151 Release release = null;
152
153 if (servletContextName.equals(
154 ReleaseConstants.DEFAULT_SERVLET_CONTEXT_NAME)) {
155
156 release = releasePersistence.fetchByPrimaryKey(
157 ReleaseConstants.DEFAULT_ID);
158 }
159 else {
160 release = releasePersistence.fetchByServletContextName(
161 servletContextName);
162 }
163
164 return release;
165 }
166
167 @Override
168 public int getBuildNumberOrCreate() throws PortalException {
169
170
171
172 DB db = DBManagerUtil.getDB();
173
174 try {
175 db.runSQL(
176 "alter table Release_ add schemaVersion VARCHAR(75) null");
177
178 populateVersion();
179 }
180 catch (Exception e) {
181 if (_log.isDebugEnabled()) {
182 _log.debug(e.getMessage());
183 }
184 }
185
186
187
188 Connection con = null;
189 PreparedStatement ps = null;
190 ResultSet rs = null;
191
192 try {
193 con = DataAccess.getConnection();
194
195 ps = con.prepareStatement(_GET_BUILD_NUMBER);
196
197 ps.setLong(1, ReleaseConstants.DEFAULT_ID);
198
199 rs = ps.executeQuery();
200
201 if (rs.next()) {
202 int buildNumber = rs.getInt("buildNumber");
203
204 if (_log.isDebugEnabled()) {
205 _log.debug("Build number " + buildNumber);
206 }
207
208
209
210 try {
211 db.runSQL("alter table Release_ add state_ INTEGER");
212 }
213 catch (Exception e) {
214 if (_log.isDebugEnabled()) {
215 _log.debug(e.getMessage());
216 }
217 }
218
219 testSupportsStringCaseSensitiveQuery();
220
221 return buildNumber;
222 }
223 }
224 catch (Exception e) {
225 if (_log.isWarnEnabled()) {
226 _log.warn(e.getMessage());
227 }
228 }
229 finally {
230 DataAccess.cleanUp(con, ps, rs);
231 }
232
233
234
235 if (GetterUtil.getBoolean(
236 PropsUtil.get(PropsKeys.SCHEMA_RUN_ENABLED))) {
237
238 releaseLocalService.createTablesAndPopulate();
239
240 testSupportsStringCaseSensitiveQuery();
241
242 Release release = fetchRelease(
243 ReleaseConstants.DEFAULT_SERVLET_CONTEXT_NAME);
244
245 return release.getBuildNumber();
246 }
247 else {
248 throw new NoSuchReleaseException(
249 "The database needs to be populated");
250 }
251 }
252
253 @Override
254 public Release updateRelease(
255 long releaseId, String schemaVersion, int buildNumber,
256 Date buildDate, boolean verified)
257 throws PortalException {
258
259 Release release = releasePersistence.findByPrimaryKey(releaseId);
260
261 release.setModifiedDate(new Date());
262 release.setSchemaVersion(schemaVersion);
263 release.setBuildNumber(buildNumber);
264 release.setBuildDate(buildDate);
265 release.setVerified(verified);
266
267 releasePersistence.update(release);
268
269 return release;
270 }
271
272 @Override
273 public void updateRelease(
274 String servletContextName, List<UpgradeProcess> upgradeProcesses,
275 int buildNumber, int previousBuildNumber, boolean indexOnUpgrade)
276 throws PortalException {
277
278 if (buildNumber <= 0) {
279 _log.error(
280 "Skipping upgrade processes for " + servletContextName +
281 " because \"release.info.build.number\" is not specified");
282
283 return;
284 }
285
286 Release release = releaseLocalService.fetchRelease(servletContextName);
287
288 if (release == null) {
289 release = releaseLocalService.addRelease(
290 servletContextName, previousBuildNumber);
291 }
292
293 if (buildNumber == release.getBuildNumber()) {
294 if (_log.isDebugEnabled()) {
295 _log.debug(
296 "Skipping upgrade processes for " + servletContextName +
297 " because it is already up to date");
298 }
299 }
300 else if (buildNumber < release.getBuildNumber()) {
301 throw new OlderVersionException(
302 "Skipping upgrade processes for " + servletContextName +
303 " because you are trying to upgrade with an older version");
304 }
305 else {
306 UpgradeProcessUtil.upgradeProcess(
307 release.getBuildNumber(), upgradeProcesses, indexOnUpgrade);
308 }
309
310 releaseLocalService.updateRelease(
311 release.getReleaseId(), release.getSchemaVersion(), buildNumber,
312 null, true);
313 }
314
315 @Override
316 public void updateRelease(
317 String servletContextName, List<UpgradeProcess> upgradeProcesses,
318 Properties unfilteredPortalProperties)
319 throws Exception {
320
321 int buildNumber = GetterUtil.getInteger(
322 unfilteredPortalProperties.getProperty(
323 PropsKeys.RELEASE_INFO_BUILD_NUMBER));
324 int previousBuildNumber = GetterUtil.getInteger(
325 unfilteredPortalProperties.getProperty(
326 PropsKeys.RELEASE_INFO_PREVIOUS_BUILD_NUMBER),
327 buildNumber);
328 boolean indexOnUpgrade = GetterUtil.getBoolean(
329 unfilteredPortalProperties.getProperty(PropsKeys.INDEX_ON_UPGRADE),
330 PropsValues.INDEX_ON_UPGRADE);
331
332 updateRelease(
333 servletContextName, upgradeProcesses, buildNumber,
334 previousBuildNumber, indexOnUpgrade);
335 }
336
337 @Override
338 public void updateRelease(
339 String servletContextName, String schemaVersion,
340 String previousSchemaVersion) {
341
342 Release release = releaseLocalService.fetchRelease(servletContextName);
343
344 if (release == null) {
345 if (previousSchemaVersion.equals("0.0.0")) {
346 release = releaseLocalService.addRelease(
347 servletContextName, previousSchemaVersion);
348 }
349 else {
350 throw new IllegalStateException(
351 "Unable to update release because it does not exist");
352 }
353 }
354
355 String currentSchemaVersion = release.getSchemaVersion();
356
357 if (Validator.isNull(currentSchemaVersion)) {
358 currentSchemaVersion = "0.0.0";
359 }
360
361 if (!previousSchemaVersion.equals(currentSchemaVersion)) {
362 StringBundler sb = new StringBundler(5);
363
364 sb.append("Unable to update release because the previous schema ");
365 sb.append("version ");
366 sb.append(previousSchemaVersion);
367 sb.append(" does not match the expected schema version ");
368 sb.append(currentSchemaVersion);
369
370 throw new IllegalStateException(sb.toString());
371 }
372
373 release.setSchemaVersion(schemaVersion);
374
375 releasePersistence.update(release);
376 }
377
378 protected void populateVersion() {
379
380
381
382
383 }
384
385 protected void testSupportsStringCaseSensitiveQuery() {
386 DB db = DBManagerUtil.getDB();
387
388 int count = testSupportsStringCaseSensitiveQuery(
389 ReleaseConstants.TEST_STRING);
390
391 if (count == 0) {
392 try {
393 db.runSQL(
394 "alter table Release_ add testString VARCHAR(1024) null");
395 }
396 catch (Exception e) {
397 if (_log.isDebugEnabled()) {
398 _log.debug(e.getMessage());
399 }
400 }
401
402 try {
403 db.runSQL(
404 "update Release_ set testString = '" +
405 ReleaseConstants.TEST_STRING + "'");
406 }
407 catch (Exception e) {
408 if (_log.isDebugEnabled()) {
409 _log.debug(e.getMessage());
410 }
411 }
412
413 count = testSupportsStringCaseSensitiveQuery(
414 ReleaseConstants.TEST_STRING);
415 }
416
417 if (count == 0) {
418 throw new SystemException(
419 "Release_ table was not initialized properly");
420 }
421
422 count = testSupportsStringCaseSensitiveQuery(
423 StringUtil.toUpperCase(ReleaseConstants.TEST_STRING));
424
425 if (count == 0) {
426 db.setSupportsStringCaseSensitiveQuery(true);
427 }
428 else {
429 db.setSupportsStringCaseSensitiveQuery(false);
430 }
431 }
432
433 protected int testSupportsStringCaseSensitiveQuery(String testString) {
434 int count = 0;
435
436 Connection con = null;
437 PreparedStatement ps = null;
438 ResultSet rs = null;
439
440 try {
441 con = DataAccess.getConnection();
442
443 ps = con.prepareStatement(_TEST_DATABASE_STRING_CASE_SENSITIVITY);
444
445 ps.setLong(1, ReleaseConstants.DEFAULT_ID);
446 ps.setString(2, testString);
447
448 rs = ps.executeQuery();
449
450 if (rs.next()) {
451 count = rs.getInt(1);
452 }
453 }
454 catch (Exception e) {
455 if (_log.isWarnEnabled()) {
456 _log.warn(e.getMessage());
457 }
458 }
459 finally {
460 DataAccess.cleanUp(con, ps, rs);
461 }
462
463 return count;
464 }
465
466 private static final String _GET_BUILD_NUMBER =
467 "select buildNumber from Release_ where releaseId = ?";
468
469 private static final String _TEST_DATABASE_STRING_CASE_SENSITIVITY =
470 "select count(*) from Release_ where releaseId = ? and testString = ?";
471
472 private static final Log _log = LogFactoryUtil.getLog(
473 ReleaseLocalServiceImpl.class);
474
475 }