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.StringUtil;
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);
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 Release fetchRelease(String servletContextName)
112                    throws SystemException {
113    
114                    if (Validator.isNull(servletContextName)) {
115                            throw new IllegalArgumentException("Servlet context name is null");
116                    }
117    
118                    Release release = null;
119    
120                    if (servletContextName.equals(
121                                    ReleaseConstants.DEFAULT_SERVLET_CONTEXT_NAME)) {
122    
123                            release = releasePersistence.fetchByPrimaryKey(
124                                    ReleaseConstants.DEFAULT_ID);
125                    }
126                    else {
127                            release = releasePersistence.fetchByServletContextName(
128                                    servletContextName);
129                    }
130    
131                    return release;
132            }
133    
134            @Override
135            public int getBuildNumberOrCreate()
136                    throws PortalException, SystemException {
137    
138                    // Get release build number
139    
140                    Connection con = null;
141                    PreparedStatement ps = null;
142                    ResultSet rs = null;
143    
144                    try {
145                            con = DataAccess.getConnection();
146    
147                            ps = con.prepareStatement(_GET_BUILD_NUMBER);
148    
149                            ps.setLong(1, ReleaseConstants.DEFAULT_ID);
150    
151                            rs = ps.executeQuery();
152    
153                            if (rs.next()) {
154                                    int buildNumber = rs.getInt("buildNumber");
155    
156                                    if (_log.isDebugEnabled()) {
157                                            _log.debug("Build number " + buildNumber);
158                                    }
159    
160                                    DB db = DBFactoryUtil.getDB();
161    
162                                    try {
163                                            db.runSQL("alter table Release_ add state_ INTEGER");
164                                    }
165                                    catch (Exception e) {
166                                            if (_log.isDebugEnabled()) {
167                                                    _log.debug(e.getMessage());
168                                            }
169                                    }
170    
171                                    testSupportsStringCaseSensitiveQuery();
172    
173                                    return buildNumber;
174                            }
175                    }
176                    catch (Exception e) {
177                            if (_log.isWarnEnabled()) {
178                                    _log.warn(e.getMessage());
179                            }
180                    }
181                    finally {
182                            DataAccess.cleanUp(con, ps, rs);
183                    }
184    
185                    // Create tables and populate with default data
186    
187                    if (GetterUtil.getBoolean(
188                                    PropsUtil.get(PropsKeys.SCHEMA_RUN_ENABLED))) {
189    
190                            releaseLocalService.createTablesAndPopulate();
191    
192                            testSupportsStringCaseSensitiveQuery();
193    
194                            Release release = fetchRelease(
195                                    ReleaseConstants.DEFAULT_SERVLET_CONTEXT_NAME);
196    
197                            return release.getBuildNumber();
198                    }
199                    else {
200                            throw new NoSuchReleaseException(
201                                    "The database needs to be populated");
202                    }
203            }
204    
205            @Override
206            public Release updateRelease(
207                            long releaseId, int buildNumber, Date buildDate, boolean verified)
208                    throws PortalException, SystemException {
209    
210                    Release release = releasePersistence.findByPrimaryKey(releaseId);
211    
212                    release.setModifiedDate(new Date());
213                    release.setBuildNumber(buildNumber);
214                    release.setBuildDate(buildDate);
215                    release.setVerified(verified);
216    
217                    releasePersistence.update(release);
218    
219                    return release;
220            }
221    
222            protected void testSupportsStringCaseSensitiveQuery()
223                    throws SystemException {
224    
225                    DB db = DBFactoryUtil.getDB();
226    
227                    int count = testSupportsStringCaseSensitiveQuery(
228                            ReleaseConstants.TEST_STRING);
229    
230                    if (count == 0) {
231                            try {
232                                    db.runSQL(
233                                            "alter table Release_ add testString VARCHAR(1024) null");
234                            }
235                            catch (Exception e) {
236                                    if (_log.isDebugEnabled()) {
237                                            _log.debug(e.getMessage());
238                                    }
239                            }
240    
241                            try {
242                                    db.runSQL(
243                                            "update Release_ set testString = '" +
244                                                    ReleaseConstants.TEST_STRING + "'");
245                            }
246                            catch (Exception e) {
247                                    if (_log.isDebugEnabled()) {
248                                            _log.debug(e.getMessage());
249                                    }
250                            }
251    
252                            count = testSupportsStringCaseSensitiveQuery(
253                                    ReleaseConstants.TEST_STRING);
254                    }
255    
256                    if (count == 0) {
257                            throw new SystemException(
258                                    "Release_ table was not initialized properly");
259                    }
260    
261                    count = testSupportsStringCaseSensitiveQuery(
262                            StringUtil.toUpperCase(ReleaseConstants.TEST_STRING));
263    
264                    if (count == 0) {
265                            db.setSupportsStringCaseSensitiveQuery(true);
266                    }
267                    else {
268                            db.setSupportsStringCaseSensitiveQuery(false);
269                    }
270            }
271    
272            protected int testSupportsStringCaseSensitiveQuery(String testString) {
273                    int count = 0;
274    
275                    Connection con = null;
276                    PreparedStatement ps = null;
277                    ResultSet rs = null;
278    
279                    try {
280                            con = DataAccess.getConnection();
281    
282                            ps = con.prepareStatement(_TEST_DATABASE_STRING_CASE_SENSITIVITY);
283    
284                            ps.setLong(1, ReleaseConstants.DEFAULT_ID);
285                            ps.setString(2, testString);
286    
287                            rs = ps.executeQuery();
288    
289                            if (rs.next()) {
290                                    count = rs.getInt(1);
291                            }
292                    }
293                    catch (Exception e) {
294                            if (_log.isWarnEnabled()) {
295                                    _log.warn(e.getMessage());
296                            }
297                    }
298                    finally {
299                            DataAccess.cleanUp(con, ps, rs);
300                    }
301    
302                    return count;
303            }
304    
305            private static final String _GET_BUILD_NUMBER =
306                    "select buildNumber from Release_ where releaseId = ?";
307    
308            private static final String _TEST_DATABASE_STRING_CASE_SENSITIVITY =
309                    "select count(*) from Release_ where releaseId = ? and testString = ?";
310    
311            private static Log _log = LogFactoryUtil.getLog(
312                    ReleaseLocalServiceImpl.class);
313    
314    }