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