Docjar: A Java Source and Docuemnt Enginecom.*    java.*    javax.*    org.*    all    new    plug-in

Quick Search    Search Deep

Source code: com/sun/facelets/StateWriter.java


1   /**
2    * Licensed under the Common Development and Distribution License,
3    * you may not use this file except in compliance with the License.
4    * You may obtain a copy of the License at
5    * 
6    *   http://www.sun.com/cddl/
7    *   
8    * Unless required by applicable law or agreed to in writing, software
9    * distributed under the License is distributed on an "AS IS" BASIS,
10   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 
11   * implied. See the License for the specific language governing
12   * permissions and limitations under the License.
13   */
14  
15  package com.sun.facelets;
16  
17  import java.io.IOException;
18  import java.io.Writer;
19  
20  import com.sun.facelets.util.FastWriter;
21  
22  /**
23   * A class for handling state insertion.  Content is written
24   * directly to "out" until an attempt to write state;  at that
25   * point, it's redirected into a buffer that can be picked through
26   * in theory, this buffer should be very small, since it only
27   * needs to be enough to contain all the content after the close
28   * of the first (and, hopefully, only) form.
29   * <p>
30   * Potential optimizations:
31   * <ul>
32   * <li>If we created a new FastWriter at each call to writingState(),
33   * and stored a List of them, then we'd know that state tokens could
34   * only possibly be near the start of each buffer (and might not be there
35   * at all).  (There might be a close-element before the state token). Then,
36   * we'd only need to check the start of the buffer for the state token;
37   * if it's there, write out the real state, then blast the rest of the
38   * buffer out.  This wouldn't even require toString(), which for
39   * large buffers is expensive.  However, this optimization is only
40   * going to be especially meaningful for the multi-form case.
41   * </li>
42   * <li>More of a FastWriter optimization than a StateWriter, but:
43   *  it is far faster to create a set of small 1K buffers than constantly
44   *  reallocating one big buffer.</li>
45   * </ul>
46   *
47   * @author Adam Winer
48   * @version $Id: StateWriter.java,v 1.1 2006/04/12 05:50:45 adamwiner Exp $
49   */
50  final class StateWriter extends Writer {
51  
52      private int initialSize;
53      private Writer out;
54      private FastWriter fast;
55      private boolean writtenState;
56      
57      static public StateWriter getCurrentInstance() {
58          return (StateWriter) CURRENT_WRITER.get();
59      }
60  
61      public StateWriter(Writer initialOut, int initialSize) {
62          if (initialSize < 0) {
63              throw new IllegalArgumentException("Initial Size cannot be less than 0");
64          }
65          
66          this.initialSize = initialSize;
67          this.out = initialOut;
68  
69          CURRENT_WRITER.set(this);
70      }
71  
72      /**
73       * Mark that state is about to be written.  Contrary to what you'd expect,
74       * we cannot and should not assume that this location is really going
75       * to have state;  it is perfectly legit to have a ResponseWriter that
76       * filters out content, and ignores an attempt to write out state
77       * at this point.  So, we have to check after the fact to see
78       * if there really are state markers.
79       */
80      public void writingState() {
81          if (!this.writtenState) {
82              this.writtenState = true;
83              this.out = this.fast = new FastWriter(this.initialSize);
84          }
85      }
86  
87      public boolean isStateWritten() {
88          return this.writtenState;
89      }
90  
91      public void close() throws IOException {
92          // do nothing
93      }
94  
95      public void flush() throws IOException {
96          // do nothing
97      }
98      
99      public void write(char[] cbuf, int off, int len) throws IOException {
100         this.out.write(cbuf, off, len);
101     }
102 
103     public void write(char[] cbuf) throws IOException {
104         this.out.write(cbuf);
105     }
106 
107     public void write(int c) throws IOException {
108         this.out.write(c);
109     }
110 
111     public void write(String str, int off, int len) throws IOException {
112         this.out.write(str, off, len);
113     }
114 
115     public void write(String str) throws IOException {
116         this.out.write(str);
117     }
118     
119     public String getAndResetBuffer() {
120         if (!this.writtenState) {
121             throw new IllegalStateException(
122                      "Did not write state;  no buffer is available");
123         }
124 
125         String result = this.fast.toString();
126         this.fast.reset();
127         return result;
128     }
129   
130     public void release() {
131         CURRENT_WRITER.set(null);
132     }
133 
134     static private final ThreadLocal CURRENT_WRITER = new ThreadLocal();
135 }