/* * RapidMiner * * Copyright (C) 2001-2011 by Rapid-I and the contributors * * Complete list of developers available at our web site: * * http://rapid-i.com * * 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.rapidminer.operator.ports; import com.rapidminer.operator.IOObject; import com.rapidminer.operator.IOObjectCollection; import com.rapidminer.operator.ports.metadata.CollectionMetaData; import com.rapidminer.operator.ports.metadata.MetaData; /** This port pair extender offers the ability to collect data at its input * ports over several iterations and deliver it to its output ports as a * collection.<br/> * * Usage: call {@link #reset()} before beginning the loop and {@link #collect()} in * every iteration. * * * @author Simon Fischer */ public class CollectingPortPairExtender extends PortPairExtender { public CollectingPortPairExtender(String name, InputPorts inPorts, OutputPorts outPorts) { super(name, inPorts, outPorts); } @Override protected MetaData transformMetaData(MetaData md) { return new CollectionMetaData(md); } /** Resets all output ports by delivering empty collection to all output ports for * which the input port is connected and clearing others. */ public void reset() { for (PortPair pair : getManagedPairs()) { if (pair.getInputPort().isConnected()) { pair.getOutputPort().deliver(new IOObjectCollection<IOObject>()); } else { pair.getOutputPort().clear(Port.CLEAR_DATA); } } } /** For all input ports that have data, this data is added to the collection currently assigned * to the output port. */ @SuppressWarnings("unchecked") public void collect() { synchronized (this) { for (PortPair pair : getManagedPairs()) { IOObject data = pair.getInputPort().getAnyDataOrNull(); if (data != null) { IOObject output = pair.getOutputPort().getAnyDataOrNull(); if (output == null) { // first iteration IOObjectCollection<IOObject> collection = new IOObjectCollection<IOObject>(); collection.add(data); pair.getOutputPort().deliver(collection); } else if (output instanceof IOObjectCollection){ ((IOObjectCollection<IOObject>)output).add(data); pair.getOutputPort().deliver(output); // necessary to trigger updates } else { pair.getOutputPort().getPorts().getOwner().getOperator().getLogger().warning("Cannot collect output at "+pair.getOutputPort().getSpec()+": data is of type " + output.getClass().getName()+ "."); } } } } } }