/** * 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.Date; import java.util.NoSuchElementException; import org.whole.lang.bindings.IBindingManager; import org.whole.lang.matchers.GenericMatcherFactory; import org.whole.lang.matchers.Matcher; import org.whole.lang.model.EnumValue; import org.whole.lang.model.IEntity; import org.whole.lang.reflect.DataKinds; import org.whole.lang.reflect.EntityDescriptor; import org.whole.lang.reflect.EntityKinds; import org.whole.lang.util.DataTypeUtils; import org.whole.lang.util.EntityUtils; import org.whole.lang.visitors.IVisitor; /** * @author Riccardo Solmi */ public class ScannerIterator<E extends IEntity> extends AbstractPatternFilterIterator<E> { protected ScannerIterator(IEntityIterator<E> iterator) { super(iterator); } protected IVisitor defaultPattern() { return GenericMatcherFactory.instance.isResolverMatcher(); } 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; } public boolean hasNext(EntityDescriptor<?> descriptor) { return hasNext() && lookahead().wGetEntityDescriptor().equals(descriptor); } @SuppressWarnings("unchecked") public <T extends IEntity> T next(EntityDescriptor<T> descriptor) { IEntity entity = next(); if (!Matcher.isAssignableAsIsFrom(descriptor, entity)) throw new NoSuchElementException(descriptor.toString()); return (T) entity; } public boolean hasNext(EntityKinds kind) { return hasNext() && lookahead().wGetEntityKind().equals(kind); } public IEntity next(EntityKinds kind) { IEntity entity = next(); if (!Matcher.match(kind, entity)) throw new NoSuchElementException(kind.toString()); return entity; } public boolean hasNext(IEntity pattern) { return hasNext() && Matcher.match(pattern, lookahead()); } public <T extends IEntity> T next(T pattern) { return next(pattern, getBindings()); //FIXME previous bindings interference } @SuppressWarnings("unchecked") public <T extends IEntity> T next(T pattern, IBindingManager bindings) { IEntity entity = next(); if (!Matcher.match(pattern, entity, bindings)) throw new NoSuchElementException(pattern.toString()); return (T) entity; } public boolean hasNext(IVisitor matcherVisitor) { return hasNext() && Matcher.match(matcherVisitor, lookahead()); } public IEntity next(IVisitor matcherVisitor) { IEntity entity = next(); if (!Matcher.match(matcherVisitor, entity)) throw new NoSuchElementException(); return entity; } private boolean hasNext(DataKinds dataKind) { return hasNext() && dataKind.equals(DataTypeUtils.getDataKind(lookahead())); } public boolean hasNextBoolean() { return hasNext(DataKinds.BOOLEAN); } public boolean nextBoolean() { return next().wBooleanValue(); } public boolean hasNextByte() { return hasNext(DataKinds.BYTE); } public byte nextByte() { return next().wByteValue(); } public boolean hasNextChar() { return hasNext(DataKinds.CHAR); } public char nextChar() { return next().wCharValue(); } public boolean hasNextDouble() { return hasNext(DataKinds.DOUBLE); } public double nextDouble() { return next().wDoubleValue(); } public boolean hasNextFloat() { return hasNext(DataKinds.FLOAT); } public float nextFloat() { return next().wFloatValue(); } public boolean hasNextInt() { return hasNext(DataKinds.INT); } public int nextInt() { return next().wIntValue(); } public boolean hasNextLong() { return hasNext(DataKinds.LONG); } public long nextLong() { return next().wLongValue(); } public boolean hasNextShort() { return hasNext(DataKinds.SHORT); } public short nextShort() { return next().wShortValue(); } public boolean hasNextString() { return hasNext(DataKinds.STRING); } public String nextString() { return next().wStringValue(); } public boolean hasNextDate() { return hasNext(DataKinds.DATE); } public Date nextDate() { return next().wDateValue(); } public boolean hasNextEnumValue() { return hasNext(DataKinds.ENUM_VALUE); } public EnumValue nextEnumValue() { return next().wEnumValue(); } public boolean hasNextValue() { return hasNext() && EntityUtils.isData(lookahead()); } public Object nextValue() { return next().wGetValue(); } public boolean skipTo(EntityDescriptor<?> descriptor) { boolean found = false; while (hasNext() && !(found = Matcher.isAssignableAsIsFrom(descriptor, lookahead()))) next(); return found; } public boolean skipTo(EntityKinds kind) { boolean found = false; while (hasNext() && !(found = Matcher.match(kind, lookahead()))) 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 (hasNext() && !(found = (entity == lookahead()))) next(); return found; } public boolean skipTo(IEntity pattern, IBindingManager bindings) { boolean found = false; while (hasNext() && !(found = Matcher.match(pattern, lookahead(), bindings))) next(); return found; } public boolean skipTo(IVisitor matcherVisitor) { boolean found = false; while (hasNext() && !(found = Matcher.match(matcherVisitor, lookahead()))) next(); return found; } @Override public void toString(StringBuilder sb) { sb.append("scanner("); sb.append(iterator.toString()); sb.append(", "); sb.append(pattern().toString()); sb.append(")"); } }