AnnotationQuery.java
- /*
- * AnnotationQuery.java
- *
- * Copyright (c) 2007-2011, The University of Sheffield.
- *
- * This file is part of GATE MÃmir (see http://gate.ac.uk/family/mimir.html),
- * and is free software, licenced under the GNU Lesser General Public License,
- * Version 3, June 2007 (also included with this distribution as file
- * LICENCE-LGPL3.html).
- *
- * Valentin Tablan, 4 Mar 2009
- *
- * $Id: AnnotationQuery.java 17236 2014-01-17 15:31:02Z valyt $
- */
- package gate.mimir.search.query;
- import gate.mimir.Constraint;
- import gate.mimir.ConstraintType;
- import gate.mimir.SemanticAnnotationHelper;
- import gate.mimir.search.QueryEngine;
- import gate.mimir.search.terms.AnnotationTermsQuery;
- import gate.mimir.search.terms.TermsResultSet;
- import it.unimi.di.big.mg4j.index.Index;
- import it.unimi.di.big.mg4j.search.visitor.DocumentIteratorVisitor;
- import it.unimi.dsi.fastutil.objects.ReferenceSet;
- import it.unimi.dsi.fastutil.objects.ReferenceSets;
- import java.io.IOException;
- import java.util.ArrayList;
- import java.util.HashMap;
- import java.util.List;
- import java.util.Map;
- import org.slf4j.Logger;
- import org.slf4j.LoggerFactory;
- /**
- * A query for the annotations index.
- */
- public class AnnotationQuery implements QueryNode {
- private static final long serialVersionUID = 5996543707885867821L;
- public static class AnnotationQueryExecutor extends AbstractQueryExecutor{
-
- /**
- * @param engine
- * @param query
- */
- public AnnotationQueryExecutor(AnnotationQuery query, QueryEngine engine) throws IOException {
- super(engine, query);
- this.query = query;
- buildQuery();
- }
-
- /**
- * The query being executed.
- */
- private AnnotationQuery query;
-
- /**
- * Logger for this class.
- */
- private static Logger logger = LoggerFactory.getLogger(AnnotationQueryExecutor.class);
- /**
- * The underlying OrQuery executor that actually does the work.
- */
- private QueryExecutor underlyingExecutor;
-
- private transient boolean isInDocumentMode;
-
- /**
- * Build the underlying OrQuery executor that this annotation query uses.
- */
- protected void buildQuery() throws IOException {
- SemanticAnnotationHelper helper = engine.getAnnotationHelper(query);
- isInDocumentMode = (helper.getMode() ==
- SemanticAnnotationHelper.Mode.DOCUMENT);
- // get the mention URIs
- TermsResultSet trs = new AnnotationTermsQuery(query).execute(engine);
- if(trs.termStrings != null && trs.termStrings.length > 0 &&
- trs.termLengths != null) {
- QueryNode[] disjuncts = new QueryNode[trs.termStrings.length];
- for(int index = 0; index < trs.termStrings.length; index++) {
- // create a term query for the mention URI
- disjuncts[index] = new TermQuery(query.annotationType,
- trs.termStrings[index], trs.termLengths[index]);
- }
- QueryNode underlyingQuery = new OrQuery(disjuncts);
- underlyingExecutor = underlyingQuery.getQueryExecutor(engine);
- } else {
- // no results from the helper => no results from us
- latestDocument = -1;
- }
- }
-
-
- /* (non-Javadoc)
- * @see gate.mimir.search.query.QueryExecutor#close()
- */
- public void close() throws IOException {
- if(closed) return;
- super.close();
- if(underlyingExecutor != null) underlyingExecutor.close();
- }
- /* (non-Javadoc)
- * @see gate.mimir.search.query.QueryExecutor#getLatestDocument()
- */
- public long getLatestDocument() {
- if(closed || latestDocument == -1) return -1;
- return underlyingExecutor.getLatestDocument();
- }
- /* (non-Javadoc)
- * @see gate.mimir.search.query.QueryExecutor#nextDocument(int)
- */
- public long nextDocument(long greaterThan) throws IOException {
- if(closed || latestDocument == -1) return -1;
- return latestDocument = underlyingExecutor.nextDocument(greaterThan);
- }
- /* (non-Javadoc)
- * @see gate.mimir.search.query.QueryExecutor#nextHit()
- */
- public Binding nextHit() throws IOException {
- if(closed || latestDocument == -1) return null;
- Binding underlyingHit = underlyingExecutor.nextHit();
- if(underlyingHit == null) return null;
- long doc = underlyingHit.getDocumentId();
- if(isInDocumentMode) {
- return new Binding(query, doc, 0, engine.getIndex().getDocumentSize(doc),
- null);
- } else {
- return new Binding(query, doc,
- underlyingHit.getTermPosition(),
- underlyingHit.getLength(),
- null);
- }
- }
-
- @Override
- public ReferenceSet<Index> indices() {
- if(underlyingExecutor != null) {
- return underlyingExecutor.indices();
- } else {
- return ReferenceSets.EMPTY_SET;
- }
- }
-
- public <T> T accept( final DocumentIteratorVisitor<T> visitor ) throws IOException {
- if(underlyingExecutor == null) return null;
- if ( ! visitor.visitPre( this ) ) return null;
- final T[] a = visitor.newArray( 1 );
- if ( a == null ) {
- if ( underlyingExecutor.accept( visitor ) == null ) return null;
- }
- else {
- if ( ( a[ 0 ] = underlyingExecutor.accept( visitor ) ) == null ) return null;
- }
- return visitor.visitPost( this, a );
- }
- public <T> T acceptOnTruePaths( final DocumentIteratorVisitor<T> visitor ) throws IOException {
- if(underlyingExecutor == null) return null;
- if ( ! visitor.visitPre( this ) ) return null;
- final T[] a = visitor.newArray( 1 );
- if ( a == null ) {
- if ( underlyingExecutor.acceptOnTruePaths( visitor ) == null ) return null;
- }
- else {
- if ( ( a[ 0 ] = underlyingExecutor.acceptOnTruePaths( visitor ) ) == null ) return null;
- }
- return visitor.visitPost( this, a );
- }
- }
-
- /**
- * Constructs a new {@link AnnotationQuery}.
- *
- * Convenience variant of {@link #AnnotationQuery(String, List)}
- * for cases where all predicates are of type
- * {@link SemanticAnnotationHelper.ConstraintType#EQ}.
- *
- * @param annotationType the desired annotation type, for the annotations to
- * be matched.
- * @param featureConstraints the constraints over the features of the
- * annotations to be found. This is represented as a {@link Map} from feature
- * name (a {@link String}) to feature value (also a {@link String}).
- *
- * @see AnnotationQuery#AnnotationQuery(String, List)
- */
- public AnnotationQuery(String annotationType,
- Map<String, String> featureConstraints) {
- if(featureConstraints == null){
- featureConstraints = new HashMap<String, String>();
- }
- this.annotationType = annotationType;
- this.constraints = new ArrayList<Constraint>(featureConstraints.size());
- for(Map.Entry<String, String> entry : featureConstraints.entrySet()){
- this.constraints.add(new Constraint(ConstraintType.EQ,
- entry.getKey(), entry.getValue()));
- }
- }
- /**
- * Constructs a new Annotation Query.
- *
- * @param annotationType the type of annotation being sought.
- * @param constraints a list of constraints placed on the feature values. An
- * empty constraints list will make no requests regarding the feature values,
- * hence it will match all annotations of the right type.
- */
- public AnnotationQuery(String annotationType, List<Constraint> constraints) {
- this.annotationType = annotationType;
- this.constraints = constraints == null ? new ArrayList<Constraint>() :constraints;
- }
-
- /* (non-Javadoc)
- * @see gate.mimir.search.query.QueryNode#getQueryExecutor(java.util.Map)
- */
- public QueryExecutor getQueryExecutor(QueryEngine engine)
- throws IOException {
- return new AnnotationQueryExecutor(this, engine);
- }
-
-
- /**
- * Gets the annotation type for this query.
- * @return the annotationType
- */
- public String getAnnotationType() {
- return annotationType;
- }
- /**
- * Gets the feature constraints, represented as a {@link Map} from
- * feature name (a {@link String}) to feature value (also a {@link String}).
- * @return the featureConstraints
- */
- public List<Constraint> getConstraints() {
- return constraints;
- }
- /**
- * The annotation type for this query.
- */
- private String annotationType;
-
- /**
- * The constrains over the annotation features.
- */
- private List<Constraint> constraints;
-
-
- public String toString() {
- return "Annotation ( type = " +
- annotationType + ", features=" +
- (constraints != null ? constraints.toString() : "[]") +
- ")";
- }
- }