001// ***************************************************************************************************************************
002// * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements.  See the NOTICE file *
003// * distributed with this work for additional information regarding copyright ownership.  The ASF licenses this file        *
004// * to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance            *
005// * with the License.  You may obtain a copy of the License at                                                              *
006// *                                                                                                                         *
007// *  http://www.apache.org/licenses/LICENSE-2.0                                                                             *
008// *                                                                                                                         *
009// * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an  *
010// * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the License for the        *
011// * specific language governing permissions and limitations under the License.                                              *
012// ***************************************************************************************************************************
013package org.apache.juneau.http.part;
014
015import static org.apache.juneau.common.internal.ArgUtils.*;
016
017import java.util.NoSuchElementException;
018
019import org.apache.http.*;
020import org.apache.juneau.common.internal.*;
021
022/**
023 * Basic implementation of a {@link PartIterator}.
024 *
025 * <h5 class='section'>Notes:</h5><ul>
026 *    <li class='warn'>This class is not thread safe.
027 * </ul>
028 *
029 * <h5 class='section'>See Also:</h5><ul>
030 *    <li class='link'><a class="doclink" href="../../../../../index.html#juneau-rest-common">juneau-rest-common</a>
031 * </ul>
032 */
033public class BasicPartIterator implements PartIterator {
034
035   private final NameValuePair[] entries;
036   private final String name;
037   private final boolean caseInsensitive;
038
039   private int currentIndex;
040
041   /**
042    * Creates a new part iterator.
043    *
044    * @param parts An array of parts over which to iterate.
045    * @param name The name of the parts over which to iterate, or <jk>null</jk> for all.
046    * @param caseInsensitive Use case-insensitive matching for part name.
047    */
048   public BasicPartIterator(NameValuePair[] parts, String name, boolean caseInsensitive) {
049      this.entries = assertArgNotNull("parts", parts);
050      this.name = name;
051      this.caseInsensitive = caseInsensitive;
052      this.currentIndex = findNext(-1);
053   }
054
055   private int findNext(int pos) {
056
057      int from = pos;
058
059      int to = entries.length - 1;
060      boolean found = false;
061      while (!found && (from < to)) {
062         from++;
063         found = filter(from);
064      }
065
066      return found ? from : -1;
067   }
068
069   private boolean filter(int index) {
070      return (name == null) || eq(name, entries[index].getName());
071   }
072
073   @Override /* Iterator */
074   public boolean hasNext() {
075      return (currentIndex >= 0);
076   }
077
078   @Override /* Iterator */
079   public NameValuePair next() throws NoSuchElementException {
080
081      int current = currentIndex;
082
083      if (current < 0)
084         throw new NoSuchElementException("Iteration already finished.");
085
086      currentIndex = findNext(current);
087
088      return entries[current];
089   }
090
091   /**
092    * Not supported.
093    */
094   @Override /* Iterator */
095   public void remove() throws UnsupportedOperationException {
096      throw new UnsupportedOperationException("Not supported.");
097   }
098
099   private boolean eq(String s1, String s2) {
100      return StringUtils.eq(caseInsensitive, s1, s2);
101   }
102}