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 }