/* * RapidMiner * * Copyright (C) 2001-2008 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.meta.branch; import java.util.List; import com.rapidminer.operator.IOContainer; import com.rapidminer.operator.IOObject; import com.rapidminer.operator.OperatorChain; import com.rapidminer.operator.OperatorDescription; import com.rapidminer.operator.OperatorException; import com.rapidminer.operator.UserError; import com.rapidminer.operator.condition.InnerOperatorCondition; import com.rapidminer.operator.condition.SimpleChainInnerOperatorCondition; import com.rapidminer.operator.preprocessing.filter.ExampleFilter; import com.rapidminer.parameter.ParameterType; import com.rapidminer.parameter.ParameterTypeString; import com.rapidminer.parameter.ParameterTypeStringCategory; import com.rapidminer.tools.Tools; /** * <p>This operator provides a conditional execution of parts of processes. * It has to have two OperatorChains as childs. The first chain is processed * if the specified condition is true, the second one is processed if it is false * (if-then-else). The second chain may be omitted (if-then). In this case, this * operator has only one inner operator.</p> * * <p> * If the condition "attribute_value_filter" is used, the same attribute * value conditions already known from the {@link ExampleFilter} operator can be used. * In addition to the known attribute value relation format (e.g. "att1>=0.7"), * this operator expects an additional definition for the used example which cam be added in * "[" and "]" after the attribute value condition. The following values * are possible: * <ul> * <li>a fixed number, e.g. "att1>0.7 [7]" meaning that the value for attribute * "att1" for the example 7 must be greater than 0.7</li> * <li>the wildcard "*" meaning that the attribute value condition must be * fulfilled for all examples, e.g. "att4<=5 [*]"</li> * <li>no example definition, meaning the same as the wildcard definition [*]</li> * </ul> * </p> * * @author Sebastian Land, Ingo Mierswa * @version $Id: ProcessBranch.java,v 1.11 2008/07/07 07:06:48 ingomierswa Exp $ */ public class ProcessBranch extends OperatorChain { public static final String PARAMETER_CONDITION_TYPE = "condition_type"; public static final String PARAMETER_CONDITION_VALUE = "condition_value"; public static final String[] CONDITION_NAMES = { "file_exists", "min_fitness", "max_fitness", "min_performance_value", "max_performance_value", "attribute_value_filter" }; public static final Class[] CONDITION_CLASSES = { FileExistsCondition.class, MinFitnessCondition.class, MaxFitnessCondition.class, MinPerformanceValueCondition.class, MaxPerformanceValueCondition.class, DataValueCondition.class }; public ProcessBranch(OperatorDescription description) { super(description); } public IOObject[] apply() throws OperatorException { IOContainer input = getInput(); // creating condition Class conditionClass = null; String selectedConditionName = ""; try { selectedConditionName = getParameterAsString(PARAMETER_CONDITION_TYPE); for (int i = 0; i < CONDITION_NAMES.length; i++) { if (selectedConditionName.toLowerCase().equals(CONDITION_NAMES[i].toLowerCase())) { conditionClass = CONDITION_CLASSES[i]; break; } } if (conditionClass == null) { try { conditionClass = Tools.classForName(selectedConditionName); } catch (ClassNotFoundException e) { throw new UserError(this, e, 904, new Object[] { selectedConditionName, e }); } } ProcessBranchCondition condition = null; try { condition = (ProcessBranchCondition) conditionClass.newInstance(); } catch (InstantiationException e) { throw new UserError(this, e, 904, new Object[] { selectedConditionName, e }); } catch (IllegalAccessException e) { throw new UserError(this, e, 904, new Object[] { selectedConditionName, e }); } if (condition != null) { // checking condition boolean conditionState = condition.check(this, getParameterAsString(PARAMETER_CONDITION_VALUE)); // execute if (conditionState) { return getOperator(0).apply(input).getIOObjects(); } else { if (getNumberOfOperators() > 1) { return getOperator(1).apply(input).getIOObjects(); } else { return input.getIOObjects(); } } } else { return input.getIOObjects(); } } catch (Exception e) { throw new UserError(this, e, 904, new Object[] {selectedConditionName, e }); } } public Class<?>[] getInputClasses() { return new Class[0]; } public Class<?>[] getOutputClasses() { return new Class[0]; } public InnerOperatorCondition getInnerOperatorCondition() { return new SimpleChainInnerOperatorCondition(); } public int getMaxNumberOfInnerOperators() { return 2; } public int getMinNumberOfInnerOperators() { return 1; } public List<ParameterType> getParameterTypes() { List<ParameterType> types = super.getParameterTypes(); types.add(new ParameterTypeStringCategory(PARAMETER_CONDITION_TYPE, "The condition which is used for the condition check.", CONDITION_NAMES)); types.add(new ParameterTypeString(PARAMETER_CONDITION_VALUE, "A condition parameter which might be desired for some condition checks.", true)); return types; } }