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.ByteArrayInputStream;
020    import java.io.ByteArrayOutputStream;
021    import java.io.InputStream;
022    import java.io.OutputStream;
023    import java.util.Map;
024    import java.util.HashMap;
025    
026    import javax.jbi.messaging.MessageExchange;
027    import javax.jbi.messaging.NormalizedMessage;
028    
029    import org.apache.servicemix.http.jetty.SmxHttpExchange;
030    import org.apache.servicemix.soap.api.InterceptorChain;
031    import org.apache.servicemix.soap.api.InterceptorProvider.Phase;
032    import org.apache.servicemix.soap.api.Message;
033    import org.apache.servicemix.soap.api.Policy;
034    import org.apache.servicemix.soap.api.model.Binding;
035    import org.apache.servicemix.soap.bindings.soap.SoapConstants;
036    import org.apache.servicemix.soap.interceptors.jbi.JbiConstants;
037    import org.apache.servicemix.soap.interceptors.xml.StaxInInterceptor;
038    import org.mortbay.io.ByteArrayBuffer;
039    import org.mortbay.jetty.HttpMethods;
040    
041    /**
042     * 
043     * @author gnodet
044     * @since 3.2
045     */
046    public class HttpSoapProviderMarshaler implements HttpProviderMarshaler {
047    
048        private Binding<?> binding;
049        private boolean useJbiWrapper = true;
050        private Policy[] policies;
051        private String baseUrl;
052        private Map<Phase, InterceptorChain> chains = new HashMap<Phase, InterceptorChain>();
053    
054        public Binding<?> getBinding() {
055            return binding;
056        }
057    
058        public void setBinding(Binding<?> binding) {
059            this.binding = binding;
060        }
061    
062        public String getBaseUrl() {
063            return baseUrl;
064        }
065    
066        public void setBaseUrl(String baseUrl) {
067            this.baseUrl = baseUrl;
068        }
069    
070        public boolean isUseJbiWrapper() {
071            return useJbiWrapper;
072        }
073    
074        public void setUseJbiWrapper(boolean useJbiWrapper) {
075            this.useJbiWrapper = useJbiWrapper;
076        }
077    
078        public Policy[] getPolicies() {
079            return policies;
080        }
081    
082        public void setPolicies(Policy[] policies) {
083            this.policies = policies;
084        }
085        
086        public void createRequest(final MessageExchange exchange,
087                                  final NormalizedMessage inMsg, 
088                                  final SmxHttpExchange httpExchange) throws Exception {
089            ByteArrayOutputStream baos = new ByteArrayOutputStream();
090            Message msg = binding.createMessage();
091            msg.put(JbiConstants.USE_JBI_WRAPPER, useJbiWrapper);
092            msg.setContent(MessageExchange.class, exchange);
093            msg.setContent(NormalizedMessage.class, inMsg);
094            msg.setContent(OutputStream.class, baos);
095            exchange.setProperty(Message.class.getName(), msg);
096    
097            InterceptorChain phaseOut = getChain(Phase.ClientOut);
098            phaseOut.doIntercept(msg);
099            httpExchange.setMethod(HttpMethods.POST);
100            httpExchange.setURL(baseUrl);
101            httpExchange.setRequestContent(new ByteArrayBuffer(baos.toByteArray()));
102            for (Map.Entry<String,String> entry : msg.getTransportHeaders().entrySet()) {
103                httpExchange.addRequestHeader(entry.getKey(), entry.getValue());
104            }
105            /*
106            httpExchange.setRequestEntity(new Entity() {
107                public void write(OutputStream os, Writer w) throws IOException {
108                    // TODO: handle http headers: Content-Type, ... 
109                }
110            });
111            */
112            // TODO: use streaming when appropriate (?)
113        }
114    
115        public void handleResponse(MessageExchange exchange, SmxHttpExchange httpExchange) throws Exception {
116            Message req = (Message) exchange.getProperty(Message.class.getName());
117            exchange.setProperty(Message.class.getName(), null);
118            Message msg = binding.createMessage(req);
119            msg.put(JbiConstants.USE_JBI_WRAPPER, useJbiWrapper);
120            msg.setContent(MessageExchange.class, exchange);
121            msg.setContent(InputStream.class, new ByteArrayInputStream(httpExchange.getResponseData()));
122            msg.put(StaxInInterceptor.ENCODING, httpExchange.getResponseEncoding());
123            InterceptorChain phaseOut = getChain(Phase.ClientIn);
124            phaseOut.doIntercept(msg);
125            // TODO: Retrieve headers ? 
126        }
127    
128        public void handleException(MessageExchange exchange, SmxHttpExchange httpExchange, Throwable ex) {
129            exchange.setError((Exception)ex);
130        }
131    
132    
133        protected InterceptorChain getChain(Phase phase) {
134            InterceptorChain chain = chains.get(phase);
135            if (chain == null) {
136                chain = binding.getInterceptorChain(phase);
137                if (policies != null) {
138                    for (int i = 0; i < policies.length; i++) {
139                        chain.add(policies[i].getInterceptors(phase));
140                    }
141                }
142                chains.put(phase, chain);
143            }
144            return chain;
145        }
146    
147    }