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