001: /*
002: * Copyright (c) 1998 - 2005 Versant Corporation
003: * All rights reserved. This program and the accompanying materials
004: * are made available under the terms of the Eclipse Public License v1.0
005: * which accompanies this distribution, and is available at
006: * http://www.eclipse.org/legal/epl-v10.html
007: *
008: * Contributors:
009: * Versant Corporation - initial API and implementation
010: */
011: package com.versant.core.jdo;
012:
013: import com.versant.core.server.CompiledQuery;
014: import com.versant.core.server.QueryResultWrapper;
015: import com.versant.core.common.QueryResultContainer;
016: import com.versant.core.common.BindingSupportImpl;
017:
018: import java.util.NoSuchElementException;
019:
020: /**
021: * A ListIterator implemenation that supports forward iteration over the results.
022: */
023: public class QueryIterator implements JDOListIterator {
024: private PMProxy pm;
025:
026: private Object[] data;
027: private int actualSize;
028: private int indexInData;
029: private QueryResultWrapper qrw;
030: private boolean noMoreDataInResultSet;
031: private boolean closed;
032: private int nextIndex;
033:
034: public QueryIterator(PMProxy pm, CompiledQuery compiledQuery,
035: Object[] params, boolean doNotFlush) {
036: this .pm = pm;
037: if (!doNotFlush
038: && !compiledQuery.getQueryDetails().isIgnoreCache()) {
039: pm.flushIfDepOn(compiledQuery.getEvictionClassBits());
040: }
041: qrw = pm.executeQuery(compiledQuery, params);
042: }
043:
044: public void remove() {
045: throw BindingSupportImpl.getInstance().unsupported(
046: "Not allowed to modify");
047: }
048:
049: public boolean hasNext() {
050: if (closed)
051: return false;
052:
053: if (!noMoreDataInResultSet
054: && (data == null || indexInData == actualSize)) {
055: getMoreData();
056: }
057: return !(data == null || indexInData == actualSize);
058: }
059:
060: /**
061: * If we have not started yet then execute the query and return the first result.
062: * If we have already started and there is still data available then return the
063: * next data. If we are at the end of the last fetched data then get more
064: * and return the first data.
065: * @return
066: */
067: public Object next() {
068: if (closed) {
069: throw new NoSuchElementException();
070: }
071:
072: if (!noMoreDataInResultSet
073: && (data == null || indexInData == actualSize)) {
074: getMoreData();
075: }
076: return getNextData();
077: }
078:
079: private void getMoreData() {
080: //get data from server
081: QueryResultContainer container = pm.getNextQueryResult(qrw, 0);
082: pm.addToCache(container.container);
083:
084: data = container.getDataArray();
085: actualSize = container.size();
086: noMoreDataInResultSet = container.isqFinished();
087: indexInData = 0;
088: }
089:
090: private Object getNextData() {
091: if (indexInData == actualSize)
092: throw new NoSuchElementException();
093: nextIndex++;
094: return QueryResultBase.resolveRow(data[indexInData++], pm);
095: }
096:
097: /**
098: * Cleanup all resources.
099: */
100: public void close() {
101: if (closed)
102: return;
103:
104: if (qrw != null) {
105: pm.closeQuery(qrw);
106: qrw = null;
107: }
108:
109: pm = null;
110: data = null;
111: qrw = null;
112:
113: closed = true;
114: }
115:
116: public int nextIndex() {
117: return nextIndex;
118: }
119:
120: public int previousIndex() {
121: return nextIndex - 1;
122: }
123:
124: public boolean hasPrevious() {
125: return nextIndex != 0;
126: }
127:
128: public Object previous() {
129: throw BindingSupportImpl.getInstance().unsupportedOperation(
130: null);
131: }
132:
133: public void add(Object o) {
134: throw BindingSupportImpl.getInstance().unsupported(
135: "Not allowed to modify");
136: }
137:
138: public void set(Object o) {
139: throw BindingSupportImpl.getInstance().unsupported(
140: "Not allowed to modify");
141: }
142: }
|