/*
* #!
* Ontopia Engine
* #-
* Copyright (C) 2001 - 2013 The Ontopia Project
* #-
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* !#
*/
package net.ontopia.persistence.proxy;
import java.util.AbstractCollection;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import net.ontopia.utils.OntopiaRuntimeException;
/**
* INTERNAL: Immutable Collection implementation that delegates its
* data retrieval to QueryIFs. This class is very useful in cases
* where the collection is extremely large.
*/
public class QueryCollection<E> extends AbstractCollection<E> {
protected TransactionIF txn;
protected String query_size;
protected String query_iterator;
protected Object[] params_size;
protected Object[] params_iterator;
public QueryCollection(TransactionIF txn,
String query_size, Object[] params_size,
String query_iterator, Object[] params_iterator) {
this.txn = txn;
this.query_size = query_size;
this.query_iterator = query_iterator;
this.params_size = params_size;
this.params_iterator = params_iterator;
}
public boolean add(E o) {
throw new UnsupportedOperationException();
}
public boolean addAll(Collection<? extends E> c) {
throw new UnsupportedOperationException();
}
public void clear() {
throw new UnsupportedOperationException();
}
// Note: Following methods are delegated to AbstractList
//! public boolean contains(Object o) {
//! throw new UnsupportedOperationException("Not yet supported.");
//! }
//!
//! public boolean containsAll(Collection c) {
//! throw new UnsupportedOperationException("Not yet supported.");
//! }
public boolean isEmpty() {
return (size() == 0);
}
public Iterator<E> iterator() {
QueryResultIF result = null;
try {
result = (QueryResultIF)txn.executeQuery(query_iterator, params_iterator);
return new QueryResultIterator<E>(result);
} catch (Throwable e) {
if (result != null) try { result.close(); } catch (Throwable t) {};
if (e instanceof OntopiaRuntimeException) throw (OntopiaRuntimeException)e;
throw new OntopiaRuntimeException(e);
}
}
public boolean remove(Object o) {
throw new UnsupportedOperationException();
}
public boolean removeAll(Collection<?> c) {
throw new UnsupportedOperationException();
}
public boolean retainAll(Collection<?> c) {
throw new UnsupportedOperationException();
}
public int size() {
QueryResultIF result = null;
try {
result = (QueryResultIF)txn.executeQuery(query_size, params_size);
result.next();
Integer integer = (Integer)result.getValue(0);
result.close();
return integer.intValue();
} catch (Throwable e) {
if (result != null) try { result.close(); } catch (Throwable t) {};
if (e instanceof OntopiaRuntimeException) throw (OntopiaRuntimeException)e;
throw new OntopiaRuntimeException(e);
}
}
public Object[] toArray() {
List result = new ArrayList();
Iterator it = iterator();
while (it.hasNext()) {
result.add(it.next());
}
return result.toArray();
}
public <T> T[] toArray(T a[]) {
List<E> result = new ArrayList<E>();
Iterator<E> it = iterator();
while (it.hasNext()) {
result.add(it.next());
}
return result.toArray(a);
//! // NOTE: implementation below does not work. got too complex,
//! then decided to chicken out going the naive route.
//! int orglen = a.length;
//! Iterator it=iterator();
//! int i=0;
//! for (; it.hasNext(); i++) {
//! Object next = it.next();
//! if (i+1 > a.length) {
//! // Iterator returned more elements than the call to size
//! // did. This probably means that some other transaction added
//! // new rows and that these changes are now visible to this
//! // transaction. Fix by allocating new longer array.
//! int newCapacity = (a.length * 3)/2 + 1;
//! Object[] na = (Object[])java.lang.reflect.Array.newInstance(
//! a.getClass().getComponentType(), newCapacity);
//! System.arraycopy(a, 0, na, 0, a.length);
//! a = na;
//! }
//! a[i] = next;
//! }
//!
//! if (i+1 > orglen && a.length > i+1) {
//! // chop down to actual length if exceeding input size and
//! // temporary allocation too big
//! Object[] na = (Object[])java.lang.reflect.Array.newInstance(
//! a.getClass().getComponentType(), i+1);
//!
//! System.arraycopy(a, 0, na, 0, i+1);
//! return na;
//!
//! } else if (i+1 < a.length) {
//! // if input size too big set next element to null as specified
//! // by contract
//! a[i+1] = null;
//! }
//! return a;
}
}