/* * Copyright 2002-2011 the original author or authors. * * Licensed 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.springframework.flex.servlet; import javax.servlet.ServletConfig; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.springframework.util.Assert; import org.springframework.web.context.ServletConfigAware; import org.springframework.web.servlet.HandlerAdapter; import org.springframework.web.servlet.HandlerMapping; import org.springframework.web.servlet.ModelAndView; import flex.messaging.FlexContext; import flex.messaging.HttpFlexSession; import flex.messaging.HttpFlexSessionProvider; import flex.messaging.MessageBroker; import flex.messaging.MessageException; import flex.messaging.endpoints.Endpoint; import flex.messaging.io.SerializationContext; /** * {@link HandlerAdapter} for routing HTTP messages to a Spring-managed {@link MessageBroker}. * * <p> * This class is automatically registered with the application context when using the <code>message-broker</code> tag in * the xml configuration namespace. * * @see MessageBroker * @see HandlerMapping * * @author Jeremy Grelle */ public class MessageBrokerHandlerAdapter implements HandlerAdapter, ServletConfigAware { private static final Log logger = LogFactory.getLog(MessageBrokerHandlerAdapter.class); private ServletConfig servletConfig; /** * * {@inheritDoc} */ public long getLastModified(HttpServletRequest request, Object handler) { return -1; } /** * * {@inheritDoc} */ public ModelAndView handle(HttpServletRequest req, HttpServletResponse res, Object handler) throws Exception { MessageBroker broker = (MessageBroker) handler; try { // Update thread locals broker.initThreadLocals(); // Set this first so it is in place for the session creation event. FlexContext.setThreadLocalObjects(null, null, broker, req, res, this.servletConfig); Object providerToCheck = broker.getFlexSessionManager().getFlexSessionProvider(HttpFlexSession.class); Assert.isInstanceOf(HttpFlexSessionProvider.class, providerToCheck, "MessageBrokerHandlerAdapter requires an instance of "+HttpFlexSessionProvider.class.getName()+ " to have been registered with the MessageBroker."); HttpFlexSessionProvider provider = (HttpFlexSessionProvider) providerToCheck; provider.getOrCreateSession(req); String contextPath = req.getContextPath(); String pathInfo = req.getPathInfo(); String endpointPath = req.getServletPath(); if (pathInfo != null) { endpointPath = endpointPath + pathInfo; } Endpoint endpoint = null; try { endpoint = broker.getEndpoint(endpointPath, contextPath); } catch (MessageException me) { if (logger.isErrorEnabled()) { logger.error("Received invalid request for endpoint path '" + endpointPath + "'."); } if (!res.isCommitted()) { res.sendError(HttpServletResponse.SC_NOT_FOUND); } return null; } try { if (logger.isInfoEnabled()) { logger.info("Channel endpoint " + endpoint.getId() + " received request."); } endpoint.service(req, res); } catch (UnsupportedOperationException ue) { if (logger.isErrorEnabled()) { logger.error("Channel endpoint " + endpoint.getId() + " received request for an unsupported operation.", ue); } if (!res.isCommitted()) { res.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED); } } } finally { FlexContext.clearThreadLocalObjects(); SerializationContext.clearThreadLocalObjects(); } return null; } /** * * {@inheritDoc} */ public void setServletConfig(ServletConfig servletConfig) { this.servletConfig = servletConfig; } /** * * {@inheritDoc} */ public boolean supports(Object handler) { return handler instanceof MessageBroker; } }