/** * Copyright (C) 2001-2017 by RapidMiner and the contributors * * Complete list of developers available at our web site: * * http://rapidminer.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 java.util.ArrayList; import java.util.List; import com.rapidminer.operator.IOObject; import com.rapidminer.operator.UserError; import com.rapidminer.operator.ports.metadata.CollectionMetaData; import com.rapidminer.operator.ports.metadata.MetaData; /** * In addition to {@link CollectingPortPairExtender}, this extender can toggle between returning a * collection and a single {@link IOObject}. See {@link CollectingPortPairExtender} for details. * * @author Marco Boeck * @since 7.4 */ public class CollectingOrIteratingPortPairExtender extends CollectingPortPairExtender { /** * The mode for the {@link CollectingOrIteratingPortPairExtender} which defines if the ports * should pass on collections or single data entries. * */ public static enum PortOutputMode { /** ports pass on a collection of {@link IOObject}s */ COLLECTING, /** ports pass on single {@link IOObject}s */ ITERATING; } private PortOutputMode outputMode = PortOutputMode.COLLECTING; public CollectingOrIteratingPortPairExtender(String name, InputPorts inPorts, OutputPorts outPorts) { super(name, inPorts, outPorts); } @Override protected MetaData transformMetaData(MetaData md) { return outputMode == PortOutputMode.COLLECTING ? new CollectionMetaData(md) : md; } /** * Changes the output mode of the port pair extender. See {@link PortOutputMode} for details. * * @param outputMode * one of {@link PortOutputMode}, must not be {@code null} */ public void setOutputMode(PortOutputMode outputMode) { if (outputMode == null) { throw new IllegalArgumentException("outputMode must not be null!"); } this.outputMode = outputMode; } /** * Returns the output mode of the port pair extender. See {@link PortOutputMode} for details. * * @return the mode, never {@code null} */ public PortOutputMode getOutputMode() { return outputMode; } /** * Resets all output ports by clearing them. */ @Override public void reset() { for (PortPair pair : getManagedPairs()) { pair.getOutputPort().clear(Port.CLEAR_DATA); } } /** * Same as {@link CollectingPortPairExtender#getData(Class)} but does not omit {@code null} * results. This ensures the correct result order in the process view on the operator output * ports. */ @Override public <T extends IOObject> List<T> getData(Class<T> desiredClass) throws UserError { List<PortPair> managedPairs = getManagedPairs(); List<T> results = new ArrayList<T>(managedPairs.size()); for (PortPair pair : managedPairs) { T data = pair.getInputPort().<T> getDataOrNull(desiredClass); results.add(data); } return results; } @Override public void collect() { // only collect if mode is set correctly if (outputMode != PortOutputMode.COLLECTING) { return; } super.collect(); // now clear all input ports to avoid multiple entries if multiple iterations are collected synchronized (this) { for (PortPair pair : getManagedPairs()) { pair.getInputPort().clear(InputPort.CLEAR_DATA); } } } }