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