/**
  * 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";
   }
 }
  /**
   * Moves the operators from this process to another process, keeping all connections intact. TODO:
   * Test more rigorously. Do we register/unregister everything correctly?
   *
   * @return the number of ports the connections of which could not be restored
   */
  public int stealOperatorsFrom(ExecutionUnit otherUnit) {
    int failedReconnects = 0;

    // remember source and sink connections so we can reconnect them later.
    Map<String, InputPort> sourceMap = new HashMap<String, InputPort>();
    Map<String, OutputPort> sinkMap = new HashMap<String, OutputPort>();
    for (OutputPort source : otherUnit.getInnerSources().getAllPorts()) {
      if (source.isConnected()) {
        sourceMap.put(source.getName(), source.getDestination());
      }
    }
    otherUnit.getInnerSources().disconnectAll();
    for (InputPort sink : otherUnit.getInnerSinks().getAllPorts()) {
      if (sink.isConnected()) {
        sinkMap.put(sink.getName(), sink.getSource());
      }
    }
    otherUnit.getInnerSinks().disconnectAll();

    // Move operators
    Iterator<Operator> i = otherUnit.operators.iterator();
    while (i.hasNext()) {
      Operator operator = i.next();
      i.remove();
      otherUnit.unregister(operator);
      Process otherProcess = operator.getProcess();
      if (otherProcess != null) {
        operator.unregisterOperator(otherProcess);
      }
      this.operators.add(operator);
      operator.setEnclosingProcess(null);
      // operator.unregisterOperator(operator.getProcess());
      registerOperator(operator, true);
      // operator.registerOperator(this.getEnclosingOperator().getProcess());
    }

    // Rewire sources and sinks
    for (Map.Entry<String, InputPort> entry : sourceMap.entrySet()) {
      OutputPort mySource = getInnerSources().getPortByName(entry.getKey());
      if (mySource != null) {
        mySource.connectTo(entry.getValue());
      } else {
        failedReconnects++;
      }
    }
    getInnerSources().unlockPortExtenders();

    for (Map.Entry<String, OutputPort> entry : sinkMap.entrySet()) {
      InputPort mySink = getInnerSinks().getPortByName(entry.getKey());
      if (mySink != null) {
        entry.getValue().connectTo(mySink);
      } else {
        failedReconnects++;
      }
    }
    getInnerSinks().unlockPortExtenders();

    fireUpdate(this);
    return failedReconnects;
  }
  @Override
  public final void doWork() throws OperatorException {
    ExampleSet inputExampleSet = exampleSetInput.getData(ExampleSet.class);
    ExampleSet applySet = null;
    // check for needed copy of original exampleset
    if (originalOutput.isConnected() && writesIntoExistingData()) {
      int type = DataRowFactory.TYPE_DOUBLE_ARRAY;
      if (inputExampleSet.getExampleTable() instanceof MemoryExampleTable) {
        DataRowReader dataRowReader = inputExampleSet.getExampleTable().getDataRowReader();
        if (dataRowReader.hasNext()) {
          type = dataRowReader.next().getType();
        }
      }
      // check if type is supported to be copied
      if (type >= 0) {
        applySet = MaterializeDataInMemory.materializeExampleSet(inputExampleSet, type);
      }
    }

    if (applySet == null) applySet = (ExampleSet) inputExampleSet.clone();

    // we apply on the materialized data, because writing can't take place in views anyway.
    ExampleSet result = apply(applySet);
    originalOutput.deliver(inputExampleSet);
    exampleSetOutput.deliver(result);
  }
 private void addReadyOutputs(LinkedList<OutputPort> readyOutputs, OutputPorts ports) {
   // add the parameters in a stack-like fashion like in pre-5.0
   // Iterator<OutputPort> i = ports.getAllPorts().iterator();
   Iterator<OutputPort> i = new LinkedList<OutputPort>(ports.getAllPorts()).descendingIterator();
   while (i.hasNext()) {
     OutputPort port = i.next();
     if (!port.isConnected() && port.shouldAutoConnect()) {
       readyOutputs.addLast(port);
     }
   }
 }
 /**
  * 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;
     }
   }
 }
  @Override
  public void doWork() throws OperatorException {
    ExampleSet exampleSet = exampleSetInput.getData(ExampleSet.class);

    // only use numeric attributes
    Tools.onlyNumericalAttributes(exampleSet, "KernelPCA");
    Tools.onlyNonMissingValues(exampleSet, getOperatorClassName(), this);

    Attributes attributes = exampleSet.getAttributes();
    int numberOfExamples = exampleSet.size();

    // calculating means for later zero centering
    exampleSet.recalculateAllAttributeStatistics();
    double[] means = new double[exampleSet.getAttributes().size()];
    int i = 0;
    for (Attribute attribute : exampleSet.getAttributes()) {
      means[i] = exampleSet.getStatistics(attribute, Statistics.AVERAGE);
      i++;
    }

    // kernel
    Kernel kernel = Kernel.createKernel(this);

    // copying zero centered exampleValues
    ArrayList<double[]> exampleValues = new ArrayList<double[]>(numberOfExamples);
    i = 0;
    for (Example columnExample : exampleSet) {
      double[] columnValues = getAttributeValues(columnExample, attributes, means);
      exampleValues.add(columnValues);
      i++;
    }

    // filling kernel matrix
    Matrix kernelMatrix = new Matrix(numberOfExamples, numberOfExamples);
    for (i = 0; i < numberOfExamples; i++) {
      for (int j = 0; j < numberOfExamples; j++) {
        kernelMatrix.set(
            i, j, kernel.calculateDistance(exampleValues.get(i), exampleValues.get(j)));
      }
    }

    // calculating eigenVectors
    EigenvalueDecomposition eig = kernelMatrix.eig();
    Model model = new KernelPCAModel(exampleSet, means, eig.getV(), exampleValues, kernel);

    if (exampleSetOutput.isConnected()) {
      exampleSetOutput.deliver(model.apply(exampleSet));
    }
    originalOutput.deliver(exampleSet);
    modelOutput.deliver(model);
  }
  /**
   * 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()));
        }
      };
    }
  }
  private void cloneConnections(
      OutputPorts originalPorts,
      ExecutionUnit originalExecutionUnit,
      Map<String, Operator> clonedOperatorsByName) {
    for (OutputPort originalSource : originalPorts.getAllPorts()) {
      if (originalSource.isConnected()) {

        OutputPort mySource;
        if (originalPorts.getOwner().getOperator()
            == originalExecutionUnit.getEnclosingOperator()) {
          // this is an inner source
          mySource = getInnerSources().getPortByName(originalSource.getName());
          if (mySource == null) {
            throw new RuntimeException(
                "Error during clone: Corresponding source for "
                    + originalSource
                    + " not found (no such inner source).");
          }
        } else {
          // this is an output port
          Operator myOperator =
              clonedOperatorsByName.get(
                  originalSource.getPorts().getOwner().getOperator().getName());
          if (myOperator == null) {
            throw new RuntimeException(
                "Error during clone: Corresponding source for "
                    + originalSource
                    + " not found (no such operator).");
          }
          mySource = myOperator.getOutputPorts().getPortByName(originalSource.getName());
          if (mySource == null) {
            throw new RuntimeException(
                "Error during clone: Corresponding source for "
                    + originalSource
                    + " not found (no such output port).");
          }
        }

        InputPort originalDestination = originalSource.getDestination();
        InputPort myDestination;
        if (originalDestination.getPorts().getOwner().getOperator()
            == originalExecutionUnit.getEnclosingOperator()) {
          // this is an inner sink
          myDestination = getInnerSinks().getPortByName(originalDestination.getName());
          if (myDestination == null) {
            throw new RuntimeException(
                "Error during clone: Corresponding destination for "
                    + originalDestination
                    + " not found (no such inner sink).");
          }
        } else {
          // this is an input port
          Operator myOperator =
              clonedOperatorsByName.get(
                  originalDestination.getPorts().getOwner().getOperator().getName());
          if (myOperator == null) {
            throw new RuntimeException(
                "Error during clone: Corresponding destination for "
                    + originalDestination
                    + " not found (no such operator).");
          }
          myDestination = myOperator.getInputPorts().getPortByName(originalDestination.getName());
          if (myDestination == null) {
            throw new RuntimeException(
                "Error during clone: Corresponding destination for "
                    + originalDestination
                    + " not found (no such input port).");
          }
        }
        mySource.connectTo(myDestination);
      }
    }
  }
  @Override
  public void doWork() throws OperatorException {
    String command = getParameterAsString(PARAMETER_COMMAND);
    final boolean logOut = !stdout.isConnected() && getParameterAsBoolean(PARAMETER_LOG_STDOUT);
    final boolean logErr = !stderr.isConnected() && getParameterAsBoolean(PARAMETER_LOG_STDERR);
    final List<Throwable> exceptions = Collections.synchronizedList(new ArrayList<Throwable>(3));
    try {
      final Process process = Runtime.getRuntime().exec(command);
      final ByteArrayOutputStream stdOutBuf = new ByteArrayOutputStream();
      final ByteArrayOutputStream stdErrBuf = new ByteArrayOutputStream();

      if (stdin.isConnected()) {
        final FileObject input = stdin.getData(FileObject.class);
        new Thread(getName() + "-stdin") {
          public void run() {
            try {
              Tools.copyStreamSynchronously(input.openStream(), process.getOutputStream(), true);
            } catch (Exception e) {
              exceptions.add(e);
            }
          };
        }.start();
      }

      new Thread(getName() + "-stdout") {
        public void run() {
          try {
            if (logOut) {
              logOutput("stdout:", process.getInputStream());
            } else {
              Tools.copyStreamSynchronously(process.getInputStream(), stdOutBuf, true);
            }
          } catch (Exception e) {
            exceptions.add(e);
          }
        }
      }.start();
      new Thread(getName() + "-stderr") {
        public void run() {
          try {
            if (logErr) {
              logOutput("stderr:", process.getErrorStream());
            } else {
              Tools.copyStreamSynchronously(process.getErrorStream(), stdErrBuf, true);
            }
          } catch (Exception e) {
            exceptions.add(e);
          }
        }
      }.start();

      Tools.waitForProcess(this, process, command);
      getLogger().info("Program exited succesfully.");

      if (stdout.isConnected()) {
        stdout.deliver(new BufferedFileObject(stdOutBuf.toByteArray()));
      }
      if (stderr.isConnected()) {
        stderr.deliver(new BufferedFileObject(stdErrBuf.toByteArray()));
      }
    } catch (IOException e) {
      throw new UserError(this, e, 310, new Object[] {command, e.getMessage()});
    } finally {
      getLogger()
          .log(
              Level.WARNING,
              "com.rapidminer.operator.CommandLineOperator.errors_occurred",
              new Object[] {exceptions.size(), command});
      for (Throwable t : exceptions) {
        getLogger().log(Level.WARNING, t.toString(), t);
      }
      if (!exceptions.isEmpty()) {
        Throwable t = exceptions.get(0);
        if (t instanceof OperatorException) {
          throw (OperatorException) t;
        } else {
          throw new UserError(this, t, 310, new Object[] {command, t.getMessage()});
        }
      }
    }

    dummyPorts.passDataThrough();
  }