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.servicemix.http.endpoints;
018    
019    import java.io.InputStream;
020    import java.io.OutputStream;
021    import java.util.Enumeration;
022    import java.util.Map;
023    import java.util.List;
024    import java.util.HashMap;
025    
026    import javax.jbi.component.ComponentContext;
027    import javax.jbi.messaging.Fault;
028    import javax.jbi.messaging.MessageExchange;
029    import javax.jbi.messaging.NormalizedMessage;
030    import javax.servlet.http.HttpServletRequest;
031    import javax.servlet.http.HttpServletResponse;
032    import javax.xml.namespace.QName;
033    
034    import org.apache.servicemix.soap.api.InterceptorChain;
035    import org.apache.servicemix.soap.api.InterceptorProvider.Phase;
036    import org.apache.servicemix.soap.api.Message;
037    import org.apache.servicemix.soap.api.Policy;
038    import org.apache.servicemix.soap.api.Interceptor;
039    import org.apache.servicemix.soap.api.model.Binding;
040    import org.apache.servicemix.soap.bindings.http.HttpConstants;
041    import org.apache.servicemix.soap.bindings.soap.SoapFault;
042    import org.apache.servicemix.soap.bindings.soap.SoapVersion;
043    import org.apache.servicemix.soap.interceptors.jbi.JbiConstants;
044    
045    /**
046     * 
047     * @author gnodet
048     * @since 3.2
049     */
050    public class HttpSoapConsumerMarshaler implements HttpConsumerMarshaler {
051    
052        private Binding<?> binding;
053        private boolean useJbiWrapper = true;
054        private Policy[] policies;
055        private Map<Phase, InterceptorChain> chains = new HashMap<Phase, InterceptorChain>();
056    
057        public Binding<?> getBinding() {
058            return binding;
059        }
060    
061        public void setBinding(Binding<?> binding) {
062            this.binding = binding;
063        }
064    
065        public boolean isUseJbiWrapper() {
066            return useJbiWrapper;
067        }
068    
069        public void setUseJbiWrapper(boolean useJbiWrapper) {
070            this.useJbiWrapper = useJbiWrapper;
071        }
072    
073        public Policy[] getPolicies() {
074            return policies;
075        }
076    
077        public void setPolicies(Policy[] policies) {
078            this.policies = policies;
079        }
080    
081        public MessageExchange createExchange(HttpServletRequest request, ComponentContext context) throws Exception {
082            String method = request.getMethod();
083            Message msg = binding.createMessage();
084            msg.put(ComponentContext.class, context);
085            msg.put(JbiConstants.USE_JBI_WRAPPER, useJbiWrapper);
086            msg.put(Message.CONTENT_TYPE, request.getContentType());
087            Map<String, String> headers = msg.getTransportHeaders();
088            for (Enumeration<?> e = request.getHeaderNames(); e.hasMoreElements();) {
089                String name = (String) e.nextElement();
090                String value = request.getHeader(name);
091                headers.put(name, value);
092            }
093            headers.put(HttpConstants.REQUEST_URI, request.getRequestURL().toString());
094            headers.put(HttpConstants.CONTENT_TYPE, request.getContentType());
095            headers.put(HttpConstants.REQUEST_METHOD, method);
096            if (HttpConstants.METHOD_POST.equals(method) || HttpConstants.METHOD_PUT.equals(method)) {
097                msg.setContent(InputStream.class, request.getInputStream());
098            }
099            request.setAttribute(Message.class.getName(), msg);
100            InterceptorChain phase = getChain(Phase.ServerIn);
101            phase.doIntercept(msg);
102            return msg.getContent(MessageExchange.class);
103        }
104    
105        public void sendAccepted(MessageExchange exchange, HttpServletRequest request, HttpServletResponse response)
106            throws Exception {
107            response.setStatus(HttpServletResponse.SC_ACCEPTED);
108        }
109    
110        public void sendOut(MessageExchange exchange, NormalizedMessage outMsg, HttpServletRequest request,
111            HttpServletResponse response) throws Exception {
112            Message in = (Message) request.getAttribute(Message.class.getName());
113            Message msg = binding.createMessage(in);
114            msg.setContent(OutputStream.class, response.getOutputStream());
115            msg.setContent(MessageExchange.class, exchange);
116            msg.setContent(NormalizedMessage.class, outMsg);
117            msg.put(SoapVersion.class, in.get(SoapVersion.class));
118            msg.put(JbiConstants.USE_JBI_WRAPPER, useJbiWrapper);
119            InterceptorChain phase = getChain(Phase.ServerOut);
120            phase.doIntercept(msg);
121            // TODO: handle http headers: Content-Type, ...
122        }
123    
124        public void sendError(MessageExchange exchange, Exception error, HttpServletRequest request,
125            HttpServletResponse response) throws Exception {
126            response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
127            Message in = (Message) request.getAttribute(Message.class.getName());
128            Message msg = binding.createMessage(in);
129            msg.setContent(OutputStream.class, response.getOutputStream());
130            msg.setContent(MessageExchange.class, exchange);
131            msg.put(SoapVersion.class, in.get(SoapVersion.class));
132            msg.put(JbiConstants.USE_JBI_WRAPPER, useJbiWrapper);
133            InterceptorChain phase = getChain(Phase.ServerOutFault);
134            SoapFault soapFault;
135            if (error instanceof SoapFault) {
136                soapFault = (SoapFault) error;
137            } else {
138                soapFault = new SoapFault(error);
139            }
140            msg.setContent(Exception.class, soapFault);
141            phase.doIntercept(msg);
142        }
143    
144        public void sendFault(MessageExchange exchange, Fault fault, HttpServletRequest request,
145            HttpServletResponse response) throws Exception {
146            response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
147            Message in = (Message) request.getAttribute(Message.class.getName());
148            Message msg = binding.createMessage(in);
149            msg.setContent(OutputStream.class, response.getOutputStream());
150            msg.setContent(MessageExchange.class, exchange);
151            msg.setContent(NormalizedMessage.class, fault);
152            msg.put(SoapVersion.class, in.get(SoapVersion.class));
153            msg.put(JbiConstants.USE_JBI_WRAPPER, useJbiWrapper);
154            InterceptorChain phase = getChain(Phase.ServerOutFault);
155            QName code = (QName) fault.getProperty("org.apache.servicemix.soap.fault.code");
156            String reason = (String) fault.getProperty("org.apache.servicemix.soap.fault.reason");
157            SoapFault soapFault = new SoapFault(code, reason, null, null, fault.getContent());
158            msg.setContent(Exception.class, soapFault);
159            phase.doIntercept(msg);
160            // TODO: handle http headers: Content-Type, ...
161        }
162    
163        protected InterceptorChain getChain(Phase phase) {
164            InterceptorChain chain = chains.get(phase);
165            if (chain == null) {
166                chain = binding.getInterceptorChain(phase);
167                if (policies != null) {
168                    for (int i = 0; i < policies.length; i++) {
169                        chain.add(policies[i].getInterceptors(phase));
170                    }
171                }
172                chains.put(phase, chain);
173            }
174            return chain;
175        }
176    
177    }