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