001/*
002 * HA-JDBC: High-Availability JDBC
003 * Copyright (C) 2013  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.io;
019
020import java.io.IOException;
021import java.io.OutputStream;
022
023import net.sf.hajdbc.Database;
024import net.sf.hajdbc.invocation.InvocationStrategies;
025import net.sf.hajdbc.invocation.Invoker;
026
027/**
028 * Static proxy for OutputStreams
029 * @author Paul Ferraro
030 * @param <Z> connection source
031 * @param <D> database
032 * @param <P> parent type
033 */
034public class OutputStreamProxy<Z, D extends Database<Z>, P> extends OutputStream
035{
036        private final OutputStreamProxyFactory<Z, D, P> factory;
037        
038        public OutputStreamProxy(OutputStreamProxyFactory<Z, D, P> factory)
039        {
040                this.factory = factory;
041        }
042
043        @Override
044        public void write(final byte[] b, final int off, final int len) throws IOException
045        {
046                OutputStreamInvoker<Z, D> invoker = new OutputStreamInvoker<Z, D>()
047                {
048                        @Override
049                        public Void invoke(D database, OutputStream output) throws IOException
050                        {
051                                output.write(b, off, len);
052                                return null;
053                        }
054                };
055                
056                InvocationStrategies.INVOKE_ON_EXISTING.invoke(this.factory, invoker);
057                
058                this.factory.record(invoker);
059        }
060
061        @Override
062        public void write(final byte[] b) throws IOException
063        {
064                OutputStreamInvoker<Z, D> invoker = new OutputStreamInvoker<Z, D>()
065                {
066                        @Override
067                        public Void invoke(D database, OutputStream output) throws IOException
068                        {
069                                output.write(b);
070                                return null;
071                        }
072                };
073                
074                InvocationStrategies.INVOKE_ON_EXISTING.invoke(this.factory, invoker);
075                
076                this.factory.record(invoker);
077        }
078
079        @Override
080        public void write(final int b) throws IOException
081        {
082                OutputStreamInvoker<Z, D> invoker = new OutputStreamInvoker<Z, D>()
083                {
084                        @Override
085                        public Void invoke(D database, OutputStream output) throws IOException
086                        {
087                                output.write(b);
088                                return null;
089                        }
090                };
091                
092                InvocationStrategies.INVOKE_ON_EXISTING.invoke(this.factory, invoker);
093                
094                this.factory.record(invoker);
095        }
096
097        @Override
098        public void flush() throws IOException
099        {
100                OutputStreamInvoker<Z, D> invoker = new OutputStreamInvoker<Z, D>()
101                {
102                        @Override
103                        public Void invoke(D database, OutputStream output) throws IOException
104                        {
105                                output.flush();
106                                return null;
107                        }
108                };
109                
110                InvocationStrategies.INVOKE_ON_EXISTING.invoke(this.factory, invoker);
111                
112                this.factory.record(invoker);
113        }
114
115        @Override
116        public void close() throws IOException
117        {
118                OutputStreamInvoker<Z, D> invoker = new OutputStreamInvoker<Z, D>()
119                {
120                        @Override
121                        public Void invoke(D database, OutputStream output) throws IOException
122                        {
123                                output.close();
124                                return null;
125                        }
126                };
127                
128                InvocationStrategies.INVOKE_ON_EXISTING.invoke(this.factory, invoker);
129                
130                this.factory.remove();
131        }
132
133        private interface OutputStreamInvoker<Z, D extends Database<Z>> extends Invoker<Z, D, OutputStream, Void, IOException>
134        {
135        }
136}