Package com.jgaap.backend

Source Code of com.jgaap.backend.API$Culling

/*
* JGAAP -- a graphical program for stylometric authorship attribution
* Copyright (C) 2009,2011 by Patrick Juola
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/
package com.jgaap.backend;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;

import org.apache.log4j.Logger;

import com.jgaap.generics.AnalysisDriver;
import com.jgaap.generics.AnalyzeException;
import com.jgaap.generics.CanonicizationException;
import com.jgaap.generics.Canonicizer;
import com.jgaap.generics.DistanceFunction;
import com.jgaap.generics.EventCuller;
import com.jgaap.generics.EventCullingException;
import com.jgaap.generics.EventDriver;
import com.jgaap.generics.EventGenerationException;
import com.jgaap.generics.Language;
import com.jgaap.generics.LanguageParsingException;
import com.jgaap.generics.NeighborAnalysisDriver;
import com.jgaap.generics.ValidationDriver;
import com.jgaap.generics.WEKAAnalysisDriver;
import com.jgaap.languages.English;
import com.jgaap.util.Document;
import com.jgaap.util.EventSet;

/**
*
* This class provides a simple interface into jgaap for use in
* other software packages and for development of any human interfaces.
*
* Instructions for using the JGAAP API:
*
* First add documents both known and unknown
*
* All other settings can be performed in any order which are setLanguage, addCanonicizer,
* addEventDriver, addEventCuller, addAnalysisDriver, addDistanceFunction
* Note: of the settings only one EventDriver and one AnalysisDriver are required to run an experiment
*
* The execute method is then used to start the experiment running
*
* Results are placed in unknown documents to access them simple use the getUnknownDocuments method in the API
* The results can be retrieved as a List<Pair<String, Double>> this is a sorted list
* from most likely to least likely author followed by a score generated based on your settings using the getRawResult method
* You can also get a Map of Maps of the raw results (Map<EventDriver, Map<AnalysisDriver, List<String, Double>>>) with the getRawResults method
* They can also be retrieved as a string using either the getFormattedResult or getResult methods.
*
* For examples of how to use the API class see the com.jgaap.ui package for a GUI example
* or the com.jgaap.backend.CLI class for a command line example
*
* @author Michael Ryan
* @since 5.0.0
*/
public class API {

  static Logger logger = Logger.getLogger(API.class);
 
  private List<Document> documents;
  private Language language;
  private List<EventDriver> eventDrivers;
  private List<EventCuller> eventCullers;
  private List<AnalysisDriver> analysisDrivers;
 
  private ExecutorService executor;

  private static final API INSTANCE = new API();
 
  private API() {
    documents = new ArrayList<Document>();
    language = new English();
    eventDrivers = new ArrayList<EventDriver>();
    eventCullers = new ArrayList<EventCuller>();
    analysisDrivers = new ArrayList<AnalysisDriver>();
  }
 
  /**
   * This allows a singleton of the api to be used in the gui
   * or any program that needs to access a single copy of JGAAP
   * from multiple classes
   *
   * @return a reference to the singleton API
   */
  public static API getInstance(){
    return INSTANCE;
  }
 
  /**
   * This is a unique instance of the api to be used when running
   * bulk experiments and you want to reset everything or if you
   * want to thread running more than one experiment at a time
   * as in the class com.jgaap.backend.ExperimentEngine
   *
   * @return a unique API instance
   */
  public static API getPrivateInstance(){
    return new API();
  }

  /**
   *
   * This allows for the addition of documents to the system.
   * Both Training (known) and Sample (unknown) documents must be provided before running an experiment.
   * Training Documents are added by providing an author(tag) for them.
   * Sample documents are added when no author(tag) is given.
   *
   * @param filepath - the system file path or URL to a document
   * @param author - the author of this document or the tag being applied to this document, if null or the empty string this document is considered unknown and is one of those classified
   * @param title - Some means of identifying the document, if null or the empty string are provided a title will be generated from the file name
   * @return - a reference to the document generated
   * @throws Exception - if there is a problem loading the document from file web or parsing file format
   */
  public Document addDocument(String filepath, String author, String title)
      throws Exception {
    Document document = new Document(filepath, author, title);
    return addDocument(document);
  }

  /**
   * Adds a previously generated document to the jgaap system.
   *
   * @param document - a file that has already been loaded as a Document
   * @return - a reference to the document generated
   */
  public Document addDocument(Document document) {
    documents.add(document);
    logger.info("Adding Document "+document.toString());
    return document;
  }

  /**
   * Removes a document from the system.
   *
   * @param document - a reference to the document that is to be removed
   * @return - true on success false on failure
   */
  public Boolean removeDocument(Document document) {
    logger.info("Removing Document "+document.toString());
    return documents.remove(document);
  }

  /**
   * Removes all documents loaded into the system.
   */
  public void removeAllDocuments() {
    logger.info("Removing all Documents");
    documents.clear();
  }

  /**
   * Get a List of all Documents currently loaded into jgaap
   *
   * @return - a List of Documents loaded into the system
   */
  public List<Document> getDocuments() {
    return documents;
  }

  /**
   * Get a List of all currently loaded Documents that do not have an author(tag)
   *
   * @return List of Documents without authors
   */
  public List<Document> getUnknownDocuments() {
    List<Document> unknownDocuments = new ArrayList<Document>();
    for (Document document : documents) {
      if (!document.isAuthorKnown()) {
        unknownDocuments.add(document);
      }
    }
    return unknownDocuments;
  }

  /**
   * Get a List of Documents currently loaded into the system that have a author(tag)
   *
   * @return List of Documents with authors
   */
  public List<Document> getKnownDocuments() {
    List<Document> knownDocuments = new ArrayList<Document>();
    for (Document document : documents) {
      if (document.isAuthorKnown()) {
        knownDocuments.add(document);
      }
    }
    return knownDocuments;
  }

  /**
   * Get a List of Documents that all have the same author(tag)
   *
   * @param author - the author(tag) to select documents on
   * @return - List of Documents limited by the author provided
   */
  public List<Document> getDocumentsByAuthor(String author) {
    List<Document> authorDocuments = new ArrayList<Document>();
    for (Document document : documents) {
      if (document.isAuthorKnown()) {
        if (author.equalsIgnoreCase(document.getAuthor())) {
          authorDocuments.add(document);
        }
      }
    }
    return authorDocuments;
  }

  /**
   * Get a List of all unique authors(tags) applied to Known(Training) Documents
   * 
   * @return List of authors
   */
  public List<String> getAuthors() {
    Set<String> authors = new HashSet<String>();
    for (Document document : documents) {
      if (document.isAuthorKnown()) {
        authors.add(document.getAuthor());
      }
    }
    List<String> authorsList = new ArrayList<String>(authors);
    Collections.sort(authorsList);
    return authorsList;
  }
 
  /**
   * Loads the documents from the file system
   * @throws Exception
   */
  public void loadDocuments() throws Exception{
    for(Document document : documents){
      document.load();
    }
  }

  /**
   * Adds the specified canonicizer to all documents currently loaded in the system.
   *
   * @param action - the unique string name representing a canonicizer (displayName())
   * @return - a reference to the canonicizer added
   * @throws Exception - if the canonicizer specified cannot be found or instanced
   */
  public Canonicizer addCanonicizer(String action) throws Exception {
    Canonicizer canonicizer = Canonicizers.getCanonicizer(action);
    for (Document document : documents) {
      addCanonicizer(canonicizer, document);
    }
    return canonicizer;
  }

  /**
   * Adds the specified canonicizer to all Documents that have the DocType docType.
   *
   * @param action - the unique string name representing a canonicizer (displayName())
   * @param docType - The DocType this canonicizer is restricted to
   * @return - a reference to the canonicizer added
   * @throws Exception - if the canonicizer specified cannot be found or instanced
   */
  public Canonicizer addCanonicizer(String action, Document.Type docType) throws Exception {
    Canonicizer canonicizer = Canonicizers.getCanonicizer(action);
    for (Document document : documents) {
      if (document.getDocType().equals(docType)) {
        addCanonicizer(canonicizer, document);
      }
    }
    return canonicizer;
  }

  /**
   * Add the Canonicizer specified to the document referenced.
   *
   * @param action - the unique string name representing a canonicizer (displayName())
   * @param document - the Document to add the canonicizer to
   * @return - a reference to the canonicizer added
   * @throws Exception - if the canonicizer specified cannot be found or instanced
   */
  public Canonicizer addCanonicizer(String action, Document document)
      throws Exception {
    Canonicizer canonicizer = Canonicizers.getCanonicizer(action);
    return addCanonicizer(canonicizer, document);
  }
 
  /**
   * Add the Canonicizer specified to the document referenced.
   *
   * @param canonicizer - the canonicizer to add
   * @param document - the Document to add the canonicizer to
   * @return - a reference to the canonicizer added
   */
  public Canonicizer addCanonicizer(Canonicizer canonicizer, Document document) {
    document.addCanonicizer(canonicizer);
    logger.info("Adding Canonicizer "+canonicizer.displayName()+" to Document "+document.toString());
    return canonicizer;
  }
 
  public Canonicizer addCanonicizer(String action, EventDriver eventDriver) throws Exception {
    Canonicizer canonicizer = Canonicizers.getCanonicizer(action);
    return addCanonicizer(canonicizer, eventDriver);
  }
 
  public Canonicizer addCanonicizer(Canonicizer canonicizer, EventDriver eventDriver) {
    eventDriver.addCanonicizer(canonicizer);
    logger.info("Adding Canonicizer "+canonicizer.displayName()+" to EventDriver "+eventDriver.displayName());
    return canonicizer;
  }

  /**
   * Removes the first instance of the canoniciser corresponding to the action(displayName())
   * from the Document referenced.
   *
   * @param canonicizer - the canonicizer to be removed
   * @param document - a reference to the Document to remove the canonicizer from
   */
  public void removeCanonicizer(Canonicizer canonicizer, Document document) {
    document.removeCanonicizer(canonicizer);
  }
 
  public void removeCanonicizer(Canonicizer canonicizer, EventDriver eventDriver) {
    eventDriver.removeCanonicizer(canonicizer);
  }

  /**
   * Removes the first occurrence of the canonicizer corresponding to the action(displayName())
   * from every document
   *
   * @param canonicizer - the canonicizer to be removed
   */
  public void removeCanonicizer(Canonicizer canonicizer) {
    for (Document document : documents) {
      removeCanonicizer(canonicizer, document);
    }
  }

  /**
   * Removes the first occurrence of the canonicizer from every Document of the DocType docType
   *
   * @param canonicizer - the canonicizer to be removed
   * @param docType - the DocType to remove the canonicizer from
   */
  public void removeCanonicizer(Canonicizer canonicizer, Document.Type docType) {
    for (Document document : documents) {
      if (document.getDocType().equals(docType)) {
        removeCanonicizer(canonicizer, document);
      }
    }
  }

  /**
   * Removes all canonicizers from Documents with the DocType docType
   *
   * @param docType - the DocType to remove canonicizers from
   */
  public void removeAllCanonicizers(Document.Type docType) {
    for (Document document : documents) {
      document.clearCanonicizers();
    }
  }

  /**
   * Removes all canonicizers from All Documents loaded in the system
   */
  public void removeAllCanonicizers() {
    for (Document document : documents) {
      document.clearCanonicizers();
    }
  }

  /**
   * Add an Event Driver which will be used to
   * eventify(Generate a List of Events order in the sequence they are found in the document)
   * all of the documents
   * @param action - the identifier for the EventDriver to add (displayName())
   * @return - a reference to the added EventDriver
   * @throws Exception - If the action is not found or the EventDriver cannot be instanced
   */
  public EventDriver addEventDriver(String action) throws Exception {
    EventDriver eventDriver = EventDrivers.getEventDriver(action);
    return addEventDriver(eventDriver);
  }
 
  /**
   * Add an Event Driver which will be used to
   * eventify(Generate a List of Events order in the sequence they are found in the document)
   * all of the documents
   * @param eventDriver - the EventDriver to add
   * @return - a reference to the added EventDriver
   */
  public EventDriver addEventDriver(EventDriver eventDriver) {
    eventDrivers.add(eventDriver);
    logger.info("Adding EventDriver "+eventDriver.displayName());
    return eventDriver;
  }

  /**
   * Removes the Event Driver reference from the system
   * @param eventDriver - the EventDriver to be removed
   * @return - true if successful false if failure
   */
  public Boolean removeEventDriver(EventDriver eventDriver) {
    logger.info("Removing EventDriver "+eventDriver.displayName());
    return eventDrivers.remove(eventDriver);
  }

  /**
   * Removes all EventDrivers from the system
   */
  public void removeAllEventDrivers() {
    eventDrivers.clear();
    for (Document document : documents) {
      document.clearEventSets();
    }
  }

  /**
   * Gets a List of all EventDrivers currently loaded in the system
   * @return List of All loaded EventDrivers
   */
  public List<EventDriver> getEventDrivers() {
    return eventDrivers;
  }

  /**
   * Add an Event Culler to the system
   *
   * @param action - unique identifier for the event culler to add (displayName())
   * @return - a reference to the added event culler
   * @throws Exception - if the EventCuller cannot be found or cannor be instanced
   */
  public EventCuller addEventCuller(String action) throws Exception {
    EventCuller eventCuller = EventCullers.getEventCuller(action);
    eventCullers.add(eventCuller);
    for(EventDriver eventDriver : eventDrivers) {
      addEventCuller(eventCuller, eventDriver);
    }
    return eventCuller;
  }
 
  public EventCuller addEventCuller(String action, EventDriver eventDriver) throws Exception {
    EventCuller eventCuller = EventCullers.getEventCuller(action);
    return addEventCuller(eventCuller, eventDriver);
  }
 
  public EventCuller addEventCuller(EventCuller eventCuller, EventDriver eventDriver) {
    eventDriver.addCuller(eventCuller);
    logger.info("Adding EventCuller "+eventCuller.displayName()+" to "+eventDriver.displayName());
    return eventCuller;
  }

  /**
   * Remove the supplied EventCuller from the system
   *
   * @param eventCuller - EventCuller to be removed
   * @return - true if success false if failure
   */
  public Boolean removeEventCuller(EventCuller eventCuller) {
    logger.info("Removing EventCuller "+eventCuller.displayName());
    eventCullers.remove(eventCuller);
    for(EventDriver eventDriver : eventDrivers){
      eventDriver.removeCuller(eventCuller);
    }
    return true;
  }

  /**
   * Removes all loaded EventCullers from the system
   */
  public void removeAllEventCullers() {
    eventCullers.clear();
    for(EventDriver eventDriver : eventDrivers){
      eventDriver.clearCullers();
    }
  }

  /**
   * Get a List of all EventCullers currently loaded in the system
   * @return List of EventCullers loaded
   */
  public List<EventCuller> getEventCullers() {
    return eventCullers;
  }

  /**
   * Add an AnalysisDriver to the system as referenced by the action.
   *
   * @param action - the unique identifier for a AnalysisDriver (alternately a DistanceFunction)
   * @return - a reference to the generated Analysis Driver
   * @throws Exception - If the AnalysisDriver cannot be found or if it cannot be instanced
   */
  public AnalysisDriver addAnalysisDriver(String action) throws Exception {
    AnalysisDriver analysisDriver = AnalysisDrivers.getAnalysisDriver(action);
    return addAnalysisDriver(analysisDriver);
  }
 
  public AnalysisDriver addAnalysisDriver(AnalysisDriver analysisDriver) {
    logger.info("Adding AnalysisDriver "+analysisDriver.displayName());
    analysisDrivers.add(analysisDriver);
    return analysisDriver;
  }

  /**
   * Removed the passed AnalysisDriver from the system
   * @param analysisDriver - reference to the AnalysisDriver to be removed
   * @return True if success false if failure
   */
  public Boolean removeAnalysisDriver(AnalysisDriver analysisDriver) {
    logger.info("Removing AnalysisDriver "+analysisDriver.displayName());
    return analysisDrivers.remove(analysisDriver);
  }

  /**
   * Removes all AnalysisDrivers from the system
   */
  public void removeAllAnalysisDrivers() {
    analysisDrivers.clear();
  }

  /**
   * Adds a DistanceFunction to the AnalysisDriver supplied.
   * Only AnalysisDrivers that extend the NeighborAnalysisDriver can be used
   *
   * @param action - unique identifier for the DistanceFunction you want to add
   * @param analysisDriver - a reference to the AnalysisDriver you want the distance added to
   * @return - a reference to the generated DistanceFunction
   * @throws Exception - if the AnalysisDriver does not extend NeighborAnalysisDriver or if the DistanceFunction cannot be found the DistanceFunction cannot be instanced
   */
  public DistanceFunction addDistanceFunction(String action,
      AnalysisDriver analysisDriver) throws Exception {
    DistanceFunction distanceFunction = DistanceFunctions
        .getDistanceFunction(action);
    return addDistanceFunction(distanceFunction, analysisDriver);
  }

  /**
   * Adds a DistanceFunction to the AnalysisDriver supplied.
   * Only AnalysisDrivers that extend the NeighborAnalysisDriver can be used
   *
   * @param distanceFunction - the DistanceFunction you want to add
   * @param analysisDriver - a reference to the AnalysisDriver you want the distance added to
   * @return - a reference to the generated DistanceFunction
   */
  public DistanceFunction addDistanceFunction(DistanceFunction distanceFunction, AnalysisDriver analysisDriver) {
    ((NeighborAnalysisDriver) analysisDriver).setDistance(distanceFunction);
    return distanceFunction;
  }
 
  /**
   * Get a List of All AnalysisDrivers currently loaded on the system
   * @return List of All AnalysisDrivers
   */
  public List<AnalysisDriver> getAnalysisDrivers() {
    return analysisDrivers;
  }

  /**
   * Get the current Language JGAAP is set to be working on
   * @return
   */
  public Language getLanguage(){
    return language;
  }
 
  /**
   * Set the Language that JGAAP will operate in.
   * This restricts what methods are available, changes the charset that is expected when reading files, and will add any pre-processing that is needed
   * @param action - the Language to operate under
   * @return - a Reference to the language object selected
   * @throws Exception - if the language cannot be found or cannot be instanced
   */
  public Language setLanguage(String action) throws Exception {
    language = Languages.getLanguage(action);
    return language;
  }

  /**
   * Pipelines the independent aspects of loading and processing a document into separate threads
   * 
   * Load the text from disk or the web
   * Take into account any special treatment based on the language currently selected
   * Place the text into canonical form using the Canonicizers
   * Use the EventDrivers to transform the text into EventSets
   *
   * @throws Exception
   */
  private void loadCanonicizeEventify() throws Exception{
    List<Future<Document>> documentsProcessing = new ArrayList<Future<Document>>(documents.size());
    for(final Document document : documents){
      Callable<Document> work = new Callable<Document>() {
        @Override
        public Document call() throws Exception {
          try {
            document.setLanguage(language);
            document.load();
            document.processCanonicizers();
            for (EventDriver eventDriver : eventDrivers) {
              char[] text = document.getText();
              for(Canonicizer canonicizer : eventDriver.getCanonicizers()){
                text = canonicizer.process(text);
              }
              try{
                document.addEventSet(eventDriver,eventDriver.createEventSet(text));
              } catch (EventGenerationException e) {
                logger.error("Could not Eventify with "+eventDriver.displayName()+" on File:"+document.getFilePath()+" Title:"+document.getTitle(),e);
                throw new Exception("Could not Eventify with "+eventDriver.displayName()+" on File:"+document.getFilePath()+" Title:"+document.getTitle(),e);
              }
            }
            document.setText("");
          } catch (LanguageParsingException e) {
            logger.fatal("Could not Parse Language: "+language.displayName()+" on File:"+document.getFilePath()+" Title:"+document.getTitle(),e);
            document.failed();
          } catch (CanonicizationException e) {
            logger.fatal("Could not Canonicize File: "+document.getFilePath()+" Title:"+document.getTitle(),e);
            document.failed();
          } catch (Exception e) {
            logger.fatal("Could not load File: "+document.getFilePath()+" Title:"+document.getTitle(),e);
            document.failed();
          }
          return document;
        }
      };
      documentsProcessing.add(executor.submit(work));
    }

    while(true){
      if(documentsProcessing.size()==0){
        break;
      }else {
        Iterator<Future<Document>> documentIterator = documentsProcessing.iterator();
        while(documentIterator.hasNext()){
          Future<Document> futureDocument = documentIterator.next();
          if(futureDocument.isDone()){
            Document document = futureDocument.get();
            if(document.hasFailed()){
              throw new Exception("One or more documents could not be read / parsed / canonicized Experiment Failed");
            }
            logger.info("Document: "+document.getTitle()+" has finished processing.");
            documentIterator.remove();
          }
        }
      }
    }
  }
 
  /**
   * Events are culled from EventSets across all Documents on a per EventDriver basis
   * @throws EventCullingException
   * @throws ExecutionException
   * @throws InterruptedException
   */
  private void cull() throws EventCullingException, InterruptedException, ExecutionException {
    List<Future<EventDriver>> futureEventDrivers = new ArrayList<Future<EventDriver>>();
    for (EventDriver eventDriver : eventDrivers) {
      if (!eventDriver.getEventCullers().isEmpty()) {
        futureEventDrivers.add(executor.submit(new Culling(eventDriver)));
      }
    }
    while(futureEventDrivers.size() != 0) {
      Iterator<Future<EventDriver>> iterator = futureEventDrivers.iterator();
      while(iterator.hasNext()) {
        Future<EventDriver> futureEventDriver = iterator.next();
        if(futureEventDriver.isDone()){
          EventDriver eventDriver = futureEventDriver.get();
          logger.info("Finished Culling "+eventDriver.displayName());
          iterator.remove();
        }
      }
    }
  }

  /**
   * All loaded AnalysisDrivers are run over All EventSets comparing the Unknown(sample) to the Known(training) Documents.
   */
  private void analyze() throws AnalyzeException {
    List<Document> knownDocuments = new ArrayList<Document>();
    List<Document> unknownDocuments = new ArrayList<Document>();
    for (Document document : documents) {
      if (document.isAuthorKnown()) {
        knownDocuments.add(document);
      } else {
        unknownDocuments.add(document);
      }
    }
    for (AnalysisDriver analysisDriver : analysisDrivers) {
      logger.info("Training " + analysisDriver.displayName());
      analysisDriver.train(knownDocuments);
      logger.info("Finished Training "+analysisDriver.displayName());
      List<Future<Document>> futureDocuments = new ArrayList<Future<Document>>();
      if (analysisDriver instanceof ValidationDriver) {
        for (Document knownDocument : knownDocuments) {
          futureDocuments.add(executor.submit(new AnalysisWorker(knownDocument, analysisDriver)));
        }
      } else if (analysisDriver instanceof WEKAAnalysisDriver){
        for (Document unknownDocument : unknownDocuments){
          logger.info("Begining Analyzing: " + unknownDocument.toString());
          unknownDocument.addResult(analysisDriver, analysisDriver.analyze(unknownDocument));
          logger.info("Finished Analyzing: "+unknownDocument.toString());
        }
      } else {
        for (Document unknownDocument : unknownDocuments) {
          futureDocuments.add(executor.submit(new AnalysisWorker(unknownDocument, analysisDriver)));
        }
      }
      //await analysis to finish
      while(futureDocuments.size() != 0){
        Iterator<Future<Document>> iterator = futureDocuments.iterator();
        while(iterator.hasNext()) {
          Future<Document> futureDocument = iterator.next();
          if(futureDocument.isDone()) {
            iterator.remove();
          }
        }
      }
      logger.info("Finished Analysis with "+analysisDriver.displayName());
    }
  }

  /**
   * Performs the canonicize eventify cull and analyze methods since a strict order has to be enforced when using them
   * @throws Exception
   */
  public void execute() throws Exception {
    clearData();
    executor = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors());
    loadCanonicizeEventify();
    cull();
    analyze();
    executor.shutdown();
    executor.awaitTermination(5, TimeUnit.SECONDS);
  }
 
  /**
   * Removes canonicizors from all documents
   */
  public void clearCanonicizers() {
    for(Document document : documents){
      document.clearCanonicizers();
    }
  }
 
  /**
   * Removes all Generated data from a run but leaves all settings untouched
   */
  public void clearData() {
    for(Document document : documents){
      document.clearEventSets();
      document.clearResults();
    }
  }
 
  private class Culling implements Callable<EventDriver> {
    private EventDriver eventDriver;
    private ExecutorService cullingExecutor = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors());
   
    Culling(EventDriver eventDriver) {
      this.eventDriver = eventDriver;
    }
   
    @Override
    public EventDriver call() throws Exception {
      List<EventSet> eventSets = new ArrayList<EventSet>();
      for(Document document : documents){
        eventSets.add(document.getEventSet(eventDriver));
      }
      for(EventCuller culler : eventDriver.getEventCullers()) {
        culler.init(eventSets);
        List<Future<EventSet>> futureEventSets = new ArrayList<Future<EventSet>>(eventSets.size());
        for(EventSet eventSet : eventSets) {
          futureEventSets.add(cullingExecutor.submit(new CullerWorker(eventSet, culler)));
        }
        eventSets.clear();
        for(Future<EventSet> futureEventSet : futureEventSets) {
          eventSets.add(futureEventSet.get());
        }
      }
      cullingExecutor.shutdown();
      for(int i = 0; i < documents.size(); i++) {
        documents.get(i).addEventSet(eventDriver, eventSets.get(i));
      }
      return eventDriver;
    }
  }
 
  private class CullerWorker implements Callable<EventSet> {
    private EventSet eventSet;
    private EventCuller culler;
   
    CullerWorker(EventSet eventSet, EventCuller culler) {
      this.eventSet = eventSet;
      this.culler = culler;
    }
   
    public EventSet call() {
      return culler.cull(eventSet);
    }
  }
 
  private class AnalysisWorker implements Callable<Document> {
    private Document document;
    private AnalysisDriver analysisDriver;
   
    AnalysisWorker(Document document, AnalysisDriver analysisDriver){
      this.document = document;
      this.analysisDriver = analysisDriver;
    }
   
    @Override
    public Document call() throws Exception {
      logger.info("Begining Analyzing: " + document.toString());
      document.addResult(analysisDriver, analysisDriver.analyze(document));
      logger.info("Finished Analyzing: "+document.toString());
      return document;
    }
  }
}
TOP

Related Classes of com.jgaap.backend.API$Culling

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.