/*
*
* * Copyright 2014 Orient Technologies LTD (info(at)orientechnologies.com)
* *
* * 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.
* *
* * For more information: http://www.orientechnologies.com
*
*/
package com.orientechnologies.orient.core.iterator;
import com.orientechnologies.common.util.OResettable;
import com.orientechnologies.common.util.OSizeable;
import com.orientechnologies.orient.core.db.record.OAutoConvertToRecord;
import com.orientechnologies.orient.core.db.record.OIdentifiable;
import java.util.Iterator;
import java.util.NoSuchElementException;
/**
* Iterator that created wrapped objects during browsing.
*
* @author Luca Garulli (l.garulli--at--orientechnologies.com)
*/
public abstract class OLazyWrapperIterator<T> implements OAutoConvertToRecord, Iterator<T>, Iterable<T>, OResettable, OSizeable {
protected final Iterator<?> iterator;
protected OIdentifiable nextRecord;
protected T nextElement;
protected final int size; // -1 = UNKNOWN
protected boolean autoConvertToRecord = true;
protected Object multiValue;
public OLazyWrapperIterator(final Iterator<?> iterator) {
this.iterator = iterator;
this.size = -1;
}
public OLazyWrapperIterator(final Iterator<?> iterator, final int iSize, final Object iOriginalValue) {
this.iterator = iterator;
this.size = iSize;
this.multiValue = iOriginalValue;
}
public abstract boolean filter(T iObject);
public abstract boolean canUseMultiValueDirectly();
public abstract T createGraphElement(Object iObject);
public OIdentifiable getGraphElementRecord(final Object iObject) {
return (OIdentifiable) iObject;
}
@Override
public Iterator<T> iterator() {
reset();
return this;
}
public int size() {
if (size > -1)
return size;
if (iterator instanceof OSizeable)
return ((OSizeable) iterator).size();
return 0;
}
@Override
public void reset() {
if (iterator instanceof OResettable)
// RESET IT FOR MULTIPLE ITERATIONS
((OResettable) iterator).reset();
nextElement = null;
}
@Override
public boolean hasNext() {
if (autoConvertToRecord) {
// ACT ON WRAPPER
while (nextElement == null && iterator.hasNext()) {
nextElement = createGraphElement(iterator.next());
if (nextElement != null && !filter(nextElement))
nextElement = null;
}
return nextElement != null;
}
// ACT ON RECORDS (FASTER & LIGHTER)
while (nextRecord == null && iterator.hasNext()) {
nextRecord = getGraphElementRecord(iterator.next());
}
return nextRecord != null;
}
@Override
public T next() {
if (hasNext())
if (autoConvertToRecord)
// ACT ON WRAPPER
try {
return nextElement;
} finally {
nextElement = null;
}
else
// ACT ON RECORDS (FASTER & LIGHTER)
try {
return (T) nextRecord;
} finally {
nextRecord = null;
}
throw new NoSuchElementException();
}
@Override
public void remove() {
iterator.remove();
}
@Override
public void setAutoConvertToRecord(final boolean convertToRecord) {
autoConvertToRecord = convertToRecord;
if (iterator instanceof OAutoConvertToRecord)
((OAutoConvertToRecord) iterator).setAutoConvertToRecord(autoConvertToRecord);
}
@Override
public boolean isAutoConvertToRecord() {
return autoConvertToRecord;
}
public Object getMultiValue() {
return multiValue;
}
}