View Javadoc
1   /* 
2    * Licensed under the Apache License, Version 2.0 (the "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.apache.org/licenses/LICENSE-2.0
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 implied.
11   * See the License for the specific language governing permissions and
12   * limitations under the License.
13   *
14   */
15  
16  package org.esigate.parser.future;
17  
18  import java.io.IOException;
19  import java.util.concurrent.ExecutionException;
20  import java.util.concurrent.Future;
21  import java.util.concurrent.TimeUnit;
22  import java.util.concurrent.TimeoutException;
23  
24  import org.esigate.HttpErrorPage;
25  import org.esigate.Parameters;
26  
27  /**
28   * This is an implementation of StringBuilder which can append Future<CharSequence> and is a
29   * Future<CharSequence> itself.
30   * <p>
31   * It is intended for temporary buffers when implementing nested tags.
32   * 
33   * 
34   * @author Nicolas Richeton
35   * 
36   */
37  public class StringBuilderFutureAppendable implements FutureAppendable, Future<CharSequence> {
38      private final StringBuilder builder;
39      private final FutureAppendableAdapter futureBuilder;
40  
41      /**
42       * Create a new builder with a default capacity of 1024.
43       */
44      public StringBuilderFutureAppendable() {
45          this(Parameters.DEFAULT_BUFFER_SIZE);
46      }
47  
48      /**
49       * Create a new builder with a custom capacity.
50       * 
51       * @param capacity
52       *            Capacity of the builder.
53       */
54      private StringBuilderFutureAppendable(int capacity) {
55          this.builder = new StringBuilder(capacity);
56          this.futureBuilder = new FutureAppendableAdapter(this.builder);
57      }
58  
59      @Override
60      public FutureAppendable enqueueAppend(Future<CharSequence> csq) {
61          return this.futureBuilder.enqueueAppend(csq);
62      }
63  
64      @Override
65      public FutureAppendable performAppends() throws IOException, HttpErrorPage {
66          return this.futureBuilder.performAppends();
67      }
68  
69      @Override
70      public boolean cancel(boolean mayInterruptIfRunning) {
71          return false;
72      }
73  
74      @Override
75      public boolean isCancelled() {
76          return false;
77      }
78  
79      @Override
80      public boolean isDone() {
81          return this.futureBuilder.hasPending();
82      }
83  
84      /*
85       * (non-Javadoc)
86       * 
87       * @see java.util.concurrent.Future#get()
88       */
89      @Override
90      public CharSequence get() throws ExecutionException {
91          try {
92              this.futureBuilder.performAppends();
93          } catch (IOException | HttpErrorPage e) {
94              throw new ExecutionException(e);
95          }
96          return this.builder.toString();
97      }
98  
99      /*
100      * (non-Javadoc)
101      * 
102      * @see java.util.concurrent.Future#get(long, java.util.concurrent.TimeUnit)
103      */
104     @Override
105     public CharSequence get(long timeout, TimeUnit unit) throws ExecutionException {
106         try {
107             this.futureBuilder.performAppends();
108         } catch (IOException | HttpErrorPage e) {
109             throw new ExecutionException(e);
110         }
111         return this.builder.toString();
112     }
113 
114     /*
115      * (non-Javadoc)
116      * 
117      * @see org.esigate.parser.future.FutureAppendable#hasPending()
118      */
119     @Override
120     public boolean hasPending() {
121         return this.futureBuilder.hasPending();
122     }
123 
124     /*
125      * (non-Javadoc)
126      * 
127      * @see org.esigate.parser.future.FutureAppendable#performAppends(int, java.util.concurrent.TimeUnit)
128      */
129     @Override
130     public FutureAppendable performAppends(int timeout, TimeUnit unit) throws IOException, HttpErrorPage,
131             TimeoutException {
132         return this.futureBuilder.performAppends(timeout, unit);
133     }
134 
135 }