001: /* AMedia.java
002:
003: {{IS_NOTE
004: Purpose:
005:
006: Description:
007:
008: History:
009: Thu May 27 15:10:46 2004, Created by tomyeh
010: }}IS_NOTE
011:
012: Copyright (C) 2004 Potix Corporation. All Rights Reserved.
013:
014: {{IS_RIGHT
015: This program is distributed under GPL Version 2.0 in the hope that
016: it will be useful, but WITHOUT ANY WARRANTY.
017: }}IS_RIGHT
018: */
019: package org.zkoss.util.media;
020:
021: import java.io.Reader;
022: import java.io.InputStream;
023: import java.io.StringReader;
024: import java.io.ByteArrayInputStream;
025:
026: import org.zkoss.io.NullInputStream;
027: import org.zkoss.io.NullReader;
028:
029: /**
030: * A media object holding content such PDF, HTML, DOC or XLS content.
031: *
032: * @author tomyeh
033: */
034: public class AMedia implements Media {
035: /** Used if you want to implement a meida whose input stream is created
036: * dynamically each time {@link #getStreamData} is called.
037: * @see #AMedia(String,String,String,InputStream)
038: */
039: protected static final InputStream DYNAMIC_STREAM = new NullInputStream();
040: /** Used if you want to implement a meida whose reader is created
041: * dynamically each time {@link #getReaderData} is called.
042: * @see #AMedia(String,String,String,Reader)
043: */
044: protected static final Reader DYNAMIC_READER = new NullReader();
045:
046: /** The binary data, {@link #getByteData}. */
047: private byte[] _bindata;
048: /** The text data, {@link #getStringData}. */
049: private String _strdata;
050: /** The input stream, {@link #getStreamData} */
051: private InputStream _isdata;
052: /** The input stream, {@link #getReaderData} */
053: private Reader _rddata;
054: /** The content type. */
055: private String _ctype;
056: /** The format (e.g., pdf). */
057: private String _format;
058: /** The name (usually filename). */
059: private String _name;
060:
061: /** Construct with name, format, content type and binary data.
062: *
063: * <p>It tries to construct format and ctype from each other or name.
064: *
065: * @param name the name (usually filename); might be null.
066: * @param format the format; might be null. Example: "html" and "xml"
067: * @param ctype the content type; might be null. Example: "text/html"
068: * and "text/xml;charset=UTF-8".
069: * @param data the binary data; never null
070: */
071: public AMedia(String name, String format, String ctype, byte[] data) {
072: if (data == null)
073: throw new NullPointerException("data");
074: _bindata = data;
075: setup(name, format, ctype);
076: }
077:
078: /** Construct with name, format, content type and text data.
079: *
080: * <p>It tries to construct format and ctype from each other or name.
081: *
082: * @param name the name (usually filename); might be null.
083: * @param format the format; might be null.
084: * @param ctype the content type; might be null.
085: * @param data the text data; never null
086: */
087: public AMedia(String name, String format, String ctype, String data) {
088: if (data == null)
089: throw new NullPointerException("data");
090: _strdata = data;
091: setup(name, format, ctype);
092: }
093:
094: /** Construct with name, format, content type and stream data (binary).
095: *
096: * <p>It tries to construct format and ctype from each other or name.
097: *
098: * @param name the name (usually filename); might be null.
099: * @param format the format; might be null.
100: * @param ctype the content type; might be null.
101: * @param data the binary data; never null.
102: * If the input stream is created dyanmically each time {@link #getStreamData}
103: * is called, you shall pass {@link #DYNAMIC_STREAM}
104: * as the data argument. Then, override {@link #getStreamData} to return
105: * the correct stream.
106: * Note: the caller of {@link #getStreamData} has to close
107: * the returned input stream.
108: */
109: public AMedia(String name, String format, String ctype,
110: InputStream data) {
111: if (data == null)
112: throw new NullPointerException("data");
113: _isdata = data;
114: setup(name, format, ctype);
115: }
116:
117: /** Construct with name, format, content type and reader data (textual).
118: *
119: * <p>It tries to construct format and ctype from each other or name.
120: *
121: * @param name the name (usually filename); might be null.
122: * @param format the format; might be null.
123: * @param ctype the content type; might be null.
124: * @param data the string data; never null
125: * If the reader is created dyanmically each tiime {@link #getReaderData}
126: * is called, you shall pass {@link #DYNAMIC_READER}
127: * as the data argument. Then, override {@link #getReaderData} to return
128: * the correct reader.
129: */
130: public AMedia(String name, String format, String ctype, Reader data) {
131: if (data == null)
132: throw new NullPointerException("data");
133: _rddata = data;
134: setup(name, format, ctype);
135: }
136:
137: /** Sets up the format and content type.
138: * It assumes one of them is not null.
139: */
140: private void setup(String name, String format, String ctype) {
141: if (ctype != null) {
142: int j = ctype.indexOf(';');
143: if (j >= 0)
144: ctype = ctype.substring(0, j);
145: }
146:
147: if (ctype != null && format == null) {
148: format = ContentTypes.getFormat(ctype);
149: } else if (ctype == null && format != null) {
150: ctype = ContentTypes.getContentType(format);
151: }
152: if (name != null) {
153: if (format == null) {
154: final int j = name.lastIndexOf('.');
155: if (j >= 0) {
156: format = name.substring(j + 1);
157: if (ctype == null) {
158: ctype = ContentTypes.getContentType(format);
159: }
160: }
161: }
162: }
163:
164: _name = name;
165: _format = format;
166: _ctype = ctype;
167: }
168:
169: //-- Media --//
170: public boolean isBinary() {
171: return _bindata != null || _isdata != null;
172: }
173:
174: public boolean inMemory() {
175: return _bindata != null || _strdata != null;
176: }
177:
178: public byte[] getByteData() {
179: if (_bindata == null)
180: throw newIllegalStateException();
181: return _bindata;
182: }
183:
184: public String getStringData() {
185: if (_strdata == null)
186: throw newIllegalStateException();
187: return _strdata;
188: }
189:
190: /** Returns the input stream of this media.
191: *
192: * <p>Note: the caller has to invoke {@link InputStream#close}
193: * after using the input stream returned by {@link #getStreamData}.
194: *
195: * @exception IllegalStateException if the media is not binary
196: * {@link #isBinary}.
197: */
198: public InputStream getStreamData() {
199: if (_isdata != null)
200: return _isdata;
201: if (_bindata != null)
202: return new ByteArrayInputStream(_bindata);
203: throw newIllegalStateException();
204: }
205:
206: /** Returns the reader of this media to retrieve the data.
207: *
208: * <p>Note: the caller has to invoke {@link Reader#close}
209: * after using the input stream returned by {@link #getReaderData}.
210: *
211: * @exception IllegalStateException if the media is binary
212: * {@link #isBinary}.
213: */
214: public Reader getReaderData() {
215: if (_rddata != null)
216: return _rddata;
217: if (_strdata != null)
218: return new StringReader(_strdata);
219: throw newIllegalStateException();
220: }
221:
222: private IllegalStateException newIllegalStateException() {
223: return new IllegalStateException(
224: "Use get"
225: + (_bindata != null ? "Byte"
226: : _strdata != null ? "String"
227: : _isdata != null ? "Stream"
228: : "Reader")
229: + "Data() instead");
230: }
231:
232: public String getName() {
233: return _name;
234: }
235:
236: public String getFormat() {
237: return _format;
238: }
239:
240: public String getContentType() {
241: return _ctype;
242: }
243:
244: //-- Object --//
245: public String toString() {
246: return _name != null ? _name : "Media " + _format;
247: }
248: }
|