001: /**
002: * Objective Database Abstraction Layer (ODAL)
003: * Copyright (c) 2004, The ODAL Development Group
004: * All rights reserved.
005: * For definition of the ODAL Development Group please refer to LICENCE.txt file
006: *
007: * Distributable under LGPL license.
008: * See terms of license at gnu.org.
009: */package com.completex.objective.components.persistency.type;
010:
011: import com.completex.objective.components.persistency.OdalPersistencyException;
012: import com.completex.objective.components.persistency.OdalRuntimePersistencyException;
013:
014: import java.io.ByteArrayInputStream;
015: import java.io.ByteArrayOutputStream;
016: import java.io.CharArrayWriter;
017: import java.io.Externalizable;
018: import java.io.IOException;
019: import java.io.InputStream;
020: import java.io.ObjectInput;
021: import java.io.ObjectOutput;
022: import java.io.OutputStream;
023: import java.io.Reader;
024: import java.io.StringReader;
025: import java.io.UnsupportedEncodingException;
026: import java.io.Writer;
027: import java.sql.Clob;
028: import java.sql.SQLException;
029:
030: /**
031: * @author Gennady Krizhevsky
032: */
033: public class ClobImpl implements Clob, Externalizable {
034:
035: public static final ClobImpl NULL_CLOB = new ClobImpl();
036:
037: static {
038: NULL_CLOB.setData("");
039: }
040:
041: private static final String MESSAGE = "This operation is unsupported in the implementation that is used to set data only";
042: private String data;
043: private Reader reader;
044: private InputStream inputStream;
045: private String charsetName;
046: private int chunkSize = TypeHandler.DEFAULT_CHUNK_SIZE;
047:
048: public ClobImpl() {
049: }
050:
051: public ClobImpl(String data, String charsetName) {
052: this (data);
053: this .charsetName = charsetName;
054: }
055:
056: public ClobImpl(String data) {
057: this .data = data;
058: this .reader = new StringReader(data);
059: }
060:
061: public ClobImpl(Reader reader, String charsetName) {
062: this .reader = reader;
063: this .charsetName = charsetName;
064: }
065:
066: public ClobImpl(Reader reader) {
067: this .reader = reader;
068: }
069:
070: public ClobImpl(InputStream inputStream, String charsetName) {
071: this .inputStream = inputStream;
072: this .charsetName = charsetName;
073: }
074:
075: public ClobImpl(InputStream inputStream) {
076: this .inputStream = inputStream;
077: }
078:
079: public int getChunkSize() {
080: return chunkSize;
081: }
082:
083: public void setChunkSize(int chunkSize) {
084: this .chunkSize = chunkSize;
085: }
086:
087: public long length() throws SQLException {
088: return data == null ? 0 : data.length();
089: }
090:
091: public String getString() throws SQLException {
092: if (data == null) {
093: if (reader != null) {
094: CharArrayWriter charArrayWriter = new CharArrayWriter();
095: writeClob(chunkSize, reader, charArrayWriter);
096: data = charArrayWriter.toString();
097: } else if (inputStream != null) {
098: ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
099: writeClob(chunkSize, inputStream, outputStream);
100: if (charsetName == null) {
101: data = new String(outputStream.toByteArray());
102: } else {
103: try {
104: data = new String(outputStream.toByteArray(),
105: charsetName);
106: } catch (UnsupportedEncodingException e) {
107: throw new OdalRuntimePersistencyException(
108: "Unsupported charset [" + charsetName
109: + "]", e);
110: }
111: }
112: }
113: }
114: return data;
115: }
116:
117: public void readExternal(ObjectInput in) throws IOException,
118: ClassNotFoundException {
119: charsetName = (String) in.readObject();
120: data = (String) in.readObject();
121: }
122:
123: public void writeExternal(ObjectOutput out) throws IOException {
124: try {
125: out.writeObject(charsetName);
126: out.writeObject(getString());
127: } catch (SQLException e) {
128: throw new IOException(e.toString());
129: }
130: }
131:
132: public static void writeClob(InputStream inputStream,
133: OutputStream outputStream) {
134: writeClob(TypeHandler.DEFAULT_CHUNK_SIZE, inputStream,
135: outputStream);
136: }
137:
138: public static void writeClob(int chunkSize,
139: InputStream inputStream, OutputStream outputStream) {
140: byte[] chunk = new byte[chunkSize];
141: int len;
142: try {
143: while ((len = inputStream.read(chunk, 0, chunkSize)) > -1) {
144: outputStream.write(chunk, 0, len);
145: }
146: } catch (IOException e) {
147: new SQLException(e.getMessage());
148: }
149: }
150:
151: public static void writeClob(Reader reader, Writer charArrayWriter) {
152: writeClob(TypeHandler.DEFAULT_CHUNK_SIZE, reader,
153: charArrayWriter);
154: }
155:
156: public static void writeClob(int chunkSize, Reader reader,
157: Writer charArrayWriter) {
158: char[] chunk = new char[chunkSize];
159: int len;
160: try {
161: while ((len = reader.read(chunk, 0, chunkSize)) > -1) {
162: charArrayWriter.write(chunk, 0, len);
163: }
164: } catch (IOException e) {
165: new SQLException(String.valueOf(e));
166: }
167: }
168:
169: public String getCharsetName() {
170: return charsetName;
171: }
172:
173: public void setCharsetName(String charsetName) {
174: this .charsetName = charsetName;
175: }
176:
177: public String getSubString(long pos, int length)
178: throws SQLException {
179: if (pos < 1 || pos > this .length()) {
180: throw new OdalRuntimePersistencyException(
181: "Invalid position in CLOB object set");
182: }
183:
184: if ((pos - 1) + length > this .length()) {
185: throw new OdalRuntimePersistencyException(
186: "Invalid position and substring length combination for this CLOB object");
187: }
188:
189: try {
190: return getString().substring((int) (pos - 1), length);
191: } catch (IndexOutOfBoundsException e) {
192: throw new OdalRuntimePersistencyException(e.toString());
193: }
194: }
195:
196: public Reader getCharacterStream() throws SQLException {
197: if (data != null) {
198: return new StringReader(data);
199: } else {
200: return reader;
201: }
202: }
203:
204: public InputStream getAsciiStream() throws SQLException {
205: InputStream stream = inputStream;
206: try {
207: if (data != null) {
208: byte[] bytes = charsetName == null ? data.getBytes()
209: : data.getBytes(charsetName);
210: stream = new ByteArrayInputStream(bytes);
211: }
212: } catch (UnsupportedEncodingException e) {
213: new OdalPersistencyException(e);
214: }
215: return stream;
216: }
217:
218: public long position(String searchstr, long start)
219: throws SQLException {
220: throw new UnsupportedOperationException(MESSAGE);
221: }
222:
223: public long position(Clob searchstr, long start)
224: throws SQLException {
225: throw new UnsupportedOperationException(MESSAGE);
226: }
227:
228: public int setString(long pos, String str) throws SQLException {
229: throw new UnsupportedOperationException(MESSAGE);
230: }
231:
232: public int setString(long pos, String str, int offset, int len)
233: throws SQLException {
234: throw new UnsupportedOperationException(MESSAGE);
235: }
236:
237: public OutputStream setAsciiStream(long pos) throws SQLException {
238: throw new UnsupportedOperationException(MESSAGE);
239: }
240:
241: public Writer setCharacterStream(long pos) throws SQLException {
242: throw new UnsupportedOperationException(MESSAGE);
243: }
244:
245: public void truncate(long len) throws SQLException {
246: throw new UnsupportedOperationException(MESSAGE);
247: }
248:
249: public String getData() {
250: return data;
251: }
252:
253: public void setData(String data) {
254: this .data = data;
255: }
256:
257: public Reader getReader() {
258: return reader;
259: }
260:
261: public void setReader(Reader reader) {
262: this .reader = reader;
263: }
264:
265: public InputStream getInputStream() {
266: return inputStream;
267: }
268:
269: public void setInputStream(InputStream inputStream) {
270: this .inputStream = inputStream;
271: }
272:
273: public void free() throws SQLException {
274: }
275:
276: public Reader getCharacterStream(long pos, long length)
277: throws SQLException {
278: return null;
279: }
280:
281: }
|