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 AbstractGenerator _generator;
40      protected final long _maxIdleTime;
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      /* ------------------------------------------------------------ */
51      public HttpOutput(AbstractGenerator generator, long maxIdleTime)
52      {
53          _generator=generator;
54          _maxIdleTime=maxIdleTime;
55      }
56  
57      /* ------------------------------------------------------------ */
58      public boolean isWritten()
59      {
60          return _generator.getContentWritten()>0;
61      }
62      
63      /* ------------------------------------------------------------ */
64      /*
65       * @see java.io.OutputStream#close()
66       */
67      @Override
68      public void close() throws IOException
69      {
70          _closed=true;
71      }
72      
73      /* ------------------------------------------------------------ */
74      public boolean isClosed()
75      {
76          return _closed;
77      }
78      
79      /* ------------------------------------------------------------ */
80      public void reopen()
81      {
82          _closed=false;
83      }
84      
85      /* ------------------------------------------------------------ */
86      @Override
87      public void flush() throws IOException
88      {
89          _generator.flush(_maxIdleTime);
90      }
91  
92      /* ------------------------------------------------------------ */
93      @Override
94      public void write(byte[] b, int off, int len) throws IOException
95      {
96          write(new ByteArrayBuffer(b,off,len));
97      }
98  
99      /* ------------------------------------------------------------ */
100     /*
101      * @see java.io.OutputStream#write(byte[])
102      */
103     @Override
104     public void write(byte[] b) throws IOException
105     {
106         write(new ByteArrayBuffer(b));
107     }
108 
109     /* ------------------------------------------------------------ */
110     /*
111      * @see java.io.OutputStream#write(int)
112      */
113     @Override
114     public void write(int b) throws IOException
115     {
116         if (_closed)
117             throw new IOException("Closed");
118         if (!_generator.isOpen())
119             throw new EofException();
120         
121         // Block until we can add _content.
122         while (_generator.isBufferFull())
123         {
124             _generator.blockForOutput(_maxIdleTime);
125             if (_closed)
126                 throw new IOException("Closed");
127             if (!_generator.isOpen())
128                 throw new EofException();
129         }
130 
131         // Add the _content
132         if (_generator.addContent((byte)b))
133             // Buffers are full so flush.
134             flush();
135        
136         if (_generator.isAllContentWritten())
137         {
138             flush();
139             close();
140         }
141     }
142 
143     /* ------------------------------------------------------------ */
144     private void write(Buffer buffer) throws IOException
145     {
146         if (_closed)
147             throw new IOException("Closed");
148         if (!_generator.isOpen())
149             throw new EofException();
150         
151         // Block until we can add _content.
152         while (_generator.isBufferFull())
153         {
154             _generator.blockForOutput(_maxIdleTime);
155             if (_closed)
156                 throw new IOException("Closed");
157             if (!_generator.isOpen())
158                 throw new EofException();
159         }
160 
161         // Add the _content
162         _generator.addContent(buffer, Generator.MORE);
163 
164         // Have to flush and complete headers?
165         
166         if (_generator.isAllContentWritten())
167         {
168             flush();
169             close();
170         } 
171         else if (_generator.isBufferFull())
172             flush();
173 
174         // Block until our buffer is free
175         while (buffer.length() > 0 && _generator.isOpen())
176         {
177             _generator.blockForOutput(_maxIdleTime);
178         }
179     }
180 
181     /* ------------------------------------------------------------ */
182     /* 
183      * @see javax.servlet.ServletOutputStream#print(java.lang.String)
184      */
185     @Override
186     public void print(String s) throws IOException
187     {
188         write(s.getBytes());
189     }
190 }