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.util.HashMap; 020 import java.util.Iterator; 021 import java.util.Map; 022 import javax.xml.namespace.QName; 023 import javax.xml.transform.Source; 024 025 import org.apache.camel.Endpoint; 026 import org.apache.camel.Exchange; 027 import org.apache.camel.ExchangePattern; 028 import org.apache.camel.Message; 029 import org.apache.camel.Processor; 030 import org.apache.camel.converter.jaxp.XmlConverter; 031 import org.apache.camel.impl.DefaultConsumer; 032 import org.apache.camel.impl.DefaultExchange; 033 import org.springframework.ws.WebServiceMessage; 034 import org.springframework.ws.context.MessageContext; 035 import org.springframework.ws.server.endpoint.MessageEndpoint; 036 import org.springframework.ws.soap.SoapHeader; 037 import org.springframework.ws.soap.SoapHeaderElement; 038 import org.springframework.ws.soap.SoapMessage; 039 040 public class SpringWebserviceConsumer extends DefaultConsumer implements MessageEndpoint { 041 042 private SpringWebserviceEndpoint endpoint; 043 private SpringWebserviceConfiguration configuration; 044 045 public SpringWebserviceConsumer(Endpoint endpoint, Processor processor) { 046 super(endpoint, processor); 047 this.endpoint = (SpringWebserviceEndpoint) endpoint; 048 this.configuration = this.endpoint.getConfiguration(); 049 } 050 051 /** 052 * Invoked by Spring-WS when a {@link WebServiceMessage} is received 053 */ 054 public void invoke(MessageContext messageContext) throws Exception { 055 Exchange exchange = new DefaultExchange(endpoint.getCamelContext(), ExchangePattern.InOptionalOut); 056 populateExchangeFromMessageContext(messageContext, exchange); 057 058 // start message processing 059 getProcessor().process(exchange); 060 061 if (exchange.getException() != null) { 062 throw exchange.getException(); 063 } else if (exchange.getPattern().isOutCapable()) { 064 Message responseMessage = exchange.getOut(Message.class); 065 if (responseMessage != null) { 066 Source responseBody = responseMessage.getBody(Source.class); 067 WebServiceMessage response = messageContext.getResponse(); 068 XmlConverter xmlConverter = configuration.getXmlConverter(); 069 xmlConverter.toResult(responseBody, response.getPayloadResult()); 070 } 071 } 072 } 073 074 private void populateExchangeFromMessageContext(MessageContext messageContext, Exchange exchange) { 075 populateExchangeWithPropertiesFromMessageContext(messageContext, exchange); 076 077 // create inbound message 078 WebServiceMessage request = messageContext.getRequest(); 079 SpringWebserviceMessage inMessage = new SpringWebserviceMessage(request); 080 inMessage.setHeaders(extractSoapHeadersFromWebServiceMessage(request)); 081 exchange.setIn(inMessage); 082 } 083 084 private void populateExchangeWithPropertiesFromMessageContext(MessageContext messageContext, Exchange exchange) { 085 // convert WebserviceMessage properties (added through interceptors) to 086 // Camel exchange properties 087 String[] propertyNames = messageContext.getPropertyNames(); 088 if (propertyNames != null) { 089 for (String propertyName : propertyNames) { 090 exchange.setProperty(propertyName, messageContext.getProperty(propertyName)); 091 } 092 } 093 } 094 095 private Map<String, Object> extractSoapHeadersFromWebServiceMessage(WebServiceMessage request) { 096 Map<String, Object> headers = new HashMap<String, Object>(); 097 if (request instanceof SoapMessage) { 098 SoapMessage soapMessage = (SoapMessage) request; 099 SoapHeader soapHeader = soapMessage.getSoapHeader(); 100 if (soapHeader != null) { 101 Iterator<?> attibutesIterator = soapHeader.getAllAttributes(); 102 while (attibutesIterator.hasNext()) { 103 QName name = (QName) attibutesIterator.next(); 104 headers.put(name.toString(), soapHeader.getAttributeValue(name)); 105 } 106 Iterator<?> elementIter = soapHeader.examineAllHeaderElements(); 107 while (elementIter.hasNext()) { 108 Object element = elementIter.next(); 109 if (element instanceof SoapHeaderElement) { 110 QName name = ((SoapHeaderElement) element).getName(); 111 headers.put(name.toString(), element); 112 } 113 } 114 } 115 } 116 return headers; 117 } 118 119 @Override 120 protected void doStop() throws Exception { 121 if (configuration.getEndpointMapping() != null) { 122 configuration.getEndpointMapping().removeConsumer(configuration.getEndpointMappingKey()); 123 } 124 super.doStop(); 125 } 126 127 @Override 128 protected void doStart() throws Exception { 129 if (configuration.getEndpointMapping() != null) { 130 configuration.getEndpointMapping().addConsumer(configuration.getEndpointMappingKey(), this); 131 } 132 super.doStart(); 133 } 134 135 }