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