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