/** * Copyright (c) 2000-present Liferay, Inc. All rights reserved. * * This library is free software; you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License as published by the Free * Software Foundation; either version 2.1 of the License, or (at your option) * any later version. * * This library is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more * details. */ package com.liferay.portal.http.service.internal.servlet; import com.liferay.portal.http.service.internal.http.ExtendedHttpService; import com.liferay.portal.http.service.internal.http.FilterTracker; import com.liferay.portal.http.service.internal.http.HttpServiceFactory; import com.liferay.portal.http.service.internal.http.HttpSupport; import com.liferay.portal.http.service.internal.http.ServletTracker; import com.liferay.portal.kernel.log.Log; import com.liferay.portal.kernel.log.LogFactoryUtil; import com.liferay.portal.kernel.servlet.PortletServlet; import com.liferay.portal.kernel.servlet.ServletContextPool; import com.liferay.portal.kernel.util.JavaConstants; import com.liferay.portal.kernel.util.ReleaseInfo; import com.liferay.portal.kernel.util.StringPool; import com.liferay.portal.kernel.util.Validator; import com.liferay.portal.kernel.util.WebKeys; import com.liferay.portal.model.Portlet; import com.liferay.portal.model.PortletApp; import com.liferay.portal.model.PortletConstants; import com.liferay.portal.service.PortletLocalServiceUtil; import com.liferay.portal.util.Portal; import com.liferay.portal.util.PortalUtil; import java.io.IOException; import java.util.Enumeration; import java.util.Hashtable; import javax.servlet.Filter; import javax.servlet.RequestDispatcher; import javax.servlet.Servlet; import javax.servlet.ServletConfig; import javax.servlet.ServletContext; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.osgi.framework.BundleContext; import org.osgi.framework.ServiceRegistration; import org.osgi.service.http.HttpService; import org.osgi.util.tracker.ServiceTracker; /** * @author Raymond Augé * @author Miguel Pastor */ public class WebExtenderServlet extends PortletServlet { public WebExtenderServlet(BundleContext bundleContext) { _bundleContext = bundleContext; } public void destroy() { _filterTracker.close(); _httpServiceRegistration.unregister(); _httpServletRegistration.unregister(); _servletTracker.close(); super.destroy(); } public BundleContext getBundleContext() { return _bundleContext; } public void init(ServletConfig servletConfig) throws ServletException { super.init(servletConfig); HttpSupport httpSupport = new HttpSupport(_bundleContext, this); HttpServiceFactory httpServiceFactory = new HttpServiceFactory( httpSupport); _filterTracker = new ServiceTracker<Filter, Filter>( _bundleContext, Filter.class, new FilterTracker(httpSupport)); _filterTracker.open(); Hashtable<String, Object> properties = new Hashtable<String, Object>(); properties.put("bean.id", HttpService.class.getName()); properties.put("original.bean", Boolean.TRUE); properties.put("service.vendor", ReleaseInfo.getVendor()); _httpServiceRegistration = _bundleContext.registerService( new String[] { ExtendedHttpService.class.getName(), HttpService.class.getName(), }, httpServiceFactory, properties); properties.put("bean.id", HttpServlet.class.getName()); _httpServletRegistration = _bundleContext.registerService( HttpServlet.class, this, properties); _servletTracker = new ServiceTracker<Servlet, Servlet>( _bundleContext, Servlet.class, new ServletTracker(httpSupport)); _servletTracker.open(); } public void service( HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { printHeaders(request); String portletId = (String)request.getAttribute(WebKeys.PORTLET_ID); String requestURI = request.getRequestURI(); String includeRequestURI = (String)request.getAttribute( JavaConstants.JAVAX_SERVLET_INCLUDE_PATH_INFO); if (Validator.isNotNull(includeRequestURI)) { requestURI = includeRequestURI; } ServletContext servletContext = getServletContext( portletId, requestURI); if (servletContext == null) { response.sendError( HttpServletResponse.SC_NOT_FOUND, "No servlet or resource mapped to " + requestURI); return; } service(request, response, servletContext, portletId, requestURI); } protected ServletContext getServletContext( String portletId, String requestURI) { Portlet portlet = null; if (Validator.isNotNull(portletId)) { try { String rootPortletId = PortletConstants.getRootPortletId( portletId); portlet = PortletLocalServiceUtil.getPortletById(rootPortletId); } catch (Exception e) { if (_log.isDebugEnabled()) { _log.debug(e, e); } } } String servletContextName = null; if (portlet != null) { PortletApp portletApp = portlet.getPortletApp(); servletContextName = portletApp.getServletContextName(); } else if (requestURI != null) { servletContextName = requestURI; String contextPath = PortalUtil.getPathContext(); if (Validator.isNotNull(contextPath) && servletContextName.startsWith(contextPath)) { servletContextName = servletContextName.substring( contextPath.length()); } String modulePath = Portal.PATH_MODULE + StringPool.SLASH; if (servletContextName.startsWith(modulePath)) { servletContextName = servletContextName.substring( modulePath.length()); } if (servletContextName.startsWith(StringPool.SLASH)) { servletContextName = servletContextName.substring(1); } int index = servletContextName.indexOf(StringPool.SLASH); if (index != -1) { servletContextName = servletContextName.substring(0, index); } } return ServletContextPool.get(servletContextName); } protected void printHeaders(HttpServletRequest request) { if (!_log.isDebugEnabled()) { return; } Enumeration<String> enumeration = request.getHeaderNames(); while (enumeration.hasMoreElements()) { Object name = enumeration.nextElement(); _log.debug(name + " = " + request.getHeader(String.valueOf(name))); } } protected void service( HttpServletRequest request, HttpServletResponse response, ServletContext servletContext, String portletId, String requestURI) throws IOException, ServletException { RequestDispatcher requestDispatcher = servletContext.getRequestDispatcher(requestURI); if (requestDispatcher != null) { requestDispatcher.forward(request, response); return; } if (requestURI.endsWith("/invoke") && Validator.isNotNull(portletId)) { super.service(request, response); return; } response.sendError( HttpServletResponse.SC_NOT_FOUND, "No servlet or resource mapped to " + requestURI); } private static Log _log = LogFactoryUtil.getLog(WebExtenderServlet.class); private BundleContext _bundleContext; private ServiceTracker<Filter, Filter> _filterTracker; private ServiceRegistration<?> _httpServiceRegistration; private ServiceRegistration<HttpServlet> _httpServletRegistration; private ServiceTracker<Servlet, Servlet> _servletTracker; }