1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
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
46 int start = 0;
47
48
49 public void setCount(int aCount) {
50 this.count = aCount;
51 }
52
53
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
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
75 source = getIterator(source);
76
77
78 if (source instanceof Iterator) {
79 iterator = (Iterator) source;
80
81
82
83 for (int i = 0; (i < start) && iterator.hasNext(); i++) {
84 iterator.next();
85 }
86
87
88
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;
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
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
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
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 }