001package org.biojava.bio.annodb;
002
003import java.util.HashSet;
004import java.util.Iterator;
005import java.util.Set;
006
007import org.biojava.bio.Annotation;
008import org.biojava.bio.AnnotationTools;
009import org.biojava.bio.AnnotationType;
010
011/**
012 * An implementation of AnnotationDB that lazily applies a filter.
013 *
014 * @author Matthew Pocock
015 * @since 1.3
016 */
017public class LazyFilteredAnnotationDB
018implements AnnotationDB {
019  private final AnnotationDB source;
020  private final AnnotationType schema;
021  private AnnotationDB result;
022
023  /**
024   * Create a new DB by wrapping another with a schema.
025   *
026   * @param name    the name for the SB
027   * @param source  the underlying DB
028   * @param schema  the schema to apply to the underlying DB to make this one
029   */
030  public LazyFilteredAnnotationDB(String name, AnnotationDB source, AnnotationType schema) {
031    this.source = source;
032    this.schema = schema;
033  }
034  
035  public String getName() {
036    return "";
037  }
038
039  public AnnotationType getSchema() {
040    if(result == null) {
041      return this.schema;
042    } else {
043      return result.getSchema();
044    }
045  }
046  
047  public Iterator iterator() {
048    if(result == null) {
049      populate();
050    }
051    
052    return result.iterator();
053  }
054  
055  public int size() {
056    if(result == null) {
057      populate();
058    }
059    
060    return result.size();
061  }
062  
063  public AnnotationDB filter(AnnotationType at) {
064    if(result == null) {
065      return new LazyFilteredAnnotationDB(
066        "",
067        source,
068        AnnotationTools.intersection(schema, at)
069      );
070    } else {
071      return new LazyFilteredAnnotationDB(
072        "",
073        result,
074        at
075      );
076    }
077  }
078  
079  public AnnotationDB search(AnnotationType at) {
080    if(result == null) {
081      return new LazySearchedAnnotationDB(
082        "",
083        this,
084        at
085      );
086    } else {
087      return new LazySearchedAnnotationDB(
088        "",
089        result,
090        at
091      );
092    }
093  }
094  
095  private void populate() {
096    if(result != null) {
097      return;
098    }
099      
100    Set hits = new  HashSet();
101    
102    for(Iterator i = iterator(); i.hasNext(); ) {
103      Annotation ann = (Annotation) i.next();
104      if(schema.instanceOf(ann)) {
105        hits.add(ann);
106      }
107    }
108    
109    if(hits.isEmpty()) {
110      result = AnnotationDB.EMPTY;
111    } else {
112      result = new SimpleAnnotationDB("", hits, schema);
113    }
114  }
115}