001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */
017:
018: package javax.sql.rowset.serial;
019:
020: import java.io.CharArrayReader;
021: import java.io.IOException;
022: import java.io.InputStream;
023: import java.io.OutputStream;
024: import java.io.Reader;
025: import java.io.Serializable;
026: import java.io.Writer;
027: import java.sql.Clob;
028: import java.sql.SQLException;
029:
030: import org.apache.harmony.sql.internal.nls.Messages;
031:
032: public class SerialClob implements Clob, Serializable, Cloneable {
033:
034: // required by serialized form
035: @SuppressWarnings("unused")
036: private static final long serialVersionUID = -1662519690087375313L;
037:
038: private char[] buf;
039:
040: // required by serialized form
041: @SuppressWarnings("unused")
042: private Clob clob;
043:
044: private long len;
045:
046: // required by serialized form
047: private long origLen;
048:
049: public SerialClob(char[] ch) throws SerialException, SQLException {
050: buf = new char[ch.length];
051: origLen = ch.length;
052: len = origLen;
053: System.arraycopy(ch, 0, buf, 0, (int) len);
054: }
055:
056: public SerialClob(Clob clob) throws SerialException, SQLException {
057: Reader characterStream;
058: InputStream asciiStream;
059:
060: if (clob == null) {
061: throw new SQLException(Messages.getString("sql.19"));//$NON-NLS-1$
062: }
063: if ((characterStream = clob.getCharacterStream()) == null
064: && (asciiStream = clob.getAsciiStream()) == null) {
065: throw new SQLException(Messages.getString("sql.20"));//$NON-NLS-1$
066: }
067:
068: this .clob = clob;
069: origLen = clob.length();
070: len = origLen;
071: buf = new char[(int) len];
072: try {
073: characterStream.read(buf);
074: } catch (IOException e) {
075: SerialException se = new SerialException("SerialClob: "
076: + e.getMessage());
077:
078: se.initCause(e);
079: throw se;
080: }
081: }
082:
083: public long length() throws SerialException {
084: checkValidation();
085: return len;
086: }
087:
088: public InputStream getAsciiStream() throws SerialException,
089: SQLException {
090: checkValidation();
091: if (clob == null) {
092: throw new SerialException(Messages.getString("sql.25")); // $NON-NLS-1$
093: }
094: return clob.getAsciiStream();
095: }
096:
097: public Reader getCharacterStream() throws SerialException {
098: checkValidation();
099: return new CharArrayReader(buf);
100: }
101:
102: public String getSubString(long pos, int length)
103: throws SerialException {
104: checkValidation();
105: if (pos < 1 || pos > len) {
106: throw new SerialException(Messages.getString("sql.21")); // $NON-NLS-1$
107: }
108: if (length < 0 || pos + length > len + 1) {
109: throw new SerialException(Messages.getString("sql.22")); // $NON-NLS-1$
110: }
111: try {
112: return new String(buf, (int) (pos - 1), length);
113: } catch (StringIndexOutOfBoundsException e) {
114: throw new SerialException();
115: }
116: }
117:
118: public long position(Clob searchClob, long start)
119: throws SerialException, SQLException {
120: checkValidation();
121: String searchString = searchClob.getSubString(1,
122: (int) searchClob.length());
123: return position(searchString, start);
124: }
125:
126: public long position(String searchString, long start)
127: throws SerialException, SQLException {
128: checkValidation();
129: if (start < 1 || len - (start - 1) < searchString.length()) {
130: return -1;
131: }
132: char[] pattern = searchString.toCharArray();
133: for (int i = (int) start - 1; i < len; i++) {
134: if (match(buf, i, pattern)) {
135: return i + 1;
136: }
137: }
138: return -1;
139: }
140:
141: /*
142: * Returns true if the chars array contains exactly the same elements from
143: * start position to start + pattern.length as pattern. Otherwise returns
144: * false.
145: */
146: private boolean match(char[] chars, int start, char[] pattern) {
147: for (int i = 0; i < pattern.length;) {
148: if (chars[start++] != pattern[i++]) {
149: return false;
150: }
151: }
152: return true;
153: }
154:
155: public OutputStream setAsciiStream(long pos)
156: throws SerialException, SQLException {
157: checkValidation();
158: if (clob == null) {
159: throw new SerialException(Messages.getString("sql.25")); // $NON-NLS-1$
160: }
161: OutputStream os = clob.setAsciiStream(pos);
162: if (os == null) {
163: throw new SerialException(Messages.getString("sql.46")); // $NON-NLS-1$
164: }
165: return os;
166: }
167:
168: public Writer setCharacterStream(long pos) throws SerialException,
169: SQLException {
170: checkValidation();
171: if (clob == null) {
172: throw new SerialException(Messages.getString("sql.25")); // $NON-NLS-1$
173: }
174: Writer writer = clob.setCharacterStream(pos);
175: if (writer == null) {
176: throw new SerialException(Messages.getString("sql.45")); // $NON-NLS-1$
177: }
178: return writer;
179: }
180:
181: public int setString(long pos, String str) throws SerialException {
182: checkValidation();
183: return setString(pos, str, 0, str.length());
184: }
185:
186: public int setString(long pos, String str, int offset, int length)
187: throws SerialException {
188: checkValidation();
189: if (pos < 1 || length < 0 || pos > (len - length + 1)) {
190: throw new SerialException(Messages.getString("sql.21")); // $NON-NLS-1$
191: }
192: if (offset < 0 || offset > (str.length() - length)) {
193: throw new SerialException(Messages.getString("sql.21")); // $NON-NLS-1$
194: }
195: if (length > len + offset) {
196: throw new SerialException(Messages.getString("sql.23")); // $NON-NLS-1$
197: }
198: str.getChars(offset, offset + length, buf, (int) pos - 1);
199: return length;
200: }
201:
202: public void truncate(long length) throws SerialException {
203: checkValidation();
204: if (length > len || length < 0) {
205: throw new SerialException(Messages.getString("sql.24"));
206: }
207: char[] truncatedBuffer = new char[(int) length];
208: System.arraycopy(buf, 0, truncatedBuffer, 0, (int) length);
209: buf = truncatedBuffer;
210: len = length;
211: }
212:
213: private void checkValidation() throws SerialException {
214: if (len == -1) {
215: throw new SerialException(Messages.getString("sql.38")); //$NON-NLS-1$
216: }
217: }
218: }
|