001
014
015 package com.liferay.portal.service.impl;
016
017 import com.liferay.portal.events.StartupHelperUtil;
018 import com.liferay.portal.exception.NoSuchReleaseException;
019 import com.liferay.portal.kernel.dao.db.DB;
020 import com.liferay.portal.kernel.dao.db.DBManagerUtil;
021 import com.liferay.portal.kernel.dao.jdbc.DataAccess;
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.upgrade.OlderVersionException;
027 import com.liferay.portal.kernel.upgrade.UpgradeProcess;
028 import com.liferay.portal.kernel.upgrade.util.UpgradeProcessUtil;
029 import com.liferay.portal.kernel.util.GetterUtil;
030 import com.liferay.portal.kernel.util.PropsKeys;
031 import com.liferay.portal.kernel.util.StringBundler;
032 import com.liferay.portal.kernel.util.StringUtil;
033 import com.liferay.portal.kernel.util.Validator;
034 import com.liferay.portal.model.Release;
035 import com.liferay.portal.model.ReleaseConstants;
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, int buildNumber, Date buildDate, boolean verified)
256 throws PortalException {
257
258 Release release = releasePersistence.findByPrimaryKey(releaseId);
259
260 release.setModifiedDate(new Date());
261 release.setBuildNumber(buildNumber);
262 release.setBuildDate(buildDate);
263 release.setVerified(verified);
264
265 releasePersistence.update(release);
266
267 return release;
268 }
269
270 @Override
271 public void updateRelease(
272 String servletContextName, List<UpgradeProcess> upgradeProcesses,
273 int buildNumber, int previousBuildNumber, boolean indexOnUpgrade)
274 throws PortalException {
275
276 if (buildNumber <= 0) {
277 _log.error(
278 "Skipping upgrade processes for " + servletContextName +
279 " because \"release.info.build.number\" is not specified");
280
281 return;
282 }
283
284 Release release = releaseLocalService.fetchRelease(servletContextName);
285
286 if (release == null) {
287 release = releaseLocalService.addRelease(
288 servletContextName, previousBuildNumber);
289 }
290
291 if (buildNumber == release.getBuildNumber()) {
292 if (_log.isDebugEnabled()) {
293 _log.debug(
294 "Skipping upgrade processes for " + servletContextName +
295 " because it is already up to date");
296 }
297 }
298 else if (buildNumber < release.getBuildNumber()) {
299 throw new OlderVersionException(
300 "Skipping upgrade processes for " + servletContextName +
301 " because you are trying to upgrade with an older version");
302 }
303 else {
304 UpgradeProcessUtil.upgradeProcess(
305 release.getBuildNumber(), upgradeProcesses, indexOnUpgrade);
306 }
307
308 releaseLocalService.updateRelease(
309 release.getReleaseId(), buildNumber, null, true);
310 }
311
312 @Override
313 public void updateRelease(
314 String servletContextName, List<UpgradeProcess> upgradeProcesses,
315 Properties unfilteredPortalProperties)
316 throws Exception {
317
318 int buildNumber = GetterUtil.getInteger(
319 unfilteredPortalProperties.getProperty(
320 PropsKeys.RELEASE_INFO_BUILD_NUMBER));
321 int previousBuildNumber = GetterUtil.getInteger(
322 unfilteredPortalProperties.getProperty(
323 PropsKeys.RELEASE_INFO_PREVIOUS_BUILD_NUMBER),
324 buildNumber);
325 boolean indexOnUpgrade = GetterUtil.getBoolean(
326 unfilteredPortalProperties.getProperty(PropsKeys.INDEX_ON_UPGRADE),
327 PropsValues.INDEX_ON_UPGRADE);
328
329 updateRelease(
330 servletContextName, upgradeProcesses, buildNumber,
331 previousBuildNumber, indexOnUpgrade);
332 }
333
334 @Override
335 public void updateRelease(
336 String servletContextName, String schemaVersion,
337 String previousSchemaVersion) {
338
339 Release release = releaseLocalService.fetchRelease(servletContextName);
340
341 if (release == null) {
342 if (previousSchemaVersion.equals("0.0.0")) {
343 release = releaseLocalService.addRelease(
344 servletContextName, previousSchemaVersion);
345 }
346 else {
347 throw new IllegalStateException(
348 "Unable to update release because it does not exist");
349 }
350 }
351
352 String currentSchemaVersion = release.getSchemaVersion();
353
354 if (Validator.isNull(currentSchemaVersion)) {
355 currentSchemaVersion = "0.0.0";
356 }
357
358 if (!previousSchemaVersion.equals(currentSchemaVersion)) {
359 StringBundler sb = new StringBundler(5);
360
361 sb.append("Unable to update release because the previous schema ");
362 sb.append("version ");
363 sb.append(previousSchemaVersion);
364 sb.append(" does not match the expected schema version ");
365 sb.append(currentSchemaVersion);
366
367 throw new IllegalStateException(sb.toString());
368 }
369
370 release.setSchemaVersion(schemaVersion);
371
372 releasePersistence.update(release);
373 }
374
375 protected void populateVersion() {
376
377
378
379
380 }
381
382 protected void testSupportsStringCaseSensitiveQuery() {
383 DB db = DBManagerUtil.getDB();
384
385 int count = testSupportsStringCaseSensitiveQuery(
386 ReleaseConstants.TEST_STRING);
387
388 if (count == 0) {
389 try {
390 db.runSQL(
391 "alter table Release_ add testString VARCHAR(1024) null");
392 }
393 catch (Exception e) {
394 if (_log.isDebugEnabled()) {
395 _log.debug(e.getMessage());
396 }
397 }
398
399 try {
400 db.runSQL(
401 "update Release_ set testString = '" +
402 ReleaseConstants.TEST_STRING + "'");
403 }
404 catch (Exception e) {
405 if (_log.isDebugEnabled()) {
406 _log.debug(e.getMessage());
407 }
408 }
409
410 count = testSupportsStringCaseSensitiveQuery(
411 ReleaseConstants.TEST_STRING);
412 }
413
414 if (count == 0) {
415 throw new SystemException(
416 "Release_ table was not initialized properly");
417 }
418
419 count = testSupportsStringCaseSensitiveQuery(
420 StringUtil.toUpperCase(ReleaseConstants.TEST_STRING));
421
422 if (count == 0) {
423 db.setSupportsStringCaseSensitiveQuery(true);
424 }
425 else {
426 db.setSupportsStringCaseSensitiveQuery(false);
427 }
428 }
429
430 protected int testSupportsStringCaseSensitiveQuery(String testString) {
431 int count = 0;
432
433 Connection con = null;
434 PreparedStatement ps = null;
435 ResultSet rs = null;
436
437 try {
438 con = DataAccess.getConnection();
439
440 ps = con.prepareStatement(_TEST_DATABASE_STRING_CASE_SENSITIVITY);
441
442 ps.setLong(1, ReleaseConstants.DEFAULT_ID);
443 ps.setString(2, testString);
444
445 rs = ps.executeQuery();
446
447 if (rs.next()) {
448 count = rs.getInt(1);
449 }
450 }
451 catch (Exception e) {
452 if (_log.isWarnEnabled()) {
453 _log.warn(e.getMessage());
454 }
455 }
456 finally {
457 DataAccess.cleanUp(con, ps, rs);
458 }
459
460 return count;
461 }
462
463 private static final String _GET_BUILD_NUMBER =
464 "select buildNumber from Release_ where releaseId = ?";
465
466 private static final String _TEST_DATABASE_STRING_CASE_SENSITIVITY =
467 "select count(*) from Release_ where releaseId = ? and testString = ?";
468
469 private static final Log _log = LogFactoryUtil.getLog(
470 ReleaseLocalServiceImpl.class);
471
472 }