001: /*
002: * Copyright (c) 2001-2004 Caucho Technology, Inc. All rights reserved.
003: *
004: * The Apache Software License, Version 1.1
005: *
006: * Redistribution and use in source and binary forms, with or without
007: * modification, are permitted provided that the following conditions
008: * are met:
009: *
010: * 1. Redistributions of source code must retain the above copyright
011: * notice, this list of conditions and the following disclaimer.
012: *
013: * 2. Redistributions in binary form must reproduce the above copyright
014: * notice, this list of conditions and the following disclaimer in
015: * the documentation and/or other materials provided with the
016: * distribution.
017: *
018: * 3. The end-user documentation included with the redistribution, if
019: * any, must include the following acknowlegement:
020: * "This product includes software developed by the
021: * Caucho Technology (http://www.caucho.com/)."
022: * Alternately, this acknowlegement may appear in the software itself,
023: * if and wherever such third-party acknowlegements normally appear.
024: *
025: * 4. The names "Hessian", "Resin", and "Caucho" must not be used to
026: * endorse or promote products derived from this software without prior
027: * written permission. For written permission, please contact
028: * info@caucho.com.
029: *
030: * 5. Products derived from this software may not be called "Resin"
031: * nor may "Resin" appear in their names without prior written
032: * permission of Caucho Technology.
033: *
034: * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
035: * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
036: * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
037: * DISCLAIMED. IN NO EVENT SHALL CAUCHO TECHNOLOGY OR ITS CONTRIBUTORS
038: * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
039: * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
040: * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
041: * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
042: * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
043: * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
044: * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
045: *
046: * @author Scott Ferguson
047: */
048:
049: package com.caucho.hessian.io;
050:
051: import java.io.IOException;
052: import java.io.OutputStream;
053:
054: /**
055: * Abstract output stream for Hessian requests.
056: *
057: * <pre>
058: * OutputStream os = ...; // from http connection
059: * AbstractOutput out = new HessianSerializerOutput(os);
060: * String value;
061: *
062: * out.startCall("hello"); // start hello call
063: * out.writeString("arg1"); // write a string argument
064: * out.completeCall(); // complete the call
065: * </pre>
066: */
067: abstract public class AbstractHessianOutput {
068: // serializer factory
069: protected SerializerFactory _serializerFactory;
070:
071: /**
072: * Sets the serializer factory.
073: */
074: public void setSerializerFactory(SerializerFactory factory) {
075: _serializerFactory = factory;
076: }
077:
078: /**
079: * Gets the serializer factory.
080: */
081: public SerializerFactory getSerializerFactory() {
082: return _serializerFactory;
083: }
084:
085: /**
086: * Gets the serializer factory.
087: */
088: public final SerializerFactory findSerializerFactory() {
089: SerializerFactory factory = _serializerFactory;
090:
091: if (factory == null)
092: _serializerFactory = factory = new SerializerFactory();
093:
094: return factory;
095: }
096:
097: /**
098: * Initialize the output with a new underlying stream.
099: */
100: public void init(OutputStream os) {
101: }
102:
103: /**
104: * Writes a complete method call.
105: */
106: public void call(String method, Object[] args) throws IOException {
107: startCall(method);
108:
109: if (args != null) {
110: for (int i = 0; i < args.length; i++)
111: writeObject(args[i]);
112: }
113:
114: completeCall();
115: }
116:
117: /**
118: * Starts the method call:
119: *
120: * <code><pre>
121: * c major minor
122: * </pre></code>
123: *
124: * @param method the method name to call.
125: */
126: abstract public void startCall() throws IOException;
127:
128: /**
129: * Starts the method call:
130: *
131: * <code><pre>
132: * c major minor
133: * m b16 b8 method-namek
134: * </pre></code>
135: *
136: * @param method the method name to call.
137: */
138: abstract public void startCall(String method) throws IOException;
139:
140: /**
141: * Writes a header name. The header value must immediately follow.
142: *
143: * <code><pre>
144: * H b16 b8 foo <em>value</em>
145: * </pre></code>
146: */
147: abstract public void writeHeader(String name) throws IOException;
148:
149: /**
150: * Writes the method tag.
151: *
152: * <code><pre>
153: * m b16 b8 method-name
154: * </pre></code>
155: *
156: * @param method the method name to call.
157: */
158: abstract public void writeMethod(String method) throws IOException;
159:
160: /**
161: * Completes the method call:
162: *
163: * <code><pre>
164: * z
165: * </pre></code>
166: */
167: abstract public void completeCall() throws IOException;
168:
169: /**
170: * Writes a boolean value to the stream. The boolean will be written
171: * with the following syntax:
172: *
173: * <code><pre>
174: * T
175: * F
176: * </pre></code>
177: *
178: * @param value the boolean value to write.
179: */
180: abstract public void writeBoolean(boolean value) throws IOException;
181:
182: /**
183: * Writes an integer value to the stream. The integer will be written
184: * with the following syntax:
185: *
186: * <code><pre>
187: * I b32 b24 b16 b8
188: * </pre></code>
189: *
190: * @param value the integer value to write.
191: */
192: abstract public void writeInt(int value) throws IOException;
193:
194: /**
195: * Writes a long value to the stream. The long will be written
196: * with the following syntax:
197: *
198: * <code><pre>
199: * L b64 b56 b48 b40 b32 b24 b16 b8
200: * </pre></code>
201: *
202: * @param value the long value to write.
203: */
204: abstract public void writeLong(long value) throws IOException;
205:
206: /**
207: * Writes a double value to the stream. The double will be written
208: * with the following syntax:
209: *
210: * <code><pre>
211: * D b64 b56 b48 b40 b32 b24 b16 b8
212: * </pre></code>
213: *
214: * @param value the double value to write.
215: */
216: abstract public void writeDouble(double value) throws IOException;
217:
218: /**
219: * Writes a date to the stream.
220: *
221: * <code><pre>
222: * T b64 b56 b48 b40 b32 b24 b16 b8
223: * </pre></code>
224: *
225: * @param time the date in milliseconds from the epoch in UTC
226: */
227: abstract public void writeUTCDate(long time) throws IOException;
228:
229: /**
230: * Writes a null value to the stream.
231: * The null will be written with the following syntax
232: *
233: * <code><pre>
234: * N
235: * </pre></code>
236: *
237: * @param value the string value to write.
238: */
239: abstract public void writeNull() throws IOException;
240:
241: /**
242: * Writes a string value to the stream using UTF-8 encoding.
243: * The string will be written with the following syntax:
244: *
245: * <code><pre>
246: * S b16 b8 string-value
247: * </pre></code>
248: *
249: * If the value is null, it will be written as
250: *
251: * <code><pre>
252: * N
253: * </pre></code>
254: *
255: * @param value the string value to write.
256: */
257: abstract public void writeString(String value) throws IOException;
258:
259: /**
260: * Writes a string value to the stream using UTF-8 encoding.
261: * The string will be written with the following syntax:
262: *
263: * <code><pre>
264: * S b16 b8 string-value
265: * </pre></code>
266: *
267: * If the value is null, it will be written as
268: *
269: * <code><pre>
270: * N
271: * </pre></code>
272: *
273: * @param value the string value to write.
274: */
275: abstract public void writeString(char[] buffer, int offset,
276: int length) throws IOException;
277:
278: /**
279: * Writes a byte array to the stream.
280: * The array will be written with the following syntax:
281: *
282: * <code><pre>
283: * B b16 b18 bytes
284: * </pre></code>
285: *
286: * If the value is null, it will be written as
287: *
288: * <code><pre>
289: * N
290: * </pre></code>
291: *
292: * @param value the string value to write.
293: */
294: abstract public void writeBytes(byte[] buffer) throws IOException;
295:
296: /**
297: * Writes a byte array to the stream.
298: * The array will be written with the following syntax:
299: *
300: * <code><pre>
301: * B b16 b18 bytes
302: * </pre></code>
303: *
304: * If the value is null, it will be written as
305: *
306: * <code><pre>
307: * N
308: * </pre></code>
309: *
310: * @param value the string value to write.
311: */
312: abstract public void writeBytes(byte[] buffer, int offset,
313: int length) throws IOException;
314:
315: /**
316: * Writes a byte buffer to the stream.
317: */
318: abstract public void writeByteBufferStart() throws IOException;
319:
320: /**
321: * Writes a byte buffer to the stream.
322: *
323: * <code><pre>
324: * b b16 b18 bytes
325: * </pre></code>
326: *
327: * @param value the string value to write.
328: */
329: abstract public void writeByteBufferPart(byte[] buffer, int offset,
330: int length) throws IOException;
331:
332: /**
333: * Writes the last chunk of a byte buffer to the stream.
334: *
335: * <code><pre>
336: * b b16 b18 bytes
337: * </pre></code>
338: *
339: * @param value the string value to write.
340: */
341: abstract public void writeByteBufferEnd(byte[] buffer, int offset,
342: int length) throws IOException;
343:
344: /**
345: * Writes a reference.
346: *
347: * <code><pre>
348: * R b32 b24 b16 b8
349: * </pre></code>
350: *
351: * @param value the integer value to write.
352: */
353: abstract public void writeRef(int value) throws IOException;
354:
355: /**
356: * Removes a reference.
357: */
358: abstract public boolean removeRef(Object obj) throws IOException;
359:
360: /**
361: * Replaces a reference from one object to another.
362: */
363: abstract public boolean replaceRef(Object oldRef, Object newRef)
364: throws IOException;
365:
366: /**
367: * Adds an object to the reference list. If the object already exists,
368: * writes the reference, otherwise, the caller is responsible for
369: * the serialization.
370: *
371: * <code><pre>
372: * R b32 b24 b16 b8
373: * </pre></code>
374: *
375: * @param object the object to add as a reference.
376: *
377: * @return true if the object has already been written.
378: */
379: abstract public boolean addRef(Object object) throws IOException;
380:
381: /**
382: * Resets the references for streaming.
383: */
384: public void resetReferences() {
385: }
386:
387: /**
388: * Writes a generic object to the output stream.
389: */
390: abstract public void writeObject(Object object) throws IOException;
391:
392: /**
393: * Writes the list header to the stream. List writers will call
394: * <code>writeListBegin</code> followed by the list contents and then
395: * call <code>writeListEnd</code>.
396: *
397: * <code><pre>
398: * <list>
399: * <type>java.util.ArrayList</type>
400: * <length>3</length>
401: * <int>1</int>
402: * <int>2</int>
403: * <int>3</int>
404: * </list>
405: * </pre></code>
406: */
407: abstract public boolean writeListBegin(int length, String type)
408: throws IOException;
409:
410: /**
411: * Writes the tail of the list to the stream.
412: */
413: abstract public void writeListEnd() throws IOException;
414:
415: /**
416: * Writes the map header to the stream. Map writers will call
417: * <code>writeMapBegin</code> followed by the map contents and then
418: * call <code>writeMapEnd</code>.
419: *
420: * <code><pre>
421: * Mt b16 b8 type (<key> <value>)z
422: * </pre></code>
423: */
424: abstract public void writeMapBegin(String type) throws IOException;
425:
426: /**
427: * Writes the tail of the map to the stream.
428: */
429: abstract public void writeMapEnd() throws IOException;
430:
431: /**
432: * Writes the object header to the stream (for Hessian 2.0), or a
433: * Map for Hessian 1.0. Object writers will call
434: * <code>writeObjectBegin</code> followed by the map contents and then
435: * call <code>writeObjectEnd</code>.
436: *
437: * <code><pre>
438: * Ot b16 b8 type (<key> <value>)* z
439: * o b32 b24 b16 b8 <value>* z
440: * </pre></code>
441: *
442: * @return true if the object has already been defined.
443: */
444: public int writeObjectBegin(String type) throws IOException {
445: writeMapBegin(type);
446:
447: return -2;
448: }
449:
450: /**
451: * Writes the end of the class.
452: */
453: public void writeClassFieldLength(int len) throws IOException {
454: }
455:
456: /**
457: * Writes the tail of the object to the stream.
458: */
459: public void writeObjectEnd() throws IOException {
460: }
461:
462: /**
463: * Writes a remote object reference to the stream. The type is the
464: * type of the remote interface.
465: *
466: * <code><pre>
467: * 'r' 't' b16 b8 type url
468: * </pre></code>
469: */
470: abstract public void writeRemote(String type, String url)
471: throws IOException;
472:
473: public void startReply() throws IOException {
474: }
475:
476: public void completeReply() throws IOException {
477: }
478:
479: public void writeFault(String code, String message, Object detail)
480: throws IOException {
481: }
482:
483: public void flush() throws IOException {
484: }
485:
486: public void close() throws IOException {
487: }
488: }
|