001: /*
002: * BlobHandler.java
003: *
004: * This file is part of SQL Workbench/J, http://www.sql-workbench.net
005: *
006: * Copyright 2002-2008, Thomas Kellerer
007: * No part of this code maybe reused without the permission of the author
008: *
009: * To contact the author please send an email to: support@sql-workbench.net
010: *
011: */
012: package workbench.gui.components;
013:
014: import java.awt.Dialog;
015: import java.awt.Dialog;
016: import java.awt.Frame;
017: import java.io.BufferedInputStream;
018: import java.io.ByteArrayInputStream;
019: import java.io.File;
020: import java.io.FileInputStream;
021: import java.io.FileOutputStream;
022: import java.io.IOException;
023: import java.io.InputStream;
024: import java.io.OutputStream;
025: import java.io.Reader;
026: import java.io.UnsupportedEncodingException;
027: import java.sql.Blob;
028: import java.sql.SQLException;
029: import workbench.WbManager;
030: import workbench.gui.WbSwingUtilities;
031: import workbench.gui.dialogs.BlobInfoDialog;
032: import workbench.gui.dialogs.ImageViewer;
033: import workbench.log.LogMgr;
034: import workbench.resource.ResourceMgr;
035: import workbench.resource.Settings;
036: import workbench.util.EncodingUtil;
037: import workbench.util.FileUtil;
038: import workbench.util.StringUtil;
039:
040: /**
041: *
042: * @author support@sql-workbench.net
043: */
044: public class BlobHandler {
045: private File uploadFile;
046: private byte[] newValue;
047:
048: private boolean setToNull = false;
049:
050: public BlobHandler() {
051: }
052:
053: public StringBuilder getByteDisplay(Object value) {
054: long l = getBlobSize(value);
055: return getByteDisplay(l);
056: }
057:
058: public boolean setToNull() {
059: return this .setToNull;
060: }
061:
062: public File getUploadFile() {
063: return uploadFile;
064: }
065:
066: public StringBuilder getByteDisplay(long l) {
067: StringBuilder result = new StringBuilder(32);
068:
069: if (l < 1024) {
070: result.append(Long.toString(l));
071: result.append(' ');
072: } else if (l < 1024 * 1024) {
073: result.append(Long.toString(l / 1024));
074: result.append(" K");
075: } else {
076: result.append(Long.toString(l / (1024 * 1024)));
077: result.append(" M");
078: }
079: result.append('B');
080: return result;
081: }
082:
083: public byte[] getBlobAsArray(Object value) {
084: if (value == null) {
085: return null;
086: }
087:
088: if (value instanceof Blob) {
089: Blob blob = (Blob) value;
090: try {
091: byte[] buffer = blob.getBytes(1, (int) blob.length());
092: return buffer;
093: } catch (Exception e) {
094: LogMgr.logError("BlobHandler.getBlobAsArray()",
095: "Error retrieving blob value", e);
096: return null;
097: }
098: } else if (value instanceof byte[]) {
099: return (byte[]) value;
100: } else if (value instanceof File) {
101: InputStream in = null;
102: try {
103: File f = (File) value;
104: in = new BufferedInputStream(new FileInputStream(f));
105: byte[] buff = FileUtil.readBytes(in);
106: return buff;
107: } catch (Exception e) {
108: LogMgr.logError("BlobHandler.getBlobAsArray()",
109: "Error retrieving blob value", e);
110: return null;
111: } finally {
112: FileUtil.closeQuitely(in);
113: }
114:
115: }
116: return null;
117: }
118:
119: public long getBlobSize(Object value) {
120: if (value == null)
121: return 0;
122: if (value instanceof Blob) {
123: Blob blob = (Blob) value;
124: try {
125: return blob.length();
126: } catch (Exception e) {
127: LogMgr.logError("BlobHandler.getBlobSize()",
128: "Could not retrieve blob size", e);
129: }
130: } else if (value instanceof File) {
131: // can happen if a file has been uploaded through the BlobInfoDialog
132: return ((File) value).length();
133: } else if (value instanceof byte[]) {
134: byte[] b = (byte[]) value;
135: return b.length;
136: }
137: return -1;
138: }
139:
140: private String convertArray(byte[] value, String encoding) {
141: String data = null;
142: try {
143: data = new String(value, encoding);
144: } catch (UnsupportedEncodingException e) {
145: LogMgr.logError("BlobHandler.convertArray()",
146: "Could not convert binary to string using encoding: "
147: + encoding, e);
148: data = new String(value);
149: }
150: return data;
151: }
152:
153: public String getBlobAsString(Object value, String encoding) {
154: if (value == null)
155: return null;
156: if (getBlobSize(value) == 0)
157: return StringUtil.EMPTY_STRING;
158:
159: if (encoding == null)
160: encoding = Settings.getInstance()
161: .getDefaultBlobTextEncoding();
162:
163: if (value instanceof Blob) {
164: Blob blob = (Blob) value;
165: try {
166: byte[] buffer = blob.getBytes(1, (int) blob.length());
167: return convertArray(buffer, encoding);
168: } catch (Exception e) {
169: LogMgr.logError("BlobHandler.getBlobAsString()",
170: "Error retrieving blob value", e);
171: return "";
172: }
173: } else if (value instanceof byte[]) {
174: return convertArray((byte[]) value, encoding);
175: } else if (value instanceof File) {
176: Reader in = null;
177: try {
178: File f = (File) value;
179: in = EncodingUtil.createReader(f, encoding);
180: String s = FileUtil.readCharacters(in);
181: return s;
182: } catch (Exception e) {
183: LogMgr.logError("BlobHandler.getBlobAsString()",
184: "Error retrieving blob value", e);
185: return "";
186: }
187: }
188: return value.toString();
189: }
190:
191: public static long saveBlobToFile(Object data, String file)
192: throws IOException, SQLException {
193: OutputStream out = new FileOutputStream(file);
194: return saveBlobToFile(data, out);
195: }
196:
197: public static long saveBlobToFile(Object data, OutputStream out)
198: throws IOException, SQLException {
199: InputStream in = null;
200: if (data instanceof java.sql.Blob) {
201: java.sql.Blob blob = (java.sql.Blob) data;
202: in = blob.getBinaryStream();
203: } else if (data instanceof byte[]) {
204: in = new ByteArrayInputStream((byte[]) data);
205: } else if (data instanceof File) {
206: in = new FileInputStream((File) data);
207: }
208:
209: if (in == null) {
210: LogMgr.logError("WbTable.saveBlobContent",
211: "No valid BLOB data found, got "
212: + data.getClass().getName() + " instead",
213: null);
214: throw new IOException("No LOB data found");
215: }
216: return FileUtil.copy(in, out);
217: }
218:
219: public void showBlobAsImage(Object value) {
220: showBlobAsImage(null, value);
221: }
222:
223: public void showBlobAsImage(Dialog parent, Object value) {
224: ImageViewer v = null;
225: if (parent != null) {
226: v = new ImageViewer(parent, ResourceMgr
227: .getString("TxtBlobData"));
228: } else {
229: v = new ImageViewer(WbManager.getInstance()
230: .getCurrentWindow(), ResourceMgr
231: .getString("TxtBlobData"));
232: }
233:
234: v.setData(value);
235: v.setVisible(true);
236: }
237:
238: public void showBlobAsText(Object value) {
239: showBlobAsText(null, value, Settings.getInstance()
240: .getDefaultBlobTextEncoding());
241: }
242:
243: /**
244: * Display the blob content as a text with the specified encoding.
245: * The window will allow editing of the data, if the user changed the
246: * data and closed the window using the OK button, this method will
247: * return true. In this case the blob value will be updated with
248: * the binary representation of the text using the specified encoding
249: */
250: public boolean showBlobAsText(Dialog parent, Object value,
251: final String encoding) {
252: String data = getBlobAsString(value, encoding);
253: String title = ResourceMgr.getString("TxtBlobData");
254: this .newValue = null;
255: final EditWindow w;
256: boolean result = false;
257:
258: if (parent != null) {
259: w = new EditWindow(parent, title, data, false, false);
260: } else {
261: w = new EditWindow(WbManager.getInstance()
262: .getCurrentWindow(), title, data, false, false);
263: }
264:
265: WbSwingUtilities.invoke(new Runnable() {
266: public void run() {
267: w.setInfoText(ResourceMgr.getString("LblFileEncoding")
268: + ": " + encoding);
269: w.setVisible(true);
270: }
271: });
272:
273: if (!w.isCancelled()) {
274: data = w.getText();
275: try {
276: if (encoding != null) {
277: this .newValue = data.getBytes(encoding);
278: this .uploadFile = null;
279: result = true;
280: }
281: } catch (Exception e) {
282: this .newValue = null;
283: result = false;
284: LogMgr.logError("BlobHandler.showBlobAsText",
285: "Error converting text to blob", e);
286: }
287: }
288:
289: return result;
290: }
291:
292: public boolean isChanged() {
293: return this .newValue != null;
294: }
295:
296: /**
297: * Returns thenew value after the user changed the data in the text window.
298: * Returns null if the user did not change the data.
299: * @see #showBlobAsText(Dialog, Object, String)
300: */
301: public byte[] getNewValue() {
302: return this .newValue;
303: }
304:
305: public void showBlobInfoDialog(Frame parent, Object blobValue) {
306: BlobInfoDialog d = new BlobInfoDialog(parent, true);
307: d.setBlobValue(blobValue);
308: d.setVisible(true);
309: this.uploadFile = d.getUploadedFile();
310: this.setToNull = d.setToNull();
311: this.newValue = d.getNewValue();
312: }
313: }
|