1 2 12 package com.versant.core.jdo; 13 14 import com.versant.core.common.QueryResultContainer; 15 import com.versant.core.server.CompiledQuery; 16 import com.versant.core.server.QueryResultWrapper; 17 18 19 20 import java.util.*; 21 import java.lang.reflect.Array ; 22 23 import com.versant.core.common.BindingSupportImpl; 24 25 30 public final class RandomAccessQueryResult extends QueryResultBase { 31 32 private QueryResultWrapper qrsIF; 33 private PMProxy pmProxy; 34 private final CompiledQuery compiledQuery; 35 private Object [] params; 36 private List openQIters = new ArrayList(); 37 private int size = -1; 38 private int fetchAmount; 39 40 41 private Object [] window; 42 private int absoluteIndexStart = -1; 43 private int windowSize; 44 45 public RandomAccessQueryResult(PMProxy pm, 46 CompiledQuery compiledQuery, Object [] params) { 47 this.pmProxy = pm; 48 this.compiledQuery = compiledQuery; 49 qrsIF = pmProxy.executeQuery(compiledQuery, params); 50 if (!compiledQuery.getQueryDetails().isIgnoreCache()) { 51 pmProxy.flushIfDepOn(compiledQuery.getEvictionClassBits()); 52 } 53 this.params = params; 54 fetchAmount = compiledQuery.getQueryDetails().getResultBatchSize(); 55 } 56 57 public void setParams(Object [] params) { 58 this.params = params; 59 } 60 61 private void checkClosed() { 62 if (qrsIF == null) { 63 throw BindingSupportImpl.getInstance().invalidOperation("Query result has been closed"); 64 } 65 } 66 67 public void setBatchFetchSize(int amount) { 68 if (amount < 1) { 69 throw BindingSupportImpl.getInstance().invalidOperation("'FetchSize of '" + amount + " is invalid"); 70 } 71 fetchAmount = amount; 72 } 73 74 public Object get(int index) { 75 checkClosed(); 76 if (index < 0) { 77 throw BindingSupportImpl.getInstance().invalidOperation("Index must be greater or equal to '0'"); 78 } 79 80 81 if (index < absoluteIndexStart) { 82 84 QueryResultContainer container = null; 85 synchronized(pmProxy) { 86 container = pmProxy.getAbsolute(qrsIF, index, fetchAmount); 87 pmProxy.addToCache(container.container); 88 } 89 90 window = container.getDataArray(); 91 absoluteIndexStart = index; 92 windowSize = container.size(); 93 94 container.reset(); 95 } else if (index > absoluteIndexStart) { 96 int absoluteIndexEnd = ((absoluteIndexStart + windowSize) - 1); 98 if (index > absoluteIndexEnd) { 99 QueryResultContainer container = pmProxy.getAbsolute(qrsIF, index, fetchAmount); 101 pmProxy.addToCache(container.container); 102 103 window = container.getDataArray(); 104 absoluteIndexStart = index; 105 windowSize = container.size(); 106 107 container.reset(); 108 } 109 } 110 111 if (windowSize == 0) { 112 throw BindingSupportImpl.getInstance().arrayIndexOutOfBounds("index '" 113 + index + "' is too big"); 114 } 115 return resolveRow(window[index - absoluteIndexStart], pmProxy); 116 } 117 118 121 public int size() { 122 if (size == -1) { 123 checkClosed(); 124 size = pmProxy.getResultCount(qrsIF); 125 } 126 return size; 127 } 128 129 public boolean isEmpty() { 130 return size() > 0; 131 } 132 133 private RuntimeException createUseNonRandomAccessException() { 134 return BindingSupportImpl.getInstance().invalidOperation( 135 "Method not available for a randomAccess=true query"); 136 } 137 138 public boolean contains(Object o) { 139 throw createUseNonRandomAccessException(); 140 } 141 142 public Object [] toArray() { 143 if (!compiledQuery.getQueryDetails().isIgnoreCache()) { 144 pmProxy.flushIfDepOn(compiledQuery.getEvictionClassBits()); 145 } 146 147 QueryResultContainer qContainer = pmProxy.getAllQueryResults(compiledQuery, params); 148 pmProxy.addToCache(qContainer.container); 149 150 Object [] resolvedData = qContainer.toResolvedObject(pmProxy); 151 int n = qContainer.size(); 152 Object [] a = new Object [n]; 153 for (int i = 0; i < n; i++) { 154 a[i] = resolvedData[i]; 155 } 156 return a; 157 } 158 159 public Object [] toArray(Object a[]) { 160 if (a == null) throw new NullPointerException ("The supplied array is null"); 161 162 if (!compiledQuery.getQueryDetails().isIgnoreCache()) { 163 pmProxy.flushIfDepOn(compiledQuery.getEvictionClassBits()); 164 } 165 166 QueryResultContainer qContainer = pmProxy.getAllQueryResults(compiledQuery, params); 167 pmProxy.addToCache(qContainer.container); 168 169 Object [] resolvedData = qContainer.toResolvedObject(pmProxy); 170 int n = qContainer.size(); 171 if (n > a.length) { 172 a = (Object []) Array.newInstance(a.getClass().getComponentType(), n); 173 } 174 175 for (int i = 0; i < n; i++) { 176 a[i] = resolvedData[i]; 177 } 178 return a; 179 } 180 181 public boolean containsAll(Collection c) { 182 throw createUseNonRandomAccessException(); 183 } 184 185 public int indexOf(Object o) { 186 throw createUseNonRandomAccessException(); 187 } 188 189 public int lastIndexOf(Object o) { 190 throw createUseNonRandomAccessException(); 191 } 192 193 public Iterator iterator() { 194 return createInternalIter(); 195 } 196 197 public ListIterator listIterator() { 198 return createInternalIter(); 199 } 200 201 public ListIterator listIterator(int index) { 202 throw BindingSupportImpl.getInstance().unsupported(null); 203 } 204 205 public List subList(int fromIndex, int toIndex) { 206 checkClosed(); 207 QueryResultContainer container = null; 208 final int toAdd = toIndex - fromIndex; 209 if (toAdd <= 0) { 210 return new ArrayList(); 211 } 212 final List list = new ArrayList(toAdd); 213 container = pmProxy.getAbsolute(qrsIF, fromIndex, toAdd); 214 215 pmProxy.addToCache(container.container); 217 218 container.resolveAndAddTo(list, pmProxy); 219 container.reset(); 220 return list; 221 } 222 223 private ListIterator createInternalIter() { 224 return createInternalIterImp(false); 225 } 226 227 private ListIterator createInternalIterImp(boolean doNotFlush) { 228 checkClosed(); 229 QueryIterator queryIterator = new QueryIterator(pmProxy, compiledQuery, params, doNotFlush); 230 openQIters.add(queryIterator); 231 return queryIterator; 232 } 233 234 public Iterator createInternalIterNoFlush() { 235 return createInternalIterImp(true); 236 } 237 238 public void close() { 239 for (int i = 0; i < openQIters.size(); i++) { 240 ((JDOListIterator)openQIters.get(i)).close(); 241 } 242 openQIters.clear(); 243 244 if (qrsIF != null) { 245 pmProxy.closeQuery(qrsIF); 246 qrsIF = null; 247 } 248 249 window = null; 250 } 251 252 } 253 | Popular Tags |