package com.googlecode.gaal.analysis.impl;
import java.util.Iterator;
import com.googlecode.gaal.analysis.api.Context;
import com.googlecode.gaal.analysis.api.Filter;
import com.googlecode.gaal.analysis.api.IntervalSetBuilder;
import com.googlecode.gaal.data.api.IntSequence;
import com.googlecode.gaal.data.api.IntervalSet;
import com.googlecode.gaal.data.api.Multiset;
import com.googlecode.gaal.data.api.SymbolTable;
import com.googlecode.gaal.suffix.api.EmbeddedSuffixTree;
import com.googlecode.gaal.suffix.api.EmbeddedSuffixTree.EmbeddedInterval;
import com.googlecode.gaal.suffix.api.IntervalTree.Interval;
import com.googlecode.gaal.suffix.api.SuffixArray;
import com.googlecode.gaal.suffix.impl.EmbeddedSuffixTreeImpl;
public class EmbeddedIntervalExtractor {
private final SuffixArray sa;
private final SymbolTable<?> symbolTable;
private final IntervalSetBuilder intervalSetBuilder;
private final Filter<EmbeddedInterval> contextFilter;
private final int windowSize;
public EmbeddedIntervalExtractor(SuffixArray sa, SymbolTable<?> symbolTable, IntervalSetBuilder intervalSetBuilder,
Filter<EmbeddedInterval> contextFilter, int windowSize) {
this.sa = sa;
this.symbolTable = symbolTable;
this.intervalSetBuilder = intervalSetBuilder;
this.contextFilter = contextFilter;
this.windowSize = windowSize;
}
public Iterator<EmbeddedInterval> iterator(Interval interval) {
return new EmbeddedIntervalIterator(interval);
}
private class EmbeddedIntervalIterator implements Iterator<EmbeddedInterval> {
private Iterator<EmbeddedInterval> embeddedIterator;
private EmbeddedInterval next;
private EmbeddedIntervalIterator(Interval interval) {
EmbeddedSuffixTree est = EmbeddedSuffixTreeImpl.create(sa, interval, windowSize, symbolTable);
if (est != null) {
IntervalSet<EmbeddedInterval> embeddedIntervalSet = intervalSetBuilder.buildIntervalSet(est);
embeddedIterator = embeddedIntervalSet.iterator();
next = advance();
}
}
@Override
public boolean hasNext() {
return next != null;
}
@Override
public EmbeddedInterval next() {
EmbeddedInterval context = next;
next = advance();
return context;
}
private EmbeddedInterval advance() {
while (embeddedIterator.hasNext()) {
EmbeddedInterval next = embeddedIterator.next();
if (contextFilter == null || contextFilter.passed(next)) {
return next;
}
}
return null;
}
@Override
public void remove() {
throw new UnsupportedOperationException();
}
};
public static class EmbeddedContext implements Context {
private final EmbeddedInterval embeddedInterval;
protected EmbeddedContext(EmbeddedInterval embeddedInterval) {
this.embeddedInterval = embeddedInterval;
}
@Override
public IntSequence leftSequence() {
return embeddedInterval.getEmbeddingInterval().label();
}
@Override
public IntSequence rightSequence() {
return embeddedInterval.label();
}
@Override
public Multiset<IntSequence> fillerSet() {
return embeddedInterval.fillerSet();
}
@Override
public int fillerSetSize() {
return embeddedInterval.size();
}
}
}