View Javadoc

1   /*
2    * Copyright 2009 University Corporation for Advanced Internet Development, Inc.
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    * http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  
17  package org.opensaml.ws.message.handler;
18  
19  import org.opensaml.ws.message.MessageContext;
20  import org.opensaml.ws.message.encoder.BaseMessageEncoder;
21  import org.opensaml.ws.message.encoder.MessageEncodingException;
22  import org.slf4j.Logger;
23  import org.slf4j.LoggerFactory;
24  
25  /**
26   * Base class for message encoders which are capable of processing the message context's outbound {@link HandlerChain}.
27   */
28  public abstract class BaseHandlerChainAwareMessageEncoder extends BaseMessageEncoder implements HandlerChainAware {
29      
30      /** Class logger. */
31      private final Logger log = LoggerFactory.getLogger(BaseHandlerChainAwareMessageEncoder.class);
32  
33      /** {@inheritDoc} */
34      protected void doEncode(MessageContext messageContext) throws MessageEncodingException {
35          prepareMessageContext(messageContext);
36          
37          processOutboundHandlerChain(messageContext);
38          
39          encodeToTransport(messageContext);
40      }
41      
42      /**
43       * Perform final binding-specific processing of message context and prepare it for encoding
44       * to the transport.  
45       * 
46       * <p>
47       * This should include constructing and populating all binding-specific structure and data that needs to be
48       * reflected by the message context's properties.
49       * </p>
50       * 
51       * <p>
52       * This method is called prior to {@link #processOutboundHandlerChain(MessageContext)}.
53       * </p>
54       * 
55       * @param messageContext the message context to process
56       * @throws MessageEncodingException thrown if there is a problem preparing the message context
57       *              for encoding
58       */
59      protected abstract void prepareMessageContext(MessageContext messageContext) throws MessageEncodingException;
60      
61      /**
62       * Encode the message context to the transport.
63       * 
64       * @param messageContext the message context to process
65       *  @throws MessageEncodingException thrown if there is a problem encoding the message context
66       *              to the transport
67       */
68      protected abstract void encodeToTransport(MessageContext messageContext) throws MessageEncodingException;
69  
70      /**
71       * Process the outbound {@link HandlerChain} for the message context, if any.
72       * 
73       * @param messageContext the message context to process
74       * @throws MessageEncodingException thrown if a handler indicates a problem handling the message
75       */
76      protected void processOutboundHandlerChain(MessageContext messageContext) throws MessageEncodingException {
77          HandlerChainResolver outboundHandlerChainResolver = messageContext.getOutboundHandlerChainResolver();
78          if (outboundHandlerChainResolver != null) {
79              log.debug("Invoking outbound handler chain on message context");
80              try {
81                  for (HandlerChain outboundHandlerChain : outboundHandlerChainResolver.resolve(messageContext)) {
82                      if (outboundHandlerChain != null) {
83                          invokeHandlerChain(outboundHandlerChain, messageContext);
84                      }
85                  }
86              } catch (HandlerException e) {
87                  log.error("Encountered HandlerException when encoding message: {}", e.getMessage());
88                  throw new MessageEncodingException("Handler exception while encoding message", e);
89              }
90          }
91      }
92      
93      /**
94       * Invoke a handler chain on the specified message context.
95       * 
96       * @param handlerChain the handle chain to invoke
97       * @param messageContext the message context to process
98       * 
99       * @throws HandlerException if handler chain encountered a problem handling the message context
100      */
101     protected void invokeHandlerChain(HandlerChain handlerChain, MessageContext messageContext)
102             throws HandlerException {
103         if (handlerChain != null && messageContext != null) {
104             handlerChain.invoke(messageContext);
105         }
106     }
107 
108 }