001
014
015 package com.liferay.portal.service.impl;
016
017 import com.liferay.portal.NoSuchReleaseException;
018 import com.liferay.portal.events.StartupHelperUtil;
019 import com.liferay.portal.kernel.dao.db.DB;
020 import com.liferay.portal.kernel.dao.db.DBFactoryUtil;
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.StringUtil;
032 import com.liferay.portal.kernel.util.Validator;
033 import com.liferay.portal.model.Release;
034 import com.liferay.portal.model.ReleaseConstants;
035 import com.liferay.portal.service.base.ReleaseLocalServiceBaseImpl;
036 import com.liferay.portal.util.PropsUtil;
037 import com.liferay.portal.util.PropsValues;
038
039 import java.sql.Connection;
040 import java.sql.PreparedStatement;
041 import java.sql.ResultSet;
042
043 import java.util.Date;
044 import java.util.List;
045 import java.util.Properties;
046
047
050 public class ReleaseLocalServiceImpl extends ReleaseLocalServiceBaseImpl {
051
052 @Override
053 public Release addRelease(String servletContextName, int buildNumber) {
054 Release release = null;
055
056 if (servletContextName.equals(
057 ReleaseConstants.DEFAULT_SERVLET_CONTEXT_NAME)) {
058
059 release = releasePersistence.create(ReleaseConstants.DEFAULT_ID);
060 }
061 else {
062 long releaseId = counterLocalService.increment();
063
064 release = releasePersistence.create(releaseId);
065 }
066
067 Date now = new Date();
068
069 release.setCreateDate(now);
070 release.setModifiedDate(now);
071 release.setServletContextName(servletContextName);
072 release.setBuildNumber(buildNumber);
073
074 if (servletContextName.equals(
075 ReleaseConstants.DEFAULT_SERVLET_CONTEXT_NAME)) {
076
077 release.setTestString(ReleaseConstants.TEST_STRING);
078 }
079
080 releasePersistence.update(release);
081
082 return release;
083 }
084
085 @Override
086 public void createTablesAndPopulate() {
087 try {
088 if (_log.isInfoEnabled()) {
089 _log.info("Create tables and populate with default data");
090 }
091
092 DB db = DBFactoryUtil.getDB();
093
094 db.runSQLTemplate("portal-tables.sql", false);
095 db.runSQLTemplate("portal-data-common.sql", false);
096 db.runSQLTemplate("portal-data-counter.sql", false);
097 db.runSQLTemplate("portal-data-release.sql", false);
098 db.runSQLTemplate("indexes.sql", false);
099 db.runSQLTemplate("sequences.sql", false);
100
101 StartupHelperUtil.setDbNew(true);
102 }
103 catch (Exception e) {
104 _log.error(e, e);
105
106 throw new SystemException(e);
107 }
108 }
109
110 @Override
111 public Release fetchRelease(String servletContextName) {
112 if (Validator.isNull(servletContextName)) {
113 throw new IllegalArgumentException("Servlet context name is null");
114 }
115
116 Release release = null;
117
118 if (servletContextName.equals(
119 ReleaseConstants.DEFAULT_SERVLET_CONTEXT_NAME)) {
120
121 release = releasePersistence.fetchByPrimaryKey(
122 ReleaseConstants.DEFAULT_ID);
123 }
124 else {
125 release = releasePersistence.fetchByServletContextName(
126 servletContextName);
127 }
128
129 return release;
130 }
131
132 @Override
133 public int getBuildNumberOrCreate() throws PortalException {
134
135
136
137 Connection con = null;
138 PreparedStatement ps = null;
139 ResultSet rs = null;
140
141 try {
142 con = DataAccess.getConnection();
143
144 ps = con.prepareStatement(_GET_BUILD_NUMBER);
145
146 ps.setLong(1, ReleaseConstants.DEFAULT_ID);
147
148 rs = ps.executeQuery();
149
150 if (rs.next()) {
151 int buildNumber = rs.getInt("buildNumber");
152
153 if (_log.isDebugEnabled()) {
154 _log.debug("Build number " + buildNumber);
155 }
156
157 DB db = DBFactoryUtil.getDB();
158
159 try {
160 db.runSQL("alter table Release_ add state_ INTEGER");
161 }
162 catch (Exception e) {
163 if (_log.isDebugEnabled()) {
164 _log.debug(e.getMessage());
165 }
166 }
167
168 testSupportsStringCaseSensitiveQuery();
169
170 return buildNumber;
171 }
172 }
173 catch (Exception e) {
174 if (_log.isWarnEnabled()) {
175 _log.warn(e.getMessage());
176 }
177 }
178 finally {
179 DataAccess.cleanUp(con, ps, rs);
180 }
181
182
183
184 if (GetterUtil.getBoolean(
185 PropsUtil.get(PropsKeys.SCHEMA_RUN_ENABLED))) {
186
187 releaseLocalService.createTablesAndPopulate();
188
189 testSupportsStringCaseSensitiveQuery();
190
191 Release release = fetchRelease(
192 ReleaseConstants.DEFAULT_SERVLET_CONTEXT_NAME);
193
194 return release.getBuildNumber();
195 }
196 else {
197 throw new NoSuchReleaseException(
198 "The database needs to be populated");
199 }
200 }
201
202 @Override
203 public Release updateRelease(
204 long releaseId, int buildNumber, Date buildDate, boolean verified)
205 throws PortalException {
206
207 Release release = releasePersistence.findByPrimaryKey(releaseId);
208
209 release.setModifiedDate(new Date());
210 release.setBuildNumber(buildNumber);
211 release.setBuildDate(buildDate);
212 release.setVerified(verified);
213
214 releasePersistence.update(release);
215
216 return release;
217 }
218
219 @Override
220 public void updateRelease(
221 String servletContextName, List<UpgradeProcess> upgradeProcesses,
222 int buildNumber, int previousBuildNumber, boolean indexOnUpgrade)
223 throws PortalException {
224
225 if (buildNumber <= 0) {
226 _log.error(
227 "Skipping upgrade processes for " + servletContextName +
228 " because \"release.info.build.number\" is not specified");
229
230 return;
231 }
232
233 Release release = releaseLocalService.fetchRelease(servletContextName);
234
235 if (release == null) {
236 release = releaseLocalService.addRelease(
237 servletContextName, previousBuildNumber);
238 }
239
240 if (buildNumber == release.getBuildNumber()) {
241 if (_log.isDebugEnabled()) {
242 _log.debug(
243 "Skipping upgrade processes for " + servletContextName +
244 " because it is already up to date");
245 }
246 }
247 else if (buildNumber < release.getBuildNumber()) {
248 throw new OlderVersionException(
249 "Skipping upgrade processes for " + servletContextName +
250 " because you are trying to upgrade with an older version");
251 }
252 else {
253 UpgradeProcessUtil.upgradeProcess(
254 release.getBuildNumber(), upgradeProcesses, indexOnUpgrade);
255 }
256
257 releaseLocalService.updateRelease(
258 release.getReleaseId(), buildNumber, null, true);
259 }
260
261 @Override
262 public void updateRelease(
263 String servletContextName, List<UpgradeProcess> upgradeProcesses,
264 Properties unfilteredPortalProperties)
265 throws Exception {
266
267 int buildNumber = GetterUtil.getInteger(
268 unfilteredPortalProperties.getProperty(
269 PropsKeys.RELEASE_INFO_BUILD_NUMBER));
270 int previousBuildNumber = GetterUtil.getInteger(
271 unfilteredPortalProperties.getProperty(
272 PropsKeys.RELEASE_INFO_PREVIOUS_BUILD_NUMBER),
273 buildNumber);
274 boolean indexOnUpgrade = GetterUtil.getBoolean(
275 unfilteredPortalProperties.getProperty(PropsKeys.INDEX_ON_UPGRADE),
276 PropsValues.INDEX_ON_UPGRADE);
277
278 updateRelease(
279 servletContextName, upgradeProcesses, buildNumber,
280 previousBuildNumber, indexOnUpgrade);
281 }
282
283 protected void testSupportsStringCaseSensitiveQuery() {
284 DB db = DBFactoryUtil.getDB();
285
286 int count = testSupportsStringCaseSensitiveQuery(
287 ReleaseConstants.TEST_STRING);
288
289 if (count == 0) {
290 try {
291 db.runSQL(
292 "alter table Release_ add testString VARCHAR(1024) null");
293 }
294 catch (Exception e) {
295 if (_log.isDebugEnabled()) {
296 _log.debug(e.getMessage());
297 }
298 }
299
300 try {
301 db.runSQL(
302 "update Release_ set testString = '" +
303 ReleaseConstants.TEST_STRING + "'");
304 }
305 catch (Exception e) {
306 if (_log.isDebugEnabled()) {
307 _log.debug(e.getMessage());
308 }
309 }
310
311 count = testSupportsStringCaseSensitiveQuery(
312 ReleaseConstants.TEST_STRING);
313 }
314
315 if (count == 0) {
316 throw new SystemException(
317 "Release_ table was not initialized properly");
318 }
319
320 count = testSupportsStringCaseSensitiveQuery(
321 StringUtil.toUpperCase(ReleaseConstants.TEST_STRING));
322
323 if (count == 0) {
324 db.setSupportsStringCaseSensitiveQuery(true);
325 }
326 else {
327 db.setSupportsStringCaseSensitiveQuery(false);
328 }
329 }
330
331 protected int testSupportsStringCaseSensitiveQuery(String testString) {
332 int count = 0;
333
334 Connection con = null;
335 PreparedStatement ps = null;
336 ResultSet rs = null;
337
338 try {
339 con = DataAccess.getConnection();
340
341 ps = con.prepareStatement(_TEST_DATABASE_STRING_CASE_SENSITIVITY);
342
343 ps.setLong(1, ReleaseConstants.DEFAULT_ID);
344 ps.setString(2, testString);
345
346 rs = ps.executeQuery();
347
348 if (rs.next()) {
349 count = rs.getInt(1);
350 }
351 }
352 catch (Exception e) {
353 if (_log.isWarnEnabled()) {
354 _log.warn(e.getMessage());
355 }
356 }
357 finally {
358 DataAccess.cleanUp(con, ps, rs);
359 }
360
361 return count;
362 }
363
364 private static final String _GET_BUILD_NUMBER =
365 "select buildNumber from Release_ where releaseId = ?";
366
367 private static final String _TEST_DATABASE_STRING_CASE_SENSITIVITY =
368 "select count(*) from Release_ where releaseId = ? and testString = ?";
369
370 private static final Log _log = LogFactoryUtil.getLog(
371 ReleaseLocalServiceImpl.class);
372
373 }