001: package com.calipso.reportgenerator.reportmanager;
002:
003: import com.calipso.reportgenerator.common.DimensionValueNode;
004:
005: import java.util.Iterator;
006: import java.util.ArrayList;
007:
008: /**
009: */
010: public class DimensionNodeIterator implements Iterator {
011:
012: private DimensionValueNode dimensionValueNode;
013: private int dimensionCount;
014: private Iterator[] iterators;
015: private Object[] currentValues;
016: private DimensionValueNode[] currentNodes;
017: private boolean withTotals;
018: private ArrayList currentTotals;
019:
020: public DimensionNodeIterator(DimensionValueNode dimensionValueNode,
021: boolean withTotals) {
022: this .dimensionValueNode = dimensionValueNode;
023: this .withTotals = withTotals;
024: this .totalsPending = withTotals;
025: initialize();
026: }
027:
028: public boolean withTotals() {
029: return this .withTotals;
030: }
031:
032: private void initialize() {
033: dimensionCount = Math.max(1, getDimensionValueNode()
034: .getDimensionCount());
035: iterators = new Iterator[dimensionCount];
036: currentValues = new Object[dimensionCount];
037: currentNodes = new DimensionValueNode[dimensionCount];
038: iterators[0] = getDimensionValueNode().getSubNodesList()
039: .iterator();
040: }
041:
042: public DimensionValueNode getDimensionValueNode() {
043: return dimensionValueNode;
044: }
045:
046: public int getDimensionCount() {
047: return dimensionCount;
048: }
049:
050: private ArrayList getCurrentTotals() {
051: if (currentTotals == null) {
052: currentTotals = new ArrayList();
053: }
054: return currentTotals;
055: }
056:
057: private boolean totalsPending;
058:
059: public boolean hasNext() {
060: Iterator iterator;
061: for (int i = 0; i < dimensionCount; i++) {
062: iterator = iterators[i];
063: if (iterator != null && iterator.hasNext()) {
064: return true;
065: }
066: }
067: //boolean xhasNext = totalsPending || getCurrentTotals().size() > 0;//!itemPending;//
068: if (withTotals) {
069: boolean xhasNext = totalsPending
070: || currentValues[0] != null
071: || getCurrentTotals().size() > 0;//!itemPending;//
072: if (totalsPending)
073: totalsPending = false;
074: return xhasNext;
075: } else {
076: return false;
077: }
078: }
079:
080: public Object next() {
081: Object[] values = new Object[getDimensionCount()];
082: advance();
083: if (getCurrentTotals().size() > 0) {
084: values = (Object[]) getCurrentTotals().get(0);
085: getCurrentTotals().remove(0);
086: } else {
087: copyFromCurrent(values);
088: }
089: return values;
090: }
091:
092: private void copyFromCurrent(Object[] values) {
093: System.arraycopy(currentValues, 0, values, 0,
094: currentValues.length);
095: }
096:
097: private boolean itemPending = false;
098:
099: private void advance() {
100: if (!itemPending) {
101: if (getCurrentTotals().size() == 0) {
102: advanceAt(getDimensionCount() - 1);
103: }
104: }
105: if (itemPending && getCurrentTotals().size() == 0) {
106: itemPending = false;
107: }
108: }
109:
110: private void advanceAt(int dimensionIndex) {
111: if (dimensionIndex >= 0) {
112: Iterator iterator = iterators[dimensionIndex];
113: if (iterator != null) {
114: if (iterator.hasNext()) {
115: updateCurrentValue(dimensionIndex,
116: (DimensionValueNode) iterator.next());
117: return;
118: } else {
119: iterators[dimensionIndex] = null;
120: updateCurrentValue(dimensionIndex, null);
121: if (withTotals) {
122: Object[] values = new Object[getDimensionCount()];
123: copyFromCurrent(values);
124: getCurrentTotals().add(values);
125: itemPending = true;
126: }
127: }
128: }
129: advanceAt(dimensionIndex - 1);
130: initializeIterator(dimensionIndex);
131: }
132: }
133:
134: private void initializeIterator(int dimensionIndex) {
135: if (dimensionIndex > 0) {
136: Iterator iterator = iteratorFor(dimensionIndex);
137: if (iterator == null) {
138: initializeIterator(dimensionIndex - 1);
139: iterator = iteratorFor(dimensionIndex);
140: }
141:
142: if (iterator != null && iterator.hasNext()) {
143: iterators[dimensionIndex] = iterator;
144: DimensionValueNode node = (DimensionValueNode) iterator
145: .next();
146: updateCurrentValue(dimensionIndex, node);
147: } else {
148: iterators[dimensionIndex] = null;
149: }
150: } else {
151: iterators[0] = null;
152: }
153: }
154:
155: private Iterator iteratorFor(int dimensionIndex) {
156: DimensionValueNode node = currentNodes[dimensionIndex - 1];
157: if (node != null) {
158: return node.iterator();
159: }
160: return null;
161: }
162:
163: private void updateCurrentValue(int dimensionIndex,
164: DimensionValueNode node) {
165: Object value = null;
166: if (node != null) {
167: value = node.getValue();
168: } else {
169: value = null;
170: }
171: currentValues[dimensionIndex] = value;
172: currentNodes[dimensionIndex] = node;
173: if (dimensionIndex < currentValues.length - 1) {
174: for (int i = dimensionIndex + 1; i < currentValues.length; i++) {
175: currentValues[i] = null;
176: currentNodes[i] = null;
177: }
178: }
179: }
180:
181: public void remove() {
182: }
183: }
|