001    // Copyright 2009 The Apache Software Foundation
002    //
003    // Licensed under the Apache License, Version 2.0 (the "License");
004    // you may not use this file except in compliance with the License.
005    // You may obtain a copy of the License at
006    //
007    //     http://www.apache.org/licenses/LICENSE-2.0
008    //
009    // Unless required by applicable law or agreed to in writing, software
010    // distributed under the License is distributed on an "AS IS" BASIS,
011    // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
012    // See the License for the specific language governing permissions and
013    // limitations under the License.
014    
015    package org.apache.tapestry5.internal.services;
016    
017    import org.apache.tapestry5.internal.util.Base64OutputStream;
018    import org.apache.tapestry5.services.ClientDataSink;
019    import org.apache.tapestry5.services.URLEncoder;
020    
021    import java.io.BufferedOutputStream;
022    import java.io.IOException;
023    import java.io.ObjectOutputStream;
024    import java.io.OutputStream;
025    import java.util.zip.GZIPOutputStream;
026    
027    public class ClientDataSinkImpl implements ClientDataSink
028    {
029        private final Base64OutputStream base64OutputStream;
030    
031        private final ObjectOutputStream objectOutputStream;
032    
033        private final URLEncoder urlEncoder;
034    
035        private boolean closed;
036    
037        public ClientDataSinkImpl(URLEncoder urlEncoder) throws IOException
038        {
039            this.urlEncoder = urlEncoder;
040            base64OutputStream = new Base64OutputStream();
041    
042            final BufferedOutputStream pipeline = new BufferedOutputStream(new GZIPOutputStream(base64OutputStream));
043    
044            OutputStream guard = new OutputStream()
045            {
046                @Override
047                public void write(int b) throws IOException
048                {
049                    pipeline.write(b);
050                }
051    
052                @Override
053                public void close() throws IOException
054                {
055                    closed = true;
056    
057                    pipeline.close();
058                }
059    
060                @Override
061                public void flush() throws IOException
062                {
063                    pipeline.flush();
064                }
065    
066                @Override
067                public void write(byte[] b) throws IOException
068                {
069                    pipeline.write(b);
070                }
071    
072                @Override
073                public void write(byte[] b, int off, int len) throws IOException
074                {
075                    pipeline.write(b, off, len);
076                }
077            };
078    
079    
080            objectOutputStream = new ObjectOutputStream(guard);
081        }
082    
083        public ObjectOutputStream getObjectOutputStream()
084        {
085            return objectOutputStream;
086        }
087    
088        public String getClientData()
089        {
090            if (!closed)
091            {
092                try
093                {
094                    objectOutputStream.close();
095                }
096                catch (IOException ex)
097                {
098                    // Ignore.
099                }
100            }
101    
102            return base64OutputStream.toBase64();
103        }
104    
105        public String getEncodedClientData()
106        {
107            return urlEncoder.encode(getClientData());
108        }
109    }