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