View Javadoc

1   /*
2    * ====================================================================
3    * Licensed to the Apache Software Foundation (ASF) under one
4    * or more contributor license agreements.  See the NOTICE file
5    * distributed with this work for additional information
6    * regarding copyright ownership.  The ASF licenses this file
7    * to you under the Apache License, Version 2.0 (the
8    * "License"); you may not use this file except in compliance
9    * with the License.  You may obtain a copy of the License at
10   *
11   *   http://www.apache.org/licenses/LICENSE-2.0
12   *
13   * Unless required by applicable law or agreed to in writing,
14   * software distributed under the License is distributed on an
15   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16   * KIND, either express or implied.  See the License for the
17   * specific language governing permissions and limitations
18   * under the License.
19   * ====================================================================
20   *
21   * This software consists of voluntary contributions made by many
22   * individuals on behalf of the Apache Software Foundation.  For more
23   * information on the Apache Software Foundation, please see
24   * <http://www.apache.org/>.
25   *
26   */
27  
28  package org.apache.http.message;
29  
30  import java.util.NoSuchElementException;
31  
32  import org.apache.http.FormattedHeader;
33  import org.apache.http.Header;
34  import org.apache.http.HeaderElement;
35  import org.apache.http.HeaderElementIterator;
36  import org.apache.http.HeaderIterator;
37  import org.apache.http.annotation.NotThreadSafe;
38  import org.apache.http.util.CharArrayBuffer;
39  
40  /**
41   * Basic implementation of a {@link HeaderElementIterator}.
42   *
43   * @since 4.0
44   */
45  @NotThreadSafe
46  public class BasicHeaderElementIterator implements HeaderElementIterator {
47  
48      private final HeaderIterator headerIt;
49      private final HeaderValueParser parser;
50  
51      private HeaderElement currentElement = null;
52      private CharArrayBuffer buffer = null;
53      private ParserCursor cursor = null;
54  
55      /**
56       * Creates a new instance of BasicHeaderElementIterator
57       */
58      public BasicHeaderElementIterator(
59              final HeaderIterator headerIterator,
60              final HeaderValueParser parser) {
61          if (headerIterator == null) {
62              throw new IllegalArgumentException("Header iterator may not be null");
63          }
64          if (parser == null) {
65              throw new IllegalArgumentException("Parser may not be null");
66          }
67          this.headerIt = headerIterator;
68          this.parser = parser;
69      }
70  
71  
72      public BasicHeaderElementIterator(final HeaderIterator headerIterator) {
73          this(headerIterator, BasicHeaderValueParser.DEFAULT);
74      }
75  
76  
77      private void bufferHeaderValue() {
78          this.cursor = null;
79          this.buffer = null;
80          while (this.headerIt.hasNext()) {
81              Header h = this.headerIt.nextHeader();
82              if (h instanceof FormattedHeader) {
83                  this.buffer = ((FormattedHeader) h).getBuffer();
84                  this.cursor = new ParserCursor(0, this.buffer.length());
85                  this.cursor.updatePos(((FormattedHeader) h).getValuePos());
86                  break;
87              } else {
88                  String value = h.getValue();
89                  if (value != null) {
90                      this.buffer = new CharArrayBuffer(value.length());
91                      this.buffer.append(value);
92                      this.cursor = new ParserCursor(0, this.buffer.length());
93                      break;
94                  }
95              }
96          }
97      }
98  
99      private void parseNextElement() {
100         // loop while there are headers left to parse
101         while (this.headerIt.hasNext() || this.cursor != null) {
102             if (this.cursor == null || this.cursor.atEnd()) {
103                 // get next header value
104                 bufferHeaderValue();
105             }
106             // Anything buffered?
107             if (this.cursor != null) {
108                 // loop while there is data in the buffer
109                 while (!this.cursor.atEnd()) {
110                     HeaderElement e = this.parser.parseHeaderElement(this.buffer, this.cursor);
111                     if (!(e.getName().length() == 0 && e.getValue() == null)) {
112                         // Found something
113                         this.currentElement = e;
114                         return;
115                     }
116                 }
117                 // if at the end of the buffer
118                 if (this.cursor.atEnd()) {
119                     // discard it
120                     this.cursor = null;
121                     this.buffer = null;
122                 }
123             }
124         }
125     }
126 
127     public boolean hasNext() {
128         if (this.currentElement == null) {
129             parseNextElement();
130         }
131         return this.currentElement != null;
132     }
133 
134     public HeaderElement nextElement() throws NoSuchElementException {
135         if (this.currentElement == null) {
136             parseNextElement();
137         }
138 
139         if (this.currentElement == null) {
140             throw new NoSuchElementException("No more header elements available");
141         }
142 
143         HeaderElement element = this.currentElement;
144         this.currentElement = null;
145         return element;
146     }
147 
148     public final Object next() throws NoSuchElementException {
149         return nextElement();
150     }
151 
152     public void remove() throws UnsupportedOperationException {
153         throw new UnsupportedOperationException("Remove not supported");
154     }
155 
156 }