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