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                    Connection connection = null;
337    
338                    try {
339                            DataSource dataSource = DataSourceFactoryUtil.initDataSource(
340                                    driverClassName, url, userName, password, jndiName);
341    
342                            connection = dataSource.getConnection();
343                    }
344                    finally {
345                            DataAccess.cleanUp(connection);
346                    }
347            }
348    
349            private static void _updateAdminUser(
350                            HttpServletRequest request, UnicodeProperties unicodeProperties)
351                    throws Exception {
352    
353                    ThemeDisplay themeDisplay = (ThemeDisplay)request.getAttribute(
354                            WebKeys.THEME_DISPLAY);
355    
356                    Company company = CompanyLocalServiceUtil.getCompanyById(
357                            themeDisplay.getCompanyId());
358    
359                    String emailAddress = ParamUtil.getString(
360                            request, "adminEmailAddress",
361                            PropsValues.DEFAULT_ADMIN_EMAIL_ADDRESS_PREFIX + StringPool.AT +
362                                    company.getMx());
363    
364                    PropsValues.ADMIN_EMAIL_FROM_ADDRESS = emailAddress;
365    
366                    unicodeProperties.put(PropsKeys.ADMIN_EMAIL_FROM_ADDRESS, emailAddress);
367    
368                    ScreenNameGenerator screenNameGenerator =
369                            ScreenNameGeneratorFactory.getInstance();
370    
371                    String screenName = GetterUtil.getString(
372                            PropsValues.DEFAULT_ADMIN_EMAIL_ADDRESS_PREFIX, "test");
373    
374                    try {
375                            screenName = screenNameGenerator.generate(0, 0, emailAddress);
376                    }
377                    catch (Exception e) {
378                    }
379    
380                    String firstName = ParamUtil.getString(
381                            request, "adminFirstName", PropsValues.DEFAULT_ADMIN_FIRST_NAME);
382                    String lastName = ParamUtil.getString(
383                            request, "adminLastName", PropsValues.DEFAULT_ADMIN_LAST_NAME);
384    
385                    FullNameGenerator fullNameGenerator =
386                            FullNameGeneratorFactory.getInstance();
387    
388                    String fullName = fullNameGenerator.getFullName(
389                            firstName, null, lastName);
390    
391                    PropsValues.ADMIN_EMAIL_FROM_NAME = fullName;
392    
393                    unicodeProperties.put(PropsKeys.ADMIN_EMAIL_FROM_NAME, fullName);
394    
395                    User user = null;
396    
397                    try {
398                            user = UserLocalServiceUtil.getUserByEmailAddress(
399                                    themeDisplay.getCompanyId(), emailAddress);
400    
401                            String greeting = LanguageUtil.format(
402                                    themeDisplay.getLocale(), "welcome-x",
403                                    StringPool.SPACE + fullName, false);
404    
405                            Contact contact = user.getContact();
406    
407                            Calendar birthdayCal = CalendarFactoryUtil.getCalendar();
408    
409                            birthdayCal.setTime(contact.getBirthday());
410    
411                            int birthdayMonth = birthdayCal.get(Calendar.MONTH);
412                            int birthdayDay = birthdayCal.get(Calendar.DAY_OF_MONTH);
413                            int birthdayYear = birthdayCal.get(Calendar.YEAR);
414    
415                            user = UserLocalServiceUtil.updateUser(
416                                    user.getUserId(), StringPool.BLANK, StringPool.BLANK,
417                                    StringPool.BLANK, false, user.getReminderQueryQuestion(),
418                                    user.getReminderQueryAnswer(), screenName, emailAddress,
419                                    user.getFacebookId(), user.getOpenId(),
420                                    themeDisplay.getLanguageId(), user.getTimeZoneId(), greeting,
421                                    user.getComments(), firstName, user.getMiddleName(), lastName,
422                                    contact.getPrefixId(), contact.getSuffixId(), contact.isMale(),
423                                    birthdayMonth, birthdayDay, birthdayYear, contact.getSmsSn(),
424                                    contact.getAimSn(), contact.getFacebookSn(), contact.getIcqSn(),
425                                    contact.getJabberSn(), contact.getMsnSn(),
426                                    contact.getMySpaceSn(), contact.getSkypeSn(),
427                                    contact.getTwitterSn(), contact.getYmSn(),
428                                    contact.getJobTitle(), null, null, null, null, null,
429                                    new ServiceContext());
430                    }
431                    catch (NoSuchUserException nsue) {
432                            UserLocalServiceUtil.addDefaultAdminUser(
433                                    themeDisplay.getCompanyId(), screenName, emailAddress,
434                                    themeDisplay.getLocale(), firstName, StringPool.BLANK,
435                                    lastName);
436    
437                            user = UserLocalServiceUtil.getUserByEmailAddress(
438                                    themeDisplay.getCompanyId(), emailAddress);
439    
440                            String defaultAdminEmailAddress =
441                                    PropsValues.DEFAULT_ADMIN_EMAIL_ADDRESS_PREFIX + "@" +
442                                            PropsValues.COMPANY_DEFAULT_WEB_ID;
443    
444                            if (!emailAddress.equals(defaultAdminEmailAddress)) {
445                                    User testUser = UserLocalServiceUtil.fetchUserByEmailAddress(
446                                            themeDisplay.getCompanyId(), defaultAdminEmailAddress);
447    
448                                    if (testUser != null) {
449                                            UserLocalServiceUtil.updateStatus(
450                                                    testUser.getUserId(),
451                                                    WorkflowConstants.STATUS_INACTIVE);
452                                    }
453                            }
454                    }
455    
456                    user = UserLocalServiceUtil.updatePasswordReset(user.getUserId(), true);
457    
458                    HttpSession session = request.getSession();
459    
460                    session.setAttribute(WebKeys.EMAIL_ADDRESS, emailAddress);
461                    session.setAttribute(WebKeys.SETUP_WIZARD_PASSWORD_UPDATED, true);
462                    session.setAttribute(WebKeys.USER_ID, user.getUserId());
463            }
464    
465            private static void _updateCompany(HttpServletRequest request)
466                    throws Exception {
467    
468                    Company company = CompanyLocalServiceUtil.getCompanyById(
469                            PortalInstances.getDefaultCompanyId());
470    
471                    Account account = company.getAccount();
472    
473                    String currentName = account.getName();
474    
475                    String newName = ParamUtil.getString(
476                            request, "companyName", PropsValues.COMPANY_DEFAULT_NAME);
477    
478                    if (!currentName.equals(newName)) {
479                            account.setName(newName);
480    
481                            AccountLocalServiceUtil.updateAccount(account);
482                    }
483    
484                    String languageId = ParamUtil.getString(
485                            request, "companyLocale", getDefaultLanguageId());
486    
487                    User defaultUser = company.getDefaultUser();
488    
489                    defaultUser.setLanguageId(languageId);
490    
491                    UserLocalServiceUtil.updateUser(defaultUser);
492    
493                    ThemeDisplay themeDisplay = (ThemeDisplay)request.getAttribute(
494                            WebKeys.THEME_DISPLAY);
495    
496                    themeDisplay.setCompany(company);
497            }
498    
499            private static boolean _writePropertiesFile(
500                    UnicodeProperties unicodeProperties) {
501    
502                    try {
503                            FileUtil.write(
504                                    PropsValues.LIFERAY_HOME, PROPERTIES_FILE_NAME,
505                                    unicodeProperties.toString());
506    
507                            if (FileUtil.exists(
508                                            PropsValues.LIFERAY_HOME + StringPool.SLASH +
509                                                    PROPERTIES_FILE_NAME)) {
510    
511                                    return true;
512                            }
513                    }
514                    catch (IOException ioe) {
515                            _log.error(ioe, ioe);
516                    }
517    
518                    return false;
519            }
520    
521            private static final String _PROPERTIES_PREFIX = "properties--";
522    
523            private static Log _log = LogFactoryUtil.getLog(SetupWizardUtil.class);
524    
525            private static boolean _setupFinished = false;
526    
527    }