55 * @serial |
55 * @serial |
56 */ |
56 */ |
57 private char buf[]; |
57 private char buf[]; |
58 |
58 |
59 /** |
59 /** |
60 * Internal Clob representation if SerialClob is intialized with a |
60 * Internal Clob representation if SerialClob is initialized with a |
61 * Clob |
61 * Clob. Null if SerialClob is initialized with a char[]. |
62 */ |
62 */ |
63 private Clob clob; |
63 private final Clob clob; |
64 |
64 |
65 /** |
65 /** |
66 * The length in characters of this <code>SerialClob</code> object's |
66 * The length in characters of this <code>SerialClob</code> object's |
67 * internal array of characters. |
67 * internal array of characters. |
68 * |
68 * |
69 * @serial |
69 * @serial |
70 */ |
70 */ |
71 private long len; |
71 private long len; |
72 |
72 |
73 /** |
73 /** |
74 * The original length in characters of tgus <code>SerialClob</code> |
74 * The original length in characters of this <code>SerialClob</code> |
75 * objects internal array of characters. |
75 * object's internal array of characters. |
76 * |
76 * |
77 * @serial |
77 * @serial |
78 */ |
78 */ |
79 private long origLen; |
79 private final long origLen; |
80 |
80 |
81 /** |
81 /** |
82 * Constructs a <code>SerialClob</code> object that is a serialized version of |
82 * Constructs a <code>SerialClob</code> object that is a serialized version of |
83 * the given <code>char</code> array. |
83 * the given <code>char</code> array. |
84 * <p> |
84 * <p> |
115 * <code>Clob</code> object should have previously brought the |
116 * <code>Clob</code> object should have previously brought the |
116 * SQL <code>CLOB</code> value's data over to the client from |
117 * SQL <code>CLOB</code> value's data over to the client from |
117 * the database. Otherwise, the new <code>SerialClob</code> object |
118 * the database. Otherwise, the new <code>SerialClob</code> object |
118 * object will contain no data. |
119 * object will contain no data. |
119 * <p> |
120 * <p> |
120 * Note: The <code>Clob</code> object supplied to this constructor cannot |
121 * Note: The <code>Clob</code> object supplied to this constructor must |
121 * return <code>null</code> for the <code>Clob.getCharacterStream()</code> |
122 * return non-null for both the <code>Clob.getCharacterStream()</code> |
122 * and <code>Clob.getAsciiStream</code> methods. This <code>SerialClob</code> |
123 * and <code>Clob.getAsciiStream</code> methods. This <code>SerialClob</code> |
123 * constructor cannot serialize a <code>Clob</code> object in this instance |
124 * constructor cannot serialize a <code>Clob</code> object in this instance |
124 * and will throw an <code>SQLException</code> object. |
125 * and will throw an <code>SQLException</code> object. |
125 * |
126 * |
126 * @param clob the <code>Clob</code> object from which this |
127 * @param clob the <code>Clob</code> object from which this |
127 * <code>SerialClob</code> object is to be constructed; cannot be null |
128 * <code>SerialClob</code> object is to be constructed; cannot be null |
128 * @throws SerialException if an error occurs during serialization |
129 * @throws SerialException if an error occurs during serialization |
129 * @throws SQLException if a SQL error occurs in capturing the CLOB; |
130 * @throws SQLException if a SQL error occurs in capturing the CLOB; |
130 * if the <code>Clob</code> object is a null; or if both the |
131 * if the <code>Clob</code> object is a null; or if either of the |
131 * <code>Clob.getCharacterStream()</code> and <code>Clob.getAsciiStream()</code> |
132 * <code>Clob.getCharacterStream()</code> and <code>Clob.getAsciiStream()</code> |
132 * methods on the <code>Clob</code> return a null |
133 * methods on the <code>Clob</code> returns a null |
133 * @see java.sql.Clob |
134 * @see java.sql.Clob |
134 */ |
135 */ |
135 public SerialClob(Clob clob) throws SerialException, SQLException { |
136 public SerialClob(Clob clob) throws SerialException, SQLException { |
136 |
137 |
137 if (clob == null) { |
138 if (clob == null) { |
142 this.clob = clob; |
143 this.clob = clob; |
143 buf = new char[(int)len]; |
144 buf = new char[(int)len]; |
144 int read = 0; |
145 int read = 0; |
145 int offset = 0; |
146 int offset = 0; |
146 |
147 |
147 BufferedReader reader; |
148 try (Reader charStream = clob.getCharacterStream()) { |
148 if ( (((reader = new BufferedReader(clob.getCharacterStream())) == null)) && |
149 if (charStream == null) { |
149 (clob.getAsciiStream() == null)) { |
150 throw new SQLException("Invalid Clob object. The call to getCharacterStream " + |
150 throw new SQLException("Invalid Clob object. Calls to getCharacterStream " + |
151 "returned null which cannot be serialized."); |
151 "and getAsciiStream return null which cannot be serialized."); |
152 } |
152 } |
153 |
153 |
154 // Note: get an ASCII stream in order to null-check it, |
154 try { |
155 // even though we don't do anything with it. |
155 do { |
156 try (InputStream asciiStream = clob.getAsciiStream()) { |
156 read = reader.read(buf, offset, (int)(len - offset)); |
157 if (asciiStream == null) { |
157 offset += read; |
158 throw new SQLException("Invalid Clob object. The call to getAsciiStream " + |
158 } while (read > 0); |
159 "returned null which cannot be serialized."); |
159 |
160 } |
|
161 } |
|
162 |
|
163 try (Reader reader = new BufferedReader(charStream)) { |
|
164 do { |
|
165 read = reader.read(buf, offset, (int)(len - offset)); |
|
166 offset += read; |
|
167 } while (read > 0); |
|
168 } |
160 } catch (java.io.IOException ex) { |
169 } catch (java.io.IOException ex) { |
161 throw new SerialException("SerialClob: " + ex.getMessage()); |
170 throw new SerialException("SerialClob: " + ex.getMessage()); |
162 } |
171 } |
163 |
172 |
164 origLen = len; |
173 origLen = len; |
205 * @throws SQLException if there is an error accessing the |
214 * @throws SQLException if there is an error accessing the |
206 * <code>CLOB</code> value represented by the <code>Clob</code> object that was |
215 * <code>CLOB</code> value represented by the <code>Clob</code> object that was |
207 * used to create this <code>SerialClob</code> object |
216 * used to create this <code>SerialClob</code> object |
208 */ |
217 */ |
209 public java.io.InputStream getAsciiStream() throws SerialException, SQLException { |
218 public java.io.InputStream getAsciiStream() throws SerialException, SQLException { |
210 if (this.clob != null) { |
219 if (this.clob != null) { |
211 return this.clob.getAsciiStream(); |
220 return this.clob.getAsciiStream(); |
212 } else { |
221 } else { |
213 throw new SerialException("Unsupported operation. SerialClob cannot " + |
222 throw new SerialException("Unsupported operation. SerialClob cannot " + |
214 "return a the CLOB value as an ascii stream, unless instantiated " + |
223 "return a the CLOB value as an ascii stream, unless instantiated " + |
215 "with a fully implemented Clob object."); |
224 "with a fully implemented Clob object."); |
216 } |
225 } |
217 } |
226 } |
218 |
227 |
219 /** |
228 /** |
220 * Returns a copy of the substring contained in this |
229 * Returns a copy of the substring contained in this |
221 * <code>SerialClob</code> object, starting at the given position |
230 * <code>SerialClob</code> object, starting at the given position |