/* Copyright (C) 2002 Univ. of Massachusetts Amherst, Computer Science Dept.
This file is part of "MALLET" (MAchine Learning for LanguagE Toolkit).
http://www.cs.umass.edu/~mccallum/mallet
This software is provided under the terms of the Common Public License,
version 1.0, as published by http://www.opensource.org. For further
information, see the file `LICENSE' included with this distribution. */
package cc.mallet.pipe;
import java.lang.reflect.*;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.io.*;
import cc.mallet.pipe.Pipe;
import cc.mallet.pipe.iterator.EmptyInstanceIterator;
import cc.mallet.types.Alphabet;
import cc.mallet.types.Instance;
/**
* Convert an instance through a sequence of pipes.
@author Andrew McCallum <a href="mailto:mccallum@cs.umass.edu">mccallum@cs.umass.edu</a>
*/
public class SerialPipes extends Pipe implements Serializable
{
ArrayList<Pipe> pipes;
public SerialPipes ()
{
this.pipes = new ArrayList<Pipe> ();
}
public SerialPipes (Pipe[] pipes)
{
this.pipes = new ArrayList<Pipe> (pipes.length);
for (int i = 0; i < pipes.length; i++)
this.pipes.add (pipes[i]);
resolveAlphabets();
}
public SerialPipes (Collection<Pipe> pipeList)
{
pipes = new ArrayList<Pipe> (pipeList);
resolveAlphabets();
}
public abstract class Predicate {
public abstract boolean predicate (Pipe p);
}
public SerialPipes newSerialPipesFromSuffix (Predicate testForStartingNewPipes) {
int i = 0;
while (i < pipes.size())
if (testForStartingNewPipes.predicate(pipes.get(i))) {
return new SerialPipes(pipes.subList(i, pipes.size()-1));
}
throw new IllegalArgumentException ("No pipes in this SerialPipe satisfied starting predicate.");
}
public SerialPipes newSerialPipesFromRange (int start, int end) {
return new SerialPipes(pipes.subList(start, end));
}
private void resolveAlphabets ()
{
Alphabet da = null, ta = null;
for (Pipe p : pipes) {
p.preceedingPipeDataAlphabetNotification(da);
da = p.getDataAlphabet();
p.preceedingPipeTargetAlphabetNotification(ta);
ta = p.getTargetAlphabet();
}
dataAlphabet = da;
targetAlphabet = ta;
}
// protected void add (Pipe pipe)
// protected void remove (int i)
// This method removed because pipes should be immutable to be safe.
// If you need an augmented pipe, you can make a new SerialPipes containing this one.
public void setTargetProcessing (boolean lookForAndProcessTarget)
{
super.setTargetProcessing (lookForAndProcessTarget);
for (Pipe p : pipes)
p.setTargetProcessing (lookForAndProcessTarget);
}
public Iterator<Instance> newIteratorFrom (Iterator<Instance> source)
{
if (pipes.size() == 0)
return new EmptyInstanceIterator();
Iterator<Instance> ret = pipes.get(0).newIteratorFrom(source);
for (int i = 1; i < pipes.size(); i++)
ret = pipes.get(i).newIteratorFrom(ret);
return ret;
}
public int size()
{
return pipes.size();
}
public Pipe getPipe (int index) {
Pipe retPipe = null;
try {
retPipe = pipes.get(index);
}
catch (Exception e) {
System.err.println("Error getting pipe. Index = " + index + ". " + e.getMessage());
}
return retPipe;
}
/** Allows access to the underlying collection of Pipes. Use with caution. */
public ArrayList<Pipe> pipes() {
return pipes;
}
public String toString ()
{
StringBuffer sb = new StringBuffer();
for (Pipe p : pipes)
sb.append (p.toString()+",");
return sb.toString();
}
// Serialization
private static final long serialVersionUID = 1;
private static final int CURRENT_SERIAL_VERSION = 0;
private void writeObject (ObjectOutputStream out) throws IOException {
out.writeInt (CURRENT_SERIAL_VERSION);
out.writeObject(pipes);
}
private void readObject (ObjectInputStream in) throws IOException, ClassNotFoundException {
int version = in.readInt ();
pipes = (ArrayList) in.readObject();
resolveAlphabets();
}
}