001: ///////////////////////////////
002: // Makumba, Makumba tag library
003: // Copyright (C) 2000-2003 http://www.makumba.org
004: //
005: // This library is free software; you can redistribute it and/or
006: // modify it under the terms of the GNU Lesser General Public
007: // License as published by the Free Software Foundation; either
008: // version 2.1 of the License, or (at your option) any later version.
009: //
010: // This library is distributed in the hope that it will be useful,
011: // but WITHOUT ANY WARRANTY; without even the implied warranty of
012: // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
013: // Lesser General Public License for more details.
014: //
015: // You should have received a copy of the GNU Lesser General Public
016: // License along with this library; if not, write to the Free Software
017: // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
018: //
019: // -------------
020: // $Id: Text.java 2111 2007-11-21 17:05:01Z manuel_gay $
021: // $Name$
022: /////////////////////////////////////
023:
024: package org.makumba;
025:
026: import java.io.ByteArrayInputStream;
027: import java.io.ByteArrayOutputStream;
028: import java.io.IOException;
029: import java.io.InputStream;
030: import java.io.OutputStream;
031: import java.io.UnsupportedEncodingException;
032:
033: import org.makumba.commons.LongData;
034: import org.makumba.commons.RuntimeWrappedException;
035:
036: /** A makumba text, a byte array that can be converted to String when needed.
037: * When texts get big, they are swapped on disk. Text swapping is logged (see {@link java.util.logging.Logger}, {@link org.makumba.MakumbaSystem#setLoggingRoot(java.lang.String)} in the logger <b><code>"abstr.longContent"</code></b> with {@link java.util.logging.Level#FINE} logging level.
038: */
039: public class Text {
040: // first alternative
041: InputStream source;
042: int len;
043:
044: // second alternative
045: LongData ld;
046:
047: public static int FILE_LIMIT;
048: static {
049: String s = null;
050: try {
051: s = System.getProperty("makumba.long-content");
052: } catch (SecurityException se) {
053: } // for applets
054: if (s != null)
055: FILE_LIMIT = Integer.parseInt(s.trim());
056: else
057: FILE_LIMIT = 32768;
058: }
059:
060: /** make a Text from the given input stream, with the given length
061: The content in the input stream must match the length.
062: No diskswap will be attempted. If you wish for the info to be swapped to disk, use the constructor Text(InputStream)*/
063: public Text(InputStream is, int length) {
064: this .source = is;
065: this .len = length;
066: }
067:
068: /** make a Text by reading the input stream. If there is a lot of data, it will be swapped to disk */
069: public Text(InputStream is) {
070: try {
071: ld = new LongData();
072: ld.appendFrom(is);
073: this .source = ld.getInputStream();
074: this .len = ld.getLength();
075: } catch (IOException e) {
076: throw new RuntimeWrappedException(e);
077: }
078: }
079:
080: /** make a Text from the String. If there is a lot of data, it will be swapped to disk */
081: public Text(String s) {
082: this (s.getBytes());
083: }
084:
085: /** make a Text from the given byte array. If there is a lot of data, it will be swapped to disk */
086: public Text(byte[] b) {
087: this (b, 0, b.length);
088: }
089:
090: /** make a Text from the given byte array. If there is a lot of data, it will be swapped to disk */
091: public Text(byte[] b, int start, int length) {
092: len = length;
093: try {
094: ld = new LongData();
095: ld.appendFrom(new ByteArrayInputStream(b, start, length));
096: source = ld.getInputStream();
097: } catch (IOException e) {
098: throw new RuntimeWrappedException(e);
099: }
100:
101: }
102:
103: /** Read the text content as a binary stream. Recommended for long content */
104: public InputStream toBinaryStream() {
105: if (source == null)
106: throw new MakumbaError(
107: "texts indicated by stream can only be consumed once");
108: if (ld != null)
109: try {
110: return ld.getInputStream();
111: } catch (IOException e) {
112: throw new RuntimeWrappedException(e);
113: }
114: InputStream s = source;
115: source = null;
116: return s;
117: }
118:
119: public int length() {
120: return len;
121: }
122:
123: /** convenience method for making a text out of another Text, InputStream, String, or byte[] */
124: public static Text getText(Object value) {
125: if (value instanceof Text)
126: return (Text) value;
127: if (value instanceof java.io.InputStream)
128: return new Text((InputStream) value);
129: if (value instanceof String)
130: return new Text((String) value);
131: if (value instanceof byte[])
132: return new Text((byte[]) value);
133: throw new InvalidValueException(
134: "unsupported type to make text of " + value.getClass());
135: }
136:
137: /** converts the text content to a string */
138: public String toString() {
139: ByteArrayOutputStream bo = new ByteArrayOutputStream(
140: len < FILE_LIMIT ? len : FILE_LIMIT);
141: try {
142: writeTo(bo);
143: } catch (IOException e) {
144: throw new RuntimeWrappedException(e);
145: }
146:
147: try {
148: if (org.makumba.db.makumba.sql.Database.supportsUTF8()) {
149: /*
150: String asd = new String(bo.toByteArray(), "UTF-8");
151: System.out.println("UTF1: "+(new String(bo.toByteArray())));
152: System.out.println("UTF: "+asd);
153: */
154: return new String(bo.toByteArray(), "UTF-8");
155: }
156: } catch (UnsupportedEncodingException e) {
157: }
158:
159: return new String(bo.toByteArray());
160: }
161:
162: /** write content to the given output stream */
163: public void writeTo(OutputStream o) throws IOException {
164: byte[] b = new byte[len < FILE_LIMIT ? len : FILE_LIMIT];
165: InputStream is = toBinaryStream();
166:
167: try {
168: int n;
169: while ((n = is.read(b, 0, b.length)) != -1)
170: o.write(b, 0, n);
171: } finally {
172: o.close();
173: is.close();
174: }
175: }
176:
177: /** compare the content to the content of a given stream, and closes the stream */
178: public boolean compare(InputStream is) throws IOException {
179: InputStream is1 = toBinaryStream();
180: try {
181: int n, m;
182: int i = 0;
183: while ((n = is.read()) != -1)
184: if (n != (m = is1.read())) {
185: java.util.logging.Logger.getLogger(
186: "org.makumba." + "debug.abstr").severe(
187: m + " " + n + " " + i);
188: return false;
189: } else
190: i++;
191: return is1.read() == -1;
192: } finally {
193: is.close();
194: is1.close();
195: }
196: }
197:
198: /** Indicates whether the other object is "equal to" this Text. */
199: public boolean equals(Object other) {
200: if (other == null)
201: return false;
202: if (this .getClass() != other.getClass())
203: return false;
204: if (this .length() != ((Text) other).length())
205: return false;
206: try {
207: return this .compare(((Text) other).toBinaryStream());
208: } catch (IOException e) {
209: return false;
210: }
211: }
212:
213: }
|