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.spring.ws;
018    
019    import java.io.IOException;
020    import java.net.URI;
021    import javax.xml.transform.Source;
022    import javax.xml.transform.TransformerException;
023    
024    import org.apache.camel.Endpoint;
025    import org.apache.camel.Exchange;
026    import org.apache.camel.TypeConverter;
027    import org.apache.camel.impl.DefaultProducer;
028    import org.apache.camel.util.ExchangeHelper;
029    import org.springframework.ws.WebServiceMessage;
030    import org.springframework.ws.client.core.SourceExtractor;
031    import org.springframework.ws.client.core.WebServiceMessageCallback;
032    import org.springframework.ws.soap.addressing.client.ActionCallback;
033    import org.springframework.ws.soap.client.core.SoapActionCallback;
034    
035    public class SpringWebserviceProducer extends DefaultProducer {
036    
037        private static final SourceExtractor SOURCE_EXTRACTOR = new NoopSourceExtractor();
038        private SpringWebserviceEndpoint endpoint;
039    
040        public SpringWebserviceProducer(Endpoint endpoint) {
041            super(endpoint);
042            this.endpoint = (SpringWebserviceEndpoint) endpoint;
043        }
044    
045        public void process(Exchange exchange) throws Exception {
046            // Let Camel TypeConverter hierarchy handle the conversion of XML messages to Source objects
047            Source sourcePayload = exchange.getIn().getMandatoryBody(Source.class);
048    
049            // Extract optional headers
050            String endpointUri = exchange.getIn().getHeader(SpringWebserviceConstants.SPRING_WS_ENDPOINT_URI, String.class);
051            String soapAction = exchange.getIn().getHeader(SpringWebserviceConstants.SPRING_WS_SOAP_ACTION, String.class);
052            URI wsAddressingAction = exchange.getIn().getHeader(SpringWebserviceConstants.SPRING_WS_ADDRESSING_ACTION, URI.class);
053    
054            WebServiceMessageCallback callback = new DefaultWebserviceMessageCallback(soapAction, wsAddressingAction);
055            Object body = null;
056            if (endpointUri != null) {
057                body = endpoint.getConfiguration().getWebServiceTemplate().sendSourceAndReceive(endpointUri, sourcePayload, callback, SOURCE_EXTRACTOR);
058            } else {
059                body = endpoint.getConfiguration().getWebServiceTemplate().sendSourceAndReceive(sourcePayload, callback, SOURCE_EXTRACTOR);
060            }
061            if (ExchangeHelper.isOutCapable(exchange)) {
062                exchange.getOut().copyFrom(exchange.getIn());
063                exchange.getOut().setBody(body);
064            }
065        }
066    
067        protected class DefaultWebserviceMessageCallback implements WebServiceMessageCallback {
068            private String soapActionHeader;
069            private URI wsAddressingActionHeader;
070    
071            public DefaultWebserviceMessageCallback(String soapAction, URI wsAddressingAction) {
072                this.soapActionHeader = soapAction;
073                this.wsAddressingActionHeader = wsAddressingAction;
074            }
075    
076            public void doWithMessage(WebServiceMessage message) throws IOException, TransformerException {
077                // Add SoapAction to webservice request. Note that exchange header
078                // takes precedence over endpoint option
079                String soapAction = soapActionHeader != null ? soapActionHeader : endpoint.getConfiguration().getSoapAction();
080                if (soapAction != null) {
081                    new SoapActionCallback(soapAction).doWithMessage(message);
082                }
083                // Add WS-Addressing Action to webservice request (the WS-Addressing
084                // 'to' header will default to the URL of the connection).
085                // Note that exchange header takes precedence over endpoint option
086                URI wsAddressingAction = wsAddressingActionHeader != null ? wsAddressingActionHeader : endpoint.getConfiguration().getWsAddressingAction();
087                if (wsAddressingAction != null) {
088                    new ActionCallback(wsAddressingAction).doWithMessage(message);
089                }
090            }
091        }
092    
093        /**
094         * A {@link SourceExtractor} that performs no conversion, instead conversion
095         * is handled by Camel's {@link TypeConverter} hierarchy.
096         */
097        private static class NoopSourceExtractor implements SourceExtractor {
098            public Object extractData(Source source) throws IOException, TransformerException {
099                return source;
100            }
101        }
102    }