@Override
  protected String conditionedApply(
      Operator operator, String operatorTypeName, XMLImporter importer) {
    if (operator.getParameters().isSpecified(parameterName)) {
      try {
        String attributeName = operator.getParameterAsString(parameterName);

        ChangeAttributeRole setRoleOp = OperatorService.createOperator(ChangeAttributeRole.class);

        // inserting operator into process
        ExecutionUnit process = operator.getExecutionUnit();
        int operatorIndex = process.getOperators().indexOf(operator);
        process.addOperator(setRoleOp, operatorIndex + 1);

        // setting parameter
        setRoleOp.setParameter(ChangeAttributeRole.PARAMETER_NAME, attributeName);
        setRoleOp.setParameter(ChangeAttributeRole.PARAMETER_TARGET_ROLE, targetRole);
        return "Inserted operator for explicitly setting attribute <code>"
            + attributeName
            + "</code> to role <code>"
            + targetRole
            + "</code>";
      } catch (UndefinedParameterError e) {
        return null;
      } catch (OperatorCreationException e) {
        return null;
      }
    }
    return null;
  }
 public void actionPerformed(ActionEvent e) {
   Operator selectedOperator = this.actions.getSelectedOperator();
   if (selectedOperator != null) {
     NewBuildingBlockDialog dialog = new NewBuildingBlockDialog();
     dialog.setVisible(true);
     if (dialog.isOk()) {
       try {
         BuildingBlock buildingBlock = dialog.getSelectedBuildingBlock();
         if (buildingBlock != null) {
           String xmlDescription = buildingBlock.getXML();
           try {
             InputSource source = new InputSource(new StringReader(xmlDescription));
             Document document =
                 DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(source);
             Element element = document.getDocumentElement();
             Operator operator =
                 Operator.createFromXML(
                     element,
                     actions.getProcess(),
                     new LinkedList<UnknownParameterInformation>(),
                     null,
                     XMLImporter.CURRENT_VERSION);
             operator.setUserDescription(buildingBlock.getDescription());
             actions.insert(Collections.singletonList(operator));
           } catch (Exception ex) {
             SwingTools.showSimpleErrorMessage(
                 "cannot_instantiate_building_block", ex, buildingBlock.getName());
           }
         }
       } catch (Exception ex) {
         SwingTools.showSimpleErrorMessage("cannot_instantiate_building_block", ex);
       }
     }
   }
 }
  @Override
  public void setSelection(List<Operator> selection) {
    Operator operator = selection.isEmpty() ? null : selection.get(0);
    if (operator == this.operator) {
      return;
    }
    if (this.operator != null) {
      this.operator.getParameters().removeObserver(parameterObserver);
    }
    this.operator = operator;
    if (operator != null) {
      this.operator.getParameters().addObserver(parameterObserver, true);
      breakpointButton.setEnabled(true);

      // compatibility level
      OperatorVersion[] versionChanges = operator.getIncompatibleVersionChanges();
      if (versionChanges.length == 0) {
        // no incompatible versions exist
        compatibilityLevelSpinner.setVisible(false);
        compatibilityLabel.setVisible(false);
      } else {
        compatibilityLevelSpinner.setVisible(true);
        compatibilityLabel.setVisible(true);
        ((CompatibilityLevelSpinnerModel) compatibilityLevelSpinner.getModel())
            .setOperator(operator);
      }

    } else {
      breakpointButton.setEnabled(false);
    }
    setNameFor(operator);
    setupComponents();
  }
  private void enableActionsNow() {
    boolean[] currentStates = new boolean[ConditionalAction.NUMBER_OF_CONDITIONS];
    Operator op = getFirstSelectedOperator();
    if (op != null) {
      currentStates[ConditionalAction.OPERATOR_SELECTED] = true;
      if (op instanceof OperatorChain) {
        currentStates[ConditionalAction.OPERATOR_CHAIN_SELECTED] = true;
      }
      if (op.getParent() == null) {
        currentStates[ConditionalAction.ROOT_SELECTED] = true;
      } else {
        currentStates[ConditionalAction.PARENT_ENABLED] = op.getParent().isEnabled();
        if (op.getExecutionUnit().getNumberOfOperators() > 1) {
          currentStates[ConditionalAction.SIBLINGS_EXIST] = true;
        }
      }
    }

    int processState = process.getProcessState();
    currentStates[ConditionalAction.PROCESS_STOPPED] =
        processState == Process.PROCESS_STATE_STOPPED;
    currentStates[ConditionalAction.PROCESS_PAUSED] = processState == Process.PROCESS_STATE_PAUSED;
    currentStates[ConditionalAction.PROCESS_RUNNING] =
        processState == Process.PROCESS_STATE_RUNNING;
    currentStates[ConditionalAction.EDIT_IN_PROGRESS] = EditBlockingProgressThread.isEditing();
    currentStates[ConditionalAction.PROCESS_SAVED] = process.hasSaveDestination();
    currentStates[ConditionalAction.PROCESS_RENDERER_IS_VISIBLE] =
        mainFrame.getProcessPanel().getProcessRenderer().isShowing();
    currentStates[ConditionalAction.PROCESS_RENDERER_HAS_UNDO_STEPS] = mainFrame.hasUndoSteps();
    currentStates[ConditionalAction.PROCESS_RENDERER_HAS_REDO_STEPS] = mainFrame.hasRedoSteps();
    ConditionalAction.updateAll(currentStates);
    updateCheckboxStates();
  }
  private JComboBox createParameterCombo(String operatorName, PropertyTable propertyTable) {
    JComboBox combo = new JComboBox();

    Operator operator = process.getOperator((String) operatorCombo.getSelectedItem());
    if (operator != null) {
      Iterator<ParameterType> i = operator.getParameters().getParameterTypes().iterator();
      while (i.hasNext()) {
        combo.addItem(i.next().getKey());
      }
    }

    if (combo.getItemCount() == 0) combo.addItem("no parameters");

    combo.addItemListener(
        new ItemListener() {
          public void itemStateChanged(ItemEvent e) {
            fireParameterChangedEvent();
            fireEditingStopped();
          }
        });

    combo.setSelectedIndex(0);

    return combo;
  }
 public void apply(Process process, Map<String, String> nameTranslation) {
   String opName = null;
   if (nameTranslation != null) {
     opName = nameTranslation.get(this.operator);
   }
   if (opName == null) {
     opName = this.operator;
   }
   process
       .getLogger()
       .fine(
           "Setting parameter '"
               + parameterKey
               + "' of operator '"
               + opName
               + "' to '"
               + parameterValue
               + "'.");
   Operator operator = process.getOperator(opName);
   if (operator == null) {
     process.getLogger().warning("No such operator: '" + opName + "'.");
   } else {
     operator.getParameters().setParameter(parameterKey, parameterValue);
   }
 }
 private void updateCheckboxStates() {
   Operator op = getSelectedOperator();
   if (op != null) {
     for (int pos = 0; pos < TOGGLE_BREAKPOINT.length; pos++) {
       TOGGLE_BREAKPOINT[pos].setSelected(op.hasBreakpoint(pos));
     }
     TOGGLE_ACTIVATION_ITEM.setSelected(op.isEnabled());
   }
 }
 /** The currently selected operator will be deleted. */
 public void delete() {
   Operator parent = null;
   for (Operator selectedOperator : new LinkedList<Operator>(getSelectedOperators())) {
     if (parent == null) {
       parent = selectedOperator.getParent();
     }
     if (selectedOperator instanceof ProcessRootOperator) {
       return;
     }
     selectedOperator.remove();
   }
   mainFrame.selectOperator(parent);
 }
  /**
   * Displays an information bubble pointing to an operator to indicate a {@link UserError} was
   * thrown by the operator.
   *
   * @param userError the error instance
   * @return the {@link OperatorInfoBubble} instance, never {@code null}
   */
  public static OperatorInfoBubble displayGenericParameterError(final ParameterError userError) {
    if (userError == null) {
      throw new IllegalArgumentException("userError must not be null!");
    }
    Operator op = userError.getOperator();
    if (op == null) {
      throw new IllegalArgumentException("ParameterError operator must not be null!");
    }
    ParameterType param = op.getParameterType(userError.getKey());
    if (param == null) {
      throw new IllegalArgumentException("ParameterError key must point to a valid ParameterType!");
    }

    return displayGenericParameterError(userError, op, param, "generic_paramerror");
  }
  @Override
  protected List<ParameterType> getProperties() {
    List<ParameterType> visible = new LinkedList<ParameterType>();
    int hidden = 0;
    if (operator != null) {
      for (ParameterType type : operator.getParameters().getParameterTypes()) {
        if (type.isHidden()) {
          continue;
        }
        if (!isExpertMode() && type.isExpert()) {
          hidden++;
          continue;
        }
        visible.add(type);
      }
    }

    if (hidden > 0) {
      expertModeHintLabel.setText(hidden + " hidden expert parameter" + (hidden == 1 ? "" : "s"));
      expertModeHintLabel.setVisible(true);
    } else {
      expertModeHintLabel.setVisible(false);
    }
    return visible;
  }
 /**
  * Returns the specified filename or "OutputFileObject" if the file OutputPort is connected.
  *
  * @return
  * @throws OperatorException
  */
 public String getSelectedFileDescription() throws OperatorException {
   if (!fileOutputPort.isConnected()) {
     return operator.getParameterAsString(fileParameterName);
   } else {
     return "OutputFileObject";
   }
 }
 @Override
 protected void setValue(Operator operator, ParameterType type, String value) {
   if (value.length() == 0) {
     value = null;
   }
   operator.setParameter(type.getKey(), value);
 }
 @Override
 public void update(Observable<String> observable, String key) {
   PropertyValueCellEditor editor = getEditorForKey(key);
   if (editor != null) {
     ParameterType type = operator.getParameters().getParameterType(key);
     String editorValue = type.toString(editor.getCellEditorValue());
     String opValue = operator.getParameters().getParameterOrNull(key);
     if (((opValue != null) && (editorValue == null))
         || ((opValue == null) && (editorValue != null))
         || ((opValue != null) && (editorValue != null) && !opValue.equals(editorValue))) {
       editor.getTableCellEditorComponent(null, opValue, false, 0, 1);
     }
   } else {
     setupComponents();
   }
 }
 private static ParameterType getParameterType(Operator operator, String key) {
   Iterator i = operator.getParameters().getParameterTypes().iterator();
   while (i.hasNext()) {
     ParameterType type = (ParameterType) i.next();
     if (type.getKey().equals(key)) return type;
   }
   return null;
 }
 @Override
 public void apply() {
   RepositoryLocation absLoc;
   try {
     absLoc = operator.getParameterAsRepositoryLocation(key);
     final RepositoryLocation processLoc = operator.getProcess().getRepositoryLocation().parent();
     if (processLoc == null) {
       SwingTools.showVerySimpleErrorMessage(
           "quickfix_failed", "Process is not stored in repository.");
     } else {
       String relative = absLoc.makeRelative(processLoc);
       operator.setParameter(key, relative);
     }
   } catch (UserError e) {
     // Should not happen. Parameter should be set, otherwise we would not have created this
     // prefix.
     SwingTools.showVerySimpleErrorMessage("quickfix_failed", e.toString());
   }
 }
  /**
   * Uses the {@link ExpressionParserBuilder} to create an {@link ExpressionParser} with all modules
   * that are registered to the {@link ExpressionRegistry}.
   *
   * @param op the operator to create the {@link ExpressionParser} for. Must not be {@code null}
   * @param exampleResolver the {@link ExampleResolver} which is used to lookup example values.
   *     Might be {@code null} in case no {@link ExampleResolver} is available
   * @return the build expression parser
   */
  public static ExpressionParser createAllModulesParser(
      final Operator op, final ExampleResolver exampleResolver) {
    ExpressionParserBuilder builder = new ExpressionParserBuilder();

    // decide which functions should be available
    builder.withCompatibility(op.getCompatibilityLevel());

    if (op.getProcess() != null) {
      builder.withProcess(op.getProcess());
      builder.withScope(new MacroResolver(op.getProcess().getMacroHandler(), op));
    }
    if (exampleResolver != null) {
      builder.withDynamics(exampleResolver);
    }

    builder.withModules(ExpressionRegistry.INSTANCE.getAll());

    return builder.build();
  }
  /**
   * Returns an OutputStream, depending on whether the {@link #fileOutputPort} is connected, a file
   * name is given and it should be appended to the end of the file.
   */
  public OutputStream openSelectedFile(boolean append) throws OperatorException {
    if (!fileOutputPort.isConnected()) {
      try {
        return new FileOutputStream(operator.getParameterAsFile(fileParameterName, true), append);
      } catch (FileNotFoundException e) {
        throw new UserError(
            operator, e, 303, operator.getParameterAsFile(fileParameterName), e.getMessage());
      }
    } else {
      return new ByteArrayOutputStream() {

        @Override
        public void close() throws IOException {
          super.close();
          fileOutputPort.deliver(new BufferedFileObject(this.toByteArray()));
        }
      };
    }
  }
  /**
   * Sets the process and the editable parameters.
   *
   * @param parameters A list of String[2] where the first String is the name of the operator and
   *     the second is the name of the parameter.
   */
  public boolean setProcess(Process process, Collection<OperatorParameterPair> parameters) {
    if (process == null) {
      parameters = new LinkedList<OperatorParameterPair>(); // enforce arraylengths = 0
    }
    updateTableData(parameters.size());

    operators = new Operator[parameters.size()];
    parameterTypes = new ParameterType[parameters.size()];

    Iterator<OperatorParameterPair> i = parameters.iterator();
    int j = 0;
    while (i.hasNext()) {
      OperatorParameterPair parameter = i.next();
      Operator operator = process.getOperator(parameter.getOperator());
      operators[j] = operator;
      ParameterType parameterType = getParameterType(operator, parameter.getParameter());
      if (operator == null || parameterType == null) {
        updateTableData(0); // enforce size of 0
        return false;
      }
      parameterTypes[j] = parameterType;
      getModel().setValueAt(operator.getName() + "." + parameterTypes[j].getKey(), j, 0);
      Object value = parameterTypes[j].getDefaultValue();
      try {
        value = operator.getParameters().getParameter(parameterTypes[j].getKey());
      } catch (UndefinedParameterError e) {
        // tries non default value. Fail --> default
      }
      getModel().setValueAt(value, j, 1);
      j++;
    }
    updateEditorsAndRenderers();

    getModel()
        .addTableModelListener(
            new TableModelListener() {
              public void tableChanged(TableModelEvent e) {
                setValue(e.getFirstRow(), getModel().getValueAt(e.getFirstRow(), 1));
              }
            });
    return true;
  }
  /**
   * Displays an information bubble that alerts the user that the attribute specified in the
   * operator parameters was not found. The bubble is located at the operator and the process view
   * will change to said operator. This method is used after the error occurred during process
   * execution.
   *
   * @param error the error containing all the information about the operator, the parameter and the
   *     name of the attribute which was not found
   * @param i18nKey the i18n key which defines the title, text and button label for the bubble.
   *     Format is "gui.bubble.{i18nKey}.title", "gui.bubble.{i18nKey}.body" and
   *     "gui.bubble.{i18nKey}.button.label".
   * @param isError if {@code true}, an error bubble will be shown; otherwise a warning bubble is
   *     displayed
   * @param arguments optional i18n arguments
   * @return the {@link OperatorInfoBubble} instance, never {@code null}
   */
  private static OperatorInfoBubble displayAttributeNotFoundParameterInformation(
      final AttributeNotFoundError error,
      final boolean isError,
      final String i18nKey,
      final Object... arguments) {
    final Operator op = error.getOperator();
    final ParameterType param = op.getParameterType(error.getKey());
    final JButton ackButton =
        new JButton(I18N.getGUIMessage("gui.bubble." + i18nKey + ".button.label", arguments));
    ackButton.setToolTipText(I18N.getGUIMessage("gui.bubble." + i18nKey + ".button.tip"));

    String decoratorKey =
        param instanceof CombinedParameterType || param instanceof ParameterTypeAttributes
            ? "attributes_not_found_decoration"
            : "attribute_not_found_decoration";

    ParameterErrorBubbleBuilder builder =
        new ParameterErrorBubbleBuilder(
            RapidMinerGUI.getMainFrame(), op, param, decoratorKey, i18nKey, arguments);
    final ParameterErrorInfoBubble attributeNotFoundParameterBubble =
        builder
            .setHideOnDisable(true)
            .setAlignment(AlignedSide.BOTTOM)
            .setStyle(isError ? BubbleStyle.ERROR : BubbleStyle.WARNING)
            .setEnsureVisible(true)
            .hideCloseButton()
            .setHideOnProcessRun(true)
            .setAdditionalComponents(new JComponent[] {ackButton})
            .build();

    ackButton.addActionListener(
        new ActionListener() {

          @Override
          public void actionPerformed(ActionEvent e) {
            attributeNotFoundParameterBubble.killBubble(true);
          }
        });

    attributeNotFoundParameterBubble.setVisible(true);
    return attributeNotFoundParameterBubble;
  }
 @Override
 public void execute(ExecutionUnit unit) throws OperatorException {
   Logger logger = unit.getEnclosingOperator().getLogger();
   if (logger.isLoggable(Level.FINE)) {
     logger.fine(
         "Executing subprocess "
             + unit.getEnclosingOperator().getName()
             + "."
             + unit.getName()
             + ". Execution order is: "
             + unit.getOperators());
   }
   Enumeration<Operator> opEnum = unit.getOperatorEnumeration();
   while (opEnum.hasMoreElements()) {
     // for (Operator operator : unit.getOperators()) {
     Operator operator = opEnum.nextElement();
     operator.execute();
     operator.freeMemory();
   }
 }
 /**
  * Same as {@link #getSelectedFile()}, but returns true if file is specified (in the respective
  * way).
  */
 public boolean isFileSpecified() {
   if (!fileOutputPort.isConnected()) {
     return operator.isParameterSet(fileParameterName);
   } else {
     try {
       return (fileOutputPort.getData(IOObject.class) instanceof FileObject);
     } catch (OperatorException e) {
       return false;
     }
   }
 }
 private void fill(Operator root) {
   int numTotal = root.getProcess().getRootOperator().getErrorList().size();
   errors = root.getErrorList();
   String errorString;
   switch (errors.size()) {
     case 0:
       errorString = "No problems found";
       break;
     case 1:
       errorString = "One potential problem";
       break;
     default:
       errorString = errors.size() + " potential problems";
       break;
   }
   if (errors.size() != numTotal) {
     errorString = errorString + " (" + (numTotal - errors.size()) + " Filtered)";
   }
   headerLabel.setText(errorString);
   model.fireTableDataChanged();
 }
Example #23
0
  public IOObject[] apply() throws OperatorException {
    ExampleSet eSet = getInput(ExampleSet.class);

    // only warning, removing is done by createSpecialAttribute(...)
    Attribute idAttribute = eSet.getAttributes().getId();
    if (idAttribute != null) {
      logWarning("Overwriting old id attribute!");
    }

    // create new id attribute
    boolean nominalIds = getParameterAsBoolean(PARAMETER_CREATE_NOMINAL_IDS);
    idAttribute =
        Tools.createSpecialAttribute(
            eSet, Attributes.ID_NAME, nominalIds ? Ontology.NOMINAL : Ontology.INTEGER);

    // set IDs
    int currentId = 1;
    Iterator<Example> r = eSet.iterator();
    while (r.hasNext()) {
      Example example = r.next();
      example.setValue(
          idAttribute,
          nominalIds ? idAttribute.getMapping().mapString("id_" + currentId) : currentId);
      currentId++;
      checkForStop();
    }

    // initialize example visualizer
    Operator visualizer = null;
    try {
      visualizer = OperatorService.createOperator(ExampleVisualizationOperator.class);
    } catch (OperatorCreationException e) {
      logNote("Cannot initialize example visualizer, skipping...");
    }
    if (visualizer != null) visualizer.apply(new IOContainer(eSet));

    return new IOObject[] {eSet};
  }
  /**
   * Displays a warning bubble that alerts the user that a mandatory parameter of an operator needs
   * a value because it has no default value. The bubble is located at the operator and the process
   * view will change to said operator. This is a bubble which occurs during the check for errors
   * before process execution so it contains a link button to disable pre-execution checks.
   *
   * @param op the operator for which to display the warning
   * @param param the parameter for which to display the warning
   * @return the {@link OperatorInfoBubble} instance, never {@code null}
   */
  public static OperatorInfoBubble displayPrecheckMissingMandatoryParameterWarning(
      final Operator op, final ParameterType param) {
    if (op == null) {
      throw new IllegalArgumentException("op must not be null!");
    }
    if (param == null) {
      throw new IllegalArgumentException("param must not be null!");
    }

    // not the user entered name because that could be god knows how long
    String opName = op.getOperatorDescription().getName();
    return displayPrecheckMissingParameterWarning(
        op, param, false, "process_precheck_mandatory_parameter_unset", opName, param.getKey());
  }
Example #25
0
  /**
   * The given operators will be inserted at the last position of the currently selected operator
   * chain.
   */
  public void insert(List<Operator> newOperators) {
    Object selectedNode = getSelectedOperator();
    if (selectedNode == null) {
      SwingTools.showVerySimpleErrorMessage("cannot_insert_operator");
      return;
    } else if (mainFrame.getProcessPanel().getProcessRenderer().getModel().getDisplayedChain()
        == selectedNode) {
      for (Operator newOperator : newOperators) {
        int index =
            mainFrame
                .getProcessPanel()
                .getProcessRenderer()
                .getProcessIndexUnder(
                    mainFrame
                        .getProcessPanel()
                        .getProcessRenderer()
                        .getModel()
                        .getCurrentMousePosition());
        if (index == -1) {
          index = 0;
        }
        ((OperatorChain) selectedNode).getSubprocess(index).addOperator(newOperator);
      }
    } else {
      int i = 0;
      Operator selectedOperator = (Operator) selectedNode;
      ExecutionUnit process = selectedOperator.getExecutionUnit();
      int parentIndex = process.getOperators().indexOf(selectedOperator) + 1;
      for (Operator newOperator : newOperators) {
        process.addOperator(newOperator, parentIndex + i);
        i++;
      }
    }

    AutoWireThread.autoWireInBackground(newOperators, true);
    mainFrame.selectOperators(newOperators);
  }
        /** Draws the operator annoations. */
        private void draw(
            final ExecutionUnit process,
            final Graphics2D g2,
            final ProcessRendererModel rendererModel,
            final boolean printing) {
          if (!visualizer.isActive()) {
            return;
          }

          // operator attached annotations
          List<Operator> selectedOperators = rendererModel.getSelectedOperators();
          for (Operator operator : process.getOperators()) {
            if (selectedOperators.contains(operator)) {
              continue;
            }
            drawOpAnno(operator, g2, rendererModel, printing);
          }
          // selected operators annotations need to be drawn over non selected ones
          for (Operator selOp : selectedOperators) {
            if (process.equals(selOp.getExecutionUnit())) {
              drawOpAnno(selOp, g2, rendererModel, printing);
            }
          }
        }
  /**
   * Displays an error bubble that alerts the user that a mandatory parameter of an operator was not
   * set and has no default value. The bubble is located at the operator and the process view will
   * change to said port. This method is used after the error occurred during process execution.
   *
   * @param op the operator for which to display the error
   * @param param the parameter for which to display the error
   * @return the {@link OperatorInfoBubble} instance, never {@code null}
   */
  public static OperatorInfoBubble displayMissingMandatoryParameterInformation(
      final Operator op, final ParameterType param) {
    if (op == null) {
      throw new IllegalArgumentException("op must not be null!");
    }
    if (param == null) {
      throw new IllegalArgumentException("param must not be null!");
    }

    String key = "process_mandatory_parameter_missing";
    // not the user entered name because that could be god knows how long
    String opName = op.getOperatorDescription().getName();
    return displayMissingMandatoryParameterInformation(
        op, param, true, key, opName, param.getKey());
  }
  private void setNameFor(Operator operator) {
    if (operator != null) {
      headerLabel.setFont(selectedFont);
      if (operator.getName().equals(operator.getOperatorDescription().getName())) {
        headerLabel.setText(operator.getName());
      } else {
        headerLabel.setText(
            operator.getName() + " (" + operator.getOperatorDescription().getName() + ")");
      }
      headerLabel.setIcon(operator.getOperatorDescription().getSmallIcon());

    } else {
      headerLabel.setFont(unselectedFont);
      headerLabel.setText("No Operator Selected");
      headerLabel.setIcon(null);
    }
  }
  /**
   * Parses the provided expression and iterates over the {@link ExampleSet}, interprets attributes
   * as variables, evaluates the function and creates a new attribute with the given name that takes
   * the expression's value. The type of the attribute depends on the expression type and is {@link
   * Ontology#NOMINAL} for strings, {@link Ontology#INTEGER} for integers, {@link Ontology#REAL} for
   * reals, {@link Ontology#DATE_TIME} for Dates, and {@link Ontology#BINOMINAL} with values
   * &quot;true&quot; and &quot;false&quot; for booleans. If the executing operator is defined,
   * there will be a check for stop before the calculation of each example.
   *
   * @param exampleSet the example set to which the generated attribute is added
   * @param name the new attribute name
   * @param expression the expression used to generate attribute values
   * @param parser the expression parser used to parse the expression argument
   * @param resolver the example resolver which is used by the parser to resolve example values
   * @param executingOperator the operator calling this method. <code>null</code> is allowed. If not
   *     null the operator will be used to check for stop
   * @throws ProcessStoppedException in case the process was stopped by the user
   * @throws ExpressionException in case parsing the expression fails
   */
  public static Attribute addAttribute(
      ExampleSet exampleSet,
      String name,
      String expression,
      ExpressionParser parser,
      ExampleResolver resolver,
      Operator executingOperator)
      throws ProcessStoppedException, ExpressionException {

    // parse the expression
    Expression parsedExpression = parser.parse(expression);

    Attribute newAttribute = null;
    // if != null this needs to be overridden
    Attribute existingAttribute = exampleSet.getAttributes().get(name);
    StringBuffer appendix = new StringBuffer();
    String targetName = name;
    if (existingAttribute != null) {
      // If an existing attribute will be overridden, first a unique temporary name has to be
      // generated by appending a random string to the attribute's name until it's a unique
      // attribute name. After the new attribute is build, it's name is set the 'targetName'
      // at the end of this method.
      //
      do {
        appendix.append(RandomGenerator.getGlobalRandomGenerator().nextString(5));
      } while (exampleSet.getAttributes().get(name + appendix.toString()) != null);
      name = name + appendix.toString();
    }

    ExpressionType resultType = parsedExpression.getExpressionType();
    int ontology = resultType.getAttributeType();
    if (ontology == Ontology.BINOMINAL) {
      newAttribute = AttributeFactory.createAttribute(name, Ontology.BINOMINAL);
      newAttribute.getMapping().mapString("false");
      newAttribute.getMapping().mapString("true");
    } else {
      newAttribute = AttributeFactory.createAttribute(name, ontology);
    }

    // set construction description
    newAttribute.setConstruction(expression);

    // add new attribute to table and example set
    exampleSet.getExampleTable().addAttribute(newAttribute);
    exampleSet.getAttributes().addRegular(newAttribute);

    // create attribute of correct type and all values
    for (Example example : exampleSet) {
      if (executingOperator != null) {
        executingOperator.checkForStop();
      }

      // bind example to resolver
      resolver.bind(example);

      // calculate result
      try {
        switch (resultType) {
          case DOUBLE:
          case INTEGER:
            example.setValue(newAttribute, parsedExpression.evaluateNumerical());
            break;
          case DATE:
            Date date = parsedExpression.evaluateDate();
            example.setValue(newAttribute, date == null ? Double.NaN : date.getTime());
            break;
          default:
            example.setValue(newAttribute, parsedExpression.evaluateNominal());
            break;
        }
      } finally {
        // avoid memory leaks
        resolver.unbind();
      }
    }

    // remove existing attribute (if necessary)
    if (existingAttribute != null) {
      AttributeRole oldRole = exampleSet.getAttributes().getRole(existingAttribute);
      exampleSet.getAttributes().remove(existingAttribute);
      newAttribute.setName(targetName);
      // restore role from old attribute to new attribute
      if (oldRole.isSpecial()) {
        exampleSet.getAttributes().setSpecialAttribute(newAttribute, oldRole.getSpecialName());
      }
    }

    // update example resolver after meta data change
    resolver.addAttributeMetaData(
        new AttributeMetaData(exampleSet.getAttributes().getRole(newAttribute), exampleSet, true));

    return newAttribute;
  }
 /** Parses a parameter list and creates the corresponding data structures. */
 public List<ParameterValues> parseParameterValues(List<String[]> parameterList)
     throws OperatorException {
   if (getProcess() == null) {
     getLogger().warning("Cannot parse parameters while operator is not attached to a process.");
     return Collections.<ParameterValues>emptyList();
   }
   List<ParameterValues> parameterValuesList = new LinkedList<ParameterValues>();
   for (String[] pair : parameterList) {
     String[] operatorParameter = ParameterTypeTupel.transformString2Tupel(pair[0]);
     if (operatorParameter.length != 2) throw new UserError(this, 907, pair[0]);
     Operator operator = lookupOperator(operatorParameter[0]);
     if (operator == null) throw new UserError(this, 109, operatorParameter[0]);
     ParameterType parameterType = operator.getParameters().getParameterType(operatorParameter[1]);
     if (parameterType == null) {
       throw new UserError(this, 906, operatorParameter[0] + "." + operatorParameter[1]);
     }
     String parameterValuesString = pair[1];
     ParameterValues parameterValues = null;
     try {
       int startIndex = parameterValuesString.indexOf("[");
       if (startIndex >= 0) {
         int endIndex = parameterValuesString.indexOf("]");
         if (endIndex > startIndex) {
           String[] parameterValuesArray =
               parameterValuesString.substring(startIndex + 1, endIndex).trim().split("[;:,]");
           switch (parameterValuesArray.length) {
             case PARAMETER_VALUES_ARRAY_LENGTH_RANGE:
               { // value range: [minValue;maxValue]
                 //							double min = Double.parseDouble(parameterValuesArray[0]);
                 //							double max = Double.parseDouble(parameterValuesArray[1]);
                 parameterValues =
                     new ParameterValueRange(
                         operator,
                         parameterType,
                         parameterValuesArray[0],
                         parameterValuesArray[1]);
               }
               break;
             case PARAMETER_VALUES_ARRAY_LENGTH_GRID:
               { // value grid: [minValue;maxValue;stepSize]
                 //							double min = Double.parseDouble(parameterValuesArray[0]);
                 //							double max = Double.parseDouble(parameterValuesArray[1]);
                 //							double stepSize = Double.parseDouble(parameterValuesArray[2]);
                 //							if (stepSize == 0) {
                 //								throw new Exception("step size of 0 is not allowed");
                 //							}
                 //							if (min <= max + stepSize) {
                 //								throw new Exception("end value must at least be as large as start value
                 // plus step size");
                 //							}
                 parameterValues =
                     new ParameterValueGrid(
                         operator,
                         parameterType,
                         parameterValuesArray[0],
                         parameterValuesArray[1],
                         parameterValuesArray[2]);
               }
               break;
             case PARAMETER_VALUES_ARRAY_LENGTH_SCALED_GRID:
               { // value grid: [minValue;maxValue;noOfSteps;scale]
                 //							double min = Double.parseDouble(parameterValuesArray[0]);
                 //							double max = Double.parseDouble(parameterValuesArray[1]);
                 //							int steps = Integer.parseInt(parameterValuesArray[2]);
                 //							if (steps == 0) {
                 //								throw new Exception("step size of 0 is not allowed");
                 //							}
                 //							String scaleName = parameterValuesArray[3];
                 parameterValues =
                     new ParameterValueGrid(
                         operator,
                         parameterType,
                         parameterValuesArray[0],
                         parameterValuesArray[1],
                         parameterValuesArray[2],
                         parameterValuesArray[3]);
               }
               break;
             default:
               throw new Exception(
                   "parameter values string could not be parsed (too many arguments)");
           }
         } else {
           throw new Exception("']' was missing");
         }
       } else {
         int colonIndex = parameterValuesString.indexOf(":");
         if (colonIndex >= 0) {
           // maintain compatibility for evolutionary parameter optimization (old format:
           // startValue:endValue without parantheses)
           String[] parameterValuesArray = parameterValuesString.trim().split(":");
           if (parameterValuesArray.length != 2) {
             throw new Exception("wrong parameter range format");
           } else {
             //							double min = Double.parseDouble(parameterValuesArray[0]);
             //							double max = Double.parseDouble(parameterValuesArray[1]);
             parameterValues =
                 new ParameterValueRange(
                     operator, parameterType, parameterValuesArray[0], parameterValuesArray[1]);
           }
         } else {
           // usual parameter value list: value1,value2,value3,...
           if (parameterValuesString.length() != 0) {
             String[] values = parameterValuesString.split(",");
             parameterValues = new ParameterValueList(operator, parameterType, values);
           }
         }
       }
     } catch (Throwable e) {
       throw new UserError(
           this,
           116,
           pair[0],
           "Unknown parameter value specification format: '"
               + pair[1]
               + "'. Error: "
               + e.getMessage());
     }
     if (parameterValues != null) {
       parameterValuesList.add(parameterValues);
     }
   }
   return parameterValuesList;
 }