001    /**
002     * Copyright (c) 2000-present 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.util;
016    
017    import com.liferay.portal.events.EventsProcessorUtil;
018    import com.liferay.portal.kernel.dao.jdbc.DataAccess;
019    import com.liferay.portal.kernel.log.Log;
020    import com.liferay.portal.kernel.log.LogFactoryUtil;
021    import com.liferay.portal.kernel.search.SearchEngineHelperUtil;
022    import com.liferay.portal.kernel.util.ArrayUtil;
023    import com.liferay.portal.kernel.util.CookieKeys;
024    import com.liferay.portal.kernel.util.GetterUtil;
025    import com.liferay.portal.kernel.util.HttpUtil;
026    import com.liferay.portal.kernel.util.PropsKeys;
027    import com.liferay.portal.kernel.util.SetUtil;
028    import com.liferay.portal.kernel.util.Validator;
029    import com.liferay.portal.kernel.util.WebKeys;
030    import com.liferay.portal.model.Company;
031    import com.liferay.portal.model.Group;
032    import com.liferay.portal.model.LayoutSet;
033    import com.liferay.portal.model.PortletCategory;
034    import com.liferay.portal.model.User;
035    import com.liferay.portal.model.VirtualHost;
036    import com.liferay.portal.security.auth.CompanyThreadLocal;
037    import com.liferay.portal.security.auth.PrincipalThreadLocal;
038    import com.liferay.portal.security.exportimport.UserImporterUtil;
039    import com.liferay.portal.security.ldap.LDAPSettingsUtil;
040    import com.liferay.portal.service.CompanyLocalServiceUtil;
041    import com.liferay.portal.service.GroupLocalServiceUtil;
042    import com.liferay.portal.service.LayoutSetLocalServiceUtil;
043    import com.liferay.portal.service.PortletLocalServiceUtil;
044    import com.liferay.portal.service.UserLocalServiceUtil;
045    import com.liferay.portal.service.VirtualHostLocalServiceUtil;
046    
047    import java.sql.Connection;
048    import java.sql.PreparedStatement;
049    import java.sql.ResultSet;
050    import java.sql.SQLException;
051    
052    import java.util.ArrayList;
053    import java.util.List;
054    import java.util.Set;
055    
056    import javax.servlet.ServletContext;
057    import javax.servlet.http.HttpServletRequest;
058    
059    /**
060     * @author Brian Wing Shun Chan
061     * @author Jose Oliver
062     * @author Atul Patel
063     * @author Mika Koivisto
064     */
065    public class PortalInstances {
066    
067            public static void addCompanyId(long companyId) {
068                    _instance._addCompanyId(companyId);
069            }
070    
071            public static long getCompanyId(HttpServletRequest request) {
072                    return _instance._getCompanyId(request);
073            }
074    
075            public static long[] getCompanyIds() {
076                    return _instance._getCompanyIds();
077            }
078    
079            public static long[] getCompanyIdsBySQL() throws SQLException {
080                    return _instance._getCompanyIdsBySQL();
081            }
082    
083            public static long getDefaultCompanyId() {
084                    return _instance._getDefaultCompanyId();
085            }
086    
087            public static String[] getWebIds() {
088                    return _instance._getWebIds();
089            }
090    
091            public static long initCompany(
092                    ServletContext servletContext, String webId) {
093    
094                    return _instance._initCompany(servletContext, webId);
095            }
096    
097            public static boolean isAutoLoginIgnoreHost(String host) {
098                    return _instance._isAutoLoginIgnoreHost(host);
099            }
100    
101            public static boolean isAutoLoginIgnorePath(String path) {
102                    return _instance._isAutoLoginIgnorePath(path);
103            }
104    
105            public static boolean isCompanyActive(long companyId) {
106                    return _instance._isCompanyActive(companyId);
107            }
108    
109            public static boolean isVirtualHostsIgnoreHost(String host) {
110                    return _instance._isVirtualHostsIgnoreHost(host);
111            }
112    
113            public static boolean isVirtualHostsIgnorePath(String path) {
114                    return _instance._isVirtualHostsIgnorePath(path);
115            }
116    
117            public static void reload(ServletContext servletContext) {
118                    _instance._reload(servletContext);
119            }
120    
121            public static void removeCompany(long companyId) {
122                    _instance._removeCompanyId(companyId);
123            }
124    
125            private PortalInstances() {
126                    _companyIds = new long[0];
127                    _autoLoginIgnoreHosts = SetUtil.fromArray(
128                            PropsUtil.getArray(PropsKeys.AUTO_LOGIN_IGNORE_HOSTS));
129                    _autoLoginIgnorePaths = SetUtil.fromArray(
130                            PropsUtil.getArray(PropsKeys.AUTO_LOGIN_IGNORE_PATHS));
131                    _virtualHostsIgnoreHosts = SetUtil.fromArray(
132                            PropsUtil.getArray(PropsKeys.VIRTUAL_HOSTS_IGNORE_HOSTS));
133                    _virtualHostsIgnorePaths = SetUtil.fromArray(
134                            PropsUtil.getArray(PropsKeys.VIRTUAL_HOSTS_IGNORE_PATHS));
135            }
136    
137            private void _addCompanyId(long companyId) {
138                    if (ArrayUtil.contains(_companyIds, companyId)) {
139                            return;
140                    }
141    
142                    long[] companyIds = new long[_companyIds.length + 1];
143    
144                    System.arraycopy(_companyIds, 0, companyIds, 0, _companyIds.length);
145    
146                    companyIds[_companyIds.length] = companyId;
147    
148                    _companyIds = companyIds;
149            }
150    
151            private long _getCompanyId(HttpServletRequest request) {
152                    if (_log.isDebugEnabled()) {
153                            _log.debug("Get company id");
154                    }
155    
156                    Long companyIdObj = (Long)request.getAttribute(WebKeys.COMPANY_ID);
157    
158                    if (_log.isDebugEnabled()) {
159                            _log.debug("Company id from request " + companyIdObj);
160                    }
161    
162                    if (companyIdObj != null) {
163                            return companyIdObj.longValue();
164                    }
165    
166                    long companyId = _getCompanyIdByVirtualHosts(request);
167    
168                    if (_log.isDebugEnabled()) {
169                            _log.debug("Company id from host " + companyId);
170                    }
171    
172                    if (companyId <= 0) {
173                            long cookieCompanyId = GetterUtil.getLong(
174                                    CookieKeys.getCookie(request, CookieKeys.COMPANY_ID, false));
175    
176                            if (cookieCompanyId > 0) {
177                                    try {
178                                            if (CompanyLocalServiceUtil.fetchCompanyById(
179                                                            cookieCompanyId) == null) {
180    
181                                                    if (_log.isWarnEnabled()) {
182                                                            _log.warn(
183                                                                    "Company id from cookie " + cookieCompanyId +
184                                                                            " does not exist");
185                                                    }
186                                            }
187                                            else {
188                                                    companyId = cookieCompanyId;
189    
190                                                    if (_log.isDebugEnabled()) {
191                                                            _log.debug("Company id from cookie " + companyId);
192                                                    }
193                                            }
194                                    }
195                                    catch (Exception e) {
196                                            _log.error(e, e);
197                                    }
198                            }
199                    }
200    
201                    if (companyId <= 0) {
202                            companyId = _getDefaultCompanyId();
203    
204                            if (_log.isDebugEnabled()) {
205                                    _log.debug("Default company id " + companyId);
206                            }
207                    }
208    
209                    if (_log.isDebugEnabled()) {
210                            _log.debug("Set company id " + companyId);
211                    }
212    
213                    request.setAttribute(WebKeys.COMPANY_ID, Long.valueOf(companyId));
214    
215                    CompanyThreadLocal.setCompanyId(companyId);
216    
217                    if (Validator.isNotNull(PropsValues.VIRTUAL_HOSTS_DEFAULT_SITE_NAME) &&
218                            (request.getAttribute(WebKeys.VIRTUAL_HOST_LAYOUT_SET) == null)) {
219    
220                            try {
221                                    Group group = GroupLocalServiceUtil.getGroup(
222                                            companyId, PropsValues.VIRTUAL_HOSTS_DEFAULT_SITE_NAME);
223    
224                                    LayoutSet layoutSet = LayoutSetLocalServiceUtil.getLayoutSet(
225                                            group.getGroupId(), false);
226    
227                                    if (Validator.isNull(layoutSet.getVirtualHostname())) {
228                                            request.setAttribute(
229                                                    WebKeys.VIRTUAL_HOST_LAYOUT_SET, layoutSet);
230                                    }
231                            }
232                            catch (Exception e) {
233                                    _log.error(e, e);
234                            }
235                    }
236    
237                    return companyId;
238            }
239    
240            private long _getCompanyIdByVirtualHosts(HttpServletRequest request) {
241                    String host = PortalUtil.getHost(request);
242    
243                    if (_log.isDebugEnabled()) {
244                            _log.debug("Host " + host);
245                    }
246    
247                    if (Validator.isNull(host) || _isVirtualHostsIgnoreHost(host)) {
248                            return 0;
249                    }
250    
251                    try {
252                            VirtualHost virtualHost =
253                                    VirtualHostLocalServiceUtil.fetchVirtualHost(host);
254    
255                            if (virtualHost == null) {
256                                    return 0;
257                            }
258    
259                            if (virtualHost.getLayoutSetId() != 0) {
260                                    LayoutSet layoutSet = LayoutSetLocalServiceUtil.getLayoutSet(
261                                            virtualHost.getLayoutSetId());
262    
263                                    if (_log.isDebugEnabled()) {
264                                            _log.debug(
265                                                    "Company " + virtualHost.getCompanyId() +
266                                                            " is associated with layout set " +
267                                                                    virtualHost.getLayoutSetId());
268                                    }
269    
270                                    request.setAttribute(
271                                            WebKeys.VIRTUAL_HOST_LAYOUT_SET, layoutSet);
272                            }
273    
274                            return virtualHost.getCompanyId();
275                    }
276                    catch (Exception e) {
277                            _log.error(e, e);
278                    }
279    
280                    return 0;
281            }
282    
283            private long[] _getCompanyIds() {
284                    return _companyIds;
285            }
286    
287            private long[] _getCompanyIdsBySQL() throws SQLException {
288                    List<Long> companyIds = new ArrayList<>();
289    
290                    Connection con = null;
291                    PreparedStatement ps = null;
292                    ResultSet rs = null;
293    
294                    try {
295                            con = DataAccess.getConnection();
296    
297                            ps = con.prepareStatement(_GET_COMPANY_IDS);
298    
299                            rs = ps.executeQuery();
300    
301                            while (rs.next()) {
302                                    long companyId = rs.getLong("companyId");
303    
304                                    companyIds.add(companyId);
305                            }
306                    }
307                    finally {
308                            DataAccess.cleanUp(con, ps, rs);
309                    }
310    
311                    return ArrayUtil.toArray(
312                            companyIds.toArray(new Long[companyIds.size()]));
313            }
314    
315            private long _getDefaultCompanyId() {
316                    return _companyIds[0];
317            }
318    
319            private String[] _getWebIds() {
320                    if (_webIds != null) {
321                            return _webIds;
322                    }
323    
324                    if (Validator.isNull(PropsValues.COMPANY_DEFAULT_WEB_ID)) {
325                            throw new RuntimeException("Default web id must not be null");
326                    }
327    
328                    try {
329                            List<Company> companies = CompanyLocalServiceUtil.getCompanies(
330                                    false);
331    
332                            List<String> webIdsList = new ArrayList<>(companies.size());
333    
334                            for (Company company : companies) {
335                                    String webId = company.getWebId();
336    
337                                    if (webId.equals(PropsValues.COMPANY_DEFAULT_WEB_ID)) {
338                                            webIdsList.add(0, webId);
339                                    }
340                                    else {
341                                            webIdsList.add(webId);
342                                    }
343                            }
344    
345                            _webIds = webIdsList.toArray(new String[webIdsList.size()]);
346                    }
347                    catch (Exception e) {
348                            _log.error(e, e);
349                    }
350    
351                    if (ArrayUtil.isEmpty(_webIds)) {
352                            _webIds = new String[] {PropsValues.COMPANY_DEFAULT_WEB_ID};
353                    }
354    
355                    return _webIds;
356            }
357    
358            private long _initCompany(ServletContext servletContext, String webId) {
359    
360                    // Begin initializing company
361    
362                    if (_log.isDebugEnabled()) {
363                            _log.debug("Begin initializing company with web id " + webId);
364                    }
365    
366                    long companyId = 0;
367    
368                    try {
369                            Company company = CompanyLocalServiceUtil.checkCompany(webId);
370    
371                            companyId = company.getCompanyId();
372                    }
373                    catch (Exception e) {
374                            _log.error(e, e);
375                    }
376    
377                    Long currentThreadCompanyId = CompanyThreadLocal.getCompanyId();
378    
379                    String currentThreadPrincipalName = PrincipalThreadLocal.getName();
380    
381                    try {
382                            CompanyThreadLocal.setCompanyId(companyId);
383    
384                            String principalName = null;
385    
386                            try {
387                                    User user = UserLocalServiceUtil.getUser(
388                                            PrincipalThreadLocal.getUserId());
389    
390                                    if (user.getCompanyId() == companyId) {
391                                            principalName = currentThreadPrincipalName;
392                                    }
393                            }
394                            catch (Exception e) {
395                            }
396    
397                            PrincipalThreadLocal.setName(principalName);
398    
399                            // Initialize display
400    
401                            if (_log.isDebugEnabled()) {
402                                    _log.debug("Initialize display");
403                            }
404    
405                            try {
406                                    String xml = HttpUtil.URLtoString(
407                                            servletContext.getResource("/WEB-INF/liferay-display.xml"));
408    
409                                    PortletCategory portletCategory =
410                                            (PortletCategory)WebAppPool.get(
411                                                    companyId, WebKeys.PORTLET_CATEGORY);
412    
413                                    if (portletCategory == null) {
414                                            portletCategory = new PortletCategory();
415                                    }
416    
417                                    PortletCategory newPortletCategory =
418                                            PortletLocalServiceUtil.getEARDisplay(xml);
419    
420                                    portletCategory.merge(newPortletCategory);
421    
422                                    for (int i = 0; i < _companyIds.length; i++) {
423                                            long currentCompanyId = _companyIds[i];
424    
425                                            PortletCategory currentPortletCategory =
426                                                    (PortletCategory)WebAppPool.get(
427                                                            currentCompanyId, WebKeys.PORTLET_CATEGORY);
428    
429                                            if (currentPortletCategory != null) {
430                                                    portletCategory.merge(currentPortletCategory);
431                                            }
432                                    }
433    
434                                    WebAppPool.put(
435                                            companyId, WebKeys.PORTLET_CATEGORY, portletCategory);
436                            }
437                            catch (Exception e) {
438                                    _log.error(e, e);
439                            }
440    
441                            // LDAP import
442    
443                            try {
444                                    if (LDAPSettingsUtil.isImportOnStartup(companyId)) {
445                                            UserImporterUtil.importUsers(companyId);
446                                    }
447                            }
448                            catch (Exception e) {
449                                    _log.error(e, e);
450                            }
451    
452                            // Process application startup events
453    
454                            if (_log.isDebugEnabled()) {
455                                    _log.debug("Process application startup events");
456                            }
457    
458                            try {
459                                    EventsProcessorUtil.process(
460                                            PropsKeys.APPLICATION_STARTUP_EVENTS,
461                                            PropsValues.APPLICATION_STARTUP_EVENTS,
462                                            new String[] {String.valueOf(companyId)});
463                            }
464                            catch (Exception e) {
465                                    _log.error(e, e);
466                            }
467    
468                            // End initializing company
469    
470                            if (_log.isDebugEnabled()) {
471                                    _log.debug(
472                                            "End initializing company with web id " + webId +
473                                                    " and company id " + companyId);
474                            }
475    
476                            addCompanyId(companyId);
477                    }
478                    finally {
479                            CompanyThreadLocal.setCompanyId(currentThreadCompanyId);
480    
481                            PrincipalThreadLocal.setName(currentThreadPrincipalName);
482                    }
483    
484                    return companyId;
485            }
486    
487            private boolean _isAutoLoginIgnoreHost(String host) {
488                    return _autoLoginIgnoreHosts.contains(host);
489            }
490    
491            private boolean _isAutoLoginIgnorePath(String path) {
492                    return _autoLoginIgnorePaths.contains(path);
493            }
494    
495            private boolean _isCompanyActive(long companyId) {
496                    try {
497                            Company company = CompanyLocalServiceUtil.fetchCompanyById(
498                                    companyId);
499    
500                            if (company != null) {
501                                    return company.isActive();
502                            }
503                    }
504                    catch (Exception e) {
505                            _log.error(e, e);
506                    }
507    
508                    return false;
509            }
510    
511            private boolean _isVirtualHostsIgnoreHost(String host) {
512                    return _virtualHostsIgnoreHosts.contains(host);
513            }
514    
515            private boolean _isVirtualHostsIgnorePath(String path) {
516                    return _virtualHostsIgnorePaths.contains(path);
517            }
518    
519            private void _reload(ServletContext servletContext) {
520                    _companyIds = new long[0];
521                    _webIds = null;
522    
523                    String[] webIds = _getWebIds();
524    
525                    for (String webId : webIds) {
526                            _initCompany(servletContext, webId);
527                    }
528            }
529    
530            private void _removeCompanyId(long companyId) {
531                    _companyIds = ArrayUtil.remove(_companyIds, companyId);
532                    _webIds = null;
533    
534                    _getWebIds();
535    
536                    SearchEngineHelperUtil.removeCompany(companyId);
537    
538                    WebAppPool.remove(companyId, WebKeys.PORTLET_CATEGORY);
539            }
540    
541            private static final String _GET_COMPANY_IDS =
542                    "select companyId from Company";
543    
544            private static final Log _log = LogFactoryUtil.getLog(
545                    PortalInstances.class);
546    
547            private static final PortalInstances _instance = new PortalInstances();
548    
549            private final Set<String> _autoLoginIgnoreHosts;
550            private final Set<String> _autoLoginIgnorePaths;
551            private long[] _companyIds;
552            private final Set<String> _virtualHostsIgnoreHosts;
553            private final Set<String> _virtualHostsIgnorePaths;
554            private String[] _webIds;
555    
556    }