KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > derby > client > am > Lob


1 /*
2
3    Derby - Class org.apache.derby.client.am.Lob
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.client.am;
23
24 import java.io.InputStream JavaDoc;
25 import java.io.IOException JavaDoc;
26 import java.util.ArrayList JavaDoc;
27
28 import org.apache.derby.shared.common.reference.SQLState;
29
30 public abstract class Lob implements UnitOfWorkListener {
31     // The following flags specify the data type(s) a LOB instance currently contains
32
public static final int STRING = 2;
33     public static final int ASCII_STREAM = 4;
34     public static final int UNICODE_STREAM = 8;
35     public static final int CHARACTER_STREAM = 16;
36     public static final int BINARY_STREAM = 32;
37     public static final int BINARY_STRING = 64;
38
39     //---------------------navigational members-----------------------------------
40
protected Agent agent_;
41
42     //-----------------------------state------------------------------------------
43
protected int dataType_ = 0; // data type(s) the LOB instance currently contains
44

45     protected long sqlLength_; // length of the LOB value, as defined by the server
46
protected boolean lengthObtained_;
47
48     //---------------------constructors/finalizer---------------------------------
49
protected Lob(Agent agent) {
50         agent_ = agent;
51         lengthObtained_ = false;
52     }
53
54     protected void finalize() throws java.lang.Throwable JavaDoc {
55         super.finalize();
56     }
57
58     // ---------------------------jdbc 2------------------------------------------
59

60     // should only be called by a synchronized method.
61

62
63     // should only be called by a synchronized method.
64
public long sqlLength() throws SqlException {
65         checkForClosedConnection();
66
67         return sqlLength_;
68     }
69
70
71     //-----------------------event callback methods-------------------------------
72

73     public void listenToUnitOfWork() {
74         agent_.connection_.CommitAndRollbackListeners_.put(this,null);
75     }
76
77     public void completeLocalCommit(java.util.Iterator JavaDoc listenerIterator) {
78         listenerIterator.remove();
79     }
80
81     public void completeLocalRollback(java.util.Iterator JavaDoc listenerIterator) {
82         listenerIterator.remove();
83     }
84
85     //----------------------------helper methods----------------------------------
86

87     public Agent getAgent() {
88         return agent_;
89     }
90
91     void checkForClosedConnection() throws SqlException {
92         if (agent_.connection_.isClosedX()) {
93             agent_.checkForDeferredExceptions();
94             throw new SqlException(agent_.logWriter_,
95                 new ClientMessageId(SQLState.LOB_METHOD_ON_CLOSED_CONNECTION));
96         } else {
97             agent_.checkForDeferredExceptions();
98         }
99     }
100
101     void completeLocalRollback() {
102         ;
103     }
104
105     void completeLocalCommit() {
106         ;
107     }
108
109     /**
110      * Materialize the given stream into memory and update the internal
111      * length variable.
112      *
113      * @param is stream to use for input
114      * @param typeDesc description of the data type we are inserting,
115      * for instance <code>java.sql.Clob</code>
116      * @return a stream whose source is the materialized data
117      * @throws SqlException if the stream exceeds 2 GB, or an error happens
118      * while reading from the stream
119      */

120     protected InputStream JavaDoc materializeStream(InputStream JavaDoc is, String JavaDoc typeDesc)
121             throws SqlException {
122         final int GROWBY = 32 * 1024; // 32 KB
123
ArrayList JavaDoc byteArrays = new ArrayList JavaDoc();
124         byte[] curBytes = new byte[GROWBY];
125         int totalLength = 0;
126         int partLength = 0;
127         // Read all data from the stream, storing it in a number of arrays.
128
try {
129             do {
130                 partLength = is.read(curBytes, 0, curBytes.length);
131                 if (partLength == curBytes.length) {
132                     byteArrays.add(curBytes);
133                     // Make sure we don't exceed 2 GB by checking for overflow.
134
int newLength = totalLength + GROWBY;
135                     if (newLength < 0 || newLength == Integer.MAX_VALUE) {
136                         curBytes = new byte[Integer.MAX_VALUE - totalLength];
137                     } else {
138                         curBytes = new byte[GROWBY];
139                     }
140                 }
141                 if (partLength > 0) {
142                     totalLength += partLength;
143                 }
144             } while (partLength == GROWBY);
145             // Make sure stream is exhausted.
146
if (is.read() != -1) {
147                 // We have exceeded 2 GB.
148
throw new SqlException(
149                             null,
150                             new ClientMessageId(
151                                 SQLState.LANG_OUTSIDE_RANGE_FOR_DATATYPE),
152                                 typeDesc
153                         );
154             }
155             if (partLength > 0) {
156                 byteArrays.add(curBytes);
157             }
158
159             // Cleanup and set state.
160
curBytes = null;
161             sqlLength_ = totalLength;
162             lengthObtained_ = true;
163             // Return a stream whose source is a list of byte arrays.
164
// This avoids having to copy all the data into a single big array.
165
return new ByteArrayCombinerStream(byteArrays, totalLength);
166         } catch (IOException JavaDoc ioe) {
167             throw new SqlException(null,
168                         new ClientMessageId(
169                             SQLState.LANG_STREAMING_COLUMN_I_O_EXCEPTION),
170                         typeDesc,
171                         ioe
172                     );
173         }
174     }
175 }
176
Popular Tags