KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > sun > enterprise > web > connector > grizzly > algorithms > StreamAlgorithmBase


1 /*
2  * The contents of this file are subject to the terms
3  * of the Common Development and Distribution License
4  * (the License). You may not use this file except in
5  * compliance with the License.
6  *
7  * You can obtain a copy of the license at
8  * https://glassfish.dev.java.net/public/CDDLv1.0.html or
9  * glassfish/bootstrap/legal/CDDLv1.0.txt.
10  * See the License for the specific language governing
11  * permissions and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL
14  * Header Notice in each file and include the License file
15  * at glassfish/bootstrap/legal/CDDLv1.0.txt.
16  * If applicable, add the following below the CDDL Header,
17  * with the fields enclosed by brackets [] replaced by
18  * you own identifying information:
19  * "Portions Copyrighted [year] [name of copyright owner]"
20  *
21  * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
22  */

23
24 package com.sun.enterprise.web.connector.grizzly.algorithms;
25
26 import com.sun.enterprise.web.connector.grizzly.Constants;
27 import com.sun.enterprise.web.connector.grizzly.Handler;
28 import com.sun.enterprise.web.connector.grizzly.StreamAlgorithm;
29 import com.sun.enterprise.web.connector.grizzly.ByteBufferFactory;
30
31 import java.nio.ByteBuffer JavaDoc;
32 import java.nio.channels.SocketChannel JavaDoc;
33
34
35 /**
36  * Base class for <code>StreamAlgorithm</code> implementation.
37  * @author Jeanfrancois Arcand
38  */

39 public abstract class StreamAlgorithmBase implements StreamAlgorithm{
40  
41     private int port = 8080;
42     
43     /**
44      * Manipulate the bytes stream and determine if the process can continue.
45      *
46      * @return true if the algorithm determines the process can continue.
47      */

48     public abstract boolean parse(ByteBuffer JavaDoc byteBuffer);
49     
50     
51     /**
52      * The actual length of the stream we are able to read.
53      */

54     protected int contentLength = -1;
55     
56            
57     /**
58      * The <code>ByteBuffer</code> current limit value
59      */

60     protected int curLimit = -1;
61     
62     
63     /**
64      * The <code>ByteBuffer</code> current position value
65      */

66     protected int curPosition = -1;
67     
68     
69     /**
70      * The position, within the <code>ByteBuffer</code>, when the HTTP
71      * headers are completely reads.
72      */

73     protected int headerLength = -1;
74     
75     
76     /**
77      * In case we were'nt able to parse the request line, we will continue
78      * parsing from that position.
79      */

80     protected int lastStatePosition = -1;
81    
82     
83     /**
84      * If the stream wasn't read fully, keep the state of the http parsing.
85      */

86     protected int state = 0;
87     
88    
89     /**
90      * If a new <code>ByteBuffer</code> is created because the stream is
91      * too small, cache the original byteBuffer and reuse it once the
92      * transaction has completed.
93      */

94     protected ByteBuffer JavaDoc primaryByteBuffer = null;
95     
96     
97     /**
98      * If <code>true</code>, use a <code>ByteBuffer</code> view instead of
99      * <code>ByteBuffer</code>
100      */

101     protected boolean useByteBufferView = false;
102    
103     
104     /**
105      * Are we using direct <code>ByteBuffer</code>
106      */

107     protected boolean useDirectByteBuffer;
108     
109     
110     /**
111      * The <code>SocketChannel</code> associated with this algorithm.
112      */

113     protected SocketChannel JavaDoc socketChannel;
114     
115     
116     /**
117      * An <code>Handler</code> implementation used to implement a
118      * static resources cache.
119      */

120     protected Handler handler;
121     
122     
123     // ------------------------------------------------------- Methods ------//
124

125     
126     /**
127      * Return the stream content-length. If the content-length wasn't parsed,
128      * return -1.
129      */

130     public int contentLength(){
131         return contentLength;
132     }
133     
134     
135     /**
136      * Return the stream header length. The header length is the length between
137      * the start of the stream and the first occurance of character '\r\n' .
138      */

139     public int headerLength(){
140         return headerLength;
141     }
142     
143     
144     /**
145      * Allocate a <code>ByteBuffer</code>
146      * @param useDirect allocate a direct <code>ByteBuffer</code>.
147      * @param useView allocate a view <code>ByteBuffer</code>.
148      * @return a new <code>ByteBuffer</code>
149      */

150     public ByteBuffer JavaDoc allocate(boolean useDirect, boolean useView){
151         useByteBufferView = useView;
152         useDirectByteBuffer = useDirect;
153         
154         return allocateByteBuffer(useDirect,useView);
155     }
156     
157     
158     /**
159      * Before parsing the bytes, initialize and prepare the algorithm.
160      * @param byteBuffer the <code>ByteBuffer</code> used by this algorithm
161      * @return <code>ByteBuffer</code> used by this algorithm
162      */

163     public ByteBuffer JavaDoc preParse(ByteBuffer JavaDoc byteBuffer){
164         if (byteBuffer.position() == byteBuffer.capacity()){
165             // Add space at the end for \n\r
166
int bufferSize = contentLength > 0 ?
167                                     contentLength + headerLength + 5:
168                                     byteBuffer.capacity() * 2;
169             byteBuffer = swapBuffer(byteBuffer,bufferSize);
170         }
171         return byteBuffer;
172     }
173     
174     /**
175      * After parsing the bytes, post process the <code>ByteBuffer</code>
176      * @param byteBuffer the <code>ByteBuffer</code> used by this algorithm
177      * @return <code>ByteBuffer</code> used by this algorithm
178      */

179     public ByteBuffer JavaDoc postParse(ByteBuffer JavaDoc byteBuffer){
180         // Swap buffer to its original size.
181
if ( primaryByteBuffer != null) {
182             primaryByteBuffer.clear();
183             byteBuffer = primaryByteBuffer;
184             primaryByteBuffer = null;
185         }
186         return byteBuffer;
187     }
188
189     
190     /**
191      * Reset this object to its default state.
192      */

193     public void recycle(){
194         contentLength = -1;
195         lastStatePosition= -1;
196         headerLength = -1;
197         curLimit = -1;
198         curPosition = -1;
199         state = 0;
200     }
201     
202     
203     // --------------------------------------------------- Utils --------------/
204

205     
206       /**
207      * Allocate a <code>ByteBuffer</code>
208      * @param useDirectByteBuffer to create a direct <code>ByteBuffer</code>
209      * @param useByteBufferView to create <code>ByteBuffer</code> view
210      * @return a <code>ByteBuffer</code> of size
211      * <code>Constants.CHANNEL_BYTE_SIZE</code>
212      */

213     protected ByteBuffer JavaDoc allocateByteBuffer(boolean useDirectByteBuffer,
214                                             boolean useByteBufferView){
215         
216         return allocateByteBuffer(useDirectByteBuffer,
217                                   useByteBufferView,
218                                   Constants.CHANNEL_BYTE_SIZE);
219     }
220     
221     
222     /**
223      * Allocate a <code>ByteBuffer</code>
224      * @param useDirectByteBuffer to create a direct <code>ByteBuffer</code>
225      * @param useByteBufferView to create <code>ByteBuffer</code> view
226      * @param size the size of the <code>ByteBuffer</code>
227      * @return a <code>ByteBuffer</code>
228      */

229     protected ByteBuffer JavaDoc allocateByteBuffer(boolean useDirectByteBuffer,
230                                             boolean useByteBufferView,
231                                             int size){
232         ByteBuffer JavaDoc byteBuffer;
233         if (useByteBufferView){
234             byteBuffer = ByteBufferFactory.allocateView(size,
235                                                         useDirectByteBuffer);
236         } else if ( useDirectByteBuffer ){
237             byteBuffer = ByteBuffer.allocateDirect(size);
238         } else {
239             byteBuffer = ByteBuffer.allocate(size);
240         }
241         return byteBuffer;
242     }
243     
244     
245     /**
246      * Allocate a new <code>ByteBuffer</code> and put the content of the current
247      * one into it.
248      */

249     private ByteBuffer JavaDoc swapBuffer(ByteBuffer JavaDoc byteBuffer, int size){
250         ByteBuffer JavaDoc tmp = allocateByteBuffer(useDirectByteBuffer,
251                                             useByteBufferView, size);
252
253         byteBuffer.flip();
254         tmp.put(byteBuffer);
255         
256         // Keep a pointer to the original one.
257
if ( primaryByteBuffer == null) {
258             primaryByteBuffer = byteBuffer;
259         }
260         byteBuffer = tmp;
261         return byteBuffer;
262     }
263     
264     
265     /**
266      * Dump the ByteBuffer content. This is used only for debugging purpose.
267      */

268     protected String JavaDoc dump(ByteBuffer JavaDoc byteBuffer){
269         ByteBuffer JavaDoc dd = byteBuffer.duplicate();
270         dd.flip();
271         
272         int length = dd.limit();
273         byte[] dump = new byte[length];
274         dd.get(dump,0,length);
275         return(new String JavaDoc(dump) + "\n----------------------------" + dd
276         + "\ncontentLength: " + contentLength
277         + "\nheaderLength: " + headerLength);
278     }
279     
280     
281     /**
282      * The SocketChannel used by this class.
283      */

284     public void setSocketChannel(SocketChannel JavaDoc socketChannel){
285         this.socketChannel = socketChannel;
286     }
287     
288     
289     /**
290      * Set the port
291      */

292     public void setPort(int port){
293         this.port = port;
294     }
295     
296     
297     /**
298      * Return the port
299      */

300     public int getPort(){
301         return port;
302     }
303 }
304
Popular Tags