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