View Javadoc

1   // ========================================================================
2   // Copyright (c) 2008-2009 Mort Bay Consulting Pty. Ltd.
3   // ------------------------------------------------------------------------
4   // All rights reserved. This program and the accompanying materials
5   // are made available under the terms of the Eclipse Public License v1.0
6   // and Apache License v2.0 which accompanies this distribution.
7   // The Eclipse Public License is available at 
8   // http://www.eclipse.org/legal/epl-v10.html
9   // The Apache License v2.0 is available at
10  // http://www.opensource.org/licenses/apache2.0.php
11  // You may elect to redistribute this code under either of these licenses. 
12  // ========================================================================
13  
14  package org.eclipse.jetty.server;
15  
16  import java.io.IOException;
17  import java.io.Writer;
18  
19  import javax.servlet.ServletOutputStream;
20  
21  import org.eclipse.jetty.http.AbstractGenerator;
22  import org.eclipse.jetty.http.Generator;
23  import org.eclipse.jetty.io.Buffer;
24  import org.eclipse.jetty.io.ByteArrayBuffer;
25  import org.eclipse.jetty.io.EofException;
26  import org.eclipse.jetty.util.ByteArrayOutputStream2;
27  
28  /** Output.
29   * 
30   * <p>
31   * Implements  {@link javax.servlet.ServletOutputStream} from the <code>javax.servlet</code> package.   
32   * </p>
33   * A {@link ServletOutputStream} implementation that writes content
34   * to a {@link AbstractGenerator}.   The class is designed to be reused
35   * and can be reopened after a close.
36   */
37  public class HttpOutput extends ServletOutputStream 
38  {
39      protected final AbstractHttpConnection _connection;
40      protected final AbstractGenerator _generator;
41      private boolean _closed;
42      
43      // These are held here for reuse by Writer
44      String _characterEncoding;
45      Writer _converter;
46      char[] _chars;
47      ByteArrayOutputStream2 _bytes;
48  
49      /* ------------------------------------------------------------ */
50      public HttpOutput(AbstractHttpConnection connection)
51      {
52          _connection=connection;
53          _generator=(AbstractGenerator)connection.getGenerator();
54      }
55  
56      /* ------------------------------------------------------------ */
57      public int getMaxIdleTime()
58      {
59          return _connection.getMaxIdleTime();
60      }
61      
62      /* ------------------------------------------------------------ */
63      public boolean isWritten()
64      {
65          return _generator.getContentWritten()>0;
66      }
67      
68      /* ------------------------------------------------------------ */
69      /*
70       * @see java.io.OutputStream#close()
71       */
72      @Override
73      public void close() throws IOException
74      {
75          _closed=true;
76      }
77      
78      /* ------------------------------------------------------------ */
79      public boolean isClosed()
80      {
81          return _closed;
82      }
83      
84      /* ------------------------------------------------------------ */
85      public void reopen()
86      {
87          _closed=false;
88      }
89      
90      /* ------------------------------------------------------------ */
91      @Override
92      public void flush() throws IOException
93      {
94          _generator.flush(getMaxIdleTime());
95      }
96  
97      /* ------------------------------------------------------------ */
98      @Override
99      public void write(byte[] b, int off, int len) throws IOException
100     {
101         write(new ByteArrayBuffer(b,off,len));
102     }
103 
104     /* ------------------------------------------------------------ */
105     /*
106      * @see java.io.OutputStream#write(byte[])
107      */
108     @Override
109     public void write(byte[] b) throws IOException
110     {
111         write(new ByteArrayBuffer(b));
112     }
113 
114     /* ------------------------------------------------------------ */
115     /*
116      * @see java.io.OutputStream#write(int)
117      */
118     @Override
119     public void write(int b) throws IOException
120     {
121         if (_closed)
122             throw new IOException("Closed");
123         if (!_generator.isOpen())
124             throw new EofException();
125         
126         // Block until we can add _content.
127         while (_generator.isBufferFull())
128         {
129             _generator.blockForOutput(getMaxIdleTime());
130             if (_closed)
131                 throw new IOException("Closed");
132             if (!_generator.isOpen())
133                 throw new EofException();
134         }
135 
136         // Add the _content
137         if (_generator.addContent((byte)b))
138             // Buffers are full so flush.
139             flush();
140        
141         if (_generator.isAllContentWritten())
142         {
143             flush();
144             close();
145         }
146     }
147 
148     /* ------------------------------------------------------------ */
149     private void write(Buffer buffer) throws IOException
150     {
151         if (_closed)
152             throw new IOException("Closed");
153         if (!_generator.isOpen())
154             throw new EofException();
155         
156         // Block until we can add _content.
157         while (_generator.isBufferFull())
158         {
159             _generator.blockForOutput(getMaxIdleTime());
160             if (_closed)
161                 throw new IOException("Closed");
162             if (!_generator.isOpen())
163                 throw new EofException();
164         }
165 
166         // Add the _content
167         _generator.addContent(buffer, Generator.MORE);
168 
169         // Have to flush and complete headers?
170         
171         if (_generator.isAllContentWritten())
172         {
173             flush();
174             close();
175         } 
176         else if (_generator.isBufferFull())
177             flush();
178 
179         // Block until our buffer is free
180         while (buffer.length() > 0 && _generator.isOpen())
181         {
182             _generator.blockForOutput(getMaxIdleTime());
183         }
184     }
185 
186     /* ------------------------------------------------------------ */
187     /* 
188      * @see javax.servlet.ServletOutputStream#print(java.lang.String)
189      */
190     @Override
191     public void print(String s) throws IOException
192     {
193         write(s.getBytes());
194     }
195 }