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 }