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