KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > derby > iapi > services > io > FormatIdOutputStream


1 /*
2
3    Derby - Class org.apache.derby.iapi.services.io.FormatIdOutputStream
4
5    Licensed to the Apache Software Foundation (ASF) under one or more
6    contributor license agreements. See the NOTICE file distributed with
7    this work for additional information regarding copyright ownership.
8    The ASF licenses this file to you under the Apache License, Version 2.0
9    (the "License"); you may not use this file except in compliance with
10    the License. You may obtain a copy of the License at
11
12       http://www.apache.org/licenses/LICENSE-2.0
13
14    Unless required by applicable law or agreed to in writing, software
15    distributed under the License is distributed on an "AS IS" BASIS,
16    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17    See the License for the specific language governing permissions and
18    limitations under the License.
19
20  */

21
22 package org.apache.derby.iapi.services.io;
23
24 import org.apache.derby.iapi.services.sanity.SanityManager;
25
26 import org.apache.derby.iapi.services.info.JVMInfo;
27
28 import java.io.DataOutputStream JavaDoc;
29 import java.io.IOException JavaDoc;
30 import java.io.ObjectOutput JavaDoc;
31 import java.io.ObjectOutputStream JavaDoc;
32 import java.io.OutputStream JavaDoc;
33 import java.io.Serializable JavaDoc;
34
35
36 /**
37   A stream for serializing objects with format id tags.
38
39   <P>An ObjectOutput (henceforth 'out') preceeds objects it writes with
40   a format id. The companion FormatIdInputStream (henceforth 'in')
41   uses these format ids in parsing the stored data. The stream
42   can be thought of as containing a sequence of (formatId,object) pairs
43   interspersed with other data. The assumption is that out.writeObject()
44   produces these pairs and in.readObject() uses the format ids to
45   construct objects from the pairs that out.writeObject produced.
46   The description below describes each supported pair and how in.readObject()
47   processes it.
48
49   <OL>
50   <LI> (NULL_FORMAT_ID, nothing) in.readObject() returns null.
51   <LI> (SRING_FORMAT_ID, UTF8 encoded string)in.readObject reads and
52        returns this string.
53   <LI> (SERIALIZABLE_FORMAT_ID,serialized object) in.readObject() reads
54        the object using java serialization and returns it.
55   <LI> (A format id for a Storable, isNull flag and object if isNull == false)
56        (see note 1) in.readObject() reads the boolean isNull flag. If is null
57        is true, in.readObject() returns a Storable object of the correct
58        class which is null. If ifNull is false, in.readObject() restores
59        the object using its readExternal() method.
60   <LI> (A format id for a Formatable which is not Storable, the stored object)
61        (see note 1) in.readObject restores the object using its
62        readExternal() method.
63   </OL>
64
65   <P>Note 1: The FormatIdInputStream uses
66   Monitor.newInstanceFromIdentifier(format id) to get the class.
67   <P>Note 2: An object may support more than one of the following
68   interfaces Storable, Formatable, Serializable. In this case out.writeObject
69   use the first of these interfaces which the object supports (based on the order
70   listed here) to determine how to write the object.
71  */

72 public class FormatIdOutputStream
73 extends DataOutputStream JavaDoc implements ObjectOutput JavaDoc, ErrorInfo
74 {
75
76     /**
77       Constructor for a FormatIdOutputStream
78
79       @param out output goes here.
80       */

81     public FormatIdOutputStream(OutputStream JavaDoc out)
82     {
83         super(out);
84     }
85
86     /**
87       Write a format id for the object provied followed by the
88       object itself to this FormatIdOutputStream.
89
90       @param ref a reference to the object.
91       @exception java.io.IOException the exception.
92       */

93     public void writeObject(Object JavaDoc ref) throws IOException JavaDoc
94     {
95         if (ref == null)
96         {
97             FormatIdUtil.writeFormatIdInteger(this, StoredFormatIds.NULL_FORMAT_ID);
98             return;
99         }
100
101         if (ref instanceof String JavaDoc)
102         {
103             // String's are special cased to use writeUTF which is more
104
// efficient than the default writeObject(String), but the format
105
// can only store 65535 bytes. The worst case size conversion is
106
// 3 bytes for each unicode character in a String, so limiting
107
// writeUTF optimization to strings smaller than 20000 should
108
// insure that we won't call writeUTF() and produce more than
109
// 65535 bytes.
110

111             String JavaDoc str = (String JavaDoc) ref;
112
113             if (str.length() <= 20000)
114             {
115                 FormatIdUtil.writeFormatIdInteger(
116                     this, StoredFormatIds.STRING_FORMAT_ID);
117
118                 this.writeUTF((String JavaDoc)ref);
119                 return;
120             }
121         }
122
123         // Add debugging code to read-in every formatable that we write
124
// to ensure that it can be read and it's correctly registered.
125
OutputStream JavaDoc oldOut = null;
126         if (SanityManager.DEBUG) {
127
128             if (ref instanceof Formatable) {
129
130                 oldOut = this.out;
131
132                 this.out = new DebugByteTeeOutputStream(oldOut);
133             }
134         }
135
136         if (ref instanceof Storable)
137         {
138             Storable s = (Storable)ref;
139
140             int fmtId = s.getTypeFormatId();
141
142             if (fmtId != StoredFormatIds.SERIALIZABLE_FORMAT_ID) {
143                 FormatIdUtil.writeFormatIdInteger(this, fmtId);
144                 boolean isNull = s.isNull();
145                 writeBoolean(isNull);
146                 if (!isNull)
147                 {
148                     s.writeExternal(this);
149                 }
150                 if (SanityManager.DEBUG) {
151                     ((DebugByteTeeOutputStream) this.out).checkObject(s);
152                     this.out = oldOut;
153                 }
154                 return;
155             }
156         }
157         else if (ref instanceof Formatable)
158         {
159             Formatable f =
160                 (Formatable) ref;
161             int fmtId = f.getTypeFormatId();
162
163             if (fmtId != StoredFormatIds.SERIALIZABLE_FORMAT_ID) {
164                 FormatIdUtil.writeFormatIdInteger(this,fmtId);
165                 f.writeExternal(this);
166
167                 if (SanityManager.DEBUG) {
168                     ((DebugByteTeeOutputStream) this.out).checkObject(f);
169                     this.out = oldOut;
170                 }
171                 return;
172             }
173         }
174
175         /*
176         ** Otherwise we assume (ref instanceof Serializable).
177         ** If it isn't we'll get an error, which is what
178         ** we would expect if someone uses something that
179         ** doesn't support Serializable/Externalizable/Formattable
180         ** when it should.
181         */

182         {
183
184             /*
185             ** If we are debugging (SerializeTrace), we are
186             ** going to print out every unexpected serialized
187             ** class. We print them out to stdout to help
188             ** in debugging (so they cause diffs in test runs).
189             ** This is only active in a SANE server.
190             */

191             if (SanityManager.DEBUG)
192             {
193                 if (SanityManager.DEBUG_ON("SerializedTrace"))
194                 {
195                     String JavaDoc name = ref.getClass().getName();
196                     if (
197                         !name.startsWith("java.lang") &&
198                         !name.startsWith("java.math"))
199                     {
200                         SanityManager.DEBUG("SerializedTrace",
201                             "...writing serialized class: "+name);
202                         System.out.println(
203                             "...writing serialized class: "+name);
204                     }
205                 }
206             }
207
208             FormatIdUtil.writeFormatIdInteger(this, StoredFormatIds.SERIALIZABLE_FORMAT_ID);
209             ObjectOutputStream JavaDoc oos = new ObjectOutputStream JavaDoc(this);
210             oos.writeObject(ref);
211             oos.flush();
212
213             if (SanityManager.DEBUG && ref instanceof Formatable) {
214                 ((DebugByteTeeOutputStream) this.out).checkObject((Formatable) ref);
215                 this.out = oldOut;
216             }
217         }
218     }
219
220     /**
221       Set the OutputStream for this FormatIdOutputStream to the stream
222       provided. It is the responsibility of the caller to flush or
223       close (as required) the previous stream this class was attached to.
224
225       @param out The new output stream.
226       */

227     public void setOutput(OutputStream JavaDoc out)
228     {
229         this.out = out;
230         this.written = 0;
231     }
232
233
234     /* Methods of ErrorInfo, used here for SQLData error reporting */
235
236     public String JavaDoc getErrorInfo()
237     {
238         return null;
239     }
240
241     public Exception JavaDoc getNestedException()
242     {
243           return null;
244     }
245
246 }
247
Popular Tags