View Javadoc

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