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