001: /*
002: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
003: *
004: * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
005: *
006: * The contents of this file are subject to the terms of either the GNU
007: * General Public License Version 2 only ("GPL") or the Common Development
008: * and Distribution License("CDDL") (collectively, the "License"). You
009: * may not use this file except in compliance with the License. You can obtain
010: * a copy of the License at https://glassfish.dev.java.net/public/CDDL+GPL.html
011: * or glassfish/bootstrap/legal/LICENSE.txt. See the License for the specific
012: * language governing permissions and limitations under the License.
013: *
014: * When distributing the software, include this License Header Notice in each
015: * file and include the License file at glassfish/bootstrap/legal/LICENSE.txt.
016: * Sun designates this particular file as subject to the "Classpath" exception
017: * as provided by Sun in the GPL Version 2 section of the License file that
018: * accompanied this code. If applicable, add the following below the License
019: * Header, with the fields enclosed by brackets [] replaced by your own
020: * identifying information: "Portions Copyrighted [year]
021: * [name of copyright owner]"
022: *
023: * Contributor(s):
024: *
025: * If you wish your version of this file to be governed by only the CDDL or
026: * only the GPL Version 2, indicate your decision by adding "[Contributor]
027: * elects to include this software in this distribution under the [CDDL or GPL
028: * Version 2] license." If you don't indicate a single choice of license, a
029: * recipient has the option to distribute your version of this file under
030: * either the CDDL, the GPL Version 2 or to extend the choice of license to
031: * its licensees as provided above. However, if you add GPL Version 2 code
032: * and therefore, elected the GPL Version 2 license, then the option applies
033: * only if the new code is made subject to such option by the copyright
034: * holder.
035: */
036: package com.sun.xml.ws.api.pipe;
037:
038: import com.sun.xml.ws.api.BindingID;
039: import com.sun.xml.ws.api.WSBinding;
040: import com.sun.xml.ws.api.message.Message;
041: import com.sun.xml.ws.api.message.Packet;
042: import com.sun.xml.ws.api.server.EndpointAwareCodec;
043:
044: import javax.xml.stream.XMLStreamWriter;
045: import java.io.IOException;
046: import java.io.InputStream;
047: import java.io.OutputStream;
048: import java.nio.ByteBuffer;
049: import java.nio.channels.ReadableByteChannel;
050: import java.nio.channels.WritableByteChannel;
051:
052: /**
053: * Encodes a {@link Message} (its XML infoset and attachments) to a sequence of bytes.
054: *
055: * <p>
056: * This interface provides pluggability for different ways of encoding XML infoset,
057: * such as plain XML (plus MIME attachments), XOP, and FastInfoset.
058: *
059: * <p>
060: * Transport usually needs a MIME content type of the encoding, so the {@link Codec}
061: * interface is designed to return this information. However, for some encoding
062: * (such as XOP), the encoding may actually change based on the actual content of
063: * {@link Message}, therefore the codec returns the content type as a result of encoding.
064: *
065: * <p>
066: * {@link Codec} does not produce transport-specific information, such as HTTP headers.
067: *
068: * <p>
069: * {@link Codec} is a non-reentrant object, meaning no two threads
070: * can concurrently invoke the decode method. This allows the implementation
071: * to easily reuse parser objects (as instance variables), which are costly otherwise.
072: *
073: *
074: * <p>
075: * {@link BindingID} determines the {@link Codec}. See {@link BindingID#createEncoder(WSBinding)}.
076: *
077: * @author Kohsuke Kawaguchi
078: * @see EndpointAwareCodec
079: */
080: public interface Codec {
081:
082: /**
083: * Get the MIME type associated with this Codec.
084: * <p>
085: * If available the MIME type will represent the media that the codec
086: * encodes and decodes.
087: *
088: * The MIME type returned will be the most general representation independent
089: * of an instance of this MIME type utilized as a MIME content-type.
090: *
091: * @return
092: * null if the MIME type can't be determined by the <code>Codec</code>
093: * implementation. Otherwise the MIME type is returned.
094: */
095: public String getMimeType();
096:
097: /**
098: * If the MIME content-type of the encoding is known statically
099: * then this method returns it.
100: *
101: * <p>
102: * Transports often need to write the content type before it writes
103: * the message body, and since the encode method returns the content type
104: * after the body is written, it requires a buffering.
105: *
106: * For those {@link Codec}s that always use a constant content type,
107: * This method allows a transport to streamline the write operation.
108: *
109: * @return
110: * null if the content-type can't be determined in short of
111: * encodin the packet. Otherwise content type for this {@link Packet},
112: * such as "application/xml".
113: */
114: ContentType getStaticContentType(Packet packet);
115:
116: /**
117: * Encodes an XML infoset portion of the {@link Message}
118: * (from <soap:Envelope> to </soap:Envelope>).
119: *
120: * <p>
121: * Internally, this method is most likely invoke {@link Message#writeTo(XMLStreamWriter)}
122: * to turn the message into infoset.
123: *
124: * @param packet
125: * @param out
126: * Must not be null. The caller is responsible for closing the stream,
127: * not the callee.
128: *
129: * @return
130: * The MIME content type of the encoded message (such as "application/xml").
131: * This information is often ncessary by transport.
132: *
133: * @throws IOException
134: * if a {@link OutputStream} throws {@link IOException}.
135: */
136: ContentType encode(Packet packet, OutputStream out)
137: throws IOException;
138:
139: /**
140: * The version of {@link #encode(Packet,OutputStream)}
141: * that writes to NIO {@link ByteBuffer}.
142: *
143: * <p>
144: * TODO: for the convenience of implementation, write
145: * an adapter that wraps {@link WritableByteChannel} to {@link OutputStream}.
146: */
147: ContentType encode(Packet packet, WritableByteChannel buffer);
148:
149: /*
150: * The following methods need to be documented and implemented.
151: *
152: * Such methods will be used by a client side
153: * transport pipe that implements the ClientEdgePipe.
154: *
155: String encode( InputStreamMessage message, OutputStream out ) throws IOException;
156: String encode( InputStreamMessage message, WritableByteChannel buffer );
157: */
158:
159: /**
160: * Creates a copy of this {@link Codec}.
161: *
162: * <p>
163: * Since {@link Codec} instance is not re-entrant, the caller
164: * who needs to encode two {@link Message}s simultaneously will
165: * want to have two {@link Codec} instances. That's what this
166: * method produces.
167: *
168: * <h3>Implentation Note</h3>
169: * <p>
170: * Note that this method might be invoked by one thread while
171: * another thread is executing one of the {@link #encode} methods.
172: * <!-- or otherwise you'd always have to maintain one idle copy -->
173: * <!-- just so that you can make copies from -->
174: * This should be OK because you'll be only copying things that
175: * are thread-safe, and creating new ones for thread-unsafe resources,
176: * but please let us know if this contract is difficult.
177: *
178: * @return
179: * always non-null valid {@link Codec} that performs
180: * the encoding work in the same way --- that is, if you
181: * copy an FI codec, you'll get another FI codec.
182: *
183: * <p>
184: * Once copied, two {@link Codec}s may be invoked from
185: * two threads concurrently; therefore, they must not share
186: * any state that requires isolation (such as temporary buffer.)
187: *
188: * <p>
189: * If the {@link Codec} implementation is already
190: * re-entrant and multi-thread safe to begin with,
191: * then this method may simply return <tt>this</tt>.
192: */
193: Codec copy();
194:
195: /**
196: * Reads bytes from {@link InputStream} and constructs a {@link Message}.
197: *
198: * <p>
199: * The design encourages lazy decoding of a {@link Message}, where
200: * a {@link Message} is returned even before the whole message is parsed,
201: * and additional parsing is done as the {@link Message} body is read along.
202: * A {@link Codec} is most likely have its own implementation of {@link Message}
203: * for this purpose.
204: *
205: * @param in
206: * the data to be read into a {@link Message}. The transport would have
207: * read any transport-specific header before it passes an {@link InputStream},
208: * and {@link InputStream} is expected to be read until EOS. Never null.
209: *
210: * <p>
211: * Some transports, such as SMTP, may 'encode' data into another format
212: * (such as uuencode, base64, etc.) It is the caller's responsibility to
213: * 'decode' these transport-level encoding before it passes data into
214: * {@link Codec}.
215: *
216: * @param contentType
217: * The MIME content type (like "application/xml") of this byte stream.
218: * Thie text includes all the sub-headers of the content-type header. Therefore,
219: * in more complex case, this could be something like
220: * <tt>multipart/related; boundary="--=_outer_boundary"; type="multipart/alternative"</tt>.
221: * This parameter must not be null.
222: *
223: * @param response
224: * The parsed {@link Message} will be set to this {@link Packet}.
225: * {@link Codec} may add additional properties to this {@link Packet}.
226: * On a successful method completion, a {@link Packet} must contain a
227: * {@link Message}.
228: *
229: * @throws IOException
230: * if {@link InputStream} throws an exception.
231: */
232: void decode(InputStream in, String contentType, Packet response)
233: throws IOException;
234:
235: /**
236: *
237: * @see #decode(InputStream, String, Packet)
238: */
239: void decode(ReadableByteChannel in, String contentType,
240: Packet response);
241:
242: /*
243: * The following methods need to be documented and implemented.
244: *
245: * Such methods will be used by a server side
246: * transport pipe that can support the invocation of methods on a
247: * ServerEdgePipe.
248: *
249: XMLStreamReaderMessage decode( InputStream in, String contentType ) throws IOException;
250: XMLStreamReaderMessage decode( ReadableByteChannel in, String contentType );
251: */
252: }
|