1 | /* |
2 | |
3 | Derby - Class org.apache.derby.iapi.services.io.FormatableArrayHolder |
4 | |
5 | Copyright 1998, 2004 The Apache Software Foundation or its licensors, as applicable. |
6 | |
7 | Licensed under the Apache License, Version 2.0 (the "License"); |
8 | you may not use this file except in compliance with the License. |
9 | You may obtain a copy of the License at |
10 | |
11 | http://www.apache.org/licenses/LICENSE-2.0 |
12 | |
13 | Unless required by applicable law or agreed to in writing, software |
14 | distributed under the License is distributed on an "AS IS" BASIS, |
15 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
16 | See the License for the specific language governing permissions and |
17 | limitations under the License. |
18 | |
19 | */ |
20 | |
21 | package org.apache.derby.iapi.services.io; |
22 | |
23 | import org.apache.derby.iapi.services.io.ArrayInputStream; |
24 | |
25 | import org.apache.derby.iapi.services.io.StoredFormatIds; |
26 | import org.apache.derby.iapi.services.io.FormatIdUtil; |
27 | import org.apache.derby.iapi.services.io.ArrayUtil; |
28 | import org.apache.derby.iapi.services.io.Formatable; |
29 | |
30 | import org.apache.derby.iapi.services.sanity.SanityManager; |
31 | |
32 | import java.io.ObjectOutput; |
33 | import java.io.ObjectInput; |
34 | import java.io.IOException; |
35 | |
36 | import java.lang.reflect.Array; |
37 | |
38 | /** |
39 | * A formatable holder for an array of formatables. |
40 | * Used to avoid serializing arrays. |
41 | */ |
42 | public class FormatableArrayHolder implements Formatable |
43 | { |
44 | /******************************************************** |
45 | ** |
46 | ** This class implements Formatable. That means that it |
47 | ** can write itself to and from a formatted stream. If |
48 | ** you add more fields to this class, make sure that you |
49 | ** also write/read them with the writeExternal()/readExternal() |
50 | ** methods. |
51 | ** |
52 | ** If, inbetween releases, you add more fields to this class, |
53 | ** then you should bump the version number emitted by the getTypeFormatId() |
54 | ** method. |
55 | ** |
56 | ********************************************************/ |
57 | |
58 | // the array |
59 | private Object[] array; |
60 | |
61 | /** |
62 | * Niladic constructor for formatable |
63 | */ |
64 | public FormatableArrayHolder() |
65 | { |
66 | } |
67 | |
68 | /** |
69 | * Construct a FormatableArrayHolder using the input |
70 | * array. |
71 | * |
72 | * @param array the array to hold |
73 | */ |
74 | public FormatableArrayHolder(Object[] array) |
75 | { |
76 | if (SanityManager.DEBUG) |
77 | { |
78 | SanityManager.ASSERT(array != null, |
79 | "array input to constructor is null, code can't handle this."); |
80 | } |
81 | |
82 | this.array = array; |
83 | } |
84 | |
85 | /** |
86 | * Set the held array to the input array. |
87 | * |
88 | * @param array the array to hold |
89 | */ |
90 | public void setArray(Object[] array) |
91 | { |
92 | if (SanityManager.DEBUG) |
93 | { |
94 | SanityManager.ASSERT(array != null, |
95 | "array input to setArray() is null, code can't handle this."); |
96 | } |
97 | |
98 | this.array = array; |
99 | } |
100 | |
101 | /** |
102 | * Get the held array of formatables, and return |
103 | * it in an array of type inputClass. |
104 | * |
105 | * @param inputClass the class to use for the returned array |
106 | * |
107 | * @return an array of formatables |
108 | */ |
109 | public Object[] getArray(Class inputClass) |
110 | { |
111 | Object[] outArray = (Object[])Array.newInstance(inputClass, array.length); |
112 | |
113 | /* |
114 | ** HACK: on as400 the following arraycopy() throws an |
115 | ** ArrayStoreException because the output array isn't |
116 | ** assignment compatible with the input array. This |
117 | ** is a bug on as400, but to get around it we are |
118 | ** going to do an element by element copy. |
119 | */ |
120 | //System.arraycopy(array, 0, outArray, 0, outArray.length); |
121 | for (int i = 0; i < outArray.length; i++) |
122 | { |
123 | outArray[i] = array[i]; |
124 | } |
125 | |
126 | return outArray; |
127 | } |
128 | |
129 | ////////////////////////////////////////////// |
130 | // |
131 | // FORMATABLE |
132 | // |
133 | ////////////////////////////////////////////// |
134 | /** |
135 | * Write this array out |
136 | * |
137 | * @param out write bytes here |
138 | * |
139 | * @exception IOException thrown on error |
140 | */ |
141 | public void writeExternal(ObjectOutput out) throws IOException |
142 | { |
143 | if (SanityManager.DEBUG) |
144 | { |
145 | SanityManager.ASSERT(array != null, "Array is null, which isn't expected"); |
146 | } |
147 | |
148 | ArrayUtil.writeArrayLength(out, array); |
149 | ArrayUtil.writeArrayItems(out, array); |
150 | } |
151 | |
152 | /** |
153 | * Read this array from a stream of stored objects. |
154 | * |
155 | * @param in read this. |
156 | * |
157 | * @exception IOException thrown on error |
158 | * @exception ClassNotFoundException thrown on error |
159 | */ |
160 | public void readExternal(ObjectInput in) |
161 | throws IOException, ClassNotFoundException |
162 | { |
163 | array = new Object[ArrayUtil.readArrayLength(in)]; |
164 | ArrayUtil.readArrayItems(in, array); |
165 | } |
166 | public void readExternal(ArrayInputStream in) |
167 | throws IOException, ClassNotFoundException |
168 | { |
169 | array = new Formatable[ArrayUtil.readArrayLength(in)]; |
170 | ArrayUtil.readArrayItems(in, array); |
171 | } |
172 | |
173 | |
174 | /** |
175 | * Get the formatID which corresponds to this class. |
176 | * |
177 | * @return the formatID of this class |
178 | */ |
179 | public int getTypeFormatId() { return StoredFormatIds.FORMATABLE_ARRAY_HOLDER_V01_ID; } |
180 | } |