001: /*
002: * $Id: SubsetIteratorFilter.java 471756 2006-11-06 15:01:43Z husted $
003: *
004: * Licensed to the Apache Software Foundation (ASF) under one
005: * or more contributor license agreements. See the NOTICE file
006: * distributed with this work for additional information
007: * regarding copyright ownership. The ASF licenses this file
008: * to you under the Apache License, Version 2.0 (the
009: * "License"); you may not use this file except in compliance
010: * with the License. You may obtain a copy of the License at
011: *
012: * http://www.apache.org/licenses/LICENSE-2.0
013: *
014: * Unless required by applicable law or agreed to in writing,
015: * software distributed under the License is distributed on an
016: * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
017: * KIND, either express or implied. See the License for the
018: * specific language governing permissions and limitations
019: * under the License.
020: */
021: package org.apache.struts2.util;
022:
023: import java.util.ArrayList;
024: import java.util.Iterator;
025: import java.util.List;
026:
027: import org.apache.commons.logging.Log;
028: import org.apache.commons.logging.LogFactory;
029:
030: import com.opensymphony.xwork2.Action;
031:
032: /**
033: * A bean that takes an iterator and outputs a subset of it.
034: *
035: */
036: public class SubsetIteratorFilter extends IteratorFilterSupport
037: implements Iterator, Action {
038:
039: private static final Log _log = LogFactory
040: .getLog(SubsetIteratorFilter.class);
041:
042: Iterator iterator;
043: Object source;
044: int count = -1;
045: int currentCount = 0;
046:
047: Decider decider;
048:
049: // Attributes ----------------------------------------------------
050: int start = 0;
051:
052: public void setCount(int aCount) {
053: this .count = aCount;
054: }
055:
056: // Public --------------------------------------------------------
057: public void setSource(Object anIterator) {
058: source = anIterator;
059: }
060:
061: public void setStart(int aStart) {
062: this .start = aStart;
063: }
064:
065: public void setDecider(Decider aDecider) {
066: this .decider = aDecider;
067: }
068:
069: // Action implementation -----------------------------------------
070: public String execute() {
071: if (source == null) {
072: LogFactory.getLog(SubsetIteratorFilter.class.getName())
073: .warn("Source is null returning empty set.");
074:
075: return ERROR;
076: }
077:
078: // Make source transformations
079: source = getIterator(source);
080:
081: // Calculate iterator filter
082: if (source instanceof Iterator) {
083: iterator = (Iterator) source;
084:
085: // Read away <start> items
086: for (int i = 0; (i < start) && iterator.hasNext(); i++) {
087: iterator.next();
088: }
089:
090: // now let Decider decide if element should be added (if a decider exist)
091: if (decider != null) {
092: List list = new ArrayList();
093: while (iterator.hasNext()) {
094: Object currentElement = iterator.next();
095: if (decide(currentElement)) {
096: list.add(currentElement);
097: }
098: }
099: iterator = list.iterator();
100: }
101:
102: } else if (source.getClass().isArray()) {
103: ArrayList list = new ArrayList(((Object[]) source).length);
104: Object[] objects = (Object[]) source;
105: int len = objects.length;
106:
107: if (count >= 0) {
108: len = start + count;
109: if (len > objects.length) {
110: len = objects.length;
111: }
112: }
113:
114: for (int j = start; j < len; j++) {
115: if (decide(objects[j])) {
116: list.add(objects[j]);
117: }
118: }
119:
120: count = -1; // Don't have to check this in the iterator code
121: iterator = list.iterator();
122: }
123:
124: if (iterator == null) {
125: throw new IllegalArgumentException(
126: "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
135: : (iterator.hasNext() && ((count < 0) || (currentCount < count)));
136: }
137:
138: public Object next() {
139: currentCount++;
140:
141: return iterator.next();
142: }
143:
144: public void remove() {
145: iterator.remove();
146: }
147:
148: // inner class ---------------------------------------------------
149: /**
150: * A decider determines if the given element should be added to the list or not.
151: */
152: public static interface Decider {
153:
154: /**
155: * Should the object be added to the list?
156: * @param element the object
157: * @return true to add.
158: * @throws Exception can be thrown.
159: */
160: boolean decide(Object element) throws Exception;
161: }
162:
163: // protected -----------------------------------------------------
164: protected boolean decide(Object element) {
165: if (decider != null) {
166: try {
167: boolean okToAdd = decider.decide(element);
168: return okToAdd;
169: } catch (Exception e) {
170: _log
171: .warn(
172: "decider ["
173: + decider
174: + "] encountered an error while decide adding element ["
175: + element
176: + "], element will be ignored, it will not appeared in subseted iterator",
177: e);
178: return false;
179: }
180: }
181: return true;
182: }
183: }
|