View Javadoc

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