/**
* Copyright 2004-2016 Riccardo Solmi. All rights reserved.
* This file is part of the Whole Platform.
*
* The Whole Platform is free software: you can redistribute it and/or modify
* it 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.
*
* The Whole Platform is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with the Whole Platform. If not, see <http://www.gnu.org/licenses/>.
*/
package org.whole.lang.iterators;
import java.util.NoSuchElementException;
import org.whole.lang.bindings.IBindingManager;
import org.whole.lang.matchers.Matcher;
import org.whole.lang.model.IEntity;
import org.whole.lang.reflect.EntityDescriptor;
import org.whole.lang.reflect.EntityKinds;
import org.whole.lang.visitors.GenericTraversalFactory;
import org.whole.lang.visitors.IVisitor;
/**
* @author Riccardo Solmi
*/
public class MatcherIterator<E extends IEntity> extends AbstractPatternFilterIterator<E> {
protected MatcherIterator(IEntityIterator<E> iterator) {
super(iterator);
}
protected IVisitor defaultPattern() {
return GenericTraversalFactory.instance.identity();
}
protected E patternFilteredLookahead() {
boolean found = false;
E lookahead = null;
while (iterator.hasNext() && !(found = Matcher.match(pattern(), lookahead = iterator.lookahead()))) {
lookaheadScope().wClear();
iterator.next();
}
if (!found)
lookahead = null;
return lookahead;
}
@SuppressWarnings("unchecked")
public <T extends IEntity> T next(EntityDescriptor<T> descriptor) {
IEntity entity = iterator.next();
if (!Matcher.isAssignableAsIsFrom(descriptor, entity))
throw new NoSuchElementException(descriptor.toString());
return (T) entity;
}
public boolean skipTo(EntityDescriptor<?> descriptor) {
boolean found = false;
while (iterator.hasNext() && !(found = Matcher.isAssignableAsIsFrom(descriptor, iterator.lookahead())))
iterator.next();
return found;
}
public boolean skipTo(EntityKinds kind) {
boolean found = false;
while (iterator.hasNext() && !(found = Matcher.match(kind, iterator.lookahead())))
iterator.next();
return found;
}
public boolean skipTo(IEntity pattern) {
return skipTo(pattern, getBindings()); //FIXME previous bindings interference
}
public boolean skipToSame(IEntity entity) {
boolean found = false;
while (iterator.hasNext() && !(found = (entity == iterator.lookahead())))
iterator.next();
return found;
}
public boolean skipTo(IEntity pattern, IBindingManager bindings) {
boolean found = false;
while (iterator.hasNext() && !(found = Matcher.match(pattern, iterator.lookahead(), bindings)))
iterator.next();
return found;
}
public boolean skipTo(IVisitor matcherVisitor) {
boolean found = false;
while (iterator.hasNext() && !(found = Matcher.match(matcherVisitor, iterator.lookahead())))
iterator.next();
return found;
}
@Override
public void toString(StringBuilder sb) {
sb.append(iterator.toString());
sb.append("[");
sb.append(pattern().toString());
sb.append("]");
}
}