001: /*
002: * Copyright (c) 2002-2003 by OpenSymphony
003: * All rights reserved.
004: */
005: package com.opensymphony.webwork.util;
006:
007: import com.opensymphony.xwork.Action;
008:
009: import org.apache.commons.logging.Log;
010: import org.apache.commons.logging.LogFactory;
011:
012: import java.util.ArrayList;
013: import java.util.Iterator;
014: import java.util.List;
015:
016: /**
017: * A bean that takes an iterator and outputs a subset of it.
018: *
019: * @author Rickard �berg (rickard@middleware-company.com)
020: * @author tm_jee (tm_jee (at) yahoo.co.uk)
021: * @version $Revision: 2371 $
022: */
023: public class SubsetIteratorFilter extends IteratorFilterSupport
024: implements Iterator, Action {
025:
026: private static final Log _log = LogFactory
027: .getLog(SubsetIteratorFilter.class);
028:
029: Iterator iterator;
030: Object source;
031: int count = -1;
032: int currentCount = 0;
033:
034: Decider decider;
035:
036: // Attributes ----------------------------------------------------
037: int start = 0;
038:
039: public void setCount(int aCount) {
040: this .count = aCount;
041: }
042:
043: // Public --------------------------------------------------------
044: public void setSource(Object anIterator) {
045: source = anIterator;
046: }
047:
048: public void setStart(int aStart) {
049: this .start = aStart;
050: }
051:
052: public void setDecider(Decider aDecider) {
053: this .decider = aDecider;
054: }
055:
056: // Action implementation -----------------------------------------
057: public String execute() {
058: if (source == null) {
059: LogFactory.getLog(SubsetIteratorFilter.class.getName())
060: .warn("Source is null returning empty set.");
061:
062: return ERROR;
063: }
064:
065: // Make source transformations
066: source = getIterator(source);
067:
068: // Calculate iterator filter
069: if (source instanceof Iterator) {
070: iterator = (Iterator) source;
071:
072: // Read away <start> items
073: for (int i = 0; (i < start) && iterator.hasNext(); i++) {
074: iterator.next();
075: }
076:
077: // now let Decider decide if element should be added (if a decider exist)
078: if (decider != null) {
079: List list = new ArrayList();
080: while (iterator.hasNext()) {
081: Object currentElement = iterator.next();
082: if (decide(currentElement)) {
083: list.add(currentElement);
084: }
085: }
086: iterator = list.iterator();
087: }
088:
089: } else if (source.getClass().isArray()) {
090: ArrayList list = new ArrayList(((Object[]) source).length);
091: Object[] objects = (Object[]) source;
092: int len = objects.length;
093:
094: if (count >= 0) {
095: len = start + count;
096: if (len > objects.length) {
097: len = objects.length;
098: }
099: }
100:
101: for (int j = start; j < len; j++) {
102: if (decide(objects[j])) {
103: list.add(objects[j]);
104: }
105: }
106:
107: count = -1; // Don't have to check this in the iterator code
108: iterator = list.iterator();
109: }
110:
111: if (iterator == null) {
112: throw new IllegalArgumentException(
113: "Source is not an iterator:" + source);
114: }
115:
116: return SUCCESS;
117: }
118:
119: // Iterator implementation ---------------------------------------
120: public boolean hasNext() {
121: return (iterator == null) ? false
122: : (iterator.hasNext() && ((count < 0) || (currentCount < count)));
123: }
124:
125: public Object next() {
126: currentCount++;
127:
128: return iterator.next();
129: }
130:
131: public void remove() {
132: iterator.remove();
133: }
134:
135: // inner class ---------------------------------------------------
136: /**
137: * A decider determines if the given element should be added to the list or not.
138: */
139: public static interface Decider {
140:
141: /**
142: * Should the object be added to the list?
143: * @param element the object
144: * @return true to add.
145: * @throws Exception can be thrown.
146: */
147: boolean decide(Object element) throws Exception;
148: }
149:
150: // protected -----------------------------------------------------
151: protected boolean decide(Object element) {
152: if (decider != null) {
153: try {
154: boolean okToAdd = decider.decide(element);
155: return okToAdd;
156: } catch (Exception e) {
157: _log
158: .warn(
159: "decider ["
160: + decider
161: + "] encountered an error while decide adding element ["
162: + element
163: + "], element will be ignored, it will not appeared in subseted iterator",
164: e);
165: return false;
166: }
167: }
168: return true;
169: }
170: }
|