/*
* 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.collections;
import java.util.List;
import com.rapidminer.operator.IOObject;
import com.rapidminer.operator.IOObjectCollection;
import com.rapidminer.operator.Operator;
import com.rapidminer.operator.OperatorDescription;
import com.rapidminer.operator.OperatorException;
import com.rapidminer.operator.ProcessSetupError.Severity;
import com.rapidminer.operator.ports.InputPort;
import com.rapidminer.operator.ports.InputPortExtender;
import com.rapidminer.operator.ports.OutputPort;
import com.rapidminer.operator.ports.metadata.CollectionMetaData;
import com.rapidminer.operator.ports.metadata.MDTransformationRule;
import com.rapidminer.operator.ports.metadata.MetaData;
import com.rapidminer.operator.ports.metadata.SimpleMetaDataError;
import com.rapidminer.parameter.ParameterType;
import com.rapidminer.parameter.ParameterTypeBoolean;
/** Takes several objects as an input at converts them into a collection.
*
* @author Simon Fischer
*/
public class CollectionOperator extends Operator {
public static final String PARAMETER_UNFOLD = "unfold";
private final InputPortExtender inExtender = new InputPortExtender("input", getInputPorts());
private final OutputPort collectionOutput = getOutputPorts().createPort("collection");
public CollectionOperator(OperatorDescription description) {
super(description);
inExtender.start();
getTransformer().addRule(new MDTransformationRule() {
@Override
public void transformMD() {
boolean unfold = getParameterAsBoolean(PARAMETER_UNFOLD);
MetaData commonSupertype = null;
for (InputPort in : inExtender.getManagedPorts()) {
MetaData md = in.getMetaData();
if (unfold && (md instanceof CollectionMetaData)) {
md = ((CollectionMetaData)md).getElementMetaDataRecursive();
}
if (md == null) {
continue;
} else if (commonSupertype == null) {
commonSupertype = md;
continue;
} else {
if (commonSupertype.getObjectClass().equals(md.getObjectClass())) {
continue;
} else if (commonSupertype.getObjectClass().isAssignableFrom(md.getObjectClass())) {
commonSupertype = md;
} else if (md.getObjectClass().isAssignableFrom(commonSupertype.getObjectClass())) {
// noop, old value was ok
//commonSupertype = commonSupertype;
} else {
in.addError(new SimpleMetaDataError(Severity.WARNING, in, "incompatible_ioobjects", commonSupertype.getObjectClass().getSimpleName(), md.getObjectClass().getSimpleName()));
collectionOutput.deliverMD(new CollectionMetaData(new MetaData()));
return;
}
}
}
collectionOutput.deliverMD(new CollectionMetaData(commonSupertype));
}
});
}
@Override
public void doWork() throws OperatorException {
List<IOObject> list = inExtender.getData(getParameterAsBoolean(PARAMETER_UNFOLD));
collectionOutput.deliver(new IOObjectCollection<IOObject>(list));
}
@Override
public List<ParameterType> getParameterTypes() {
List<ParameterType> types = super.getParameterTypes();
types.add(new ParameterTypeBoolean(PARAMETER_UNFOLD, "Determines whether collections received at the input ports are unfolded.", false));
return types;
}
}