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

weka.gui.beans.InstanceStreamToBatchMaker Maven / Gradle / Ivy

/*
 *   This program is free software: you can redistribute it and/or modify
 *   it under the terms of the GNU 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 General Public License for more details.
 *
 *   You should have received a copy of the GNU General Public License
 *   along with this program.  If not, see .
 */

/*
 *    InstanceStreamToBatchMaker.java
 *    Copyright (C) 2008-2012 University of Waikato, Hamilton, New Zealand
 *
 */

package weka.gui.beans;

import java.awt.BorderLayout;
import java.beans.EventSetDescriptor;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;

import javax.swing.JPanel;

import weka.core.Instance;
import weka.core.Instances;
import weka.gui.Logger;

/**
 * Bean that converts an instance stream into a (batch) data set. Useful in
 * conjunction with the Reservoir sampling filter.
 * 
 * @author Mark Hall (mhall{[at]}pentaho{[dot]}com)
 * @version $Revision: 10220 $
 */
@KFStep(category = "Flow", toolTipText = "Converts an incoming instance stream into a data set batch")
public class InstanceStreamToBatchMaker extends JPanel implements BeanCommon,
  Visible, InstanceListener, EventConstraints, DataSource {

  /**
   * For serialization
   */
  private static final long serialVersionUID = -7037141087208627799L;

  protected BeanVisual m_visual = new BeanVisual("InstanceStreamToBatchMaker",
    BeanVisual.ICON_PATH + "InstanceStreamToBatchMaker.gif",
    BeanVisual.ICON_PATH + "InstanceStreamToBatchMaker_animated.gif");

  /**
   * The log.
   */
  private transient Logger m_log;

  /**
   * Component connected to us.
   */
  private Object m_listenee;

  private final ArrayList m_dataListeners = new ArrayList();

  /**
   * Collects up the instances.
   */
  private List m_batch;

  private Instances m_structure;

  public InstanceStreamToBatchMaker() {
    setLayout(new BorderLayout());
    add(m_visual, BorderLayout.CENTER);
  }

  /**
   * Accept an instance to add to the batch.
   * 
   * @param e an InstanceEvent value
   */
  @Override
  public void acceptInstance(InstanceEvent e) {
    if (e.getStatus() == InstanceEvent.FORMAT_AVAILABLE) {
      m_batch = new LinkedList();
      m_structure = e.getStructure();

      // notify dataset listeners of structure available
      if (m_log != null) {
        m_log.logMessage("[InstanceStreamToBatch] passing on structure.");
      }
      DataSetEvent dse = new DataSetEvent(this, m_structure);
      notifyDataListeners(dse);
    } else if (e.getStatus() == InstanceEvent.INSTANCE_AVAILABLE) {
      m_batch.add(e.getInstance());
    } else {
      // batch finished

      if (e.getInstance() != null) {
        // add the last instance
        m_batch.add(e.getInstance());
      }

      // create the new Instances
      Instances dataSet = new Instances(m_structure, m_batch.size());
      for (Instance i : m_batch) {
        dataSet.add(i);
      }
      dataSet.compactify();

      // save memory
      m_batch = null;

      if (m_log != null) {
        m_log.logMessage("[InstanceStreamToBatch] sending batch to listeners.");
      }

      // notify dataset listeners
      DataSetEvent dse = new DataSetEvent(this, dataSet);
      notifyDataListeners(dse);
    }
  }

  /**
   * Returns true if, at this time, the object will accept a connection
   * according to the supplied EventSetDescriptor
   * 
   * @param esd the EventSetDescriptor
   * @return true if the object will accept a connection
   */
  @Override
  public boolean connectionAllowed(EventSetDescriptor esd) {
    return connectionAllowed(esd.getName());
  }

  /**
   * Returns true if, at this time, the object will accept a connection with
   * respect to the named event
   * 
   * @param eventName the event
   * @return true if the object will accept a connection
   */
  @Override
  public boolean connectionAllowed(String eventName) {
    if (m_listenee != null || !eventName.equals("instance")) {
      return false;
    }
    return true;
  }

  /**
   * Notify this object that it has been registered as a listener with a source
   * with respect to the named event
   * 
   * @param eventName the event
   * @param source the source with which this object has been registered as a
   *          listener
   */
  @Override
  public void connectionNotification(String eventName, Object source) {
    if (connectionAllowed(eventName)) {
      m_listenee = source;
    }
  }

  /**
   * Notify this object that it has been deregistered as a listener with a
   * source with respect to the supplied event name
   * 
   * @param eventName the event
   * @param source the source with which this object has been registered as a
   *          listener
   */
  @Override
  public void disconnectionNotification(String eventName, Object source) {
    m_listenee = null;
  }

  /**
   * Returns true if, at the current time, the named event could be generated.
   * 
   * @param eventName the name of the event in question
   * @return true if the named event could be generated
   */
  @Override
  public boolean eventGeneratable(String eventName) {
    if (!eventName.equals("dataSet")) {
      return false;
    }

    if (m_listenee == null) {
      return false;
    }

    if (m_listenee instanceof EventConstraints) {
      if (!((EventConstraints) m_listenee).eventGeneratable("instance")) {
        return false;
      }
    }

    return true;
  }

  /**
   * Get the custom (descriptive) name for this bean (if one has been set)
   * 
   * @return the custom name (or the default name)
   */
  @Override
  public String getCustomName() {
    return m_visual.getText();
  }

  /**
   * Set a custom (descriptive) name for this bean
   * 
   * @param name the name to use
   */
  @Override
  public void setCustomName(String name) {
    m_visual.setText(name);
  }

  /**
   * Set a logger
   * 
   * @param logger a Logger value
   */
  @Override
  public void setLog(Logger logger) {
    m_log = logger;
  }

  /**
   * Returns true if. at this time, the bean is busy with some (i.e. perhaps a
   * worker thread is performing some calculation).
   * 
   * @return true if the bean is busy.
   */
  @Override
  public boolean isBusy() {
    return false;
  }

  /**
   * Stop any action (if possible).
   */
  @Override
  public void stop() {
    // not much we can do. Stopping depends on upstream components.
  }

  /**
   * Gets the visual appearance of this wrapper bean
   */
  @Override
  public BeanVisual getVisual() {
    return m_visual;
  }

  /**
   * Sets the visual appearance of this wrapper bean
   * 
   * @param newVisual a BeanVisual value
   */
  @Override
  public void setVisual(BeanVisual newVisual) {
    m_visual = newVisual;
  }

  /**
   * Use the default visual appearance for this bean
   */
  @Override
  public void useDefaultVisual() {
    m_visual.loadIcons(BeanVisual.ICON_PATH + "InstanceStreamToBatchMaker.gif",
      BeanVisual.ICON_PATH + "InstanceStreamToBatchMaker_animated.gif");
  }

  /**
   * Notify all data source listeners.
   * 
   * @param tse the DataSetEvent to pass on.
   */
  @SuppressWarnings("unchecked")
  protected void notifyDataListeners(DataSetEvent tse) {
    ArrayList l;
    synchronized (this) {
      l = (ArrayList) m_dataListeners.clone();
    }
    if (l.size() > 0) {
      for (int i = 0; i < l.size(); i++) {
        l.get(i).acceptDataSet(tse);
      }
    }
  }

  @Override
  public synchronized void addDataSourceListener(DataSourceListener tsl) {
    m_dataListeners.add(tsl);
    // pass on any format that we might know about
    if (m_structure != null) {
      DataSetEvent e = new DataSetEvent(this, m_structure);
      tsl.acceptDataSet(e);
    }
  }

  @Override
  public synchronized void removeDataSourceListener(DataSourceListener tsl) {
    m_dataListeners.remove(tsl);
  }

  @Override
  public synchronized void addInstanceListener(InstanceListener il) {
    // we don't produce instance events
  }

  @Override
  public synchronized void removeInstanceListener(InstanceListener il) {
    // we don't produce instance events
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy