001/*
002 * HA-JDBC: High-Availability JDBC
003 * Copyright (C) 2012  Paul Ferraro
004 *
005 * This program is free software: you can redistribute it and/or modify
006 * it under the terms of the GNU Lesser General Public License as published by
007 * the Free Software Foundation, either version 3 of the License, or
008 * (at your option) any later version.
009 *
010 * This program 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
013 * GNU Lesser General Public License for more details.
014 *
015 * You should have received a copy of the GNU Lesser General Public License
016 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
017 */
018package net.sf.hajdbc.sql;
019
020import java.io.BufferedReader;
021import java.io.File;
022import java.io.FileInputStream;
023import java.io.FileOutputStream;
024import java.io.FileReader;
025import java.io.FileWriter;
026import java.io.IOException;
027import java.io.InputStream;
028import java.io.Reader;
029import java.io.Writer;
030import java.nio.ByteBuffer;
031import java.nio.CharBuffer;
032import java.nio.channels.Channels;
033import java.nio.channels.FileChannel;
034import java.nio.channels.ReadableByteChannel;
035import java.sql.SQLException;
036import java.util.LinkedList;
037import java.util.List;
038
039import net.sf.hajdbc.ExceptionFactory;
040import net.sf.hajdbc.util.Files;
041import net.sf.hajdbc.util.Resources;
042
043/**
044 * @author  Paul Ferraro
045 * @since   1.0
046 */
047public class FileSupportImpl<E extends Exception> implements FileSupport<E>
048{
049        private static final String TEMP_FILE_SUFFIX = ".lob";
050        private static final int BUFFER_SIZE = 8192;
051        
052        private final List<File> files = new LinkedList<File>();
053        private final ExceptionFactory<E> exceptionFactory;
054        
055        public FileSupportImpl(ExceptionFactory<E> exceptionFactory)
056        {
057                this.exceptionFactory = exceptionFactory;
058        }
059        
060        /**
061         * @see net.sf.hajdbc.sql.FileSupport#createFile(java.io.InputStream)
062         */
063        @Override
064        public File createFile(InputStream inputStream) throws E
065        {
066                try
067                {
068                        File file = this.createTempFile();
069                        FileOutputStream output = new FileOutputStream(file);
070                        try
071                        {
072                                FileChannel fileChannel = output.getChannel();
073                                ReadableByteChannel inputChannel = Channels.newChannel(inputStream);
074                                
075                                ByteBuffer buffer = ByteBuffer.allocate(BUFFER_SIZE);
076                                
077                                while (inputChannel.read(buffer) > 0)
078                                {
079                                        buffer.flip();
080                                        fileChannel.write(buffer);
081                                        buffer.compact();
082                                }
083                                
084                                return file;
085                        }
086                        finally
087                        {
088                                Resources.close(output);
089                        }
090                }
091                catch (IOException e)
092                {
093                        throw this.exceptionFactory.createException(e);
094                }
095        }
096        
097        /**
098         * @see net.sf.hajdbc.sql.FileSupport#createFile(java.io.Reader)
099         */
100        @Override
101        public File createFile(Reader reader) throws E
102        {
103                try
104                {
105                        File file = this.createTempFile();
106                        Writer writer = new FileWriter(file);
107                        try
108                        {
109                                CharBuffer buffer = CharBuffer.allocate(BUFFER_SIZE);
110                                
111                                while (reader.read(buffer) > 0)
112                                {
113                                        buffer.flip();
114                                        writer.append(buffer);
115                                        buffer.clear();
116                                }
117                                
118                                return file;
119                        }
120                        finally
121                        {
122                                Resources.close(writer);
123                        }
124                }
125                catch (IOException e)
126                {
127                        throw this.exceptionFactory.createException(e);
128                }
129        }
130        
131        /**
132         * @see net.sf.hajdbc.sql.FileSupport#getReader(java.io.File)
133         */
134        @Override
135        public Reader getReader(File file) throws E
136        {
137                try
138                {
139                        return new BufferedReader(new FileReader(file), BUFFER_SIZE);
140                }
141                catch (IOException e)
142                {
143                        throw this.exceptionFactory.createException(e);
144                }
145        }
146        
147        /**
148         * @see net.sf.hajdbc.sql.FileSupport#getInputStream(java.io.File)
149         */
150        @Override
151        public InputStream getInputStream(File file) throws E
152        {
153                try
154                {
155                        return Channels.newInputStream(new FileInputStream(file).getChannel());
156                }
157                catch (IOException e)
158                {
159                        throw this.exceptionFactory.createException(e);
160                }
161        }
162        
163        /**
164         * Creates a temp file and stores a reference to it so that it can be deleted later.
165         * @return a temp file
166         * @throws SQLException if an IO error occurs
167         */
168        private File createTempFile() throws IOException
169        {
170                File file = Files.createTempFile(TEMP_FILE_SUFFIX);
171                
172                this.files.add(file);
173                
174                return file;
175        }
176        
177        /**
178         * @see net.sf.hajdbc.sql.FileSupport#close()
179         */
180        @Override
181        public void close()
182        {
183                for (File file: this.files)
184                {
185                        if (!file.delete())
186                        {
187                                file.deleteOnExit();
188                        }
189                }
190                this.files.clear();
191        }
192        
193        /**
194         * @see java.lang.Object#finalize()
195         */
196        @Override
197        protected void finalize() throws Throwable
198        {
199                this.close();
200                
201                super.finalize();
202        }
203}