001    /**
002     * Licensed to the Apache Software Foundation (ASF) under one or more
003     * contributor license agreements.  See the NOTICE file distributed with
004     * this work for additional information regarding copyright ownership.
005     * The ASF licenses this file to You under the Apache License, Version 2.0
006     * (the "License"); you may not use this file except in compliance with
007     * the License.  You may obtain a copy of the License at
008     *
009     *      http://www.apache.org/licenses/LICENSE-2.0
010     *
011     * Unless required by applicable law or agreed to in writing, software
012     * distributed under the License is distributed on an "AS IS" BASIS,
013     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014     * See the License for the specific language governing permissions and
015     * limitations under the License.
016     */
017    package org.apache.camel.component.http;
018    
019    import java.io.IOException;
020    import java.util.concurrent.ConcurrentHashMap;
021    
022    import javax.servlet.ServletException;
023    import javax.servlet.http.HttpServlet;
024    import javax.servlet.http.HttpServletRequest;
025    import javax.servlet.http.HttpServletResponse;
026    
027    import org.apache.camel.ExchangePattern;
028    import org.apache.camel.impl.DefaultExchange;
029    
030    /**
031     * @version $Revision: 813653 $
032     */
033    public class CamelServlet extends HttpServlet {
034    
035        private static final long serialVersionUID = -7061982839117697829L;
036    
037        private ConcurrentHashMap<String, HttpConsumer> consumers = new ConcurrentHashMap<String, HttpConsumer>();
038       
039        @Override
040        protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
041            try {
042    
043                // Is there a consumer registered for the request.
044                HttpConsumer consumer = resolve(request);
045                if (consumer == null) {
046                    response.sendError(HttpServletResponse.SC_NOT_FOUND);
047                    return;
048                }
049    
050                // Have the camel process the HTTP exchange.
051                DefaultExchange exchange = new DefaultExchange(consumer.getEndpoint(), ExchangePattern.InOut);
052                exchange.setIn(new HttpMessage(exchange, request, response));
053                consumer.getProcessor().process(exchange);
054    
055                // HC: The getBinding() is interesting because it illustrates the
056                // impedance miss-match between
057                // HTTP's stream oriented protocol, and Camels more message oriented
058                // protocol exchanges.
059    
060                // now lets output to the response
061                consumer.getBinding().writeResponse(exchange, response);
062    
063            } catch (Exception e) {
064                e.printStackTrace();
065                throw new ServletException(e);
066            }
067        }
068    
069        protected HttpConsumer resolve(HttpServletRequest request) {
070            String path = request.getPathInfo();
071            if (path == null) {
072                return null;
073            }
074            HttpConsumer answer = consumers.get(path);
075                   
076            if (answer == null) {
077                for (String key : consumers.keySet()) {
078                    if (consumers.get(key).getEndpoint().isMatchOnUriPrefix() && path.startsWith(key)) {
079                        answer = consumers.get(key);
080                        break;
081                    }
082                }
083            }
084            return answer;
085        }
086    
087        public void connect(HttpConsumer consumer) {
088            consumers.put(consumer.getPath(), consumer);
089        }
090    
091        public void disconnect(HttpConsumer consumer) {
092            consumers.remove(consumer.getPath());
093        }
094        
095    }