Added javadoc comments
diff --git a/src/main/java/de/ids_mannheim/korap/query/SpanAttributeQuery.java b/src/main/java/de/ids_mannheim/korap/query/SpanAttributeQuery.java
index bf7ce85..49e3cb6 100644
--- a/src/main/java/de/ids_mannheim/korap/query/SpanAttributeQuery.java
+++ b/src/main/java/de/ids_mannheim/korap/query/SpanAttributeQuery.java
@@ -14,17 +14,17 @@
import de.ids_mannheim.korap.query.spans.AttributeSpans;
/**
- * SpanAttributeQuery retrieves attribute spans, that are tokens annotated with
- * prefix @, for example {@literal @}:class=header. SpanAttributeQueries are
- * commonly used to search for elements or relations having some specific
- * attribute(s).
+ * SpanAttributeQuery retrieves {@link AttributeSpans}, that are tokens
+ * annotated with prefix @, for example {@literal @}:class=header.
+ * SpanAttributeQueries are commonly used to search for elements or relations
+ * having some specific attribute(s).
*
* Example: <br/>
* <br/>
*
* <pre>
* SpanAttributeQuery saq = new SpanAttributeQuery(new SpanTermQuery(new Term(
- * "base", "@:class=title")), true);
+ * "tokens", "@:class=title")), true);
* </pre>
*
* Negation enables searching for elements <em>without</em> some attribute(s).
@@ -32,7 +32,7 @@
*
* <pre>
* SpanAttributeQuery saq = new SpanAttributeQuery(new SpanTermQuery(new Term(
- * "base", "@:class=title")), true, true);
+ * "token", "@:class=title")), true, true);
* </pre>
*
* @author margaretha
diff --git a/src/main/java/de/ids_mannheim/korap/query/spans/AttributeSpans.java b/src/main/java/de/ids_mannheim/korap/query/spans/AttributeSpans.java
index 74aafc7..abf00a4 100644
--- a/src/main/java/de/ids_mannheim/korap/query/spans/AttributeSpans.java
+++ b/src/main/java/de/ids_mannheim/korap/query/spans/AttributeSpans.java
@@ -16,188 +16,266 @@
import org.slf4j.LoggerFactory;
import de.ids_mannheim.korap.query.SpanAttributeQuery;
+import org.apache.lucene.search.spans.TermSpans;
-/** Span enumeration of attributes which are treated as a normal term with
- * special payload assignment referring to to which element it belongs.
- * The class is basically a wrapper of the TermSpan with additional
- * functionality regarding element reference. Element reference is
- * annotated ascendingly starting from the left side.
+/**
+ * Span enumeration of attributes which are term spans with special payload
+ * assignment referring to another span (e.g. element/relation span) to which an
+ * attribute span belongs.
*
- * The enumeration is ordered firstly by the start position of the attribute
- * and secondly by the element reference descendingly with respect to the
- * nature of the order of the element enumeration.
- *
- * @author margaretha
+ * The class is basically a wrapper of Lucene {@link TermSpans} with additional
+ * functionality regarding element/relation reference. Element/relation id is
+ * annotated ascendingly starting from the left side.
+ *
+ * The enumeration is ordered firstly by the start position of the attribute and
+ * secondly by the element/relation id descendingly. This order helps to match
+ * element and attributes faster.
+ *
+ * @author margaretha
* */
-public class AttributeSpans extends SimpleSpans{
-
- private List<CandidateAttributeSpan> candidateList;
- private int currentDoc, currentPosition;
- private short spanId;
- private boolean isFinish;
- private int elementEnd;
-
- protected Logger logger = LoggerFactory.getLogger(AttributeSpans.class);
+public class AttributeSpans extends SimpleSpans {
- public AttributeSpans(SpanAttributeQuery simpleSpanQuery,
- AtomicReaderContext context, Bits acceptDocs,
- Map<Term, TermContext> termContexts) throws IOException {
- super(simpleSpanQuery, context, acceptDocs, termContexts);
- candidateList = new ArrayList<>();
- hasMoreSpans = firstSpans.next();
- if (hasMoreSpans) {
- currentDoc = firstSpans.doc();
- currentPosition = firstSpans.start();
- }
- }
+ private List<CandidateAttributeSpan> candidateList;
+ private int currentDoc, currentPosition;
+ private short spanId;
+ private boolean isFinish;
+ private int elementEnd;
- @Override
- public boolean next() throws IOException {
- isStartEnumeration=false;
- matchPayload.clear();
- return advance();
- }
+ protected Logger logger = LoggerFactory.getLogger(AttributeSpans.class);
+ /**
+ * Constructs Attributespans based on the specified SpanAttributeQuery.
+ *
+ * @param spanAttributeQuery a spanAttributeQuery
+ * @param context
+ * @param acceptDocs
+ * @param termContexts
+ * @throws IOException
+ */
+ public AttributeSpans(SpanAttributeQuery spanAttributeQuery,
+ AtomicReaderContext context, Bits acceptDocs,
+ Map<Term, TermContext> termContexts) throws IOException {
+ super(spanAttributeQuery, context, acceptDocs, termContexts);
+ candidateList = new ArrayList<>();
+ hasMoreSpans = firstSpans.next();
+ if (hasMoreSpans) {
+ currentDoc = firstSpans.doc();
+ currentPosition = firstSpans.start();
+ }
+ }
- /** Get the next match by first checking the candidate match list
- * and setting the list when it is empty.
- * */
- private boolean advance() throws IOException {
- while(hasMoreSpans || !candidateList.isEmpty()){
- if (!candidateList.isEmpty()){
- // set AttributeSpan from
- CandidateAttributeSpan cs = candidateList.get(0);
- this.matchDocNumber = cs.getDoc();
- this.matchStartPosition = cs.getStart();
- this.matchEndPosition = cs.getEnd();
- this.setSpanId(cs.getSpanId());
- this.setElementEnd(cs.getElementEnd());
- candidateList.remove(0);
- return true;
- }
- else{
- //logger.info("Setting candidate list");
- setCandidateList();
-// for (CandidateAttributeSpan cs: candidateList){
-// logger.info("cs ref "+cs.getElementRef());
-// }
- currentDoc = firstSpans.doc();
- currentPosition = firstSpans.start();
- }
- }
- return false;
- }
-
- /** Collects all the attributes in the same start position and sort
- * them by elementRef in reverse order (the ones with the bigger
- * elementRef first).
- * */
- private void setCandidateList() throws IOException {
-
- while (hasMoreSpans && firstSpans.doc() == currentDoc &&
- firstSpans.start() == currentPosition){
-
- candidateList.add(createCandidateSpan(firstSpans));
- hasMoreSpans = firstSpans.next();
- }
-
- Collections.sort(candidateList);
- Collections.reverse(candidateList);
- }
-
- private CandidateAttributeSpan createCandidateSpan(Spans firstSpans) throws IOException {
- List<byte[]> payload = (List<byte[]>) firstSpans.getPayload();
- ByteBuffer wrapper = ByteBuffer.wrap(payload.get(0));
-
- short spanId = wrapper.getShort(0);
- int elementEnd = -1;
- if (payload.get(0).length == 6){
- elementEnd = wrapper.getInt(2);
- }
- return new CandidateAttributeSpan(firstSpans,spanId, elementEnd);
- }
-
- public short getSpanId(){
- return this.spanId;
- }
+ @Override
+ public boolean next() throws IOException {
+ isStartEnumeration = false;
+ matchPayload.clear();
+ return advance();
+ }
- public void setSpanId(short spanId) {
- this.spanId = spanId;
- }
+ /**
+ * Moves to the next match by checking the candidate match list or setting
+ * the list first when it is empty.
+ *
+ * @return true if a match is found
+ * @throws IOException
+ */
+ private boolean advance() throws IOException {
+ while (hasMoreSpans || !candidateList.isEmpty()) {
+ if (!candidateList.isEmpty()) {
+ // set the current match from the first CandidateAttributeSpan
+ // in the candidate list
+ CandidateAttributeSpan cs = candidateList.get(0);
+ this.matchDocNumber = cs.getDoc();
+ this.matchStartPosition = cs.getStart();
+ this.matchEndPosition = cs.getEnd();
+ this.setSpanId(cs.getSpanId());
+ this.setElementEnd(cs.getElementEnd());
+ candidateList.remove(0);
+ return true;
+ } else {
+ setCandidateList();
+ currentDoc = firstSpans.doc();
+ currentPosition = firstSpans.start();
+ }
+ }
+ return false;
+ }
- public int getElementEnd() {
- return elementEnd;
- }
+ /**
+ * Collects all the attributes in the same start position and sort them by
+ * element/relation Id in a reverse order (the ones with the bigger
+ * element/relation Id first).
+ *
+ * @throws IOException
+ */
+ private void setCandidateList() throws IOException {
- public void setElementEnd(int elementEnd) {
- this.elementEnd = elementEnd;
- }
+ while (hasMoreSpans && firstSpans.doc() == currentDoc
+ && firstSpans.start() == currentPosition) {
- public boolean isFinish() {
- return isFinish;
- }
+ candidateList.add(createCandidateSpan());
+ hasMoreSpans = firstSpans.next();
+ }
- public void setFinish(boolean isFinish) {
- this.isFinish = isFinish;
- }
+ Collections.sort(candidateList);
+ Collections.reverse(candidateList);
+ }
- @Override
- public boolean skipTo(int target) throws IOException {
- if (hasMoreSpans && (firstSpans.doc() < target)){
- if (!firstSpans.skipTo(target)){
- candidateList.clear();
- return false;
- }
- }
- setCandidateList();
- matchPayload.clear();
- isStartEnumeration=false;
- return advance();
- }
+ /**
+ * Creates a CandidateAttributeSpan based on the child span and set the
+ * spanId and elementEnd from its payloads.
+ *
+ * @param firstSpans an AttributeSpans
+ * @return a CandidateAttributeSpan
+ * @throws IOException
+ */
+ private CandidateAttributeSpan createCandidateSpan() throws IOException {
+ List<byte[]> payload = (List<byte[]>) firstSpans.getPayload();
+ ByteBuffer wrapper = ByteBuffer.wrap(payload.get(0));
- @Override
- public long cost() {
- return firstSpans.cost();
- }
-
- /** Match candidate for attribute spans.
- * */
- class CandidateAttributeSpan extends CandidateSpans
- implements Comparable<CandidateSpans>{
+ short spanId = wrapper.getShort(0);
+ int elementEnd = -1;
+ if (payload.get(0).length == 6) {
+ elementEnd = wrapper.getInt(2);
+ }
+ return new CandidateAttributeSpan(firstSpans, spanId, elementEnd);
+ }
- private short spanId;
- private int elementEnd;
-
- public CandidateAttributeSpan(Spans span, short spanId, int elementEnd)
- throws IOException {
- super(span);
- setSpanId(spanId);
- setElementEnd(elementEnd);
- }
-
- public void setSpanId(short spanId) {
- this.spanId = spanId;
- }
- public short getSpanId() {
- return spanId;
- }
+ /**
+ * Return the span id to which an attribute span belongs, for instance a
+ * relation id or an element id.
+ *
+ * @return a span id, for instance a relation id or an element id
+ */
+ public short getSpanId() {
+ return this.spanId;
+ }
- public int getElementEnd() {
- return elementEnd;
- }
+ /**
+ * Sets the span id to which an attribute span belongs, for instance a
+ * relation id or an element id.
+ *
+ * @param spanId the span id to which an attribute span belongs, for
+ * instance a relation id or an element id.
+ */
+ public void setSpanId(short spanId) {
+ this.spanId = spanId;
+ }
- public void setElementEnd(int elementEnd) {
- this.elementEnd = elementEnd;
- }
+ /**
+ * Returns the end position of the element to which an attribute span
+ * belongs.
+ *
+ * @return an element end position
+ */
+ public int getElementEnd() {
+ return elementEnd;
+ }
- @Override
- public int compareTo(CandidateSpans o) {
- CandidateAttributeSpan cs = (CandidateAttributeSpan) o;
- if (this.spanId == cs.spanId)
- return 0;
- else if (this.spanId > cs.spanId )
- return 1;
- return -1;
- }
- }
+ /**
+ * Sets the end position of the element to which an attribute span belongs.
+ *
+ * @param elementEnd the end position of the element to which an attribute
+ * span belongs.
+ */
+ public void setElementEnd(int elementEnd) {
+ this.elementEnd = elementEnd;
+ }
+
+ /**
+ * Tells if the enumeration of the AttributeSpans has come to an end.
+ *
+ * @return true if the enumeration has finished.
+ */
+ public boolean isFinish() {
+ return isFinish;
+ }
+
+ /**
+ * Sets true if the enumeration of the AttributeSpans has come to an end.
+ *
+ * @param isFinish <code>true</code> if the enumeration of the
+ * AttributeSpans has come to an end, <code>false</code> otherwise.
+ */
+ public void setFinish(boolean isFinish) {
+ this.isFinish = isFinish;
+ }
+
+ @Override
+ public boolean skipTo(int target) throws IOException {
+ if (hasMoreSpans && (firstSpans.doc() < target)) {
+ if (!firstSpans.skipTo(target)) {
+ candidateList.clear();
+ return false;
+ }
+ }
+ setCandidateList();
+ matchPayload.clear();
+ isStartEnumeration = false;
+ return advance();
+ }
+
+ @Override
+ public long cost() {
+ return firstSpans.cost();
+ }
+
+ /**
+ * CandidateAttributeSpan contains information about an Attribute span. All
+ * attribute spans occurring in an identical position are collected as
+ * CandidateAttributeSpans. The list of these CandidateAttributeSpans are
+ * sorted based on the span ids to which the attributes belong to. The
+ * attributes with smaller spanIds come first on the list.
+ *
+ * */
+ class CandidateAttributeSpan extends CandidateSpans implements
+ Comparable<CandidateSpans> {
+
+ private short spanId;
+ private int elementEnd;
+
+ /**
+ * Construct a CandidateAttributeSpan based on the given span, spanId,
+ * and elementEnd.
+ *
+ * @param span an AttributeSpans
+ * @param spanId the element or relation span id to which the current
+ * state of the specified AttributeSpans belongs to.
+ * @param elementEnd the end position of the element or relation span to
+ * which the current state of the specified AttributeSpans
+ * belongs to.
+ * @throws IOException
+ */
+ public CandidateAttributeSpan(Spans span, short spanId, int elementEnd)
+ throws IOException {
+ super(span);
+ setSpanId(spanId);
+ setElementEnd(elementEnd);
+ }
+
+ public void setSpanId(short spanId) {
+ this.spanId = spanId;
+ }
+
+ public short getSpanId() {
+ return spanId;
+ }
+
+ public int getElementEnd() {
+ return elementEnd;
+ }
+
+ public void setElementEnd(int elementEnd) {
+ this.elementEnd = elementEnd;
+ }
+
+ @Override
+ public int compareTo(CandidateSpans o) {
+ CandidateAttributeSpan cs = (CandidateAttributeSpan) o;
+ if (this.spanId == cs.spanId)
+ return 0;
+ else if (this.spanId > cs.spanId)
+ return 1;
+ return -1;
+ }
+ }
}