001
014
015 package com.liferay.portal.osgi;
016
017 import com.liferay.portal.kernel.log.Log;
018 import com.liferay.portal.kernel.log.LogFactoryUtil;
019 import com.liferay.portal.kernel.util.JavaConstants;
020 import com.liferay.portal.kernel.util.StringPool;
021 import com.liferay.portal.kernel.util.Validator;
022 import com.liferay.portal.osgi.service.OSGiServiceUtil;
023 import com.liferay.portal.util.PortalUtil;
024
025 import java.io.IOException;
026
027 import java.util.Hashtable;
028
029 import javax.servlet.ServletConfig;
030 import javax.servlet.ServletException;
031 import javax.servlet.http.HttpServlet;
032 import javax.servlet.http.HttpServletRequest;
033 import javax.servlet.http.HttpServletRequestWrapper;
034 import javax.servlet.http.HttpServletResponse;
035
036 import org.osgi.framework.BundleContext;
037 import org.osgi.framework.ServiceReference;
038 import org.osgi.framework.launch.Framework;
039
040
043 public class OSGiServlet extends HttpServlet {
044
045 @Override
046 public void init(ServletConfig servletConfig) throws ServletException {
047 super.init(servletConfig);
048
049 BundleContext bundleContext = getBundleContext();
050
051 if (bundleContext == null) {
052 if (_log.isWarnEnabled()) {
053 _log.warn("No framework available");
054 }
055
056 return;
057 }
058
059 registerServletConfig(servletConfig);
060
061 _serviceReference = bundleContext.getServiceReference(
062 _HTTP_SERVICE_SERVLET_WRAPPER);
063
064 if (_serviceReference == null) {
065 _log.warn("No HTTP service available");
066
067 return;
068 }
069
070 HttpServlet httpServlet = (HttpServlet)bundleContext.getService(
071 _serviceReference);
072
073 httpServlet.init(servletConfig);
074 }
075
076 @Override
077 public void service(
078 HttpServletRequest request, HttpServletResponse response)
079 throws IOException, ServletException {
080
081 BundleContext bundleContext = getBundleContext();
082
083 if (bundleContext == null) {
084 PortalUtil.sendError(
085 HttpServletResponse.SC_SERVICE_UNAVAILABLE,
086 new IllegalStateException("No framework available"),
087 request, response);
088
089 return;
090 }
091
092 String pathInfo = request.getPathInfo();
093
094 if (Validator.isNull(pathInfo) || pathInfo.equals(StringPool.SLASH)) {
095 PortalUtil.sendError(
096 HttpServletResponse.SC_NOT_FOUND,
097 new IllegalArgumentException("No path was available"), request,
098 response);
099
100 return;
101 }
102
103 if (isExtensionMapping(pathInfo)) {
104 request = new ExtensionMappingRequest(request);
105 }
106
107 if (request.getAttribute(
108 JavaConstants.JAVAX_SERVLET_INCLUDE_REQUEST_URI) != null) {
109
110 String includePathInfo = (String)request.getAttribute(
111 JavaConstants.JAVAX_SERVLET_INCLUDE_PATH_INFO);
112
113 if (Validator.isNull(includePathInfo)) {
114 String includeServletPath = (String)request.getAttribute(
115 JavaConstants.JAVAX_SERVLET_INCLUDE_SERVLET_PATH);
116
117 String servletPath = request.getServletPath();
118
119 if (includeServletPath.contains(servletPath)) {
120 includeServletPath = includeServletPath.substring(
121 servletPath.length());
122 }
123
124 if (isExtensionMapping(includeServletPath)) {
125 request = new IncludedExtensionMappingRequest(
126 request, servletPath);
127 }
128 }
129 }
130
131 _serviceReference = bundleContext.getServiceReference(
132 _HTTP_SERVICE_SERVLET_WRAPPER);
133
134 if (_serviceReference == null) {
135 PortalUtil.sendError(
136 HttpServletResponse.SC_SERVICE_UNAVAILABLE,
137 new IllegalStateException("No HTTP service available"),
138 request, response);
139
140 return;
141 }
142
143 HttpServlet httpServlet = (HttpServlet)bundleContext.getService(
144 _serviceReference);
145
146 httpServlet.init(getServletConfig());
147
148 httpServlet.service(request, response);
149 }
150
151 protected BundleContext getBundleContext() {
152 if (_bundleContext != null) {
153 return _bundleContext;
154 }
155
156 Framework framework = OSGiServiceUtil.getFramework();
157
158 if (framework != null) {
159 _bundleContext = framework.getBundleContext();
160 }
161
162 return _bundleContext;
163 }
164
165 protected boolean isExtensionMapping(String servletPath) {
166 int pos = servletPath.lastIndexOf(StringPool.SLASH);
167
168 if (pos != -1) {
169 servletPath = servletPath.substring(pos + 1);
170 }
171
172 return servletPath.indexOf(StringPool.PERIOD) != -1;
173 }
174
175 protected void registerServletConfig(ServletConfig servletConfig) {
176 Hashtable<String, Object> properties = new Hashtable<String, Object>();
177
178 properties.put(OSGiConstants.BEAN_ID, ServletConfig.class.getName());
179 properties.put(OSGiConstants.ORIGINAL_BEAN, Boolean.TRUE);
180
181 _bundleContext.registerService(
182 new String[] {ServletConfig.class.getName()}, servletConfig,
183 properties);
184 }
185
186 private static final String _HTTP_SERVICE_SERVLET_WRAPPER =
187 "com.liferay.osgi.http.HttpServiceServletWrapper";
188
189 private static Log _log = LogFactoryUtil.getLog(OSGiServlet.class);
190
191 private BundleContext _bundleContext;
192 private ServiceReference<?> _serviceReference;
193
194 private class ExtensionMappingRequest extends HttpServletRequestWrapper {
195
196 public ExtensionMappingRequest(HttpServletRequest request) {
197 super(request);
198 }
199
200 @Override
201 public String getServletPath() {
202 return StringPool.BLANK;
203 }
204
205 }
206
207 private class IncludedExtensionMappingRequest
208 extends ExtensionMappingRequest {
209
210 private String _servletPath;
211
212 public IncludedExtensionMappingRequest(
213 HttpServletRequest request, String servletPath) {
214
215 super(request);
216
217 _servletPath = servletPath;
218 }
219
220 @Override
221 public Object getAttribute(String attributeName) {
222 if (attributeName.equals(
223 JavaConstants.JAVAX_SERVLET_INCLUDE_SERVLET_PATH)) {
224
225 return StringPool.BLANK;
226 }
227 else if (attributeName.equals(
228 JavaConstants.JAVAX_SERVLET_INCLUDE_PATH_INFO)) {
229
230 String includeServletPath = (String)super.getAttribute(
231 JavaConstants.JAVAX_SERVLET_INCLUDE_SERVLET_PATH);
232
233 if (includeServletPath.contains(_servletPath)) {
234 includeServletPath = includeServletPath.substring(
235 _servletPath.length());
236 }
237
238 return includeServletPath;
239 }
240
241 return super.getAttribute(attributeName);
242 }
243
244 }
245
246 }