001: /*
002: * ImportFileHandler.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.db.importer;
013:
014: import java.io.BufferedReader;
015: import java.io.File;
016: import java.io.FileInputStream;
017: import java.io.FileNotFoundException;
018: import java.io.IOException;
019: import java.io.InputStream;
020: import java.io.Reader;
021: import java.io.StringReader;
022: import java.util.Enumeration;
023: import java.util.zip.ZipEntry;
024: import java.util.zip.ZipFile;
025: import workbench.db.exporter.RowDataConverter;
026: import workbench.util.ClipboardFile;
027: import workbench.util.EncodingUtil;
028: import workbench.util.FileUtil;
029: import workbench.util.WbFile;
030: import workbench.util.ZipUtil;
031:
032: /**
033: * This class manages access to an import file and possible attachments that
034: * were created by {@link workbench.db.exporter.DataExporter}
035: * The import file can either be a regular file, or stored in a ZIP archive.
036: *
037: * @author support@sql-workbench.net
038: */
039: public class ImportFileHandler {
040: private File baseFile;
041: private File baseDir;
042: private String encoding;
043: private boolean isZip;
044: private ZipFile mainArchive;
045: private ZipFile attachments;
046: private BufferedReader mainReader;
047:
048: public ImportFileHandler() {
049: }
050:
051: /**
052: * Define the main input file used by this handler.
053: * If the file is a ZIP Archive getMainFileReader() will
054: * return a Reader for the first file in the archive.
055: * (DataExporter creates an archive with a single
056: * file in it).
057: * @param mainFile the basefile
058: * @param enc the encoding for the basefile
059: */
060: public void setMainFile(File mainFile, String enc)
061: throws IOException {
062: this .done();
063: this .mainArchive = null;
064: this .attachments = null;
065: this .encoding = enc;
066:
067: this .baseFile = mainFile;
068: this .baseDir = baseFile.getParentFile();
069: if (this .baseDir == null)
070: baseDir = new File(".");
071: isZip = ZipUtil.isZipFile(baseFile);
072: this .initAttachements();
073: }
074:
075: boolean isZip() {
076: return isZip;
077: }
078:
079: /**
080: * Return a Reader that is suitable for reading the contents
081: * of the main file. The reader will be created with the
082: * encoding that was specified in {@link #setMainFile(File, String)}
083: * @return a BufferedReader for the main file
084: * @see #setMainFile(File, String)
085: */
086: public BufferedReader getMainFileReader() throws IOException {
087: if (this .mainReader != null) {
088: try {
089: mainReader.close();
090: } catch (Throwable th) {
091: }
092: }
093: Reader r = null;
094: if (baseFile instanceof ClipboardFile) {
095: ClipboardFile cb = (ClipboardFile) baseFile;
096: r = new StringReader(cb.getContents());
097: } else if (isZip) {
098: mainArchive = new ZipFile(baseFile);
099: Enumeration entries = mainArchive.entries();
100: if (entries.hasMoreElements()) {
101: ZipEntry entry = (ZipEntry) entries.nextElement();
102: InputStream in = mainArchive.getInputStream(entry);
103: r = EncodingUtil.createReader(in, encoding);
104: } else {
105: throw new FileNotFoundException("Zipfile "
106: + this .baseFile.getAbsolutePath()
107: + " does not contain any entries!");
108: }
109: } else {
110: r = EncodingUtil.createReader(baseFile, encoding);
111: }
112: mainReader = new BufferedReader(r, 32 * 1024);
113: return mainReader;
114: }
115:
116: private void initAttachements() throws IOException {
117: if (baseFile instanceof ClipboardFile)
118: return;
119:
120: WbFile f = new WbFile(baseFile);
121: String basename = f.getFileName();
122: String attFileName = basename
123: + RowDataConverter.BLOB_ARCHIVE_SUFFIX + ".zip";
124: File attFile = new File(baseDir, attFileName);
125: if (attFile.exists()) {
126: this .attachments = new ZipFile(attFile);
127: }
128: }
129:
130: protected ZipEntry findEntry(File f) throws IOException {
131: ZipEntry entry = this .attachments.getEntry(f.getName());
132: if (entry != null)
133: return entry;
134:
135: throw new FileNotFoundException("Attachment file "
136: + f.getName() + " not found in archive "
137: + this .attachments.getName());
138: }
139:
140: /**
141: * When exporting LOB data {@link workbench.db.exporter.DataExporter} will write
142: * the LOB data for each row/column into separate files. These files might
143: * reside in a second ZIP archive.
144: * @param attachmentFile the attachment to read
145: * @return an InputStream to read the attachment
146: */
147:
148: public InputStream getAttachedFileStream(File attachmentFile)
149: throws IOException {
150: if (baseFile instanceof ClipboardFile)
151: throw new IOException(
152: "Attachments not supported for Clipboard");
153:
154: if (this .isZip) {
155: ZipEntry entry = findEntry(attachmentFile);
156: return attachments.getInputStream(entry);
157: } else {
158: if (attachmentFile.isAbsolute()) {
159: return new FileInputStream(attachmentFile);
160: } else {
161: File realFile = new File(this .baseDir, attachmentFile
162: .getName());
163: return new FileInputStream(realFile);
164: }
165: }
166: }
167:
168: public long getCharacterLength(File f) throws IOException {
169: if (this .isZip) {
170: return getLength(f);
171: }
172:
173: long result = 0;
174: if (f.isAbsolute()) {
175: result = FileUtil.getCharacterLength(f, this .encoding);
176: } else {
177: File realFile = new File(this .baseDir, f.getName());
178: result = FileUtil.getCharacterLength(realFile,
179: this .encoding);
180: }
181: return result;
182: }
183:
184: public long getLength(File f) throws IOException {
185: if (this .isZip) {
186: ZipEntry entry = findEntry(f);
187: return entry.getSize();
188: } else {
189: if (f.isAbsolute()) {
190: return f.length();
191: }
192: File realFile = new File(this .baseDir, f.getName());
193: return realFile.length();
194: }
195: }
196:
197: public String getEncoding() {
198: return this .encoding;
199: }
200:
201: public void done() {
202:
203: try {
204: if (mainReader != null)
205: mainReader.close();
206: } catch (Throwable th) {
207: }
208: try {
209: if (mainArchive != null)
210: mainArchive.close();
211: } catch (Throwable th) {
212: }
213: try {
214: if (attachments != null)
215: attachments.close();
216: } catch (Throwable th) {
217: }
218: mainReader = null;
219: mainArchive = null;
220: attachments = null;
221: }
222: }
|