/******************************************************************************* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. * *******************************************************************************/ package org.apache.wink.server.internal.servlet; import java.io.IOException; import java.util.Enumeration; import javax.servlet.Filter; import javax.servlet.FilterChain; import javax.servlet.FilterConfig; import javax.servlet.ServletConfig; import javax.servlet.ServletContext; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponseWrapper; import org.apache.wink.server.internal.DeploymentConfiguration; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * <p> * Filter that is used by the runtime to handle the incoming request. * </p> * Initialization and configuration options are the same as the RestServlet. * * @see RestServlet */ public class RestFilter implements Filter { private RestServlet restServlet; private static final Logger logger = LoggerFactory.getLogger(RestFilter.class); private static class FilteredHttpServletResponse extends HttpServletResponseWrapper { private static final Logger logger = LoggerFactory .getLogger(FilteredHttpServletResponse.class); public FilteredHttpServletResponse(HttpServletResponse response) { super(response); } private int statusCode; @Override public void setStatus(int statusCode) { super.setStatus(statusCode); this.statusCode = statusCode; logger.trace("FilteredHttpServletResponse set status code to {}", statusCode); //$NON-NLS-1$ } @Override public void setStatus(int statusCode, String msg) { super.setStatus(statusCode, msg); this.statusCode = statusCode; logger.trace("FilteredHttpServletResponse set status code to {}", statusCode); //$NON-NLS-1$ } int getStatusCode() { return this.statusCode; } } public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain chain) throws IOException, ServletException { if (servletRequest instanceof HttpServletRequest && servletResponse instanceof HttpServletResponse) { FilteredHttpServletResponse httpServletResponse = new FilteredHttpServletResponse((HttpServletResponse)servletResponse); restServlet.service((HttpServletRequest)servletRequest, (HttpServletResponse)httpServletResponse); if (!httpServletResponse.isCommitted() && httpServletResponse.getStatusCode() == HttpServletResponse.SC_NOT_FOUND) { /* * reset the status to 200 so that if a future * HttpServletResponse call uses an include (or writes * directly), then the status code is like the filter was never * invoked */ logger .trace("Filter {} did not match a resource so letting request continue on FilterChain {}", //$NON-NLS-1$ this, chain); httpServletResponse.setStatus(HttpServletResponse.SC_OK); chain.doFilter(servletRequest, servletResponse); } } else { logger .trace("Filter {} did not expect a non-HttpServletRequest and/or non-HttpServletResponse but letting chain continue", this); //$NON-NLS-1$ chain.doFilter(servletRequest, servletResponse); } } protected static class RestServletForFilter extends RestServlet { protected FilterConfig filterConfig; private static final long serialVersionUID = 5230595914609866319L; public RestServletForFilter(FilterConfig config) { super(); this.filterConfig = config; } @Override protected DeploymentConfiguration getDeploymentConfiguration() throws ClassNotFoundException, InstantiationException, IllegalAccessException, IOException { DeploymentConfiguration deploymentConfiguration = super.getDeploymentConfiguration(); deploymentConfiguration.setFilterConfig(filterConfig); return deploymentConfiguration; } } public void init(final FilterConfig filterConfig) throws ServletException { restServlet = new RestServletForFilter(filterConfig); logger.trace("Initializing RestFilter {} with {} config and {} servlet", new Object[] { //$NON-NLS-1$ this, filterConfig, restServlet}); restServlet.init(new ServletConfig() { public String getServletName() { return filterConfig.getFilterName(); } public ServletContext getServletContext() { return filterConfig.getServletContext(); } public Enumeration<?> getInitParameterNames() { return filterConfig.getInitParameterNames(); } public String getInitParameter(String paramName) { return filterConfig.getInitParameter(paramName); } }); } public void destroy() { logger.trace("Destroying RestFilter {}", this); //$NON-NLS-1$ restServlet.destroy(); } }