All Downloads are FREE. Search and download functionalities are using the official Maven repository.

gate.composite.impl.CompositeDocumentImpl Maven / Gradle / Ivy

There is a newer version: 8.6.1
Show newest version
package gate.composite.impl;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import gate.Annotation;
import gate.AnnotationSet;
import gate.Document;
import gate.Factory;
import gate.FeatureMap;
import gate.Resource;
import gate.composite.CombiningMethod;
import gate.composite.CompositeDocument;
import gate.composite.OffsetDetails;
import gate.compound.CompoundDocument;
import gate.corpora.DocumentImpl;
import gate.creole.ResourceInstantiationException;
import gate.event.AnnotationEvent;
import gate.event.AnnotationListener;
import gate.event.AnnotationSetEvent;
import gate.event.AnnotationSetListener;
import gate.event.DocumentEvent;
import gate.event.DocumentListener;
import gate.event.FeatureMapListener;
import gate.util.GateRuntimeException;
import gate.util.InvalidOffsetException;

/**
 * Implementation of the Composite Document.
 * 
 * @author niraj
 */
public class CompositeDocumentImpl extends DocumentImpl implements
                                                       CompositeDocument,
                                                       AnnotationSetListener,
                                                       DocumentListener,
                                                       AnnotationListener,
                                                       FeatureMapListener {

  private static final long serialVersionUID = -1379936764549428131L;

  /**
   * CombiningMethod that was used for creating this document.
   */
  protected CombiningMethod combiningMethod;

  /**
   * A Map that contains offet mappings. This is used for copying and removing
   * annotations to the respective documents.
   */
  protected HashMap> offsetMappings;

  /**
   * Set of ids of combined documents.
   */
  protected Set combinedDocumentIds;

  /**
   * The compound document which the current composite document belongs to.
   */
  protected CompoundDocument compoundDocument;

  /**
   * When a new annotation is added to the composite document, this parameter
   * tells whether the annotation copying and deletion to their respective
   * documents should be carried out or not.
   */
  protected boolean disableListener = false;

  // init method
  public Resource init() throws ResourceInstantiationException {
    super.init();
    this.getAnnotations().addAnnotationSetListener(this);
    Map namedAnnotationSets = this.getNamedAnnotationSets();
    if(namedAnnotationSets != null) {
      Set annotNames = namedAnnotationSets.keySet();
      if(annotNames != null && !annotNames.isEmpty()) {
        Iterator iter = annotNames.iterator();
        while(iter.hasNext()) {
          String asName = iter.next();
          this.getAnnotations(asName).addAnnotationSetListener(this);
        }
      }
    }
    this.addDocumentListener(this);
    this.getFeatures().addFeatureMapListener(this);
    return this;
  }

  /**
   * Gets the combing method used for creating the composite document.
   */
  public CombiningMethod getCombiningMethod() {
    return combiningMethod;
  }

  /**
   * Sets the combining method to be used for creating the composite document.
   */
  public void setCombiningMethod(CombiningMethod combiningMethod) {
    this.combiningMethod = combiningMethod;
  }

  /**
   * Annotation added event
   */
  public void annotationAdded(AnnotationSetEvent ase) {

    if(!disableListener && ase.getSourceDocument() == this) {
      AnnotationSet as = (AnnotationSet)ase.getSource();
      Annotation annot = ase.getAnnotation();
      annot.addAnnotationListener(this);

      FeatureMap features = Factory.newFeatureMap();
      features.putAll(annot.getFeatures());

      boolean defaultAS = as.getName() == null;
      for(String docID : combinedDocumentIds) {
        Document aDoc = compoundDocument.getDocument(docID);
        long stOffset =
          getOffsetInSrcDocument(docID, annot.getStartNode().getOffset()
            .longValue());
        if(stOffset == -1) continue;
        long enOffset =
          getOffsetInSrcDocument(docID, annot.getEndNode().getOffset()
            .longValue());
        if(enOffset == -1) continue;
        Annotation originalAnnot = null;
        try {
          Integer id = annot.getId();
          if(defaultAS) {
            
              aDoc.getAnnotations().add(id, new Long(stOffset), new Long(enOffset),
                annot.getType(), features);
            originalAnnot = aDoc.getAnnotations().get(id);
          }
          else {
              aDoc.getAnnotations(as.getName()).add(id,new Long(stOffset),
                new Long(enOffset), annot.getType(), features);
            originalAnnot = aDoc.getAnnotations(as.getName()).get(id);
          }
        }
        catch(InvalidOffsetException ioe) {
          System.out.println(aDoc.getName() + "=" + stOffset + "=" + enOffset);
          throw new GateRuntimeException(ioe);
        }

        OffsetDetails od = new OffsetDetails();
        od.setOldStartOffset(stOffset);
        od.setOldEndOffset(enOffset);
        od.setNewStartOffset(annot.getStartNode().getOffset().longValue());
        od.setNewEndOffset(annot.getEndNode().getOffset().longValue());
        od.setOriginalAnnotation(originalAnnot);
        od.setNewAnnotation(annot);
        addNewOffsetDetails(docID, od);
        break;
      }
    }
  }

  /**
   * Annotation remove event
   */
  public void annotationRemoved(AnnotationSetEvent ase) {
    if(!disableListener && ase.getSourceDocument() == this) {
      AnnotationSet as = (AnnotationSet)ase.getSource();
      Annotation annot = ase.getAnnotation();
      FeatureMap features = Factory.newFeatureMap();
      features.putAll(annot.getFeatures());
      
      

      boolean defaultAS = as.getName() == null;
      for(String docID : combinedDocumentIds) {
        Document aDoc = compoundDocument.getDocument(docID);

        // find out the details which refer to the deleted annotation
        OffsetDetails od = getOffsetDetails(docID, as.getName(), annot);
        if(od == null) continue;

        if(defaultAS) {
          aDoc.getAnnotations().remove(od.getOriginalAnnotation());
        }
        else {
          aDoc.getAnnotations(as.getName()).remove(od.getOriginalAnnotation());
        }
        removeOffsetDetails(docID, od);
        break;
      }
    }
  }

  /**
   * This method returns the respective offset in the source document.
   */
  public long getOffsetInSrcDocument(String srcDocumentID, long offset) {
    List list = offsetMappings.get(srcDocumentID);
    if(list == null) return -1;

    for(int i = 0; i < list.size(); i++) {
      OffsetDetails od = list.get(i);
      if(offset >= od.getNewStartOffset() && offset <= od.getNewEndOffset()) {
        // so = 10 eo = 15
        // offset = 15
        // difference = offset - so = 5
        // oso = 0 oeo = 5 newoffset = oso + diff = 0 + 5 = 5
        long difference = offset - od.getNewStartOffset();
        return od.getOldStartOffset() + difference;
      }
    }
    return -1;
  }

  /**
   * This method returns the respective offset in the source document.
   */
  public OffsetDetails getOffsetDetails(String srcDocumentID, String asName,
    Annotation newAnnot) {
    List list = offsetMappings.get(srcDocumentID);
    if(list == null) return null;

    for(int i = 0; i < list.size(); i++) {
      OffsetDetails od = list.get(i);
      if(od.getNewAnnotation() != null
        && od.getNewAnnotation().equals(newAnnot)) return od;
    }
    return null;
  }

  /**
   * This method returns the respective offset in the source document.
   */
  public OffsetDetails getOffsetDetails(String srcDocumentID, Integer id) {
    List list = offsetMappings.get(srcDocumentID);
    if(list == null) return null;

    for(int i = 0; i < list.size(); i++) {
      OffsetDetails od = list.get(i);
      if(od.getNewAnnotation() != null
        && od.getNewAnnotation().getId().equals(id)) return od;
    }
    return null;
  }

  /**
   * This method returns the respective offset in the source document.
   */
  public void addNewOffsetDetails(String srcDocumentID, OffsetDetails od) {
    List list = offsetMappings.get(srcDocumentID);
    if(list == null) {
      list = new ArrayList();
      offsetMappings.put(srcDocumentID, list);
    }

    list.add(od);
  }

  /**
   * This method returns the respective offset in the source document.
   */
  public void removeOffsetDetails(String srcDocumentID, OffsetDetails od) {
    List list = offsetMappings.get(srcDocumentID);
    if(list != null) list.remove(od);
  }

  /**
   * sets the offset mapping information
   */
  public void setOffsetMappingInformation(
    HashMap> offsetMappings) {
    this.offsetMappings = offsetMappings;
  }

  /**
   * return the IDs of combined documents
   */
  public Set getCombinedDocumentsIds() {
    return this.combinedDocumentIds;
  }

  /**
   * Sets the combined document IDs
   * 
   * @param combinedDocumentIds
   */
  public void setCombinedDocumentsIds(Set combinedDocumentIds) {
    this.combinedDocumentIds = combinedDocumentIds;
  }

  /**
   * This method returns the compoundDocument whose member this composite
   * document is.
   */
  public CompoundDocument getCompoundDocument() {
    return this.compoundDocument;
  }

  /**
   * Sets the compound document.
   * 
   * @param compoundDocument
   */
  public void setCompoundDocument(CompoundDocument compoundDocument) {
    this.compoundDocument = compoundDocument;
  }

  public void annotationSetAdded(DocumentEvent de) {
    Document doc = (Document)de.getSource();
    if(this == doc) {
      doc.getAnnotations(de.getAnnotationSetName()).addAnnotationSetListener(
        this);
    }
  }

  public void annotationSetRemoved(DocumentEvent de) {
    Document doc = (Document)de.getSource();
    if(this == doc) {
      doc.getAnnotations(de.getAnnotationSetName())
        .removeAnnotationSetListener(this);
    }
  }

  public void contentEdited(DocumentEvent de) {
    // do nothing
  }

  public void annotationUpdated(AnnotationEvent e) {
    if(e.getType() == AnnotationEvent.FEATURES_UPDATED) {
      if(!disableListener) {
        Annotation annot = (Annotation)e.getSource();
        // lets find out which annotation set it belongs to
        AnnotationSet as = null;
        if(getAnnotations().contains(annot)) {
          as = getAnnotations();
        }
        else {
          Map ass = getNamedAnnotationSets();
          if(ass == null) return;
          Iterator namesIter = getNamedAnnotationSets().keySet().iterator();
          while(namesIter.hasNext()) {
            String name = namesIter.next();
            as = getNamedAnnotationSets().get(name);
            if(as.contains(annot)) {
              break;
            }
            else as = null;
          }
        }

        if(as == null) return;
        for(String docID : combinedDocumentIds) {
          OffsetDetails od = getOffsetDetails(docID, as.getName(), annot);
          if(od == null) continue;
          Annotation toUse = od.getOriginalAnnotation();
          toUse.setFeatures(annot.getFeatures());
        }
      }
    }
  }

  public void featureMapUpdated() {
    @SuppressWarnings("unchecked")
    Map>> matches =
      (Map>>)this.getFeatures().get("MatchesAnnots");
    if(matches == null) return;
    for(List> topList : matches.values()) {
      for(List list : topList) {
        Map> newList =
          new HashMap>();
        for(Integer id : list) {
          for(String docID : combinedDocumentIds) {
            // find out the details which refer to the deleted
            // annotation
            OffsetDetails od = getOffsetDetails(docID, id);
            if(od == null) continue;

            // bingo found it
            List subMatches = newList.get(docID);
            if(subMatches == null) {
              subMatches = new ArrayList();
              newList.put(docID, subMatches);
            }
            subMatches.add(od.getOriginalAnnotation().getId());
          }
        }
        for(String docID : newList.keySet()) {
          Document aDoc = compoundDocument.getDocument(docID);
          @SuppressWarnings("unchecked")
          Map>> docMatches =
            (Map>>)aDoc.getFeatures().get(
              "MatchesAnnots");
          if(docMatches == null) {
            docMatches = new HashMap>>();
            aDoc.getFeatures().put("MatchesAnnots", docMatches);
          }

          List> listOfList = docMatches.get(null);
          if(listOfList == null) {
            listOfList = new ArrayList>();
            docMatches.put(null, listOfList);
          }
          listOfList.add(newList.get(docID));
        }
      }
    }
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy