001    /**
002     * Copyright (c) 2000-2013 Liferay, Inc. All rights reserved.
003     *
004     * This library is free software; you can redistribute it and/or modify it under
005     * the terms of the GNU Lesser General Public License as published by the Free
006     * Software Foundation; either version 2.1 of the License, or (at your option)
007     * any later version.
008     *
009     * This library is distributed in the hope that it will be useful, but WITHOUT
010     * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
011     * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
012     * details.
013     */
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.dao.shard.ShardUtil;
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.util.GetterUtil;
027    import com.liferay.portal.kernel.util.PropsKeys;
028    import com.liferay.portal.kernel.util.Validator;
029    import com.liferay.portal.model.Release;
030    import com.liferay.portal.model.ReleaseConstants;
031    import com.liferay.portal.service.base.ReleaseLocalServiceBaseImpl;
032    import com.liferay.portal.util.PropsUtil;
033    import com.liferay.portal.util.PropsValues;
034    
035    import java.sql.Connection;
036    import java.sql.PreparedStatement;
037    import java.sql.ResultSet;
038    
039    import java.util.Date;
040    
041    /**
042     * @author Brian Wing Shun Chan
043     */
044    public class ReleaseLocalServiceImpl extends ReleaseLocalServiceBaseImpl {
045    
046            @Override
047            public Release addRelease(String servletContextName, int buildNumber)
048                    throws SystemException {
049    
050                    Release release = null;
051    
052                    if (servletContextName.equals(
053                                    ReleaseConstants.DEFAULT_SERVLET_CONTEXT_NAME)) {
054    
055                            release = releasePersistence.create(ReleaseConstants.DEFAULT_ID);
056                    }
057                    else {
058                            long releaseId = counterLocalService.increment();
059    
060                            release = releasePersistence.create(releaseId);
061                    }
062    
063                    Date now = new Date();
064    
065                    release.setCreateDate(now);
066                    release.setModifiedDate(now);
067                    release.setServletContextName(servletContextName);
068                    release.setBuildNumber(buildNumber);
069    
070                    if (servletContextName.equals(
071                                    ReleaseConstants.DEFAULT_SERVLET_CONTEXT_NAME)) {
072    
073                            release.setTestString(ReleaseConstants.TEST_STRING);
074                    }
075    
076                    releasePersistence.update(release);
077    
078                    return release;
079            }
080    
081            @Override
082            public void createTablesAndPopulate() throws SystemException {
083                    try {
084                            if (_log.isInfoEnabled()) {
085                                    _log.info("Create tables and populate with default data");
086                            }
087    
088                            DB db = DBFactoryUtil.getDB();
089    
090                            db.runSQLTemplate("portal-tables.sql", false);
091                            db.runSQLTemplate("portal-data-common.sql", false);
092                            db.runSQLTemplate("portal-data-counter.sql", false);
093    
094                            if (!PropsValues.SCHEMA_RUN_MINIMAL && !ShardUtil.isEnabled()) {
095                                    db.runSQLTemplate("portal-data-sample.vm", false);
096                            }
097    
098                            db.runSQLTemplate("portal-data-release.sql", false);
099                            db.runSQLTemplate("indexes.sql", false);
100                            db.runSQLTemplate("sequences.sql", false);
101                    }
102                    catch (Exception e) {
103                            _log.error(e, e);
104    
105                            throw new SystemException(e);
106                    }
107            }
108    
109            @Override
110            public Release fetchRelease(String servletContextName)
111                    throws SystemException {
112    
113                    if (Validator.isNull(servletContextName)) {
114                            throw new IllegalArgumentException("Servlet context name is null");
115                    }
116    
117                    Release release = null;
118    
119                    if (servletContextName.equals(
120                                    ReleaseConstants.DEFAULT_SERVLET_CONTEXT_NAME)) {
121    
122                            release = releasePersistence.fetchByPrimaryKey(
123                                    ReleaseConstants.DEFAULT_ID);
124                    }
125                    else {
126                            release = releasePersistence.fetchByServletContextName(
127                                    servletContextName);
128                    }
129    
130                    return release;
131            }
132    
133            @Override
134            public int getBuildNumberOrCreate()
135                    throws PortalException, SystemException {
136    
137                    // Get release build number
138    
139                    Connection con = null;
140                    PreparedStatement ps = null;
141                    ResultSet rs = null;
142    
143                    try {
144                            con = DataAccess.getConnection();
145    
146                            ps = con.prepareStatement(_GET_BUILD_NUMBER);
147    
148                            ps.setLong(1, ReleaseConstants.DEFAULT_ID);
149    
150                            rs = ps.executeQuery();
151    
152                            if (rs.next()) {
153                                    int buildNumber = rs.getInt("buildNumber");
154    
155                                    if (_log.isDebugEnabled()) {
156                                            _log.debug("Build number " + buildNumber);
157                                    }
158    
159                                    DB db = DBFactoryUtil.getDB();
160    
161                                    try {
162                                            db.runSQL("alter table Release_ add state_ INTEGER");
163                                    }
164                                    catch (Exception e) {
165                                            if (_log.isDebugEnabled()) {
166                                                    _log.debug(e.getMessage());
167                                            }
168                                    }
169    
170                                    testSupportsStringCaseSensitiveQuery();
171    
172                                    return buildNumber;
173                            }
174                    }
175                    catch (Exception e) {
176                            if (_log.isWarnEnabled()) {
177                                    _log.warn(e.getMessage());
178                            }
179                    }
180                    finally {
181                            DataAccess.cleanUp(con, ps, rs);
182                    }
183    
184                    // Create tables and populate with default data
185    
186                    if (GetterUtil.getBoolean(
187                                    PropsUtil.get(PropsKeys.SCHEMA_RUN_ENABLED))) {
188    
189                            releaseLocalService.createTablesAndPopulate();
190    
191                            testSupportsStringCaseSensitiveQuery();
192    
193                            Release release = fetchRelease(
194                                    ReleaseConstants.DEFAULT_SERVLET_CONTEXT_NAME);
195    
196                            return release.getBuildNumber();
197                    }
198                    else {
199                            throw new NoSuchReleaseException(
200                                    "The database needs to be populated");
201                    }
202            }
203    
204            @Override
205            public Release updateRelease(
206                            long releaseId, int buildNumber, Date buildDate, boolean verified)
207                    throws PortalException, SystemException {
208    
209                    Release release = releasePersistence.findByPrimaryKey(releaseId);
210    
211                    release.setModifiedDate(new Date());
212                    release.setBuildNumber(buildNumber);
213                    release.setBuildDate(buildDate);
214                    release.setVerified(verified);
215    
216                    releasePersistence.update(release);
217    
218                    return release;
219            }
220    
221            protected void testSupportsStringCaseSensitiveQuery()
222                    throws SystemException {
223    
224                    DB db = DBFactoryUtil.getDB();
225    
226                    int count = testSupportsStringCaseSensitiveQuery(
227                            ReleaseConstants.TEST_STRING);
228    
229                    if (count == 0) {
230                            try {
231                                    db.runSQL(
232                                            "alter table Release_ add testString VARCHAR(1024) null");
233                            }
234                            catch (Exception e) {
235                                    if (_log.isDebugEnabled()) {
236                                            _log.debug(e.getMessage());
237                                    }
238                            }
239    
240                            try {
241                                    db.runSQL(
242                                            "update Release_ set testString = '" +
243                                                    ReleaseConstants.TEST_STRING + "'");
244                            }
245                            catch (Exception e) {
246                                    if (_log.isDebugEnabled()) {
247                                            _log.debug(e.getMessage());
248                                    }
249                            }
250    
251                            count = testSupportsStringCaseSensitiveQuery(
252                                    ReleaseConstants.TEST_STRING);
253                    }
254    
255                    if (count == 0) {
256                            throw new SystemException(
257                                    "Release_ table was not initialized properly");
258                    }
259    
260                    count = testSupportsStringCaseSensitiveQuery(
261                            ReleaseConstants.TEST_STRING.toUpperCase());
262    
263                    if (count == 0) {
264                            db.setSupportsStringCaseSensitiveQuery(true);
265                    }
266                    else {
267                            db.setSupportsStringCaseSensitiveQuery(false);
268                    }
269            }
270    
271            protected int testSupportsStringCaseSensitiveQuery(String testString) {
272                    int count = 0;
273    
274                    Connection con = null;
275                    PreparedStatement ps = null;
276                    ResultSet rs = null;
277    
278                    try {
279                            con = DataAccess.getConnection();
280    
281                            ps = con.prepareStatement(_TEST_DATABASE_STRING_CASE_SENSITIVITY);
282    
283                            ps.setLong(1, ReleaseConstants.DEFAULT_ID);
284                            ps.setString(2, testString);
285    
286                            rs = ps.executeQuery();
287    
288                            if (rs.next()) {
289                                    count = rs.getInt(1);
290                            }
291                    }
292                    catch (Exception e) {
293                            if (_log.isWarnEnabled()) {
294                                    _log.warn(e.getMessage());
295                            }
296                    }
297                    finally {
298                            DataAccess.cleanUp(con, ps, rs);
299                    }
300    
301                    return count;
302            }
303    
304            private static final String _GET_BUILD_NUMBER =
305                    "select buildNumber from Release_ where releaseId = ?";
306    
307            private static final String _TEST_DATABASE_STRING_CASE_SENSITIVITY =
308                    "select count(*) from Release_ where releaseId = ? and testString = ?";
309    
310            private static Log _log = LogFactoryUtil.getLog(
311                    ReleaseLocalServiceImpl.class);
312    
313    }