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.cxf;
018    
019    import java.io.InputStream;
020    import java.lang.reflect.Method;
021    import java.util.ArrayList;
022    import java.util.HashMap;
023    import java.util.HashSet;
024    import java.util.List;
025    import java.util.Map;
026    import java.util.Set;
027    
028    import javax.activation.DataHandler;
029    import javax.security.auth.Subject;
030    import javax.xml.namespace.QName;
031    import javax.xml.transform.dom.DOMSource;
032    import javax.xml.ws.Holder;
033    
034    import org.w3c.dom.Element;
035    import org.w3c.dom.Node;
036    
037    import org.apache.camel.Exchange;
038    import org.apache.camel.ExchangePattern;
039    import org.apache.camel.spi.HeaderFilterStrategy;
040    import org.apache.camel.spi.HeaderFilterStrategyAware;
041    import org.apache.commons.logging.Log;
042    import org.apache.commons.logging.LogFactory;
043    import org.apache.cxf.attachment.AttachmentImpl;
044    import org.apache.cxf.binding.soap.SoapHeader;
045    import org.apache.cxf.endpoint.Client;
046    import org.apache.cxf.endpoint.Endpoint;
047    import org.apache.cxf.frontend.MethodDispatcher;
048    import org.apache.cxf.headers.Header;
049    import org.apache.cxf.helpers.CastUtils;
050    import org.apache.cxf.helpers.DOMUtils;
051    import org.apache.cxf.helpers.XMLUtils;
052    import org.apache.cxf.jaxws.context.WrappedMessageContext;
053    import org.apache.cxf.message.Attachment;
054    import org.apache.cxf.message.Message;
055    import org.apache.cxf.message.MessageContentsList;
056    import org.apache.cxf.security.SecurityContext;
057    import org.apache.cxf.service.Service;
058    import org.apache.cxf.service.model.BindingMessageInfo;
059    import org.apache.cxf.service.model.BindingOperationInfo;
060    import org.apache.cxf.service.model.MessagePartInfo;
061    import org.apache.cxf.service.model.OperationInfo;
062    
063    /**
064     * The Default CXF binding implementation.
065     * 
066     * @version $Revision: 19959 $
067     */
068    public class DefaultCxfBinding implements CxfBinding, HeaderFilterStrategyAware {
069        private static final Log LOG = LogFactory.getLog(DefaultCxfBinding.class);
070        private HeaderFilterStrategy headerFilterStrategy;
071    
072        // CxfBinding Methods
073        // -------------------------------------------------------------------------
074        
075        /**
076         * <p>
077         * This method is called by {@link CxfProducer#process(Exchange)}. It populates 
078         * the CXF exchange and invocation context (i.e. request/response) contexts, it 
079         * but does not create and populate a CXF message as a ClientImpl's invoke method
080         * will create a new CXF Message.  That method will put all properties from the 
081         * CXF exchange and request context to the CXF message.
082         * </p>
083         */
084        public void populateCxfRequestFromExchange(
085                org.apache.cxf.message.Exchange cxfExchange, Exchange camelExchange,
086                Map<String, Object> requestContext) {
087                   
088            // propagate request context
089            Map<String, Object> camelHeaders = camelExchange.getIn().getHeaders();
090            extractInvocationContextFromCamel(camelExchange, camelHeaders,
091                    requestContext, Client.REQUEST_CONTEXT);
092                    
093            // propagate headers
094            propagateHeadersFromCamelToCxf(camelExchange, camelHeaders, cxfExchange, 
095                    requestContext);
096            
097            // propagate attachments
098            Set<Attachment> attachments = null;
099            for (Map.Entry<String, DataHandler> entry : camelExchange.getIn().getAttachments().entrySet()) {
100                if (attachments == null) {
101                    attachments = new HashSet<Attachment>();
102                }
103                AttachmentImpl attachment = new AttachmentImpl(entry.getKey(), entry.getValue());
104                attachment.setXOP(true); // only supports MTOM
105                attachments.add(attachment);
106            }
107            
108            if (attachments != null) {
109                requestContext.put(CxfConstants.CAMEL_CXF_ATTACHMENTS, attachments);
110            }
111        }
112        
113        /**
114         * This method is called by {@link CxfProducer#process(Exchange)}.  It propagates 
115         * information from CXF Exchange to Camel Exchange.  The CXF Exchange contains a 
116         * request from a CXF server.
117         */
118        public void populateExchangeFromCxfResponse(Exchange camelExchange,
119                org.apache.cxf.message.Exchange cxfExchange, 
120                Map<String, Object> responseContext) {
121          
122            Message cxfMessage = cxfExchange.getInMessage();
123            
124            if (LOG.isTraceEnabled()) {
125                LOG.trace("Populate exchange from CXF response message: " + cxfMessage);
126            }
127            
128            // propagate body
129            camelExchange.getOut().setBody(DefaultCxfBinding.getContentFromCxf(cxfMessage, 
130                    camelExchange.getProperty(CxfConstants.DATA_FORMAT_PROPERTY, DataFormat.class)));
131            
132            // propagate response context
133            if (responseContext != null && responseContext.size() > 0) {
134                if (!headerFilterStrategy.applyFilterToExternalHeaders(Client.RESPONSE_CONTEXT, 
135                                                                       responseContext, camelExchange)) {        
136                    camelExchange.getOut().setHeader(Client.RESPONSE_CONTEXT, responseContext);
137                    if (LOG.isTraceEnabled()) {
138                        LOG.trace("Set header = " + Client.RESPONSE_CONTEXT + " value = " 
139                                  + responseContext);
140                    }
141                }
142            }
143            
144            // propagate protocol headers
145            propagateHeadersFromCxfToCamel(cxfMessage, camelExchange.getOut(), camelExchange);
146            
147            if (cxfMessage.getAttachments() != null) {
148                // TODO: workaround for CXF-2503
149                try {
150                    cxfMessage.getAttachments().size();
151                } catch (java.util.ConcurrentModificationException e) {
152                    // ignore
153                }
154                // end of workaround
155    
156                // propagate attachments
157                for (Attachment attachment : cxfMessage.getAttachments()) {
158                    camelExchange.getOut().addAttachment(attachment.getId(), attachment.getDataHandler());
159                }        
160            }
161        }
162        
163        /**
164         * This method is called by {@link CxfConsumer}.
165         */
166        public void populateExchangeFromCxfRequest(org.apache.cxf.message.Exchange cxfExchange,
167                Exchange camelExchange) {
168            
169            Method method = null;
170            QName operationName = null;
171            ExchangePattern mep = ExchangePattern.InOut;
172            
173            // extract binding operation information
174            BindingOperationInfo boi = camelExchange.getProperty(BindingOperationInfo.class.getName(), 
175                                                                 BindingOperationInfo.class);
176            if (boi != null) {
177                Service service = (Service)cxfExchange.get(Service.class); 
178                if (service != null) {
179                    MethodDispatcher md = (MethodDispatcher)service
180                        .get(MethodDispatcher.class.getName());
181                    if (md != null) {
182                        method = md.getMethod(boi);
183                    }
184                }
185                
186                if (boi.getOperationInfo().isOneWay()) {
187                    mep = ExchangePattern.InOnly;
188                }
189                    
190                operationName = boi.getName();
191            }
192            
193            // set operation name in header
194            if (operationName != null) {
195                camelExchange.getIn().setHeader(CxfConstants.OPERATION_NAMESPACE, 
196                        boi.getName().getNamespaceURI());
197                camelExchange.getIn().setHeader(CxfConstants.OPERATION_NAME, 
198                        boi.getName().getLocalPart());
199                if (LOG.isTraceEnabled()) {
200                    LOG.trace("Set IN header: " + CxfConstants.OPERATION_NAMESPACE + "=" 
201                             + boi.getName().getNamespaceURI());
202                    LOG.trace("Set IN header: " + CxfConstants.OPERATION_NAME + "=" 
203                            + boi.getName().getLocalPart());
204                }
205            } else if (method != null) {
206                camelExchange.getIn().setHeader(CxfConstants.OPERATION_NAME, method.getName());
207                if (LOG.isTraceEnabled()) {
208                    LOG.trace("Set IN header: " + CxfConstants.OPERATION_NAME + "=" 
209                            + method.getName());
210                }
211            }
212                    
213            // set message exchange pattern
214            camelExchange.setPattern(mep);
215            if (LOG.isTraceEnabled()) {
216                LOG.trace("Set exchange MEP: " + mep);
217            }
218    
219            // propagate headers
220            Message cxfMessage = cxfExchange.getInMessage();
221            propagateHeadersFromCxfToCamel(cxfMessage, camelExchange.getIn(), camelExchange);
222            
223            // propagate the security subject from CXF security context
224            SecurityContext securityContext = cxfMessage.get(SecurityContext.class);
225            if (securityContext != null && securityContext.getUserPrincipal() != null) {
226                Subject subject = new Subject();
227                subject.getPrincipals().add(securityContext.getUserPrincipal());
228                camelExchange.getIn().getHeaders().put(Exchange.AUTHENTICATION, subject);
229            }
230            
231            // Propagating properties from CXF Exchange to Camel Exchange has an  
232            // side effect of copying reply side stuff when the producer is retried.
233            // So, we do not want to do this.
234            //camelExchange.getProperties().putAll(cxfExchange);
235            
236            // propagate request context
237            Object value = cxfMessage.get(Client.REQUEST_CONTEXT);
238            if (value != null && !headerFilterStrategy.applyFilterToExternalHeaders(
239                    Client.REQUEST_CONTEXT, value, camelExchange)) {
240                camelExchange.getIn().setHeader(Client.REQUEST_CONTEXT, value);
241                if (LOG.isTraceEnabled()) {
242                    LOG.trace("Populate context from CXF message " + Client.REQUEST_CONTEXT 
243                            + " value=" + value);
244                }
245            }
246               
247            // set body
248            Object body = DefaultCxfBinding.getContentFromCxf(cxfMessage, 
249                    camelExchange.getProperty(CxfConstants.DATA_FORMAT_PROPERTY, DataFormat.class));
250            if (body != null) {
251                camelExchange.getIn().setBody(body);
252            }  
253            
254            // propagate attachments
255            if (cxfMessage.getAttachments() != null) {
256                for (Attachment attachment : cxfMessage.getAttachments()) {
257                    camelExchange.getIn().addAttachment(attachment.getId(), attachment.getDataHandler());
258                }
259            }
260        }
261    
262        /**
263         * This method is called by {@link CxfConsumer} to populate a CXF response exchange 
264         * from a Camel exchange.
265         */
266        public void populateCxfResponseFromExchange(Exchange camelExchange, 
267                org.apache.cxf.message.Exchange cxfExchange) {
268            
269            // create response context
270            Map<String, Object> responseContext = new HashMap<String, Object>();
271            
272            // propagate response context
273            Map<String, Object> camelHeaders = camelExchange.getOut().getHeaders();
274            extractInvocationContextFromCamel(camelExchange, camelHeaders, 
275                    responseContext, Client.RESPONSE_CONTEXT);
276            
277            propagateHeadersFromCamelToCxf(camelExchange, camelHeaders, cxfExchange, 
278                    responseContext);
279            // create out message
280            Endpoint ep = cxfExchange.get(Endpoint.class);
281            Message outMessage = ep.getBinding().createMessage();
282            cxfExchange.setOutMessage(outMessage);       
283    
284            DataFormat dataFormat = camelExchange.getProperty(CxfConstants.DATA_FORMAT_PROPERTY,  
285                    DataFormat.class);
286            
287            // make sure the "requestor role" property does not get propagated as we do switch role
288            responseContext.remove(Message.REQUESTOR_ROLE);
289            
290            outMessage.putAll(responseContext);
291            
292            // Do we still need to put the response context back like this
293            outMessage.put(Client.RESPONSE_CONTEXT, responseContext);      
294            
295            if (LOG.isTraceEnabled()) {
296                LOG.trace("Set out response context = " + responseContext);
297            }
298            
299            // set body
300            Object outBody = DefaultCxfBinding.getBodyFromCamel(camelExchange.getOut(), dataFormat);
301            
302            if (outBody != null) {
303                if (dataFormat == DataFormat.PAYLOAD) {
304                    CxfPayload<?> payload = (CxfPayload<?>)outBody;
305                    outMessage.setContent(List.class, getResponsePayloadList(cxfExchange, payload.getBody()));
306                    outMessage.put(Header.HEADER_LIST, payload.getHeaders());
307                } else {
308                    if (responseContext.get(Header.HEADER_LIST) != null) {
309                        outMessage.put(Header.HEADER_LIST, responseContext.get(Header.HEADER_LIST));
310                    }
311    
312                    MessageContentsList resList = null;
313                    if (outBody instanceof MessageContentsList) {
314                        resList = (MessageContentsList)outBody;
315                    } else if (outBody instanceof List) {
316                        resList = new MessageContentsList((List<?>)outBody);
317                    } else if (outBody.getClass().isArray()) {
318                        resList = new MessageContentsList((Object[])outBody);
319                    } else {
320                        resList = new MessageContentsList(outBody);
321                    }
322    
323                    if (resList != null) {
324                        outMessage.setContent(List.class, resList);
325                        if (LOG.isTraceEnabled()) {
326                            LOG.trace("Set Out CXF message content = " + resList);
327                        }
328                    }
329                }
330            }         
331            
332            // propagate attachments
333            Set<Attachment> attachments = null;
334            for (Map.Entry<String, DataHandler> entry : camelExchange.getOut().getAttachments().entrySet()) {
335                if (attachments == null) {
336                    attachments = new HashSet<Attachment>();
337                }
338                AttachmentImpl attachment = new AttachmentImpl(entry.getKey(), entry.getValue());
339                attachment.setXOP(true); // only supports MTOM
340                attachments.add(attachment);
341            }
342            
343            if (attachments != null) {
344                outMessage.setAttachments(attachments);
345            }
346           
347            BindingOperationInfo boi = cxfExchange.get(BindingOperationInfo.class);
348            if (boi != null) {
349                cxfExchange.put(BindingMessageInfo.class, boi.getOutput());
350            }
351            
352        }
353    
354        // HeaderFilterStrategyAware Methods
355        // -------------------------------------------------------------------------
356        
357    
358        public HeaderFilterStrategy getHeaderFilterStrategy() {
359            return headerFilterStrategy;
360        }
361    
362        public void setHeaderFilterStrategy(HeaderFilterStrategy strategy) {
363            this.headerFilterStrategy = strategy;
364        }
365    
366           
367        // Non public methods
368        // -------------------------------------------------------------------------
369        
370        protected MessageContentsList getResponsePayloadList(org.apache.cxf.message.Exchange exchange, 
371                                                             List<Element> elements) {
372            BindingOperationInfo boi = exchange.getBindingOperationInfo();
373    
374            if (boi.isUnwrapped()) {
375                boi = boi.getWrappedOperation();
376                exchange.put(BindingOperationInfo.class, boi);
377            }
378            
379            MessageContentsList answer = new MessageContentsList();
380    
381            int i = 0;
382            
383            for (MessagePartInfo partInfo : boi.getOperationInfo().getOutput().getMessageParts()) {
384                if (elements.size() > i) {
385                    answer.put(partInfo, elements.get(i++));
386                    
387                }
388            }
389    
390            return answer;
391            
392        }
393        
394        /**
395         * @param camelExchange
396         * @param cxfContext Request or Response context
397         * @param camelHeaders 
398         * @param contextKey 
399         */
400        @SuppressWarnings("unchecked")
401        protected void extractInvocationContextFromCamel(Exchange camelExchange,
402                Map<String, Object> camelHeaders, Map<String, Object> cxfContext,
403                String contextKey) {
404            
405            // extract from header
406            Map context = (Map)camelHeaders.get(contextKey);
407            if (context != null) {
408                cxfContext.putAll(context);
409                if (LOG.isTraceEnabled()) {
410                    LOG.trace("Propagate " + contextKey + " from header context = " 
411                            + ((context instanceof WrappedMessageContext) 
412                                    ? ((WrappedMessageContext)context).getWrappedMap() 
413                                            : context));
414                }
415            }
416            
417            // extract from exchange property
418            context = (Map)camelExchange.getProperty(contextKey);
419            if (context != null) {
420                cxfContext.putAll(context);
421                if (LOG.isTraceEnabled()) {
422                    LOG.trace("Propagate " + contextKey + " from exchange property context = " 
423                            + ((context instanceof WrappedMessageContext) 
424                                    ? ((WrappedMessageContext)context).getWrappedMap() 
425                                            : context));
426                }
427            }
428            
429            // copy camel exchange properties into context
430            if (camelExchange.getProperties() != null) {
431                cxfContext.putAll(camelExchange.getProperties());
432            }
433            
434            camelExchange.setProperty(contextKey, cxfContext);
435        }
436    
437        /**
438         * @param cxfMessage
439         * @param camelMessage
440         * @param exchange provides context for filtering
441         */
442        @SuppressWarnings("unchecked")
443        protected void propagateHeadersFromCxfToCamel(Message cxfMessage,
444                org.apache.camel.Message camelMessage, Exchange exchange) {
445            
446            Map<String, List<String>> cxfHeaders = (Map)cxfMessage.get(Message.PROTOCOL_HEADERS);
447            Map<String, Object> camelHeaders = camelMessage.getHeaders();
448    
449            if (cxfHeaders != null) {
450                for (Map.Entry<String, List<String>> entry : cxfHeaders.entrySet()) {
451                    if (!headerFilterStrategy.applyFilterToExternalHeaders(entry.getKey(), 
452                                                                           entry.getValue(), exchange)) {
453                        camelHeaders.put(entry.getKey(), entry.getValue().get(0));
454                        if (LOG.isTraceEnabled()) {
455                            LOG.trace("Populate header from CXF header=" + entry.getKey() + " value="
456                                    + entry.getValue());
457                        }
458                    }
459                }
460            }
461            
462            
463            // propagate SOAP/protocol header list
464            String key = Header.HEADER_LIST;
465            Object value = cxfMessage.get(key);
466            if (value != null) {
467                if (!headerFilterStrategy.applyFilterToExternalHeaders(key, value, exchange)) {
468                    camelHeaders.put(key, value);
469                    if (LOG.isTraceEnabled()) {
470                        LOG.trace("Populate header from CXF header=" + key + " value=" + value);
471                    }
472                } else {
473                    ((List<?>)value).clear();
474                }
475            }       
476        }
477    
478        @SuppressWarnings("unchecked")
479        protected void propagateHeadersFromCamelToCxf(Exchange camelExchange, 
480                Map<String, Object> camelHeaders,
481                org.apache.cxf.message.Exchange cxfExchange, 
482                Map<String, Object> cxfContext) {
483            
484            // get cxf transport headers (if any) from camel exchange
485            Map<String, List<String>> transportHeaders = new HashMap<String, List<String>>();
486            if (camelExchange != null) {
487                Map<String, List<String>> h = (Map)camelExchange.getProperty(Message.PROTOCOL_HEADERS);
488                if (h != null) {
489                    transportHeaders.putAll(h);
490                }
491            }
492            Map<String, List<String>> headers = (Map)camelHeaders.get(Message.PROTOCOL_HEADERS);
493            if (headers != null) {
494                transportHeaders.putAll(headers);
495            }
496                
497            for (Map.Entry<String, Object> entry : camelHeaders.entrySet()) {    
498                // this header should be filtered, continue to the next header
499                if (headerFilterStrategy.applyFilterToCamelHeaders(entry.getKey(), entry.getValue(), camelExchange)) {
500                    continue;
501                }
502                
503                if (LOG.isTraceEnabled()) {
504                    LOG.trace("Propagate to CXF header: " + entry.getKey() + " value: " + entry.getValue());
505                }
506                
507                // put response code in request context so it will be copied to CXF message's property
508                if (Message.RESPONSE_CODE.equals(entry.getKey())) {
509                    cxfContext.put(entry.getKey(), entry.getValue());
510                    continue;
511                }
512                
513                // put SOAP/protocol header list in exchange
514                if (Header.HEADER_LIST.equals(entry.getKey())) {
515                    List<Header> headerList = (List<Header>)entry.getValue();
516                    for (Header header : headerList) {
517                        header.setDirection(Header.Direction.DIRECTION_OUT);
518                        if (LOG.isTraceEnabled()) {
519                            LOG.trace("Propagate SOAP/protocol header: " + header.getName() + " : " + header.getObject());
520                        }
521                    }
522                    
523                    //cxfExchange.put(Header.HEADER_LIST, headerList);
524                    cxfContext.put(entry.getKey(), headerList);
525                    continue;
526                }
527                
528                // things that are not filtered and not specifically copied will be put in transport headers
529                if (entry.getValue() instanceof List) {
530                    transportHeaders.put(entry.getKey(), (List<String>)entry.getValue());
531                } else {
532                    List<String> listValue = new ArrayList<String>();
533                    listValue.add(entry.getValue().toString());
534                    transportHeaders.put(entry.getKey(), listValue);
535                }
536                
537            }
538            
539            if (transportHeaders.size() > 0) {
540                cxfContext.put(Message.PROTOCOL_HEADERS, transportHeaders);
541            }        
542        }
543    
544        protected static Object getContentFromCxf(Message message, DataFormat dataFormat) {
545            Set<Class<?>> contentFormats = message.getContentFormats();
546            Object answer = null;
547            if (contentFormats != null) {
548                
549                if (LOG.isTraceEnabled()) {
550                    for (Class<?> contentFormat : contentFormats) {
551                        LOG.trace("Content format=" + contentFormat + " value=" 
552                                + message.getContent(contentFormat));
553                    }
554                }
555                
556                if (dataFormat == DataFormat.POJO) {
557                    answer = message.getContent(List.class);  
558                    if (answer == null) {
559                        answer = message.getContent(Object.class);
560                        if (answer != null) {
561                            answer = new MessageContentsList(answer);
562                        }
563                    }
564                } else if (dataFormat == DataFormat.PAYLOAD) {
565                    List<SoapHeader> headers = CastUtils.cast((List<?>)message.get(Header.HEADER_LIST));
566                    answer = new CxfPayload<SoapHeader>(headers, getPayloadBodyElements(message));
567                    
568                } else if (dataFormat == DataFormat.MESSAGE) {
569                    answer = message.getContent(InputStream.class);
570                }
571    
572                if (LOG.isTraceEnabled()) {
573                    LOG.trace("Extracted body from CXF message = " + answer);
574                }
575            }
576            return answer;
577        }
578        
579    
580        protected static List<Element> getPayloadBodyElements(Message message) {
581            MessageContentsList inObjects = MessageContentsList.getContentsList(message);
582            org.apache.cxf.message.Exchange exchange = message.getExchange();
583            BindingOperationInfo boi = exchange.getBindingOperationInfo();
584    
585            OperationInfo op = boi.getOperationInfo();
586            
587            if (boi.isUnwrapped()) {
588                op = boi.getWrappedOperation().getOperationInfo();
589            } 
590            
591            
592            List<MessagePartInfo> partInfos = null;
593            boolean client = Boolean.TRUE.equals(message.get(Message.REQUESTOR_ROLE));
594            if (client) {
595                // it is a response
596                partInfos = op.getOutput().getMessageParts();            
597                
598            } else {
599                // it is a request
600                partInfos = op.getInput().getMessageParts();            
601            }
602            
603            List<Element> answer = new ArrayList<Element>();
604    
605            for (MessagePartInfo partInfo : partInfos) {
606                if (!inObjects.hasValue(partInfo)) {
607                    continue;
608                }
609                
610                Object part = inObjects.get(partInfo);
611                
612                if (part instanceof Holder) {
613                    part = ((Holder)part).value;
614                }
615                            
616                if (part instanceof DOMSource) {
617                    Element element = getFirstElement(((DOMSource)part).getNode());
618    
619                    if (element != null) {
620                        answer.add(element);
621                    }
622                    
623                    if (LOG.isTraceEnabled()) {
624                        LOG.trace("Extract body element " 
625                                  + (element == null ? "null" : XMLUtils.toString(element)));
626                    }
627                    
628                } else if (part instanceof Element) {
629                    answer.add((Element)part);
630                } else {
631                    if (LOG.isDebugEnabled()) {
632                        LOG.debug("Unhandled part type '" + part.getClass());
633                    }
634                }
635            }
636    
637            return answer;
638        }
639    
640    
641        public static Object getBodyFromCamel(org.apache.camel.Message out,
642                DataFormat dataFormat) {
643            Object answer = null;
644            
645            if (dataFormat == DataFormat.POJO) {
646                answer = out.getBody();
647            } else if (dataFormat == DataFormat.PAYLOAD) {
648                answer = out.getBody(CxfPayload.class);
649            } else if (dataFormat == DataFormat.MESSAGE) {
650                answer = out.getBody(InputStream.class);
651            }
652            return answer;
653        }
654    
655        private static Element getFirstElement(Node node) {
656            if (node.getNodeType() == Node.ELEMENT_NODE) {
657                return (Element)node;
658            } 
659            
660            return DOMUtils.getFirstElement(node);
661        }
662        
663        public void copyJaxWsContext(org.apache.cxf.message.Exchange cxfExchange, Map<String, Object> context) {
664            if (cxfExchange.getOutMessage() != null) {
665                org.apache.cxf.message.Message outMessage = cxfExchange.getOutMessage();
666                for (Map.Entry<String, Object> entry : context.entrySet()) {
667                    if (outMessage.get(entry.getKey()) == null) {
668                        outMessage.put(entry.getKey(), entry.getValue());
669                    }
670                }
671            }
672        }
673    
674        public void extractJaxWsContext(org.apache.cxf.message.Exchange cxfExchange, Map<String, Object> context) {
675            org.apache.cxf.message.Message inMessage = cxfExchange.getInMessage();
676            for (Map.Entry<String, Object> entry : inMessage.entrySet()) {
677                if (entry.getKey().startsWith("javax.xml.ws")) {
678                    context.put(entry.getKey(), entry.getValue());
679                }
680            }
681            
682        }
683    
684    }