/*
* Copyright 2013 SFB 632.
*
* 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.
*/
package annis.sqlgen;
import annis.dao.objects.AnnotatedMatch;
import annis.dao.objects.AnnotatedSpan;
import annis.model.Annotation;
import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import org.springframework.jdbc.core.RowMapper;
/**
* Implements an {@link Iterator} for a {@link AnnotatedMatch} from
* a JDBC {@link ResultSet}.
* @author Thomas Krause <krauseto@hu-berlin.de>
*/
public class AnnotatedMatchIterator implements Iterator<AnnotatedMatch>
{
private ResultSetTypedIterator<AnnotatedSpan> itSpan;
private AnnotatedSpan lastSpan;
public AnnotatedMatchIterator(ResultSet rs, RowMapper<AnnotatedSpan> mapper)
{
this.itSpan = new ResultSetTypedIterator<>(rs, mapper);
this.lastSpan = null;
}
/**
* Returns to the beginning of the iteration.
*/
public void reset()
{
lastSpan = null;
itSpan.reset();
}
@Override
public boolean hasNext()
{
return lastSpan != null || itSpan.hasNext();
}
@Override
public AnnotatedMatch next()
{
List<Long> key = new ArrayList<>();
AnnotatedSpan[] matchedSpans = new AnnotatedSpan[0];
if(lastSpan != null)
{
key = lastSpan.getKey();
matchedSpans = new AnnotatedSpan[key.size()];
setSpanForAllMatchedPositions(key, matchedSpans, lastSpan);
lastSpan = null;
}
while(itSpan.hasNext())
{
AnnotatedSpan span = itSpan.next();
List<Long> newKey = span.getKey();
if(matchedSpans.length == 0)
{
matchedSpans = new AnnotatedSpan[newKey.size()];
}
if(key.isEmpty() || newKey.equals(key))
{
setSpanForAllMatchedPositions(newKey, matchedSpans, span);
key = newKey;
lastSpan = null;
}
else
{
// save reference to the already fetched span since we can't get back
lastSpan = span;
// we finished collecting all relevant spans
break;
}
}
// HACK: delete metadata spans for non-first nodes
for(int i=1; i < matchedSpans.length; i++)
{
matchedSpans[i].setMetadata(new LinkedList<Annotation>());
}
return new AnnotatedMatch(matchedSpans);
}
@Override
public void remove()
{
throw new UnsupportedOperationException("Not supported yet.");
}
private void setSpanForAllMatchedPositions(List<Long> key,
AnnotatedSpan[] matchedSpans, AnnotatedSpan span)
{
// set annotation spans for *all* positions of the id
// (node could have matched several times)
int i=0;
for(long l : key)
{
if(l == span.getId())
{
matchedSpans[i] = new AnnotatedSpan(span);
}
i++;
}
}
}