/*
* Copyright (c) 2013 Data Harmonisation Panel
*
* All rights reserved. This program and the accompanying materials are made
* available under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation, either version 3 of the License,
* or (at your option) any later version.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this distribution. If not, see <http://www.gnu.org/licenses/>.
*
* Contributors:
* Data Harmonisation Panel <http://www.dhpanel.eu>
*/
package eu.esdihumboldt.hale.common.instance.model.ext.helper;
import eu.esdihumboldt.hale.common.instance.model.Instance;
import eu.esdihumboldt.hale.common.instance.model.ResourceIterator;
import eu.esdihumboldt.hale.common.instance.model.ext.InstanceIterator;
import eu.esdihumboldt.hale.common.schema.model.TypeDefinition;
/**
* Adds full instance iterator support to an existing instance resource
* iterator.
*
* @author Simon Templer
*/
public class FullInstanceIteratorSupport extends InstanceIteratorDecorator {
/**
* Stores the next instance of type peek is not supported in the decoratee.
*/
private Instance peekInstance;
/**
* Add full instance iterator support to a given instance resource iterator,
* even if it does not implement {@link InstanceIterator}.
*
* @param decoratee the decoratee
*/
public FullInstanceIteratorSupport(ResourceIterator<Instance> decoratee) {
super(decoratee);
}
@Override
public boolean hasNext() {
proceedToNext();
if (super.supportsTypePeek()) {
/*
* Type peek supported - hasNext is equivalent to decoratee
*/
return super.hasNext();
}
else {
/*
* No type peek supported - has next if valid candidate was found
*/
return peekInstance != null;
}
}
@Override
public TypeDefinition typePeek() {
proceedToNext();
if (super.supportsTypePeek()) {
/*
* Type peek supported - typePeek is equivalent to decoratee
*/
return super.typePeek();
}
else {
/*
* No type peek supported - has next if valid candidate was found
*/
if (peekInstance != null) {
return peekInstance.getDefinition();
}
else {
return null;
}
}
}
@Override
public void skip() {
if (super.supportsTypePeek()) {
super.skip();
}
else {
doNext();
}
}
private void proceedToNext() {
if (super.supportsTypePeek()) {
// do nothing, peek support already there
}
else {
/*
* No type peek supported - need to peek at instance
*/
if (peekInstance == null) {
if (super.hasNext()) {
peekInstance = super.next();
}
}
}
}
private Instance doNext() {
proceedToNext();
if (super.supportsTypePeek()) {
/*
* Type peek supported - next is equivalent to decoratee
*/
return super.next();
}
else {
/*
* No type peek supported - next is cached next instance
*/
Instance next = peekInstance;
peekInstance = null;
return next;
}
}
@Override
public Instance next() {
return doNext();
}
@Override
public boolean supportsTypePeek() {
return true;
}
}