001    /**
002     * Copyright (c) 2000-2012 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.setup;
016    
017    import com.liferay.portal.NoSuchUserException;
018    import com.liferay.portal.dao.jdbc.util.DataSourceSwapper;
019    import com.liferay.portal.events.StartupAction;
020    import com.liferay.portal.kernel.cache.CacheRegistryUtil;
021    import com.liferay.portal.kernel.cache.MultiVMPoolUtil;
022    import com.liferay.portal.kernel.dao.jdbc.DataAccess;
023    import com.liferay.portal.kernel.dao.jdbc.DataSourceFactoryUtil;
024    import com.liferay.portal.kernel.deploy.hot.HotDeployUtil;
025    import com.liferay.portal.kernel.language.LanguageUtil;
026    import com.liferay.portal.kernel.log.Log;
027    import com.liferay.portal.kernel.log.LogFactoryUtil;
028    import com.liferay.portal.kernel.util.CalendarFactoryUtil;
029    import com.liferay.portal.kernel.util.CentralizedThreadLocal;
030    import com.liferay.portal.kernel.util.FileUtil;
031    import com.liferay.portal.kernel.util.ListUtil;
032    import com.liferay.portal.kernel.util.LocaleUtil;
033    import com.liferay.portal.kernel.util.ParamUtil;
034    import com.liferay.portal.kernel.util.PortalLifecycleUtil;
035    import com.liferay.portal.kernel.util.PropertiesParamUtil;
036    import com.liferay.portal.kernel.util.PropertiesUtil;
037    import com.liferay.portal.kernel.util.PropsKeys;
038    import com.liferay.portal.kernel.util.StringPool;
039    import com.liferay.portal.kernel.util.SystemProperties;
040    import com.liferay.portal.kernel.util.UnicodeProperties;
041    import com.liferay.portal.kernel.util.Validator;
042    import com.liferay.portal.kernel.webcache.WebCachePoolUtil;
043    import com.liferay.portal.model.Account;
044    import com.liferay.portal.model.Company;
045    import com.liferay.portal.model.Contact;
046    import com.liferay.portal.model.User;
047    import com.liferay.portal.security.auth.FullNameGenerator;
048    import com.liferay.portal.security.auth.FullNameGeneratorFactory;
049    import com.liferay.portal.security.auth.ScreenNameGenerator;
050    import com.liferay.portal.security.auth.ScreenNameGeneratorFactory;
051    import com.liferay.portal.service.AccountLocalServiceUtil;
052    import com.liferay.portal.service.CompanyLocalServiceUtil;
053    import com.liferay.portal.service.QuartzLocalServiceUtil;
054    import com.liferay.portal.service.ServiceContext;
055    import com.liferay.portal.service.UserLocalServiceUtil;
056    import com.liferay.portal.theme.ThemeDisplay;
057    import com.liferay.portal.util.PortalInstances;
058    import com.liferay.portal.util.PortalUtil;
059    import com.liferay.portal.util.PropsUtil;
060    import com.liferay.portal.util.PropsValues;
061    import com.liferay.portal.util.WebKeys;
062    
063    import java.io.IOException;
064    
065    import java.sql.Connection;
066    
067    import java.util.Calendar;
068    import java.util.List;
069    import java.util.Locale;
070    import java.util.Properties;
071    
072    import javax.servlet.http.HttpServletRequest;
073    import javax.servlet.http.HttpServletResponse;
074    import javax.servlet.http.HttpSession;
075    
076    import javax.sql.DataSource;
077    
078    import org.apache.struts.Globals;
079    
080    /**
081     * @author Manuel de la Peña
082     * @author Julio Camarero
083     * @author Brian Wing Shun Chan
084     */
085    public class SetupWizardUtil {
086    
087            public static final String PROPERTIES_FILE_NAME =
088                    "portal-setup-wizard.properties";
089    
090            public static boolean isDefaultDatabase(HttpServletRequest request) {
091                    boolean hsqldb = ParamUtil.getBoolean(
092                            request, "defaultDatabase",
093                            PropsValues.JDBC_DEFAULT_URL.contains("hsqldb"));
094    
095                    boolean jndi = Validator.isNotNull(PropsValues.JDBC_DEFAULT_JNDI_NAME);
096    
097                    return hsqldb && !jndi;
098            }
099    
100            public static boolean isSetupFinished() {
101                    if (PropsValues.SETUP_WIZARD_ENABLED) {
102                            return _setupFinished;
103                    }
104    
105                    return true;
106            }
107    
108            public static void setSetupFinished(boolean setupFinished) {
109                    _setupFinished = setupFinished;
110            }
111    
112            public static void testDatabase(HttpServletRequest request)
113                    throws Exception {
114    
115                    String driverClassName = _getParameter(
116                            request, PropsKeys.JDBC_DEFAULT_DRIVER_CLASS_NAME,
117                            PropsValues.JDBC_DEFAULT_DRIVER_CLASS_NAME);
118                    String url = _getParameter(request, PropsKeys.JDBC_DEFAULT_URL, null);
119                    String userName = _getParameter(
120                            request, PropsKeys.JDBC_DEFAULT_USERNAME, null);
121                    String password = _getParameter(
122                            request, PropsKeys.JDBC_DEFAULT_PASSWORD, null);
123    
124                    _testConnection(driverClassName, url, userName, password);
125            }
126    
127            public static void updateLanguage(
128                    HttpServletRequest request, HttpServletResponse response) {
129    
130                    String languageId = _getParameter(
131                            request, PropsKeys.COMPANY_DEFAULT_LOCALE,
132                            PropsValues.COMPANY_DEFAULT_LOCALE);
133    
134                    Locale locale = LocaleUtil.fromLanguageId(languageId);
135    
136                    List<Locale> availableLocales = ListUtil.fromArray(
137                            LanguageUtil.getAvailableLocales());
138    
139                    if (!availableLocales.contains(locale)) {
140                            return;
141                    }
142    
143                    PropsValues.COMPANY_DEFAULT_LOCALE = languageId;
144    
145                    HttpSession session = request.getSession();
146    
147                    session.setAttribute(Globals.LOCALE_KEY, locale);
148                    session.setAttribute(WebKeys.SETUP_WIZARD_DEFAULT_LOCALE, languageId);
149    
150                    LanguageUtil.updateCookie(request, response, locale);
151    
152                    ThemeDisplay themeDisplay = (ThemeDisplay)request.getAttribute(
153                            WebKeys.THEME_DISPLAY);
154    
155                    themeDisplay.setLanguageId(languageId);
156                    themeDisplay.setLocale(locale);
157            }
158    
159            public static void updateSetup(
160                            HttpServletRequest request, HttpServletResponse response)
161                    throws Exception {
162    
163                    UnicodeProperties unicodeProperties =
164                            PropertiesParamUtil.getProperties(request, _PROPERTIES_PREFIX);
165    
166                    unicodeProperties.setProperty(
167                            PropsKeys.LIFERAY_HOME,
168                            SystemProperties.get(PropsKeys.LIFERAY_HOME));
169    
170                    boolean databaseConfigured = _isDatabaseConfigured(unicodeProperties);
171    
172                    _processAdminProperties(request, unicodeProperties);
173                    _processDatabaseProperties(
174                            request, unicodeProperties, databaseConfigured);
175    
176                    updateLanguage(request, response);
177    
178                    unicodeProperties.put(
179                            PropsKeys.SETUP_WIZARD_ENABLED, String.valueOf(false));
180    
181                    PropsUtil.addProperties(unicodeProperties);
182    
183                    HttpSession session = request.getSession();
184    
185                    session.setAttribute(
186                            WebKeys.SETUP_WIZARD_PROPERTIES, unicodeProperties);
187    
188                    boolean propertiesFileUpdated = _writePropertiesFile(unicodeProperties);
189    
190                    session.setAttribute(
191                            WebKeys.SETUP_WIZARD_PROPERTIES_UPDATED, propertiesFileUpdated);
192    
193                    if (!databaseConfigured) {
194                            _reloadServletContext(request, unicodeProperties);
195                    }
196    
197                    _updateCompany();
198                    _updateAdminUser(request);
199    
200                    _initPlugins();
201            }
202    
203            private static String _getParameter(
204                    HttpServletRequest request, String name, String defaultValue) {
205    
206                    name = _PROPERTIES_PREFIX.concat(name).concat(StringPool.DOUBLE_DASH);
207    
208                    return ParamUtil.getString(request, name, defaultValue);
209            }
210    
211            /**
212             * @see {@link com.liferay.portal.servlet.MainServlet#initPlugins}
213             */
214            private static void _initPlugins() {
215                    HotDeployUtil.setCapturePrematureEvents(false);
216    
217                    PortalLifecycleUtil.flushInits();
218            }
219    
220            private static boolean _isDatabaseConfigured(
221                    UnicodeProperties unicodeProperties) {
222    
223                    String defaultDriverClassName = unicodeProperties.get(
224                            PropsKeys.JDBC_DEFAULT_DRIVER_CLASS_NAME);
225                    String defaultPassword = unicodeProperties.get(
226                            PropsKeys.JDBC_DEFAULT_PASSWORD);
227                    String defaultURL = unicodeProperties.get(PropsKeys.JDBC_DEFAULT_URL);
228                    String defaultUsername = unicodeProperties.get(
229                            PropsKeys.JDBC_DEFAULT_USERNAME);
230    
231                    if (PropsValues.JDBC_DEFAULT_DRIVER_CLASS_NAME.equals(
232                                    defaultDriverClassName) &&
233                            PropsValues.JDBC_DEFAULT_PASSWORD.equals(defaultPassword) &&
234                            PropsValues.JDBC_DEFAULT_URL.equals(defaultURL) &&
235                            PropsValues.JDBC_DEFAULT_USERNAME.equals(defaultUsername) ) {
236    
237                            return true;
238                    }
239    
240                    return false;
241            }
242    
243            private static void _processAdminProperties(
244                            HttpServletRequest request, UnicodeProperties unicodeProperties)
245                    throws Exception {
246    
247                    String companyName = _getParameter(
248                            request, PropsKeys.COMPANY_DEFAULT_NAME, "Liferay");
249    
250                    PropsValues.COMPANY_DEFAULT_NAME = companyName;
251    
252                    FullNameGenerator fullNameGenerator =
253                            FullNameGeneratorFactory.getInstance();
254    
255                    String firstName = _getParameter(
256                            request, PropsKeys.DEFAULT_ADMIN_FIRST_NAME, "Test");
257    
258                    PropsValues.DEFAULT_ADMIN_FIRST_NAME = firstName;
259    
260                    String lastName = _getParameter(
261                            request, PropsKeys.DEFAULT_ADMIN_LAST_NAME, "Test");
262    
263                    PropsValues.DEFAULT_ADMIN_LAST_NAME = lastName;
264    
265                    String fullName = fullNameGenerator.getFullName(
266                            firstName, null, lastName);
267    
268                    PropsValues.ADMIN_EMAIL_FROM_NAME = fullName;
269    
270                    unicodeProperties.put(PropsKeys.ADMIN_EMAIL_FROM_NAME, fullName);
271    
272                    String emailAddress = _getParameter(
273                            request, PropsKeys.ADMIN_EMAIL_FROM_ADDRESS, "test@liferay.com");
274    
275                    PropsValues.ADMIN_EMAIL_FROM_ADDRESS = emailAddress;
276                    PropsValues.DEFAULT_ADMIN_EMAIL_ADDRESS = emailAddress;
277    
278                    unicodeProperties.put(
279                            PropsKeys.DEFAULT_ADMIN_EMAIL_ADDRESS, emailAddress);
280    
281                    ScreenNameGenerator screenNameGenerator =
282                            ScreenNameGeneratorFactory.getInstance();
283    
284                    String screenName = null;
285    
286                    try {
287                            screenName = screenNameGenerator.generate(0, 0, emailAddress);
288                    }
289                    catch (Exception e) {
290                            screenName = "test";
291                    }
292    
293                    PropsValues.DEFAULT_ADMIN_SCREEN_NAME = screenName;
294    
295                    unicodeProperties.put(PropsKeys.DEFAULT_ADMIN_SCREEN_NAME, screenName);
296            }
297    
298            private static void _processDatabaseProperties(
299                            HttpServletRequest request, UnicodeProperties unicodeProperties,
300                            boolean databaseConfigured)
301                    throws Exception {
302    
303                    boolean defaultDatabase = ParamUtil.getBoolean(
304                            request, "defaultDatabase", true);
305    
306                    if (defaultDatabase || databaseConfigured) {
307                            unicodeProperties.remove(PropsKeys.JDBC_DEFAULT_URL);
308                            unicodeProperties.remove(PropsKeys.JDBC_DEFAULT_DRIVER_CLASS_NAME);
309                            unicodeProperties.remove(PropsKeys.JDBC_DEFAULT_USERNAME);
310                            unicodeProperties.remove(PropsKeys.JDBC_DEFAULT_PASSWORD);
311                    }
312            }
313    
314            private static void _reloadServletContext(
315                            HttpServletRequest request, UnicodeProperties unicodeProperties)
316                    throws Exception {
317    
318                    // Data sources
319    
320                    Properties jdbcProperties = new Properties();
321    
322                    jdbcProperties.putAll(unicodeProperties);
323    
324                    jdbcProperties = PropertiesUtil.getProperties(
325                            jdbcProperties,"jdbc.default.",true);
326    
327                    DataSourceSwapper.swapCounterDataSource(jdbcProperties);
328                    DataSourceSwapper.swapLiferayDataSource(jdbcProperties);
329    
330                    // Caches
331    
332                    CacheRegistryUtil.clear();
333                    MultiVMPoolUtil.clear();
334                    WebCachePoolUtil.clear();
335                    CentralizedThreadLocal.clearShortLivedThreadLocals();
336    
337                    // Quartz
338    
339                    QuartzLocalServiceUtil.checkQuartzTables();
340    
341                    // Startup
342    
343                    StartupAction startupAction = new StartupAction();
344    
345                    startupAction.run(null);
346    
347                    // Servlet context
348    
349                    HttpSession session = request.getSession();
350    
351                    PortalInstances.reload(session.getServletContext());
352            }
353    
354            private static void _testConnection(
355                            String driverClassName, String url, String userName,
356                            String password)
357                    throws Exception {
358    
359                    Class.forName(driverClassName);
360    
361                    Connection connection = null;
362    
363                    try {
364                            DataSource dataSource = DataSourceFactoryUtil.initDataSource(
365                                    driverClassName, url, userName, password);
366    
367                            connection = dataSource.getConnection();
368                    }
369                    finally {
370                            DataAccess.cleanUp(connection);
371                    }
372            }
373    
374            private static void _updateAdminUser(HttpServletRequest request)
375                    throws Exception {
376    
377                    // Email address
378    
379                    ThemeDisplay themeDisplay = (ThemeDisplay)request.getAttribute(
380                            WebKeys.THEME_DISPLAY);
381    
382                    User user = null;
383    
384                    try {
385                            user = UserLocalServiceUtil.getUserByEmailAddress(
386                                    PortalUtil.getDefaultCompanyId(),
387                                    PropsValues.ADMIN_EMAIL_FROM_ADDRESS);
388                    }
389                    catch (NoSuchUserException nsue) {
390                            user = UserLocalServiceUtil.getUserByEmailAddress(
391                                    PortalUtil.getDefaultCompanyId(), "test@liferay.com");
392    
393                            user = UserLocalServiceUtil.updateEmailAddress(
394                                    user.getUserId(), StringPool.BLANK,
395                                    PropsValues.ADMIN_EMAIL_FROM_ADDRESS,
396                                    PropsValues.ADMIN_EMAIL_FROM_ADDRESS);
397                    }
398    
399                    // First and last name
400    
401                    String greeting = LanguageUtil.format(
402                            themeDisplay.getLocale(), "welcome-x",
403                            " " + PropsValues.ADMIN_EMAIL_FROM_NAME, false);
404    
405                    Contact contact = user.getContact();
406    
407                    Calendar birthdayCal = CalendarFactoryUtil.getCalendar();
408    
409                    birthdayCal.setTime(contact.getBirthday());
410    
411                    int birthdayMonth = birthdayCal.get(Calendar.MONTH);
412                    int birthdayDay = birthdayCal.get(Calendar.DAY_OF_MONTH);
413                    int birthdayYear = birthdayCal.get(Calendar.YEAR);
414    
415                    user = UserLocalServiceUtil.updateUser(
416                            user.getUserId(), StringPool.BLANK, StringPool.BLANK,
417                            StringPool.BLANK, false, user.getReminderQueryQuestion(),
418                            user.getReminderQueryAnswer(), user.getScreenName(),
419                            user.getEmailAddress(), user.getFacebookId(), user.getOpenId(),
420                            themeDisplay.getLanguageId(), user.getTimeZoneId(), greeting,
421                            user.getComments(), PropsValues.DEFAULT_ADMIN_FIRST_NAME,
422                            user.getMiddleName(), PropsValues.DEFAULT_ADMIN_LAST_NAME,
423                            contact.getPrefixId(), contact.getSuffixId(), contact.isMale(),
424                            birthdayMonth, birthdayDay, birthdayYear, contact.getSmsSn(),
425                            contact.getAimSn(), contact.getFacebookSn(), contact.getIcqSn(),
426                            contact.getJabberSn(), contact.getMsnSn(), contact.getMySpaceSn(),
427                            contact.getSkypeSn(), contact.getTwitterSn(), contact.getYmSn(),
428                            contact.getJobTitle(), null, null, null, null, null,
429                            new ServiceContext());
430    
431                    // Password
432    
433                    user = UserLocalServiceUtil.updatePasswordReset(user.getUserId(), true);
434    
435                    HttpSession session = request.getSession();
436    
437                    session.setAttribute(WebKeys.SETUP_WIZARD_PASSWORD_UPDATED, true);
438            }
439    
440            private static void _updateCompany() throws Exception {
441                    Company company = CompanyLocalServiceUtil.getCompanyById(
442                            PortalInstances.getDefaultCompanyId());
443    
444                    Account account = company.getAccount();
445    
446                    String name = account.getName();
447    
448                    if (!name.equals(PropsValues.COMPANY_DEFAULT_NAME)) {
449                            account.setName(PropsValues.COMPANY_DEFAULT_NAME);
450    
451                            AccountLocalServiceUtil.updateAccount(account);
452                    }
453            }
454    
455            private static boolean _writePropertiesFile(
456                    UnicodeProperties unicodeProperties) {
457    
458                    try {
459                            FileUtil.write(
460                                    PropsValues.LIFERAY_HOME, PROPERTIES_FILE_NAME,
461                                    unicodeProperties.toString());
462    
463                            return true;
464                    }
465                    catch (IOException ioe) {
466                            _log.error(ioe, ioe);
467    
468                            return false;
469                    }
470            }
471    
472            private final static String _PROPERTIES_PREFIX = "properties--";
473    
474            private static Log _log = LogFactoryUtil.getLog(SetupWizardUtil.class);
475    
476            private static boolean _setupFinished = false;
477    
478    }