View Javadoc

    1   /*
    2    * $Id: SubsetIteratorFilter.java 471756 2006-11-06 15:01:43Z husted $
    3    *
    4    * Licensed to the Apache Software Foundation (ASF) under one
    5    * or more contributor license agreements.  See the NOTICE file
    6    * distributed with this work for additional information
    7    * regarding copyright ownership.  The ASF licenses this file
    8    * to you under the Apache License, Version 2.0 (the
    9    * "License"); you may not use this file except in compliance
    10   * with the License.  You may obtain a copy of the License at
    11   *
    12   *  http://www.apache.org/licenses/LICENSE-2.0
    13   *
    14   * Unless required by applicable law or agreed to in writing,
    15   * software distributed under the License is distributed on an
    16   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
    17   * KIND, either express or implied.  See the License for the
    18   * specific language governing permissions and limitations
    19   * under the License.
    20   */
    21  package org.apache.struts2.util;
    22
    23  import java.util.ArrayList;
    24  import java.util.Iterator;
    25  import java.util.List;
    26
    27  import org.apache.commons.logging.Log;
    28  import org.apache.commons.logging.LogFactory;
    29
    30  import com.opensymphony.xwork2.Action;
    31
    32
    33  /***
    34   * A bean that takes an iterator and outputs a subset of it.
    35   *
    36   */
    37  public class SubsetIteratorFilter extends IteratorFilterSupport implements Iterator, Action {
    38
    39      private static final Log _log = LogFactory.getLog(SubsetIteratorFilter.class);
    40
    41      Iterator iterator;
    42      Object source;
    43      int count = -1;
    44      int currentCount = 0;
    45
    46      Decider decider;
    47
    48      // Attributes ----------------------------------------------------
    49      int start = 0;
    50
    51
    52      public void setCount(int aCount) {
    53          this.count = aCount;
    54      }
    55
    56      // Public --------------------------------------------------------
    57      public void setSource(Object anIterator) {
    58          source = anIterator;
    59      }
    60
    61      public void setStart(int aStart) {
    62          this.start = aStart;
    63      }
    64
    65      public void setDecider(Decider aDecider) {
    66          this.decider = aDecider;
    67      }
    68
    69      // Action implementation -----------------------------------------
    70      public String execute() {
    71          if (source == null) {
    72              LogFactory.getLog(SubsetIteratorFilter.class.getName()).warn("Source is null returning empty set.");
    73
    74              return ERROR;
    75          }
    76
    77          // Make source transformations
    78          source = getIterator(source);
    79
    80          // Calculate iterator filter
    81          if (source instanceof Iterator) {
    82              iterator = (Iterator) source;
    83
    84
    85              // Read away <start> items
    86              for (int i = 0; (i < start) && iterator.hasNext(); i++) {
    87                  iterator.next();
    88              }
    89
    90
    91              // now let Decider decide if element should be added (if a decider exist)
    92              if (decider != null) {
    93                  List list = new ArrayList();
    94                  while(iterator.hasNext()) {
    95                      Object currentElement = iterator.next();
    96                      if (decide(currentElement)) {
    97                          list.add(currentElement);
    98                      }
    99                  }
    100                 iterator = list.iterator();
    101             }
    102
    103         } else if (source.getClass().isArray()) {
    104             ArrayList list = new ArrayList(((Object[]) source).length);
    105             Object[] objects = (Object[]) source;
    106             int len = objects.length;
    107
    108             if (count >= 0) {
    109                 len = start + count;
    110                 if (len > objects.length) {
    111                     len = objects.length;
    112                 }
    113             }
    114
    115             for (int j = start; j < len; j++) {
    116                 if (decide(objects[j])) {
    117                     list.add(objects[j]);
    118                 }
    119             }
    120
    121             count = -1; // Don't have to check this in the iterator code
    122             iterator = list.iterator();
    123         }
    124
    125         if (iterator == null) {
    126             throw new IllegalArgumentException("Source is not an iterator:" + source);
    127         }
    128
    129         return SUCCESS;
    130     }
    131
    132     // Iterator implementation ---------------------------------------
    133     public boolean hasNext() {
    134         return (iterator == null) ? false : (iterator.hasNext() && ((count < 0) || (currentCount < count)));
    135     }
    136
    137     public Object next() {
    138         currentCount++;
    139
    140         return iterator.next();
    141     }
    142
    143     public void remove() {
    144         iterator.remove();
    145     }
    146
    147     // inner class ---------------------------------------------------
    148     /***
    149      * A decider determines if the given element should be added to the list or not.
    150      */
    151     public static interface Decider {
    152
    153         /***
    154          * Should the object be added to the list?
    155          * @param element  the object
    156          * @return true to add.
    157          * @throws Exception can be thrown.
    158          */
    159         boolean decide(Object element) throws Exception;
    160     }
    161
    162     // protected -----------------------------------------------------
    163     protected boolean decide(Object element) {
    164         if (decider != null) {
    165             try {
    166                 boolean okToAdd = decider.decide(element);
    167                 return okToAdd;
    168             }
    169             catch(Exception e) {
    170                 _log.warn("decider ["+decider+"] encountered an error while decide adding element ["+element+"], element will be ignored, it will not appeared in subseted iterator", e);
    171                 return false;
    172             }
    173         }
    174         return true;
    175     }
    176 }