dev@jax-ws.java.net

Proposal to modify the encoder/decoder framework

From: Paul Sandoz <Paul.Sandoz_at_Sun.COM>
Date: Thu, 06 Apr 2006 18:37:45 +0200

Hi,

This email is a proposal to make the Encoder/Decoder framework easier
for transports to use Encoders while ensuring that transport level
details like content negotation and SOAPAction are kept local to the
transports. A disadvantage of this approach is that a transport is
required to perform some level of functionality associated with the binding.


Some proposed classes are at the end of the email.

General points:

- Encoders/Decoders operate on Message.

- Encoders/Decoders are not responsible for constructing or processing
   the HTTP Content-Type field, that is the responsibility of the
   transport.

- Encoders take encoding parameters/values and return encoding
   parameters to be used as meta-data by the transport. This enables
   the MTOM encoder to return the boundary parameter.

- Decoders take decoding parameter/values that are meta-data from the
   transport.

- Because generic string parameters are used it is still possible to
   implement an encoder/decoder facade but i think that should be the
   choice of the transport to decide if it wants to use that.
   However, since a DecoderFacade is much more likely to be used perhaps
   having the content type as a specific parameter is still appropriate
   for performance reasons.

- The BindingID will return a map of encoders/decoders with keys that is
   the static MIME type.


A transport could do:

   DecodeFacade df = new DecoderFacade(bindingID.createDecoders());
   Map<String, String> parameters = new HashMap();

   ...

   InputStream in = ...
   String contentType = ... // content type from transport
   // get parameters from content type and add them to
   // parameters
   map.put("Content-Type", contentType);
   Message m = df.decode(in, parameters);


For conneg the following can be performed by the transport:

   Encoder e = null;
   if (contentNegotation == ContentNegotiation.optimistic)
     e = fiEncoder;
   else
     if (binding.isMTOMEnabled())
       e = mtomEncoder;
     else
       e = soapEncoder;

And for SOAP action support the following:

    String ct = e.getStaticMimeType();
    p = e.encode(message, out, p);
    if (p.size() > 0) {
        // Append parameters to ct
    }

    if (soapVersion == SOAPVersion.SOAP_11)
        // Add Packet.soapAction as HTTP header
    else
        // Append Packet.soapAction to ct


Both the conneg and SOAP action support is kept local to the transport.
Infact it no longer seems necessary to have soapAction on packet and it
could be part of the request context instead.

Paul.


public interface Encoder {
     /**
      * Return the static MIME type associated with the Encoder.
      */
     String getStaticMimeType();

     /**
      * Encode a message.
      *
      * @param parameters Encoder specific parameters that are used to
      * encode
      * @return Encoder specific parameters generated from the encoding.
      * The instance returned may be the same instance as that
      * for parameter.
      */
     Map<String, String> encode(Message message,
             OutputStream out,
             Map<String, String> parameters) throws IOException;

     /**
      * Encode a message.
      *
      * @param parameters Encoder specific parameters that are used to
      * encode
      * @return Encoder specific parameters generated from the encoding.
      * The instance returned may be the same instance as that
      * for parameter.
      */
     Map<String, String> encode(Message message,
             WritableByteChannel buffer,
             Map<String, String> parameters);

     Encoder copy();
}


public interface Decoder {
     /**
      * Return the static MIME type associated with the Encoder.
      */
     String getStaticMimeType();

     /**
      * Decode a message.
      *
      * @param parameters Decoder specific parameters that are used to
      * decode
      */
     Message decode(InputStream in,
             Map<String, String> parameters) throws IOException;

     /**
      * Decode a message.
      *
      * @param parameters Decoder specific parameters that are used to
      * decode
      */
     Message decode(ReadableByteChannel in,
             Map<String, String> parameters);

     Decoder copy();
}


public abstract class BindingID {

     .... all the other methods ....

     /**
      * Create the set of Encoder supported by the binding.
      * <p>
      * @return a map of static MIME type to the Encoder responsible
      * for encoding a Message as specified by the MIME type.
      */
     public abstract @NotNull Map<String, Encoder>
             createEncoders(@NotNull WSBinding binding);

     /**
      * Create the set of Decoder supported by the binding.
      * <p>
      * @return a map of static MIME type to the Decoder responsible
      * for decoding a Message as specified by the MIME type.
      */
     public abstract @NotNull Map<String, Encoder>
             createDecoders(@NotNull WSBinding binding);

}

-- 
| ? + ? = To question
----------------\
    Paul Sandoz
         x38109
+33-4-76188109