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