package __BASE_PACKAGE__; import java.io.File import java.io.IOException import org.knime.core.data.DataCell import org.knime.core.data.DataColumnSpec import org.knime.core.data.DataColumnSpecCreator import org.knime.core.data.DataRow import org.knime.core.data.DataTableSpec import org.knime.core.data.RowKey import org.knime.core.data.`def`.DefaultRow import org.knime.core.data.`def`.DoubleCell import org.knime.core.data.`def`.IntCell import org.knime.core.data.`def`.StringCell import org.knime.core.node.BufferedDataContainer import org.knime.core.node.BufferedDataTable import org.knime.core.node.CanceledExecutionException import org.knime.core.node.ExecutionContext import org.knime.core.node.ExecutionMonitor import org.knime.core.node.InvalidSettingsException import org.knime.core.node.NodeLogger import org.knime.core.node.NodeModel import org.knime.core.node.NodeSettingsRO import org.knime.core.node.NodeSettingsWO import org.knime.core.node.defaultnodesettings.SettingsModelIntegerBounded import org.knime.workbench.scala.Implicits._ /** * Companion object for __NODE_NAME__NodeModel. */ object __NODE_NAME__NodeModel { // the logger instance private[__NODE_NAME__NodeModel] final val logger = NodeLogger.getLogger(classOf[__NODE_NAME__NodeModel]) /** * the settings key which is used to retrieve and * store the settings (from the dialog or from a settings file) * (package visibility to be usable from the dialog). */ private[__BASE_PACKAGE_LAST__] final val CFGKEY_COUNT = "Count" /** initial default count value. */ private[__BASE_PACKAGE_LAST__] final val DEFAULT_COUNT = 100 } /** * This is the model implementation of __NODE_NAME__. * * __DESCRIPTION__ * * @author __VENDOR_NAME__ */ class __NODE_NAME__NodeModel extends NodeModel(1, 1) { import __NODE_NAME__NodeModel.logger // example value: the models count variable filled from the dialog // and used in the models execution method. The default components of the // dialog work with "SettingsModels". private[this] final val count = new SettingsModelIntegerBounded(__NODE_NAME__NodeModel.CFGKEY_COUNT, __NODE_NAME__NodeModel.DEFAULT_COUNT, Integer.MIN_VALUE, Integer.MAX_VALUE); /** * {@inheritDoc} */ @throws[Exception] protected override def execute(inData: Array[BufferedDataTable], exec: ExecutionContext): Array[BufferedDataTable] = { implicit val executionContext = exec // TODO do something here logger.info("Node Model Stub... this is not yet implemented !") // the data table spec of the single output table, // the table will have three columns: val allColSpecs = new Array[DataColumnSpec](3) allColSpecs(0) = new DataColumnSpecCreator("Column 0", StringCell.TYPE) allColSpecs(1) = new DataColumnSpecCreator("Column 1", DoubleCell.TYPE) allColSpecs(2) = new DataColumnSpecCreator("Column 2", IntCell.TYPE) val outputSpec: DataTableSpec = allColSpecs // the execution context will provide us with storage capacity, in this // case a data container to which we will add rows sequentially // Note, this container can also handle arbitrary big data tables, it // will buffer to disc if necessary. val container: BufferedDataContainer = outputSpec // let's add m_count rows to it for (i <- 0 until count) { val key: RowKey = i // the cells of the current row, the types of the cells must match // the column spec (see above) val cells = new Array[DataCell](3) cells(0) = a"String_$i" cells(1) = 0.5 * i cells(2) = i val row: DataRow = key withData cells // check if the execution monitor was cancelled checkCancelled setProgress(i / count.toDouble, "Adding row " + i) } // once we are done, we close the container and return its table //container.close //val out = container.getTable Array[BufferedDataTable] { container } } /** * @inheritdoc */ protected override def reset: Unit = { // TODO Code executed on reset. // Models build during execute are cleared here. // Also data handled in load/saveInternals will be erased here. } /** * @inheritdoc */ @throws[InvalidSettingsException] protected override def configure(inSpecs: Array[DataTableSpec]): Array[DataTableSpec] = { // TODO: check if user settings are available, fit to the incoming // table structure, and the incoming types are feasible for the node // to execute. If the node can execute in its current state return // the spec of its output data table(s) (if you can, otherwise an array // with null elements), or throw an exception with a useful user message Array[DataTableSpec] { null } } /** * @inheritdoc */ protected override def saveSettingsTo(settings: NodeSettingsWO): Unit = { // TODO save user settings to the config object. count.saveSettingsTo(settings) } /** * @inheritdoc */ @throws[InvalidSettingsException] protected override def loadValidatedSettingsFrom(settings: NodeSettingsRO): Unit = { // TODO load (valid) settings from the config object. // It can be safely assumed that the settings are valided by the // method below. count.loadSettingsFrom(settings) } /** * @inheritdoc */ @throws[InvalidSettingsException] protected override def validateSettings(settings: NodeSettingsRO): Unit = { // TODO check if the settings could be applied to our model // e.g. if the count is in a certain range (which is ensured by the // SettingsModel). // Do not actually set any values of any member variables. count.validateSettings(settings) } /** * @inheritdoc */ @throws[IOException] @throws[CanceledExecutionException] protected override def loadInternals(internDir: File, exec: ExecutionMonitor): Unit = { // TODO load internal data. // Everything handed to output ports is loaded automatically (data // returned by the execute method, models loaded in loadModelContent, // and user settings set through loadSettingsFrom - is all taken care // of). Load here only the other internals that need to be restored // (e.g. data used by the views). } /** * @inheritdoc */ @throws[IOException] @throws[CanceledExecutionException] protected override def saveInternals(internDir: File, exec: ExecutionMonitor): Unit = { // TODO save internal models. // Everything written to output ports is saved automatically (data // returned by the execute method, models saved in the saveModelContent, // and user settings saved through saveSettingsTo - is all taken care // of). Save here only the other internals that need to be preserved // (e.g. data used by the views). } }