Log in Help
Print
Homereleasesgate-5.1-beta2-build3402-ALLpluginsAlignmentsrcgatecompoundimpl 〉 CompoundDocumentImpl.java
 
package gate.compound.impl;

import java.io.File;
import java.util.*;

import gate.*;
import gate.alignment.Alignment;
import gate.alignment.gui.AlignmentFactory;
import gate.compound.CompoundDocumentEvent;
import gate.compound.CompoundDocumentListener;
import gate.creole.ResourceInstantiationException;

/**
 * Implemention of the CompoundDocument. Compound Document is a set of
 * one or more documents. It provides a more convenient way to group
 * documents and interpret them as a single document. It has a
 * capability to switch the focus among the different memebers of it.
 * 
 * @author niraj
 */
public class CompoundDocumentImpl extends AbstractCompoundDocument {

  private static final long serialVersionUID = 8114328411647768889L;

  private transient ArrayList<CompoundDocumentListener> listeners;

  /**
   * Constructor
   */
  public CompoundDocumentImpl() {
    listeners = new ArrayList<CompoundDocumentListener>();
    this.features = Factory.newFeatureMap();
    this.documents = new HashMap<String, Document>();
    this.documentIDs = new ArrayList<String>();
  }

  /** Initialise this resource, and return it. */
  public Resource init() throws ResourceInstantiationException {
    // set up the source URL and create the content

    if(markupAware == null) {
      throw new ResourceInstantiationException(
              "The markupAware cannot be null.");
    }

    if(collectRepositioningInfo == null) {
      throw new ResourceInstantiationException(
              "The collectRepositioningInfo is null!");
    }

    if(preserveOriginalContent == null) {
      throw new ResourceInstantiationException(
              "The preserveOriginalContent is null!");
    }

    if(sourceUrl != null) {

      if(documentIDs == null || documentIDs.isEmpty()) {
        throw new ResourceInstantiationException(
                "You must provide atleast one document id");
      }

      // source URL can be a file
      File file = new File(sourceUrl.getFile());
      if(file.isDirectory()) {
        throw new ResourceInstantiationException(
                "You must select one of the files!");
      }

      // instancetiate all documents
      createDocuments(file);
    }
    else {
      documents = new HashMap<String, Document>();
      documentIDs = new ArrayList<String>();
    }

    currentDocument = null;
    return this;
  } // init()

  /**
   * Given a file name it should try to identify other language pairs
   * 
   * @param file
   * @throws ResourceInstantiationException
   */
  protected void createDocuments(File file)
          throws ResourceInstantiationException {
    // if it is a file
    // it should follow the name conventions
    // which is X.language.extension
    String name = file.getName();
    int index = name.lastIndexOf('.');
    String extension = "";
    if(index == -1) {
      // there is no extension
    }
    else {
      extension = name.substring(index, name.length());
      name = name.substring(0, index);
    }

    // so the name contains X.language
    index = name.lastIndexOf('.');
    if(index == -1) {
      // no id provided
      throw new ResourceInstantiationException(
              "You must select one of the file that is named as X.language.ext");
    }

    String documentID = name.substring(index + 1, name.length());
    if(documentID.trim().length() == 0) {
      throw new ResourceInstantiationException(
              "You must select one of the file that is named as X.language.ext");
    }
    else {
      name = name.substring(0, index);
    }

    // else search for the language in the documentIDs
    index = documentIDs.indexOf(documentID);
    if(index == -1) {
      throw new ResourceInstantiationException(
              "Document ID of the selected file does not exist in the provided documentIDs");
    }

    try {
      documents = new HashMap<String, Document>();
      for(int i = 0; i < documentIDs.size(); i++) {
        // apart from the index, we need to search for all other files
        // create file Name
        documentID = (String)documentIDs.get(i);
        String fileNameToSearch = file.getParentFile().getAbsolutePath() + "/"
                + name + "." + documentID + extension;
        File newFile = new File(fileNameToSearch);
        if(!newFile.exists()) {
          System.err.println("File " + fileNameToSearch + " does not exist!");
          documentIDs.remove(i);
          i--;
          continue;
        }
        FeatureMap features = Factory.newFeatureMap();
        features.put("collectRepositioningInfo", collectRepositioningInfo);
        features.put("encoding", encoding);
        features.put("markupAware", new Boolean(true));
        features.put("preserveOriginalContent", preserveOriginalContent);
        features.put("sourceUrl", newFile.toURL());
        FeatureMap subFeatures = Factory.newFeatureMap();
        Gate.setHiddenAttribute(subFeatures, true);
        Document doc = (Document)Factory.createResource(
                "gate.corpora.DocumentImpl", features, subFeatures);
        doc.setName(documentID);
        documents.put(documentID, doc);
      }

      if(documents.isEmpty())
        throw new ResourceInstantiationException("No documents found");

    }
    catch(Exception e) {
      throw new ResourceInstantiationException(e);
    }
  }

  /**
   * Adds a new document member to the compound document.
   */
  public void addDocument(String documentID, Document document) {
    if(document.getName() == null) {
      document.setName(documentID);
    }
    
    if(documents.containsKey(documentID)) return;
    documents.put(documentID, document);
    documentIDs.add(documentID);
    fireDocumentAdded(documentID);
  }

  /**
   * Removes the provided document member from the compound document.
   * Please note that the event is fired first and document is removed
   * after that.
   */
  public void removeDocument(String documentID) {
    if(documentIDs.contains(documentID)) {
      fireDocumentRemoved(documentID);
      documentIDs.remove(documentID);
      documents.remove(documentID);
    }
  }

  /**
   * Objects wishing to listen to document addition and removal events
   * should implement the CompoundDocumentListener interface register
   * themselves to the compound document.
   */
  public void addCompoundDocumentListener(CompoundDocumentListener listener) {
    if(this.listeners == null)
      this.listeners = new ArrayList<CompoundDocumentListener>();
    this.listeners.add(listener);
  }

  /**
   * Objects no longer wishing listen to document addition and removal
   * events should call this method to get unregistered.
   */
  public void removeCompoundDocumentListener(CompoundDocumentListener listener) {
    this.listeners.remove(listener);
  }

  /**
   * Fires the new document addition event.
   * 
   * @param documentID
   */
  public void fireDocumentAdded(String documentID) {
    CompoundDocumentEvent cde = new CompoundDocumentEvent(this, documentID);
    for(int i = 0; i < listeners.size(); i++) {
      CompoundDocumentListener cdl = (CompoundDocumentListener)listeners.get(i);
      cdl.documentAdded(cde);
    }
  }

  /**
   * Fires the document removal event.
   * 
   * @param documentID
   */
  public void fireDocumentRemoved(String documentID) {
    CompoundDocumentEvent cde = new CompoundDocumentEvent(this, documentID);
    for(int i = 0; i < listeners.size(); i++) {
      CompoundDocumentListener cdl = (CompoundDocumentListener)listeners.get(i);
      cdl.documentRemoved(cde);
    }
  }

  /**
   * The alignment object contains information about the alignment of
   * text.
   * 
   * @param alignmentFeatureName
   * @return
   */
  public Alignment getAlignmentInformation(String alignmentFeatureName) {
    if(alignmentFeatureName == null) {
      alignmentFeatureName = AlignmentFactory.ALIGNMENT_FEATURE_NAME;
    }
    if(this.features.get(alignmentFeatureName) == null) {
      this.features.put(alignmentFeatureName, new Alignment(this));
    }

    return (Alignment)this.features.get(alignmentFeatureName);
  }

  /**
   * This method returns all available alignment feature names
   * 
   * @return
   */
  public Set<String> getAllAlignmentFeatureNames() {
    Set<String> toReturn = new HashSet<String>();
    if(this.features.keySet() != null) {
      for(Object key : this.features.keySet()) {
        if(this.features.get(key) instanceof Alignment) {
          toReturn.add(key.toString());
        }
      }
    }
    return toReturn;
  }

  /**
   * Alignment object with the provided feature name is deleted
   * 
   * @param alignmentFeatureName
   */
  public void removeAlignmentInformation(String alignmentFeatureName) {
    if(this.features.keySet() != null) {
      this.features.remove(alignmentFeatureName);
    }
  }

} // class CompoundDocumentImpl