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.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 {@link 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",
422                                    StringPool.SPACE + fullName, false);
423    
424                            Contact contact = user.getContact();
425    
426                            Calendar birthdayCal = CalendarFactoryUtil.getCalendar();
427    
428                            birthdayCal.setTime(contact.getBirthday());
429    
430                            int birthdayMonth = birthdayCal.get(Calendar.MONTH);
431                            int birthdayDay = birthdayCal.get(Calendar.DAY_OF_MONTH);
432                            int birthdayYear = birthdayCal.get(Calendar.YEAR);
433    
434                            user = UserLocalServiceUtil.updateUser(
435                                    user.getUserId(), StringPool.BLANK, StringPool.BLANK,
436                                    StringPool.BLANK, false, user.getReminderQueryQuestion(),
437                                    user.getReminderQueryAnswer(), screenName, emailAddress,
438                                    user.getFacebookId(), user.getOpenId(),
439                                    themeDisplay.getLanguageId(), user.getTimeZoneId(), greeting,
440                                    user.getComments(), firstName, user.getMiddleName(), lastName,
441                                    contact.getPrefixId(), contact.getSuffixId(), contact.isMale(),
442                                    birthdayMonth, birthdayDay, birthdayYear, contact.getSmsSn(),
443                                    contact.getAimSn(), contact.getFacebookSn(), contact.getIcqSn(),
444                                    contact.getJabberSn(), contact.getMsnSn(),
445                                    contact.getMySpaceSn(), contact.getSkypeSn(),
446                                    contact.getTwitterSn(), contact.getYmSn(),
447                                    contact.getJobTitle(), null, null, null, null, null,
448                                    new ServiceContext());
449                    }
450                    else {
451                            UserLocalServiceUtil.addDefaultAdminUser(
452                                    themeDisplay.getCompanyId(), screenName, emailAddress,
453                                    themeDisplay.getLocale(), firstName, StringPool.BLANK,
454                                    lastName);
455    
456                            user = UserLocalServiceUtil.getUserByEmailAddress(
457                                    themeDisplay.getCompanyId(), emailAddress);
458    
459                            String defaultAdminEmailAddress =
460                                    PropsValues.DEFAULT_ADMIN_EMAIL_ADDRESS_PREFIX + "@" +
461                                            PropsValues.COMPANY_DEFAULT_WEB_ID;
462    
463                            if (!emailAddress.equals(defaultAdminEmailAddress)) {
464                                    User testUser = UserLocalServiceUtil.fetchUserByEmailAddress(
465                                            themeDisplay.getCompanyId(), defaultAdminEmailAddress);
466    
467                                    if (testUser != null) {
468                                            UserLocalServiceUtil.updateStatus(
469                                                    testUser.getUserId(),
470                                                    WorkflowConstants.STATUS_INACTIVE);
471                                    }
472                            }
473                    }
474    
475                    user = UserLocalServiceUtil.updatePasswordReset(user.getUserId(), true);
476    
477                    HttpSession session = request.getSession();
478    
479                    session.setAttribute(WebKeys.EMAIL_ADDRESS, emailAddress);
480                    session.setAttribute(WebKeys.SETUP_WIZARD_PASSWORD_UPDATED, true);
481                    session.setAttribute(WebKeys.USER, user);
482                    session.setAttribute(WebKeys.USER_ID, user.getUserId());
483    
484                    EventsProcessorUtil.process(
485                            PropsKeys.LOGIN_EVENTS_POST, PropsValues.LOGIN_EVENTS_POST, request,
486                            response);
487            }
488    
489            private static void _updateCompany(HttpServletRequest request)
490                    throws Exception {
491    
492                    Company company = CompanyLocalServiceUtil.getCompanyById(
493                            PortalInstances.getDefaultCompanyId());
494    
495                    Account account = company.getAccount();
496    
497                    String currentName = account.getName();
498    
499                    String newName = ParamUtil.getString(
500                            request, "companyName", PropsValues.COMPANY_DEFAULT_NAME);
501    
502                    if (!currentName.equals(newName)) {
503                            account.setName(newName);
504    
505                            AccountLocalServiceUtil.updateAccount(account);
506                    }
507    
508                    String languageId = ParamUtil.getString(
509                            request, "companyLocale", getDefaultLanguageId());
510    
511                    User defaultUser = company.getDefaultUser();
512    
513                    defaultUser.setLanguageId(languageId);
514    
515                    UserLocalServiceUtil.updateUser(defaultUser);
516    
517                    ThemeDisplay themeDisplay = (ThemeDisplay)request.getAttribute(
518                            WebKeys.THEME_DISPLAY);
519    
520                    themeDisplay.setCompany(company);
521            }
522    
523            private static boolean _writePropertiesFile(
524                    UnicodeProperties unicodeProperties) {
525    
526                    try {
527                            FileUtil.write(
528                                    PropsValues.LIFERAY_HOME, PROPERTIES_FILE_NAME,
529                                    unicodeProperties.toString());
530    
531                            if (FileUtil.exists(
532                                            PropsValues.LIFERAY_HOME + StringPool.SLASH +
533                                                    PROPERTIES_FILE_NAME)) {
534    
535                                    return true;
536                            }
537                    }
538                    catch (IOException ioe) {
539                            _log.error(ioe, ioe);
540                    }
541    
542                    return false;
543            }
544    
545            private static final String _PROPERTIES_PREFIX = "properties--";
546    
547            private static Log _log = LogFactoryUtil.getLog(SetupWizardUtil.class);
548    
549            private static boolean _setupFinished = false;
550    
551    }