From 896eba860158be8b3c06435aa3779d5707f4f919 Mon Sep 17 00:00:00 2001 From: david Date: Sun, 23 Feb 2020 15:44:25 +1100 Subject: [PATCH 01/56] Reorg, moving git up a level Checkin to include runtime workspace --- .gitignore | 2 +- .../andl-relational-algebra/.classpath | 0 .../andl-relational-algebra/.gitignore | 1 + .../andl-relational-algebra/.project | 0 .../META-INF}/MANIFEST.MF | 0 .../andl-relational-algebra/build.properties | 0 .../andl-relational-algebra/plugin.xml | 0 .../org/andl/ra/RaProjectionNodeDialog.java | 0 .../org/andl/ra/RaProjectionNodeFactory.java | 0 .../org/andl/ra/RaProjectionNodeFactory.xml | 0 .../org/andl/ra/RaProjectionNodeModel.java | 0 .../org/andl/ra/RaProjectionNodePlugin.java | 0 .../org/andl/ra/RaProjectionNodeView.java | 0 .../src}/org/andl/ra/RaTuple.java | 0 .../src}/org/andl/ra/package.html | 0 .../src}/org/andl/ra/projection.png | Bin .../andl-try-numberformatter/.classpath | 7 + .../andl-try-numberformatter/.project | 28 ++ .../META-INF/MANIFEST.MF | 15 + .../andl-try-numberformatter/alpha.png | Bin 0 -> 3286 bytes .../trying/TryNumberFormatterNodeDialog.class | Bin 0 -> 962 bytes .../TryNumberFormatterNodeFactory.class | Bin 0 -> 1606 bytes .../trying/TryNumberFormatterNodeFactory.xml | 37 ++ .../trying/TryNumberFormatterNodeModel.class | Bin 0 -> 7651 bytes .../trying/TryNumberFormatterNodePlugin.class | Bin 0 -> 849 bytes .../trying/TryNumberFormatterNodeView.class | Bin 0 -> 1234 bytes .../bin/org/andl/trying/default.png | Bin 0 -> 607 bytes .../bin/org/andl/trying/package.html | 25 ++ .../andl-try-numberformatter/build.properties | 4 + .../andl-try-numberformatter/plugin.xml | 23 ++ .../trying/TryNumberFormatterNodeDialog.java | 63 +++ .../trying/TryNumberFormatterNodeFactory.java | 63 +++ .../trying/TryNumberFormatterNodeFactory.xml | 37 ++ .../trying/TryNumberFormatterNodeModel.java | 384 ++++++++++++++++++ .../trying/TryNumberFormatterNodePlugin.java | 65 +++ .../trying/TryNumberFormatterNodeView.java | 65 +++ .../src/org/andl/trying/default.png | Bin 0 -> 607 bytes .../src/org/andl/trying/package.html | 25 ++ 38 files changed, 843 insertions(+), 1 deletion(-) rename .classpath => dev-workspace/andl-relational-algebra/.classpath (100%) create mode 100644 dev-workspace/andl-relational-algebra/.gitignore rename .project => dev-workspace/andl-relational-algebra/.project (100%) rename {META-INF => dev-workspace/andl-relational-algebra/META-INF}/MANIFEST.MF (100%) rename build.properties => dev-workspace/andl-relational-algebra/build.properties (100%) rename plugin.xml => dev-workspace/andl-relational-algebra/plugin.xml (100%) rename {src => dev-workspace/andl-relational-algebra/src}/org/andl/ra/RaProjectionNodeDialog.java (100%) rename {src => dev-workspace/andl-relational-algebra/src}/org/andl/ra/RaProjectionNodeFactory.java (100%) rename {src => dev-workspace/andl-relational-algebra/src}/org/andl/ra/RaProjectionNodeFactory.xml (100%) rename {src => dev-workspace/andl-relational-algebra/src}/org/andl/ra/RaProjectionNodeModel.java (100%) rename {src => dev-workspace/andl-relational-algebra/src}/org/andl/ra/RaProjectionNodePlugin.java (100%) rename {src => dev-workspace/andl-relational-algebra/src}/org/andl/ra/RaProjectionNodeView.java (100%) rename {src => dev-workspace/andl-relational-algebra/src}/org/andl/ra/RaTuple.java (100%) rename {src => dev-workspace/andl-relational-algebra/src}/org/andl/ra/package.html (100%) rename {src => dev-workspace/andl-relational-algebra/src}/org/andl/ra/projection.png (100%) create mode 100644 dev-workspace/andl-try-numberformatter/.classpath create mode 100644 dev-workspace/andl-try-numberformatter/.project create mode 100644 dev-workspace/andl-try-numberformatter/META-INF/MANIFEST.MF create mode 100644 dev-workspace/andl-try-numberformatter/alpha.png create mode 100644 dev-workspace/andl-try-numberformatter/bin/org/andl/trying/TryNumberFormatterNodeDialog.class create mode 100644 dev-workspace/andl-try-numberformatter/bin/org/andl/trying/TryNumberFormatterNodeFactory.class create mode 100644 dev-workspace/andl-try-numberformatter/bin/org/andl/trying/TryNumberFormatterNodeFactory.xml create mode 100644 dev-workspace/andl-try-numberformatter/bin/org/andl/trying/TryNumberFormatterNodeModel.class create mode 100644 dev-workspace/andl-try-numberformatter/bin/org/andl/trying/TryNumberFormatterNodePlugin.class create mode 100644 dev-workspace/andl-try-numberformatter/bin/org/andl/trying/TryNumberFormatterNodeView.class create mode 100644 dev-workspace/andl-try-numberformatter/bin/org/andl/trying/default.png create mode 100644 dev-workspace/andl-try-numberformatter/bin/org/andl/trying/package.html create mode 100644 dev-workspace/andl-try-numberformatter/build.properties create mode 100644 dev-workspace/andl-try-numberformatter/plugin.xml create mode 100644 dev-workspace/andl-try-numberformatter/src/org/andl/trying/TryNumberFormatterNodeDialog.java create mode 100644 dev-workspace/andl-try-numberformatter/src/org/andl/trying/TryNumberFormatterNodeFactory.java create mode 100644 dev-workspace/andl-try-numberformatter/src/org/andl/trying/TryNumberFormatterNodeFactory.xml create mode 100644 dev-workspace/andl-try-numberformatter/src/org/andl/trying/TryNumberFormatterNodeModel.java create mode 100644 dev-workspace/andl-try-numberformatter/src/org/andl/trying/TryNumberFormatterNodePlugin.java create mode 100644 dev-workspace/andl-try-numberformatter/src/org/andl/trying/TryNumberFormatterNodeView.java create mode 100644 dev-workspace/andl-try-numberformatter/src/org/andl/trying/default.png create mode 100644 dev-workspace/andl-try-numberformatter/src/org/andl/trying/package.html diff --git a/.gitignore b/.gitignore index d8bb511..1ff0378 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1 @@ -/bin/org/andl/ra +.metadata diff --git a/.classpath b/dev-workspace/andl-relational-algebra/.classpath similarity index 100% rename from .classpath rename to dev-workspace/andl-relational-algebra/.classpath diff --git a/dev-workspace/andl-relational-algebra/.gitignore b/dev-workspace/andl-relational-algebra/.gitignore new file mode 100644 index 0000000..d8bb511 --- /dev/null +++ b/dev-workspace/andl-relational-algebra/.gitignore @@ -0,0 +1 @@ +/bin/org/andl/ra diff --git a/.project b/dev-workspace/andl-relational-algebra/.project similarity index 100% rename from .project rename to dev-workspace/andl-relational-algebra/.project diff --git a/META-INF/MANIFEST.MF b/dev-workspace/andl-relational-algebra/META-INF/MANIFEST.MF similarity index 100% rename from META-INF/MANIFEST.MF rename to dev-workspace/andl-relational-algebra/META-INF/MANIFEST.MF diff --git a/build.properties b/dev-workspace/andl-relational-algebra/build.properties similarity index 100% rename from build.properties rename to dev-workspace/andl-relational-algebra/build.properties diff --git a/plugin.xml b/dev-workspace/andl-relational-algebra/plugin.xml similarity index 100% rename from plugin.xml rename to dev-workspace/andl-relational-algebra/plugin.xml diff --git a/src/org/andl/ra/RaProjectionNodeDialog.java b/dev-workspace/andl-relational-algebra/src/org/andl/ra/RaProjectionNodeDialog.java similarity index 100% rename from src/org/andl/ra/RaProjectionNodeDialog.java rename to dev-workspace/andl-relational-algebra/src/org/andl/ra/RaProjectionNodeDialog.java diff --git a/src/org/andl/ra/RaProjectionNodeFactory.java b/dev-workspace/andl-relational-algebra/src/org/andl/ra/RaProjectionNodeFactory.java similarity index 100% rename from src/org/andl/ra/RaProjectionNodeFactory.java rename to dev-workspace/andl-relational-algebra/src/org/andl/ra/RaProjectionNodeFactory.java diff --git a/src/org/andl/ra/RaProjectionNodeFactory.xml b/dev-workspace/andl-relational-algebra/src/org/andl/ra/RaProjectionNodeFactory.xml similarity index 100% rename from src/org/andl/ra/RaProjectionNodeFactory.xml rename to dev-workspace/andl-relational-algebra/src/org/andl/ra/RaProjectionNodeFactory.xml diff --git a/src/org/andl/ra/RaProjectionNodeModel.java b/dev-workspace/andl-relational-algebra/src/org/andl/ra/RaProjectionNodeModel.java similarity index 100% rename from src/org/andl/ra/RaProjectionNodeModel.java rename to dev-workspace/andl-relational-algebra/src/org/andl/ra/RaProjectionNodeModel.java diff --git a/src/org/andl/ra/RaProjectionNodePlugin.java b/dev-workspace/andl-relational-algebra/src/org/andl/ra/RaProjectionNodePlugin.java similarity index 100% rename from src/org/andl/ra/RaProjectionNodePlugin.java rename to dev-workspace/andl-relational-algebra/src/org/andl/ra/RaProjectionNodePlugin.java diff --git a/src/org/andl/ra/RaProjectionNodeView.java b/dev-workspace/andl-relational-algebra/src/org/andl/ra/RaProjectionNodeView.java similarity index 100% rename from src/org/andl/ra/RaProjectionNodeView.java rename to dev-workspace/andl-relational-algebra/src/org/andl/ra/RaProjectionNodeView.java diff --git a/src/org/andl/ra/RaTuple.java b/dev-workspace/andl-relational-algebra/src/org/andl/ra/RaTuple.java similarity index 100% rename from src/org/andl/ra/RaTuple.java rename to dev-workspace/andl-relational-algebra/src/org/andl/ra/RaTuple.java diff --git a/src/org/andl/ra/package.html b/dev-workspace/andl-relational-algebra/src/org/andl/ra/package.html similarity index 100% rename from src/org/andl/ra/package.html rename to dev-workspace/andl-relational-algebra/src/org/andl/ra/package.html diff --git a/src/org/andl/ra/projection.png b/dev-workspace/andl-relational-algebra/src/org/andl/ra/projection.png similarity index 100% rename from src/org/andl/ra/projection.png rename to dev-workspace/andl-relational-algebra/src/org/andl/ra/projection.png diff --git a/dev-workspace/andl-try-numberformatter/.classpath b/dev-workspace/andl-try-numberformatter/.classpath new file mode 100644 index 0000000..1fa3e68 --- /dev/null +++ b/dev-workspace/andl-try-numberformatter/.classpath @@ -0,0 +1,7 @@ + + + + + + + diff --git a/dev-workspace/andl-try-numberformatter/.project b/dev-workspace/andl-try-numberformatter/.project new file mode 100644 index 0000000..9448cc9 --- /dev/null +++ b/dev-workspace/andl-try-numberformatter/.project @@ -0,0 +1,28 @@ + + + andl-try-numberformatter + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.pde.ManifestBuilder + + + + + org.eclipse.pde.SchemaBuilder + + + + + + org.eclipse.pde.PluginNature + org.eclipse.jdt.core.javanature + + diff --git a/dev-workspace/andl-try-numberformatter/META-INF/MANIFEST.MF b/dev-workspace/andl-try-numberformatter/META-INF/MANIFEST.MF new file mode 100644 index 0000000..0edac0c --- /dev/null +++ b/dev-workspace/andl-try-numberformatter/META-INF/MANIFEST.MF @@ -0,0 +1,15 @@ +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: TryNumberFormatter-Node extension for KNIME Workbench +Bundle-SymbolicName: org.andl.trying; singleton:=true +Bundle-Version: 1.0.0.qualifier +Bundle-ClassPath: trynumberformatter.jar +Bundle-Activator: org.andl.trying.TryNumberFormatterNodePlugin +Bundle-Vendor: andl +Require-Bundle: org.eclipse.core.runtime, + org.knime.workbench.core, + org.knime.workbench.repository, + org.knime.base +Bundle-ActivationPolicy: lazy +Export-Package: org.andl.trying + diff --git a/dev-workspace/andl-try-numberformatter/alpha.png b/dev-workspace/andl-try-numberformatter/alpha.png new file mode 100644 index 0000000000000000000000000000000000000000..a65c01e923c8618ed100051e77b5851167761a00 GIT binary patch literal 3286 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 UN{;)0bN~PV07*qoM6N<$f)K4YvH$=8 literal 0 HcmV?d00001 diff --git a/dev-workspace/andl-try-numberformatter/bin/org/andl/trying/TryNumberFormatterNodeDialog.class b/dev-workspace/andl-try-numberformatter/bin/org/andl/trying/TryNumberFormatterNodeDialog.class new file mode 100644 index 0000000000000000000000000000000000000000..f7c8fef852e515bb08bf89e463d943295d1cc9e7 GIT binary patch literal 962 zcmbtTQBM;=5dOA3xq4Qpr=o(&0WU2eml&RG(FX{L$w^GwG=aCJx0J=ZU9#O8`B}aQ zfy5u+k222oN}@cNOL*DYnVoO;oB4Ks{l5AMU<<20DhwOi3}dd+EVkxcs$twS=lkRQ zNSHlsa&E0K`#Kf7l4pA8!(;g15MPwcMLf_(#EOpNR2=hhX5D@ytffMuc(;f-cy}86 z%#~o6=}0B*dxmPW)o1W_C?h}>_v^TanE(&)&_|tNy&Shs1kdW2#T>)ZzzA-|-yPiC zJxL?_%~n#jgMXl1YpAWZk4FsKWh)eO+tK-%RzlgLMh%Y{77LD1G3Mw^l$7Ue*q@%k0 zzb~-q=80vRUzL6l$a?P4lJ&_uq_skJVeJC7O9aWrW36dslNb1`ZCUg{blj&0B!GGj~ zzO;!Z#%F(&@y_l9HUujqKJ0wnbLQN0XZF|cZ$ALMKs5=Aq3Wrg!`*J*@zqGWJ?B`B zTEoGqP<2lYxbF+q^17nVJHDqzNyHiQ8uH$i1L1T$B^;Obok$SF(w=mszt0dWmf8&Q zR}^6*hI9rAEHPx8(iPz;$NaP}7*?BJhxglDNj*1OyRUJ>%!ECGUH^z{|G` zYZEWSjYIBI(oao=XL&S3bG9LkvCKwQJ4CqY+d_6pTFZ5oZ&EVd6rc3kQXf~c|iWte*;L-h+Z+ZNt!v- zGwKuNE2O^Cz=BP!-UgO&gW60OK>ae!=rJHmtp@K>w2n)CNABbbt6yjw#ji*3sWJW* z)(pNvy~bOy&r`^J1Zj(|UGi>d9l%AR|r`$ce|(YHAU@aU%DU?$Q&3FOyE4hh5&N{6y{&+tUmz gV6Xtft>Br#ZBwruOq4HC{40dgENhdnW6Z1k0r41o00000 literal 0 HcmV?d00001 diff --git a/dev-workspace/andl-try-numberformatter/bin/org/andl/trying/TryNumberFormatterNodeFactory.xml b/dev-workspace/andl-try-numberformatter/bin/org/andl/trying/TryNumberFormatterNodeFactory.xml new file mode 100644 index 0000000..8c1916c --- /dev/null +++ b/dev-workspace/andl-try-numberformatter/bin/org/andl/trying/TryNumberFormatterNodeFactory.xml @@ -0,0 +1,37 @@ + + + TryNumberFormatter + + + Basic generator + + + + this is the intro field with more + + + + + + + + + + Description of first input port... + + Description of first output port... + + + + Description of first view... + + + diff --git a/dev-workspace/andl-try-numberformatter/bin/org/andl/trying/TryNumberFormatterNodeModel.class b/dev-workspace/andl-try-numberformatter/bin/org/andl/trying/TryNumberFormatterNodeModel.class new file mode 100644 index 0000000000000000000000000000000000000000..6680b60a57b64a5b431736b9a1f3de9cc5f03521 GIT binary patch literal 7651 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 C+9f9d literal 0 HcmV?d00001 diff --git a/dev-workspace/andl-try-numberformatter/bin/org/andl/trying/TryNumberFormatterNodePlugin.class b/dev-workspace/andl-try-numberformatter/bin/org/andl/trying/TryNumberFormatterNodePlugin.class new file mode 100644 index 0000000000000000000000000000000000000000..0f540b26aac29258d019ecc10f6a454bb8ab4178 GIT binary patch literal 849 zcmb7D%Wl&^6g`uq2{ERH7RsZA5>!MIP>n=c1-hV+Ra7BSbw72dVT$94#$#yzipQc7 z3qF94LYx^#1tbLO#xwVE&OP_o{{G|ZHvpUHv``axWb8PR`9YRAd!qAkvTILv%E`X6 zLt`h>Ic0aufqI>lW1Y9q5LojFm1cTcs3bL3CAQ3+o~Wd15@=3Cx4_2eJnRD^pXpq? zErEKsw# ztm1WDk8uTy0{Yvd*u7lf9k1HF&4Re6|@4cnY5F{wbpV7sQ_!)G*KId;qQxu*&w^SYR%$ znsGT$3GWHJmss(%R|Dl1Gc{(K{fDPm{>2xC>;uZ^1+L|)YsSTX+`!EshfcBfC+mVd$!|sT|1O#!t2=w z@@#L=KjL!7mwhJ;x!m)+ye;^918IhNm4D)iKDRr*E<@pa!7C9s zM=tL&utSDyt>X$$gms2gsoZ8rHwbEC91{jChTL1{onyNWNocr4V&NWg423Qagyh|q zSG29r2?s$$aySNtDGM3sgl`Iu$I1^>S%!Sm?>KJTkwWd0!wJH7PIjHsWUto}QBOfS@0w)R6AO!2qCk&_>e3S4#Zoz99mu*q39X7rUo76vUUOS>Aq)iaf67ckFZq(2~?`i#ksbeKY(e)T9NhiUrOXx*ok zfo8p+i693G2~(YdDy&zkmzYs-ErOfT=?p=N5k(=+!W`|@qhlVAh$D^1Lsf!u6j!lw zfrTGfZhpe#IdavX82^gZHj0xtnv*JZKM*jhH`aAH5w>2xkB+*J6qxv_Do-|zqWYl*|jl0a3}81n$f zxhQa;TrRK2oC8oS7Plv|*=^gl#~sJ{$DrA4=Iu;o1=V>#5V_E3G_t*3@2dk)tJSV5 zj1MQM*X!=y$;k!Vac-cR{0E0T&uasV(rUE|Vp*?&OhWKM;F`iJa4hATKW)o8;fQ6e t4GjbAS9p{%7}uUK4A(?echT)!zX6z`tp*)C$Z!Av002ovPDHLkV1ir~2)_UT literal 0 HcmV?d00001 diff --git a/dev-workspace/andl-try-numberformatter/bin/org/andl/trying/package.html b/dev-workspace/andl-try-numberformatter/bin/org/andl/trying/package.html new file mode 100644 index 0000000..4eae2ea --- /dev/null +++ b/dev-workspace/andl-try-numberformatter/bin/org/andl/trying/package.html @@ -0,0 +1,25 @@ + + +This package implements ... (insert package description here) +

+The TryNumberFormatterModel ... (short comments on the classes) +

+The TryNumberFormatterDialog ... (short comments on the classes) +

+More comments ... +
+ + diff --git a/dev-workspace/andl-try-numberformatter/build.properties b/dev-workspace/andl-try-numberformatter/build.properties new file mode 100644 index 0000000..f0cd466 --- /dev/null +++ b/dev-workspace/andl-try-numberformatter/build.properties @@ -0,0 +1,4 @@ +source.trynumberformatter.jar = src/ +bin.includes = plugin.xml,\ + META-INF/,\ + trynumberformatter.jar diff --git a/dev-workspace/andl-try-numberformatter/plugin.xml b/dev-workspace/andl-try-numberformatter/plugin.xml new file mode 100644 index 0000000..9ed36ba --- /dev/null +++ b/dev-workspace/andl-try-numberformatter/plugin.xml @@ -0,0 +1,23 @@ + + + + + + + + + + + + + diff --git a/dev-workspace/andl-try-numberformatter/src/org/andl/trying/TryNumberFormatterNodeDialog.java b/dev-workspace/andl-try-numberformatter/src/org/andl/trying/TryNumberFormatterNodeDialog.java new file mode 100644 index 0000000..f9e5678 --- /dev/null +++ b/dev-workspace/andl-try-numberformatter/src/org/andl/trying/TryNumberFormatterNodeDialog.java @@ -0,0 +1,63 @@ +package org.andl.trying; + +import org.knime.core.node.defaultnodesettings.DefaultNodeSettingsPane; +import org.knime.core.node.defaultnodesettings.DialogComponentString; +import org.knime.core.node.defaultnodesettings.SettingsModelString; + +/** + * This is an example implementation of the node dialog of the + * "TryNumberFormatter" node. + * + * This node dialog derives from {@link DefaultNodeSettingsPane} which allows + * creation of a simple dialog with standard components. If you need a more + * complex dialog please derive directly from + * {@link org.knime.core.node.NodeDialogPane}. In general, one can create an + * arbitrary complex dialog using Java Swing. + * + * @author andl + */ +public class TryNumberFormatterNodeDialog extends DefaultNodeSettingsPane { + + /** + * New dialog pane for configuring the node. The dialog created here + * will show up when double clicking on a node in KNIME Analytics Platform. + */ + protected TryNumberFormatterNodeDialog() { + super(); + + /* + * The DefaultNodeSettingsPane provides methods to add simple standard + * components to the dialog pane via the addDialogComponent(...) method. This + * method expects a new DialogComponet object that should be added to the dialog + * pane. There are many already predefined components for the most commonly used + * configuration needs like a text box (DialogComponentString) to enter some + * String or a number spinner (DialogComponentNumber) to enter some number in a + * specific range and step size. + * + * The dialog components are connected to the node model via settings model + * objects that can easily load and save their settings to the node settings. + * Depending on the type of input the dialog component should receive, the + * constructor of the component requires a suitable settings model object. E.g. + * the DialogComponentString requires a SettingsModelString. Additionally, + * dialog components sometimes allow to further configure the behavior of the + * component in the constructor. E.g. to disallow empty inputs (like below). + * Here, the loading/saving in the dialog is already taken care of by the + * DefaultNodeSettingsPane. It is important to use the same key for the settings + * model here as used in the node model implementation (it does not need to be + * the same object). One best practice is to use package private static methods + * to create the settings model as we did in the node model implementation (see + * createNumberFormatSettingsModel() in the NodeModel class). + * + * Here we create a simple String DialogComponent that will display a label + * String besides a text box in which the use can enter a value. The + * DialogComponentString has additional options to disallow empty inputs, hence + * we do not need to worry about that in the model implementation anymore. + * + */ + // First, create a new settings model using the create method from the node model. + SettingsModelString stringSettings = TryNumberFormatterNodeModel.createNumberFormatSettingsModel(); + // Add a new String component to the dialog. + addDialogComponent(new DialogComponentString(stringSettings, "Number Format - modified x2", true, 10)); + } +} + diff --git a/dev-workspace/andl-try-numberformatter/src/org/andl/trying/TryNumberFormatterNodeFactory.java b/dev-workspace/andl-try-numberformatter/src/org/andl/trying/TryNumberFormatterNodeFactory.java new file mode 100644 index 0000000..70af028 --- /dev/null +++ b/dev-workspace/andl-try-numberformatter/src/org/andl/trying/TryNumberFormatterNodeFactory.java @@ -0,0 +1,63 @@ +package org.andl.trying; + +import org.knime.core.node.NodeDialogPane; +import org.knime.core.node.NodeFactory; +import org.knime.core.node.NodeView; + +/** + * This is an example implementation of the node factory of the + * "TryNumberFormatter" node. + * + * @author andl + */ +public class TryNumberFormatterNodeFactory + extends NodeFactory { + + /** + * {@inheritDoc} + */ + @Override + public TryNumberFormatterNodeModel createNodeModel() { + // Create and return a new node model. + return new TryNumberFormatterNodeModel(); + } + + /** + * {@inheritDoc} + */ + @Override + public int getNrNodeViews() { + // The number of views the node should have, in this cases there is none. + return 0; + } + + /** + * {@inheritDoc} + */ + @Override + public NodeView createNodeView(final int viewIndex, + final TryNumberFormatterNodeModel nodeModel) { + // We return null as this example node does not provide a view. Also see "getNrNodeViews()". + return null; + } + + /** + * {@inheritDoc} + */ + @Override + public boolean hasDialog() { + // Indication whether the node has a dialog or not. + return true; + } + + /** + * {@inheritDoc} + */ + @Override + public NodeDialogPane createNodeDialogPane() { + // This example node has a dialog, hence we create and return it here. Also see "hasDialog()". + return new TryNumberFormatterNodeDialog(); + } + +} + diff --git a/dev-workspace/andl-try-numberformatter/src/org/andl/trying/TryNumberFormatterNodeFactory.xml b/dev-workspace/andl-try-numberformatter/src/org/andl/trying/TryNumberFormatterNodeFactory.xml new file mode 100644 index 0000000..8c1916c --- /dev/null +++ b/dev-workspace/andl-try-numberformatter/src/org/andl/trying/TryNumberFormatterNodeFactory.xml @@ -0,0 +1,37 @@ + + + TryNumberFormatter + + + Basic generator + + + + this is the intro field with more + + + + + + + + + + Description of first input port... + + Description of first output port... + + + + Description of first view... + + + diff --git a/dev-workspace/andl-try-numberformatter/src/org/andl/trying/TryNumberFormatterNodeModel.java b/dev-workspace/andl-try-numberformatter/src/org/andl/trying/TryNumberFormatterNodeModel.java new file mode 100644 index 0000000..ccf5729 --- /dev/null +++ b/dev-workspace/andl-try-numberformatter/src/org/andl/trying/TryNumberFormatterNodeModel.java @@ -0,0 +1,384 @@ +package org.andl.trying; + +import java.io.File; +import java.io.IOException; + +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.IllegalFormatException; +import java.util.List; + +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.container.CloseableRowIterator; +import org.knime.core.data.def.DefaultRow; +import org.knime.core.data.def.DoubleCell; +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.SettingsModelString; + + +/** + * This is an example implementation of the node model of the + * "TryNumberFormatter" node. + * + * This example node performs simple number formatting + * ({@link String#format(String, Object...)}) using a user defined format string + * on all double columns of its input table. + * + * @author andl + */ +public class TryNumberFormatterNodeModel extends NodeModel { + + /** + * The logger is used to print info/warning/error messages to the KNIME console + * and to the KNIME log file. Retrieve it via 'NodeLogger.getLogger' providing + * the class of this node model. + */ + private static final NodeLogger LOGGER = NodeLogger.getLogger(TryNumberFormatterNodeModel.class); + + /** + * The settings key to retrieve and store settings shared between node dialog + * and node model. In this case, the key for the number format String that + * should be entered by the user in the dialog. + */ + private static final String KEY_NUMBER_FOMAT = "number_format"; + + /** + * The default number format String. This default will round to three decimal + * places. For an explanation of the format String specification please refer to + * https://docs.oracle.com/javase/tutorial/java/data/numberformat.html + */ + private static final String DEFAULT_NUMBER_FORMAT = "%.3f"; + + /** + * The settings model to manage the shared settings. This model will hold the + * value entered by the user in the dialog and will update once the user changes + * the value. Furthermore, it provides methods to easily load and save the value + * to and from the shared settings (see: + *
+ * {@link #loadValidatedSettingsFrom(NodeSettingsRO)}, + * {@link #saveSettingsTo(NodeSettingsWO)}). + *
+ * Here, we use a SettingsModelString as the number format is a String. + * There are models for all common data types. Also have a look at the comments + * in the constructor of the {@link TryNumberFormatterNodeDialog} as the settings + * models are also used to create simple dialogs. + */ + private final SettingsModelString m_numberFormatSettings = createNumberFormatSettingsModel(); + + /** + * Constructor for the node model. + */ + protected TryNumberFormatterNodeModel() { + /** + * Here we specify how many data input and output tables the node should have. + * In this case its one input and one output table. + */ + super(1, 1); + } + + /** + * A convenience method to create a new settings model used for the number + * format String. This method will also be used in the {@link TryNumberFormatterNodeDialog}. + * The settings model will sync via the above defined key. + * + * @return a new SettingsModelString with the key for the number format String + */ + static SettingsModelString createNumberFormatSettingsModel() { + return new SettingsModelString(KEY_NUMBER_FOMAT, DEFAULT_NUMBER_FORMAT); + } + + /** + * + * {@inheritDoc} + */ + @Override + protected BufferedDataTable[] execute(final BufferedDataTable[] inData, final ExecutionContext exec) + throws Exception { + /* + * The functionality of the node is implemented in the execute method. This + * implementation will format each double column of the input table using a user + * provided format String. The output will be one String column for each double + * column of the input containing the formatted number from the input table. For + * simplicity, all other columns are ignored in this example. + * + * Some example log output. This will be printed to the KNIME console and KNIME + * log. + */ + LOGGER.info("This is an example info."); + + /* + * The input data table to work with. The "inData" array will contain as many + * input tables as specified in the constructor. In this case it can only be one + * (see constructor). + */ + BufferedDataTable inputTable = inData[0]; + + /* + * Create the spec of the output table, for each double column of the input + * table we will create one formatted String column in the output. See the + * javadoc of the "createOutputSpec(...)" for more information. + */ + DataTableSpec outputSpec = createOutputSpec(inputTable.getDataTableSpec()); + + /* + * The execution context provides storage capacity, in this case a + * data container to which we will add rows sequentially. Note, this container + * can handle arbitrary big data tables, it will buffer to disc if necessary. + * The execution context is provided as an argument to the execute method by the + * framework. Have a look at the methods of the "exec". There is a lot of + * functionality to create and change data tables. + */ + BufferedDataContainer container = exec.createDataContainer(outputSpec); + + /* + * Get the row iterator over the input table which returns each row one-by-one + * from the input table. + */ + CloseableRowIterator rowIterator = inputTable.iterator(); + + /* + * A counter for how many rows have already been processed. This is used to + * calculate the progress of the node, which is displayed as a loading bar under + * the node icon. + */ + int currentRowCounter = 0; + // Iterate over the rows of the input table. + while (rowIterator.hasNext()) { + DataRow currentRow = rowIterator.next(); + int numberOfCells = currentRow.getNumCells(); + /* + * A list to collect the cells to output for the current row. The type and + * amount of cells must match the DataTableSpec we used when creating the + * DataContainer. + */ + List cells = new ArrayList<>(); + // Iterate over the cells of the current row. + for (int i = 0; i < numberOfCells; i++) { + DataCell cell = currentRow.getCell(i); + /* + * We only care about double cells. Hence, we check if the current cell equals + * DoubleCell.class. All other cells in the input table will be ignored. + */ + if (cell.getType().getCellClass().equals((DoubleCell.class))) { + // Cast the cell as we know is must be a DoubleCell. + DoubleCell doubleCell = (DoubleCell) cell; + /* + * Format the double value using the user defined number format. The format is + * retrieved from the settings model member that we created above. + */ + String format = m_numberFormatSettings.getStringValue(); + String formatedValue = String.format(format, doubleCell.getDoubleValue()); + // Create a new StringCell and add it to our cell list. + cells.add(new StringCell(formatedValue)); + } + /* + * In this example we do not check for missing cells. If there are missing cells + * in a row, the node will throw an Exception because we try to create a row + * with less cells than specified in the table specification we used to create + * the data container above. Hence, for your node implementation keep in mind to + * check for missing cells in the input table. Then create missing cells with an + * appropriate message or throw an Exception with a nice error message in case + * missing cells are not allowed at all. Here, this could be done in an 'else + * if' clause checking 'cell.isMissing()'. Then, add a new MissingCell to the + * list of cells. + */ + } + // Add the new row to the output data container + DataRow row = new DefaultRow(currentRow.getKey(), cells); + container.addRowToTable(row); + + // We finished processing one row, hence increase the counter + currentRowCounter++; + + /* + * Here we check if a user triggered a cancel of the node. If so, this call will + * throw an exception and the execution will stop. This should be done + * frequently during execution, e.g. after the processing of one row if + * possible. + */ + exec.checkCanceled(); + + /* + * Calculate the percentage of execution progress and inform the + * ExecutionMonitor. Additionally, we can set a message what the node is + * currently doing (the message will be displayed as a tooltip when hovering + * over the progress bar of the node). This is especially useful to inform the + * user about the execution status for long running nodes. + */ + exec.setProgress(currentRowCounter / (double) inputTable.size(), "Formatting row " + currentRowCounter); + } + + /* + * Once we are done, we close the container and return its table. Here we need + * to return as many tables as we specified in the constructor. This node has + * one output, hence return one table (wrapped in an array of tables). + */ + container.close(); + BufferedDataTable out = container.getTable(); + return new BufferedDataTable[] { out }; + } + + /** + * {@inheritDoc} + */ + @Override + protected DataTableSpec[] configure(final DataTableSpec[] inSpecs) throws InvalidSettingsException { + /* + * Check if the node is executable, e.g. all required user settings are + * available and valid, or the incoming types are feasible for the node to + * execute. In case the node can execute in its current configuration with the + * current input, calculate and return the table spec that would result of the + * execution of this node. I.e. this method precalculates the table spec of the + * output table. + * + * Here we perform a sanity check on the entered number format String. In this + * case we just try to apply it to some dummy double number. If there is a + * problem, an IllegalFormatException will be thrown. We catch the exception and + * wrap it in a InvalidSettingsException with an informative message for the + * user. The message should make clear what the problem is and how it can be + * fixed if this information is available. This will be displayed in the KNIME + * console and printed to the KNIME log. The log will also contain the stack + * trace. + */ + String format = m_numberFormatSettings.getStringValue(); + try { + String.format(format, 0.0123456789); + } catch (IllegalFormatException e) { + throw new InvalidSettingsException( + "The entered format is not a valid pattern String! Reason: " + e.getMessage(), e); + } + + /* + * Similar to the return type of the execute method, we need to return an array + * of DataTableSpecs with the length of the number of outputs ports of the node + * (as specified in the constructor). The resulting table created in the execute + * methods must match the spec created in this method. As we will need to + * calculate the output table spec again in the execute method in order to + * create a new data container, we create a new method to do that. + */ + DataTableSpec inputTableSpec = inSpecs[0]; + return new DataTableSpec[] { createOutputSpec(inputTableSpec) }; + } + + /** + * Creates the output table spec from the input spec. For each double column in + * the input, one String column will be created containing the formatted double + * value as String. + * + * @param inputTableSpec + * @return + */ + private DataTableSpec createOutputSpec(DataTableSpec inputTableSpec) { + List newColumnSpecs = new ArrayList<>(); + // Iterate over the input column specs + for (int i = 0; i < inputTableSpec.getNumColumns(); i++) { + DataColumnSpec columnSpec = inputTableSpec.getColumnSpec(i); + /* + * If the column is a double column (hence there are double cells), we create a + * new DataColumnSpec with column type String and a new column name. Here, we + * wrap the original column name with 'Formatted(...)'. + */ + if (columnSpec.getType().getCellClass().equals(DoubleCell.class)) { + String newName = "Formatted(" + columnSpec.getName() + ")"; + DataColumnSpecCreator specCreator = new DataColumnSpecCreator(newName, StringCell.TYPE); + newColumnSpecs.add(specCreator.createSpec()); + } + } + + // Create and return a new DataTableSpec from the list of DataColumnSpecs. + DataColumnSpec[] newColumnSpecsArray = newColumnSpecs.toArray(new DataColumnSpec[newColumnSpecs.size()]); + return new DataTableSpec(newColumnSpecsArray); + } + + /** + * {@inheritDoc} + */ + @Override + protected void saveSettingsTo(final NodeSettingsWO settings) { + /* + * Save user settings to the NodeSettings object. SettingsModels already know how to + * save them self to a NodeSettings object by calling the below method. In general, + * the NodeSettings object is just a key-value store and has methods to write + * all common data types. Hence, you can easily write your settings manually. + * See the methods of the NodeSettingsWO. + */ + m_numberFormatSettings.saveSettingsTo(settings); + } + + /** + * {@inheritDoc} + */ + @Override + protected void loadValidatedSettingsFrom(final NodeSettingsRO settings) throws InvalidSettingsException { + /* + * Load (valid) settings from the NodeSettings object. It can be safely assumed that + * the settings are validated by the method below. + * + * The SettingsModel will handle the loading. After this call, the current value + * (from the view) can be retrieved from the settings model. + */ + m_numberFormatSettings.loadSettingsFrom(settings); + } + + /** + * {@inheritDoc} + */ + @Override + protected void validateSettings(final NodeSettingsRO settings) throws InvalidSettingsException { + /* + * Check if the settings could be applied to our model e.g. if the user provided + * format String is empty. In this case we do not need to check as this is + * already handled in the dialog. Do not actually set any values of any member + * variables. + */ + m_numberFormatSettings.validateSettings(settings); + } + + @Override + protected void loadInternals(File nodeInternDir, ExecutionMonitor exec) + throws IOException, CanceledExecutionException { + /* + * Advanced method, usually left empty. Everything that is + * handed to the 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). Only load the internals + * that need to be restored (e.g. data used by the views). + */ + } + + @Override + protected void saveInternals(File nodeInternDir, ExecutionMonitor exec) + throws IOException, CanceledExecutionException { + /* + * Advanced method, usually left empty. Everything + * written to the 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 only the internals + * that need to be preserved (e.g. data used by the views). + */ + } + + @Override + protected void reset() { + /* + * Code executed on a reset of the node. Models built during execute are cleared + * and the data handled in loadInternals/saveInternals will be erased. + */ + } +} + diff --git a/dev-workspace/andl-try-numberformatter/src/org/andl/trying/TryNumberFormatterNodePlugin.java b/dev-workspace/andl-try-numberformatter/src/org/andl/trying/TryNumberFormatterNodePlugin.java new file mode 100644 index 0000000..b0f1cee --- /dev/null +++ b/dev-workspace/andl-try-numberformatter/src/org/andl/trying/TryNumberFormatterNodePlugin.java @@ -0,0 +1,65 @@ +/* @(#)$RCSfile$ + * $Revision$ $Date$ $Author$ + * + */ +package org.andl.trying; + +import org.eclipse.core.runtime.Plugin; +import org.osgi.framework.BundleContext; + +/** + * This is the eclipse bundle activator. + * Note: KNIME node developers probably won't have to do anything in here, + * as this class is only needed by the eclipse platform/plugin mechanism. + * If you want to move/rename this file, make sure to change the plugin.xml + * file in the project root directory accordingly. + * + * @author andl + */ +public class TryNumberFormatterNodePlugin extends Plugin { + // The shared instance. + private static TryNumberFormatterNodePlugin plugin; + + /** + * The constructor. + */ + public TryNumberFormatterNodePlugin() { + super(); + plugin = this; + } + + /** + * This method is called upon plug-in activation. + * + * @param context The OSGI bundle context + * @throws Exception If this plugin could not be started + */ + @Override + public void start(final BundleContext context) throws Exception { + super.start(context); + + } + + /** + * This method is called when the plug-in is stopped. + * + * @param context The OSGI bundle context + * @throws Exception If this plugin could not be stopped + */ + @Override + public void stop(final BundleContext context) throws Exception { + super.stop(context); + plugin = null; + } + + /** + * Returns the shared instance. + * + * @return Singleton instance of the Plugin + */ + public static TryNumberFormatterNodePlugin getDefault() { + return plugin; + } + +} + diff --git a/dev-workspace/andl-try-numberformatter/src/org/andl/trying/TryNumberFormatterNodeView.java b/dev-workspace/andl-try-numberformatter/src/org/andl/trying/TryNumberFormatterNodeView.java new file mode 100644 index 0000000..34a5535 --- /dev/null +++ b/dev-workspace/andl-try-numberformatter/src/org/andl/trying/TryNumberFormatterNodeView.java @@ -0,0 +1,65 @@ +package org.andl.trying; + +import org.knime.core.node.NodeView; + + +/** + * This is an example implementation of the node view of the + * "TryNumberFormatter" node. + * + * As this example node does not have a view, this is just an empty stub of the + * NodeView class which not providing a real view pane. + * + * @author andl + */ +public class TryNumberFormatterNodeView extends NodeView { + + /** + * Creates a new view. + * + * @param nodeModel The model (class: {@link TryNumberFormatterNodeModel}) + */ + protected TryNumberFormatterNodeView(final TryNumberFormatterNodeModel nodeModel) { + super(nodeModel); + + // TODO instantiate the components of the view here. + + } + + /** + * {@inheritDoc} + */ + @Override + protected void modelChanged() { + + // TODO retrieve the new model from your nodemodel and + // update the view. + TryNumberFormatterNodeModel nodeModel = + (TryNumberFormatterNodeModel)getNodeModel(); + assert nodeModel != null; + + // be aware of a possibly not executed nodeModel! The data you retrieve + // from your nodemodel could be null, emtpy, or invalid in any kind. + + } + + /** + * {@inheritDoc} + */ + @Override + protected void onClose() { + + // TODO things to do when closing the view + } + + /** + * {@inheritDoc} + */ + @Override + protected void onOpen() { + + // TODO things to do when opening the view + } + +} + diff --git a/dev-workspace/andl-try-numberformatter/src/org/andl/trying/default.png b/dev-workspace/andl-try-numberformatter/src/org/andl/trying/default.png new file mode 100644 index 0000000000000000000000000000000000000000..18c2575f81cc16d413255a046114b81f77cb9a6a GIT binary patch literal 607 zcmV-l0-*hgP)j0xtnv*JZKM*jhH`aAH5w>2xkB+*J6qxv_Do-|zqWYl*|jl0a3}81n$f zxhQa;TrRK2oC8oS7Plv|*=^gl#~sJ{$DrA4=Iu;o1=V>#5V_E3G_t*3@2dk)tJSV5 zj1MQM*X!=y$;k!Vac-cR{0E0T&uasV(rUE|Vp*?&OhWKM;F`iJa4hATKW)o8;fQ6e t4GjbAS9p{%7}uUK4A(?echT)!zX6z`tp*)C$Z!Av002ovPDHLkV1ir~2)_UT literal 0 HcmV?d00001 diff --git a/dev-workspace/andl-try-numberformatter/src/org/andl/trying/package.html b/dev-workspace/andl-try-numberformatter/src/org/andl/trying/package.html new file mode 100644 index 0000000..4eae2ea --- /dev/null +++ b/dev-workspace/andl-try-numberformatter/src/org/andl/trying/package.html @@ -0,0 +1,25 @@ + + +This package implements ... (insert package description here) +

+The TryNumberFormatterModel ... (short comments on the classes) +

+The TryNumberFormatterDialog ... (short comments on the classes) +

+More comments ... +
+ + From 10b4509bba574fd156b4e3755c12cac7dca8ae53 Mon Sep 17 00:00:00 2001 From: david Date: Mon, 24 Feb 2020 20:52:57 +1100 Subject: [PATCH 02/56] Added Set Operation Added test workflow to AP Union, Minus, Intersect, Difference working. --- .../.classpath | 0 .../.gitignore | 0 .../.project | 2 +- .../META-INF/MANIFEST.MF | 0 .../andl-ra-projection/bin/.gitignore | 1 + .../build.properties | 0 .../plugin.xml | 0 .../org/andl/ra/RaProjectionNodeDialog.java | 2 +- .../org/andl/ra/RaProjectionNodeFactory.java | 20 +- .../org/andl/ra/RaProjectionNodeFactory.xml | 9 +- .../org/andl/ra/RaProjectionNodeModel.java | 2 +- .../org/andl/ra/RaProjectionNodePlugin.java | 0 .../src/org/andl/ra/RaProjectionNodeView.java | 0 .../src/org/andl/ra/RaTuple.java | 3 +- .../src/org/andl/ra/package.html | 0 .../src/org/andl/ra/projection.png | Bin dev-workspace/andl-ra-set/.classpath | 7 + dev-workspace/andl-ra-set/.project | 28 ++ .../andl-ra-set/META-INF/MANIFEST.MF | 15 + dev-workspace/andl-ra-set/bin/.gitignore | 1 + dev-workspace/andl-ra-set/build.properties | 4 + dev-workspace/andl-ra-set/plugin.xml | 25 ++ .../src/org/andl/ra/set/RaSetNodeDialog.java | 23 ++ .../src/org/andl/ra/set/RaSetNodeFactory.java | 48 +++ .../src/org/andl/ra/set/RaSetNodeFactory.xml | 22 ++ .../src/org/andl/ra/set/RaSetNodeModel.java | 285 ++++++++++++++++++ .../src/org/andl/ra/set/RaSetNodePlugin.java | 65 ++++ .../src/org/andl/ra/set/RaSetNodeView.java | 65 ++++ .../src/org/andl/ra/set/RaTuple.java | 111 +++++++ .../src/org/andl/ra/set/package.html | 25 ++ .../andl-ra-set/src/org/andl/ra/set/set.png | Bin 0 -> 486 bytes 31 files changed, 739 insertions(+), 24 deletions(-) rename dev-workspace/{andl-relational-algebra => andl-ra-projection}/.classpath (100%) rename dev-workspace/{andl-relational-algebra => andl-ra-projection}/.gitignore (100%) rename dev-workspace/{andl-relational-algebra => andl-ra-projection}/.project (94%) rename dev-workspace/{andl-relational-algebra => andl-ra-projection}/META-INF/MANIFEST.MF (100%) create mode 100644 dev-workspace/andl-ra-projection/bin/.gitignore rename dev-workspace/{andl-relational-algebra => andl-ra-projection}/build.properties (100%) rename dev-workspace/{andl-relational-algebra => andl-ra-projection}/plugin.xml (100%) rename dev-workspace/{andl-relational-algebra => andl-ra-projection}/src/org/andl/ra/RaProjectionNodeDialog.java (97%) rename dev-workspace/{andl-relational-algebra => andl-ra-projection}/src/org/andl/ra/RaProjectionNodeFactory.java (82%) rename dev-workspace/{andl-relational-algebra => andl-ra-projection}/src/org/andl/ra/RaProjectionNodeFactory.xml (67%) rename dev-workspace/{andl-relational-algebra => andl-ra-projection}/src/org/andl/ra/RaProjectionNodeModel.java (99%) rename dev-workspace/{andl-relational-algebra => andl-ra-projection}/src/org/andl/ra/RaProjectionNodePlugin.java (100%) rename dev-workspace/{andl-relational-algebra => andl-ra-projection}/src/org/andl/ra/RaProjectionNodeView.java (100%) rename dev-workspace/{andl-relational-algebra => andl-ra-projection}/src/org/andl/ra/RaTuple.java (98%) rename dev-workspace/{andl-relational-algebra => andl-ra-projection}/src/org/andl/ra/package.html (100%) rename dev-workspace/{andl-relational-algebra => andl-ra-projection}/src/org/andl/ra/projection.png (100%) create mode 100644 dev-workspace/andl-ra-set/.classpath create mode 100644 dev-workspace/andl-ra-set/.project create mode 100644 dev-workspace/andl-ra-set/META-INF/MANIFEST.MF create mode 100644 dev-workspace/andl-ra-set/bin/.gitignore create mode 100644 dev-workspace/andl-ra-set/build.properties create mode 100644 dev-workspace/andl-ra-set/plugin.xml create mode 100644 dev-workspace/andl-ra-set/src/org/andl/ra/set/RaSetNodeDialog.java create mode 100644 dev-workspace/andl-ra-set/src/org/andl/ra/set/RaSetNodeFactory.java create mode 100644 dev-workspace/andl-ra-set/src/org/andl/ra/set/RaSetNodeFactory.xml create mode 100644 dev-workspace/andl-ra-set/src/org/andl/ra/set/RaSetNodeModel.java create mode 100644 dev-workspace/andl-ra-set/src/org/andl/ra/set/RaSetNodePlugin.java create mode 100644 dev-workspace/andl-ra-set/src/org/andl/ra/set/RaSetNodeView.java create mode 100644 dev-workspace/andl-ra-set/src/org/andl/ra/set/RaTuple.java create mode 100644 dev-workspace/andl-ra-set/src/org/andl/ra/set/package.html create mode 100644 dev-workspace/andl-ra-set/src/org/andl/ra/set/set.png diff --git a/dev-workspace/andl-relational-algebra/.classpath b/dev-workspace/andl-ra-projection/.classpath similarity index 100% rename from dev-workspace/andl-relational-algebra/.classpath rename to dev-workspace/andl-ra-projection/.classpath diff --git a/dev-workspace/andl-relational-algebra/.gitignore b/dev-workspace/andl-ra-projection/.gitignore similarity index 100% rename from dev-workspace/andl-relational-algebra/.gitignore rename to dev-workspace/andl-ra-projection/.gitignore diff --git a/dev-workspace/andl-relational-algebra/.project b/dev-workspace/andl-ra-projection/.project similarity index 94% rename from dev-workspace/andl-relational-algebra/.project rename to dev-workspace/andl-ra-projection/.project index cf7f642..37be964 100644 --- a/dev-workspace/andl-relational-algebra/.project +++ b/dev-workspace/andl-ra-projection/.project @@ -1,6 +1,6 @@ - andl-relational-algebra + andl-ra-projection diff --git a/dev-workspace/andl-relational-algebra/META-INF/MANIFEST.MF b/dev-workspace/andl-ra-projection/META-INF/MANIFEST.MF similarity index 100% rename from dev-workspace/andl-relational-algebra/META-INF/MANIFEST.MF rename to dev-workspace/andl-ra-projection/META-INF/MANIFEST.MF diff --git a/dev-workspace/andl-ra-projection/bin/.gitignore b/dev-workspace/andl-ra-projection/bin/.gitignore new file mode 100644 index 0000000..cf1db2e --- /dev/null +++ b/dev-workspace/andl-ra-projection/bin/.gitignore @@ -0,0 +1 @@ +/org/ diff --git a/dev-workspace/andl-relational-algebra/build.properties b/dev-workspace/andl-ra-projection/build.properties similarity index 100% rename from dev-workspace/andl-relational-algebra/build.properties rename to dev-workspace/andl-ra-projection/build.properties diff --git a/dev-workspace/andl-relational-algebra/plugin.xml b/dev-workspace/andl-ra-projection/plugin.xml similarity index 100% rename from dev-workspace/andl-relational-algebra/plugin.xml rename to dev-workspace/andl-ra-projection/plugin.xml diff --git a/dev-workspace/andl-relational-algebra/src/org/andl/ra/RaProjectionNodeDialog.java b/dev-workspace/andl-ra-projection/src/org/andl/ra/RaProjectionNodeDialog.java similarity index 97% rename from dev-workspace/andl-relational-algebra/src/org/andl/ra/RaProjectionNodeDialog.java rename to dev-workspace/andl-ra-projection/src/org/andl/ra/RaProjectionNodeDialog.java index a3a8357..51b6f47 100644 --- a/dev-workspace/andl-relational-algebra/src/org/andl/ra/RaProjectionNodeDialog.java +++ b/dev-workspace/andl-ra-projection/src/org/andl/ra/RaProjectionNodeDialog.java @@ -14,7 +14,7 @@ import org.knime.core.node.util.filter.column.DataColumnSpecFilterPanel; /** - * Implement dialog for the selecting projection columns. + * Implement dialog for selecting projection columns. */ public class RaProjectionNodeDialog extends NodeDialogPane { diff --git a/dev-workspace/andl-relational-algebra/src/org/andl/ra/RaProjectionNodeFactory.java b/dev-workspace/andl-ra-projection/src/org/andl/ra/RaProjectionNodeFactory.java similarity index 82% rename from dev-workspace/andl-relational-algebra/src/org/andl/ra/RaProjectionNodeFactory.java rename to dev-workspace/andl-ra-projection/src/org/andl/ra/RaProjectionNodeFactory.java index e638ca3..8d3886f 100644 --- a/dev-workspace/andl-relational-algebra/src/org/andl/ra/RaProjectionNodeFactory.java +++ b/dev-workspace/andl-ra-projection/src/org/andl/ra/RaProjectionNodeFactory.java @@ -12,42 +12,32 @@ public class RaProjectionNodeFactory extends NodeFactory { - /** - * {@inheritDoc} - */ + /** {@inheritDoc} */ @Override public RaProjectionNodeModel createNodeModel() { return new RaProjectionNodeModel(); } - /** - * {@inheritDoc} - */ + /** {@inheritDoc} */ @Override public int getNrNodeViews() { return 0; } - /** - * {@inheritDoc} - */ + /** {@inheritDoc} */ @Override public NodeView createNodeView(final int viewIndex, final RaProjectionNodeModel nodeModel) { return null; } - /** - * {@inheritDoc} - */ + /** {@inheritDoc} */ @Override public boolean hasDialog() { return true; } - /** - * {@inheritDoc} - */ + /** {@inheritDoc} */ @Override public NodeDialogPane createNodeDialogPane() { return new RaProjectionNodeDialog(); diff --git a/dev-workspace/andl-relational-algebra/src/org/andl/ra/RaProjectionNodeFactory.xml b/dev-workspace/andl-ra-projection/src/org/andl/ra/RaProjectionNodeFactory.xml similarity index 67% rename from dev-workspace/andl-relational-algebra/src/org/andl/ra/RaProjectionNodeFactory.xml rename to dev-workspace/andl-ra-projection/src/org/andl/ra/RaProjectionNodeFactory.xml index 1bcff36..98fec67 100644 --- a/dev-workspace/andl-relational-algebra/src/org/andl/ra/RaProjectionNodeFactory.xml +++ b/dev-workspace/andl-ra-projection/src/org/andl/ra/RaProjectionNodeFactory.xml @@ -7,14 +7,15 @@ - This is the projection operator defined for the relational algebra. It is equivalent to removing some columns and then copying the table removing duplicates. - + This is the projection operator defined for the relational algebra. + It is equivalent to removing some columns and then copying the table removing duplicates. + - Description of first input port... - Description of first output port... + Input table. + Result of projection. diff --git a/dev-workspace/andl-relational-algebra/src/org/andl/ra/RaProjectionNodeModel.java b/dev-workspace/andl-ra-projection/src/org/andl/ra/RaProjectionNodeModel.java similarity index 99% rename from dev-workspace/andl-relational-algebra/src/org/andl/ra/RaProjectionNodeModel.java rename to dev-workspace/andl-ra-projection/src/org/andl/ra/RaProjectionNodeModel.java index da0eb8b..1c37c40 100644 --- a/dev-workspace/andl-relational-algebra/src/org/andl/ra/RaProjectionNodeModel.java +++ b/dev-workspace/andl-ra-projection/src/org/andl/ra/RaProjectionNodeModel.java @@ -43,7 +43,7 @@ /** - * Implements the node model of the "RaProjection" node. + * Implements the model for the "RaProjection" node. * * Include the columns comprising a projection subset. * Copy across required columns of input rows. diff --git a/dev-workspace/andl-relational-algebra/src/org/andl/ra/RaProjectionNodePlugin.java b/dev-workspace/andl-ra-projection/src/org/andl/ra/RaProjectionNodePlugin.java similarity index 100% rename from dev-workspace/andl-relational-algebra/src/org/andl/ra/RaProjectionNodePlugin.java rename to dev-workspace/andl-ra-projection/src/org/andl/ra/RaProjectionNodePlugin.java diff --git a/dev-workspace/andl-relational-algebra/src/org/andl/ra/RaProjectionNodeView.java b/dev-workspace/andl-ra-projection/src/org/andl/ra/RaProjectionNodeView.java similarity index 100% rename from dev-workspace/andl-relational-algebra/src/org/andl/ra/RaProjectionNodeView.java rename to dev-workspace/andl-ra-projection/src/org/andl/ra/RaProjectionNodeView.java diff --git a/dev-workspace/andl-relational-algebra/src/org/andl/ra/RaTuple.java b/dev-workspace/andl-ra-projection/src/org/andl/ra/RaTuple.java similarity index 98% rename from dev-workspace/andl-relational-algebra/src/org/andl/ra/RaTuple.java rename to dev-workspace/andl-ra-projection/src/org/andl/ra/RaTuple.java index 9d66e19..5f8d535 100644 --- a/dev-workspace/andl-relational-algebra/src/org/andl/ra/RaTuple.java +++ b/dev-workspace/andl-ra-projection/src/org/andl/ra/RaTuple.java @@ -47,7 +47,6 @@ */ package org.andl.ra; -import java.util.ArrayList; import java.util.Arrays; import org.knime.core.data.DataCell; import org.knime.core.data.DataRow; @@ -57,7 +56,7 @@ * * @author Andl */ -class RaTuple { +public class RaTuple { private DataCell[] m_cells; /** diff --git a/dev-workspace/andl-relational-algebra/src/org/andl/ra/package.html b/dev-workspace/andl-ra-projection/src/org/andl/ra/package.html similarity index 100% rename from dev-workspace/andl-relational-algebra/src/org/andl/ra/package.html rename to dev-workspace/andl-ra-projection/src/org/andl/ra/package.html diff --git a/dev-workspace/andl-relational-algebra/src/org/andl/ra/projection.png b/dev-workspace/andl-ra-projection/src/org/andl/ra/projection.png similarity index 100% rename from dev-workspace/andl-relational-algebra/src/org/andl/ra/projection.png rename to dev-workspace/andl-ra-projection/src/org/andl/ra/projection.png diff --git a/dev-workspace/andl-ra-set/.classpath b/dev-workspace/andl-ra-set/.classpath new file mode 100644 index 0000000..156f8ae --- /dev/null +++ b/dev-workspace/andl-ra-set/.classpath @@ -0,0 +1,7 @@ + + + + + + + diff --git a/dev-workspace/andl-ra-set/.project b/dev-workspace/andl-ra-set/.project new file mode 100644 index 0000000..b8eef92 --- /dev/null +++ b/dev-workspace/andl-ra-set/.project @@ -0,0 +1,28 @@ + + + andl-ra-set + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.pde.ManifestBuilder + + + + + org.eclipse.pde.SchemaBuilder + + + + + + org.eclipse.pde.PluginNature + org.eclipse.jdt.core.javanature + + diff --git a/dev-workspace/andl-ra-set/META-INF/MANIFEST.MF b/dev-workspace/andl-ra-set/META-INF/MANIFEST.MF new file mode 100644 index 0000000..7882788 --- /dev/null +++ b/dev-workspace/andl-ra-set/META-INF/MANIFEST.MF @@ -0,0 +1,15 @@ +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: RaSet-Node extension for KNIME Workbench +Bundle-SymbolicName: org.andl.ra.set; singleton:=true +Bundle-Version: 1.0.0.qualifier +Bundle-ClassPath: raset.jar +Bundle-Activator: org.andl.ra.set.RaSetNodePlugin +Bundle-Vendor: andl +Require-Bundle: org.eclipse.core.runtime, + org.knime.workbench.core, + org.knime.workbench.repository, + org.knime.base +Bundle-ActivationPolicy: lazy +Export-Package: org.andl.ra.set + diff --git a/dev-workspace/andl-ra-set/bin/.gitignore b/dev-workspace/andl-ra-set/bin/.gitignore new file mode 100644 index 0000000..cf1db2e --- /dev/null +++ b/dev-workspace/andl-ra-set/bin/.gitignore @@ -0,0 +1 @@ +/org/ diff --git a/dev-workspace/andl-ra-set/build.properties b/dev-workspace/andl-ra-set/build.properties new file mode 100644 index 0000000..c08efca --- /dev/null +++ b/dev-workspace/andl-ra-set/build.properties @@ -0,0 +1,4 @@ +source.raset.jar = src/ +bin.includes = plugin.xml,\ + META-INF/,\ + raset.jar diff --git a/dev-workspace/andl-ra-set/plugin.xml b/dev-workspace/andl-ra-set/plugin.xml new file mode 100644 index 0000000..5d393f8 --- /dev/null +++ b/dev-workspace/andl-ra-set/plugin.xml @@ -0,0 +1,25 @@ + + + + + + + + + + + diff --git a/dev-workspace/andl-ra-set/src/org/andl/ra/set/RaSetNodeDialog.java b/dev-workspace/andl-ra-set/src/org/andl/ra/set/RaSetNodeDialog.java new file mode 100644 index 0000000..b8e069e --- /dev/null +++ b/dev-workspace/andl-ra-set/src/org/andl/ra/set/RaSetNodeDialog.java @@ -0,0 +1,23 @@ +package org.andl.ra.set; + +import org.knime.core.node.defaultnodesettings.DefaultNodeSettingsPane; +import org.knime.core.node.defaultnodesettings.DialogComponentStringSelection; +import org.knime.core.node.defaultnodesettings.SettingsModel; +import org.knime.core.node.defaultnodesettings.SettingsModelString; + +/** + * Implement dialog for selecting which set operation. + * + * @author andl + */ +public class RaSetNodeDialog extends DefaultNodeSettingsPane { + + protected RaSetNodeDialog() { + super(); + + SettingsModelString settings = RaSetNodeModel.createSettingsModel(); + addDialogComponent(new DialogComponentStringSelection(settings, "Set Operation", + RaSetNodeModel.ALL_SET_OPERATIONS)); + } +} + diff --git a/dev-workspace/andl-ra-set/src/org/andl/ra/set/RaSetNodeFactory.java b/dev-workspace/andl-ra-set/src/org/andl/ra/set/RaSetNodeFactory.java new file mode 100644 index 0000000..b10abdc --- /dev/null +++ b/dev-workspace/andl-ra-set/src/org/andl/ra/set/RaSetNodeFactory.java @@ -0,0 +1,48 @@ +package org.andl.ra.set; + +import org.knime.core.node.NodeDialogPane; +import org.knime.core.node.NodeFactory; +import org.knime.core.node.NodeView; + +/** + * This is an example implementation of the node factory of the + * "RaSet" node. + * + * @author andl + */ +public class RaSetNodeFactory + extends NodeFactory { + + /** {@inheritDoc} */ + @Override + public RaSetNodeModel createNodeModel() { + return new RaSetNodeModel(); + } + + /** {@inheritDoc} */ + @Override + public int getNrNodeViews() { + return 0; + } + + /** {@inheritDoc} */ + @Override + public NodeView createNodeView(final int viewIndex, + final RaSetNodeModel nodeModel) { + return null; + } + + /** {@inheritDoc} */ + @Override + public boolean hasDialog() { + return true; + } + + /** {@inheritDoc} */ + @Override + public NodeDialogPane createNodeDialogPane() { + return new RaSetNodeDialog(); + } + +} + diff --git a/dev-workspace/andl-ra-set/src/org/andl/ra/set/RaSetNodeFactory.xml b/dev-workspace/andl-ra-set/src/org/andl/ra/set/RaSetNodeFactory.xml new file mode 100644 index 0000000..d4b520a --- /dev/null +++ b/dev-workspace/andl-ra-set/src/org/andl/ra/set/RaSetNodeFactory.xml @@ -0,0 +1,22 @@ + + + RaSetOperation + + Combine two tables using a selected set operation. + + + Combine two tables using a selected set operation. + Duplicates if any are removed from the output. + + + + + + + + + Left (top) input table. + Right (bottom) input table. + Result of set operation. + + diff --git a/dev-workspace/andl-ra-set/src/org/andl/ra/set/RaSetNodeModel.java b/dev-workspace/andl-ra-set/src/org/andl/ra/set/RaSetNodeModel.java new file mode 100644 index 0000000..4ee66be --- /dev/null +++ b/dev-workspace/andl-ra-set/src/org/andl/ra/set/RaSetNodeModel.java @@ -0,0 +1,285 @@ +package org.andl.ra.set; + +import java.io.File; +import java.io.IOException; +import java.nio.channels.CancelledKeyException; +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashSet; +import java.util.IllegalFormatException; +import java.util.Iterator; +import java.util.List; + +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.container.CloseableRowIterator; +import org.knime.core.data.def.DefaultRow; +import org.knime.core.data.def.DoubleCell; +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.SettingsModelString; + +/** + * Implements the model for the "RaSet" node. + * + * Union merges two tables and removes duplicates + * Minus outputs rows in the first table but not in the second + * Intersect outputs rows found in both tables + * Difference outputs rows in the first table or the second but not both + * + * @author andl + */ +public class RaSetNodeModel extends NodeModel { + + private static final NodeLogger LOGGER = NodeLogger.getLogger(RaSetNodeModel.class); + private static final String KEY_SET_OPERATION = "set-operation"; + private static final String DEFAULT_SET_OPERATION = "Union"; + static final String[] ALL_SET_OPERATIONS = { + "Union", "Minus", "Intersect", "Difference" + }; + private final SettingsModelString m_SetOperationSettings = createSettingsModel(); + + /** + * Constructor for the node model. + */ + protected RaSetNodeModel() { + super(2, 1); + } + + /** + * @return a new SettingsModelString with the key for the set operation String + */ + static SettingsModelString createSettingsModel() { + return new SettingsModelString(KEY_SET_OPERATION, DEFAULT_SET_OPERATION); + } + + /** {@inheritDoc} */ + @Override + protected BufferedDataTable[] execute(final BufferedDataTable[] inData, final ExecutionContext exec) + throws Exception { + + String operation = m_SetOperationSettings.getStringValue(); + LOGGER.debug("Begin setop=" + operation); + + outputGenerator outgen = new outputGenerator(exec, inData[0].getDataTableSpec()); + BufferedDataTable out = + operation == ALL_SET_OPERATIONS[0] ? outgen.getUnion(inData) + : operation == ALL_SET_OPERATIONS[1] ? outgen.getMinus(inData) + : operation == ALL_SET_OPERATIONS[2] ? outgen.getIntersect(inData) + : operation == ALL_SET_OPERATIONS[3] ? outgen.getDifference(inData) + : null; + return new BufferedDataTable[] { out }; + } + + /** {@inheritDoc} */ + @Override + protected DataTableSpec[] configure(final DataTableSpec[] inSpecs) throws InvalidSettingsException { + if (!(Arrays.asList(ALL_SET_OPERATIONS).contains(m_SetOperationSettings.getStringValue()))) + throw new InvalidSettingsException("The selection operation is not valid"); + + return new DataTableSpec[] { createOutputSpec(inSpecs[0]) }; + } + + private DataTableSpec createOutputSpec(DataTableSpec inSpec) { + return inSpec; + } + + /** {@inheritDoc} */ + @Override + protected void saveSettingsTo(final NodeSettingsWO settings) { + m_SetOperationSettings.saveSettingsTo(settings); + } + + /** {@inheritDoc} */ + @Override + protected void loadValidatedSettingsFrom(final NodeSettingsRO settings) throws InvalidSettingsException { + m_SetOperationSettings.loadSettingsFrom(settings); + } + + /** {@inheritDoc} */ + @Override + protected void validateSettings(final NodeSettingsRO settings) throws InvalidSettingsException { + m_SetOperationSettings.validateSettings(settings); + } + + /** {@inheritDoc} */ + @Override + protected void loadInternals(File nodeInternDir, ExecutionMonitor exec) + throws IOException, CanceledExecutionException { } + + /** {@inheritDoc} */ + @Override + protected void saveInternals(File nodeInternDir, ExecutionMonitor exec) + throws IOException, CanceledExecutionException { } + + /** {@inheritDoc} */ + @Override + protected void reset() { } +} + +/** + * Implement the algorithms to combine two inputs to one output by a Set operation + */ +class outputGenerator { + final ExecutionContext _exec; + DataTableSpec _outputSpec; + BufferedDataContainer _container; + long _insize = 0; + int _incounter = 0; + int _outcounter = 0; + + outputGenerator(ExecutionContext exec, DataTableSpec outputSpec) { + _exec = exec; + _outputSpec = outputSpec; + } + + // return the Set Union of the two input tables + BufferedDataTable getUnion(BufferedDataTable[] inputs) throws Exception { + _container = _exec.createDataContainer(_outputSpec); + HashSet hashset = new HashSet<>(); + _insize = inputs[0].size() + inputs[1].size(); + + // copy all rows to the output, removing duplicates + for (BufferedDataTable input : inputs) { + for (CloseableRowIterator iter = input.iterator(); iter.hasNext(); ) { + ++_incounter; + DataRow row = iter.next(); + RaTuple tuple = new RaTuple(row); + if (!(hashset.contains(tuple))) { + addRow(row); + hashset.add(tuple); + } + } + } + _container.close(); + return _container.getTable(); + } + + // return the Set Minus of the two input tables + BufferedDataTable getMinus(BufferedDataTable[] inputs) throws Exception { + _container = _exec.createDataContainer(_outputSpec); + HashSet hashset = new HashSet<>(); + _insize = inputs[0].size() + inputs[1].size(); + + // add all the right table rows to the hashset + for (CloseableRowIterator iter = inputs[1].iterator(); iter.hasNext(); ) { + ++_incounter; + DataRow row = iter.next(); + RaTuple tuple = new RaTuple(row); + hashset.add(tuple); + } + + // copy left table rows to the output, removing right rows + // add to hashset to remove duplicates + for (CloseableRowIterator iter = inputs[0].iterator(); iter.hasNext(); ) { + ++_incounter; + DataRow row = iter.next(); + RaTuple tuple = new RaTuple(row); + if (!(hashset.contains(tuple))) { + addRow(row); + hashset.add(tuple); + } + } + _container.close(); + return _container.getTable(); + } + + // return the Set Intersection of the two input tables + BufferedDataTable getIntersect(BufferedDataTable[] inputs) throws Exception { + _container = _exec.createDataContainer(_outputSpec); + HashSet hashset = new HashSet<>(); + _insize = inputs[0].size() + inputs[1].size(); + + // add all the right table rows to the hashset + for (CloseableRowIterator iter = inputs[1].iterator(); iter.hasNext(); ) { + ++_incounter; + DataRow row = iter.next(); + RaTuple tuple = new RaTuple(row); + hashset.add(tuple); + } + + // copy left table rows to the output if found in hashset + // remove from hashset so no duplicates + for (CloseableRowIterator iter = inputs[0].iterator(); iter.hasNext(); ) { + ++_incounter; + DataRow row = iter.next(); + RaTuple tuple = new RaTuple(row); + if (hashset.contains(tuple)) { + addRow(row); + hashset.remove(tuple); + } + } + _container.close(); + return _container.getTable(); + } + + // return the Set Symmetrical Difference of the two input tables + // this way takes two passes through the right table. Could do better by marking + // tuples in the hashset. + BufferedDataTable getDifference(BufferedDataTable[] inputs) throws Exception { + _container = _exec.createDataContainer(_outputSpec); + // two hashsets, one for each side + HashSet hashset0 = new HashSet<>(); + HashSet hashset1 = new HashSet<>(); + _insize = inputs[0].size() + 2 * inputs[1].size(); + + // add all the right table rows to the hashset + for (CloseableRowIterator iter = inputs[1].iterator(); iter.hasNext(); ) { + ++_incounter; + DataRow row = iter.next(); + RaTuple tuple = new RaTuple(row); + hashset1.add(tuple); + } + + // copy left table rows to the output if not found in hashset + // add to hashset so no duplicates + for (CloseableRowIterator iter = inputs[0].iterator(); iter.hasNext(); ) { + ++_incounter; + DataRow row = iter.next(); + RaTuple tuple = new RaTuple(row); + hashset0.add(tuple); + if (!hashset1.contains(tuple)) { + addRow(row); + hashset1.add(tuple); + } + } + + // copy right table rows to the output if not found in hashset + // add to hashset so no duplicates + for (CloseableRowIterator iter = inputs[1].iterator(); iter.hasNext(); ) { + ++_incounter; + DataRow row = iter.next(); + RaTuple tuple = new RaTuple(row); + if (!hashset0.contains(tuple)) { + addRow(row); + hashset0.add(tuple); + } + } + + _container.close(); + return _container.getTable(); + } + + void addRow(DataRow row) throws Exception { + DataRow newrow = new DefaultRow("Row" + _outcounter++, row); + _container.addRowToTable(newrow); + _exec.checkCanceled(); + _exec.setProgress(_incounter / _insize, "Input row " + _incounter); + } + +} + diff --git a/dev-workspace/andl-ra-set/src/org/andl/ra/set/RaSetNodePlugin.java b/dev-workspace/andl-ra-set/src/org/andl/ra/set/RaSetNodePlugin.java new file mode 100644 index 0000000..fd0098b --- /dev/null +++ b/dev-workspace/andl-ra-set/src/org/andl/ra/set/RaSetNodePlugin.java @@ -0,0 +1,65 @@ +/* @(#)$RCSfile$ + * $Revision$ $Date$ $Author$ + * + */ +package org.andl.ra.set; + +import org.eclipse.core.runtime.Plugin; +import org.osgi.framework.BundleContext; + +/** + * This is the eclipse bundle activator. + * Note: KNIME node developers probably won't have to do anything in here, + * as this class is only needed by the eclipse platform/plugin mechanism. + * If you want to move/rename this file, make sure to change the plugin.xml + * file in the project root directory accordingly. + * + * @author andl + */ +public class RaSetNodePlugin extends Plugin { + // The shared instance. + private static RaSetNodePlugin plugin; + + /** + * The constructor. + */ + public RaSetNodePlugin() { + super(); + plugin = this; + } + + /** + * This method is called upon plug-in activation. + * + * @param context The OSGI bundle context + * @throws Exception If this plugin could not be started + */ + @Override + public void start(final BundleContext context) throws Exception { + super.start(context); + + } + + /** + * This method is called when the plug-in is stopped. + * + * @param context The OSGI bundle context + * @throws Exception If this plugin could not be stopped + */ + @Override + public void stop(final BundleContext context) throws Exception { + super.stop(context); + plugin = null; + } + + /** + * Returns the shared instance. + * + * @return Singleton instance of the Plugin + */ + public static RaSetNodePlugin getDefault() { + return plugin; + } + +} + diff --git a/dev-workspace/andl-ra-set/src/org/andl/ra/set/RaSetNodeView.java b/dev-workspace/andl-ra-set/src/org/andl/ra/set/RaSetNodeView.java new file mode 100644 index 0000000..a0d135a --- /dev/null +++ b/dev-workspace/andl-ra-set/src/org/andl/ra/set/RaSetNodeView.java @@ -0,0 +1,65 @@ +package org.andl.ra.set; + +import org.knime.core.node.NodeView; + + +/** + * This is an example implementation of the node view of the + * "RaSet" node. + * + * As this example node does not have a view, this is just an empty stub of the + * NodeView class which not providing a real view pane. + * + * @author andl + */ +public class RaSetNodeView extends NodeView { + + /** + * Creates a new view. + * + * @param nodeModel The model (class: {@link RaSetNodeModel}) + */ + protected RaSetNodeView(final RaSetNodeModel nodeModel) { + super(nodeModel); + + // TODO instantiate the components of the view here. + + } + + /** + * {@inheritDoc} + */ + @Override + protected void modelChanged() { + + // TODO retrieve the new model from your nodemodel and + // update the view. + RaSetNodeModel nodeModel = + (RaSetNodeModel)getNodeModel(); + assert nodeModel != null; + + // be aware of a possibly not executed nodeModel! The data you retrieve + // from your nodemodel could be null, emtpy, or invalid in any kind. + + } + + /** + * {@inheritDoc} + */ + @Override + protected void onClose() { + + // TODO things to do when closing the view + } + + /** + * {@inheritDoc} + */ + @Override + protected void onOpen() { + + // TODO things to do when opening the view + } + +} + diff --git a/dev-workspace/andl-ra-set/src/org/andl/ra/set/RaTuple.java b/dev-workspace/andl-ra-set/src/org/andl/ra/set/RaTuple.java new file mode 100644 index 0000000..e50b004 --- /dev/null +++ b/dev-workspace/andl-ra-set/src/org/andl/ra/set/RaTuple.java @@ -0,0 +1,111 @@ +/* + * ------------------------------------------------------------------------ + * Copyright by KNIME AG, Zurich, Switzerland + * Website: http://www.knime.com; Email: contact@knime.com + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License, Version 3, as + * published by the Free Software Foundation. + * + * 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + * + * Additional permission under GNU GPL version 3 section 7: + * + * KNIME interoperates with ECLIPSE solely via ECLIPSE's plug-in APIs. + * Hence, KNIME and ECLIPSE are both independent programs and are not + * derived from each other. Should, however, the interpretation of the + * GNU GPL Version 3 ("License") under any applicable laws result in + * KNIME and ECLIPSE being a combined program, KNIME AG herewith grants + * you the additional permission to use and propagate KNIME together with + * ECLIPSE with only the license terms in place for ECLIPSE applying to + * ECLIPSE and the GNU GPL Version 3 applying for KNIME, provided the + * license terms of ECLIPSE themselves allow for the respective use and + * propagation of ECLIPSE together with KNIME. + * + * Additional permission relating to nodes for KNIME that extend the Node + * Extension (and in particular that are based on subclasses of NodeModel, + * NodeDialog, and NodeView) and that only interoperate with KNIME through + * standard APIs ("Nodes"): + * Nodes are deemed to be separate and independent programs and to not be + * covered works. Notwithstanding anything to the contrary in the + * License, the License does not apply to Nodes, you are not required to + * license Nodes under the License, and you are granted a license to + * prepare and propagate Nodes, in each case even if such Nodes are + * propagated with or for interoperation with KNIME. The owner of a Node + * may freely choose the license terms applicable to such Node, including + * when such Node is propagated with or for interoperation with KNIME. + * ------------------------------------------------------------------------ + * + * History + * 25.11.2009 (Heiko Hofer): created + */ +package org.andl.ra.set; + +import java.util.Arrays; +import org.knime.core.data.DataCell; +import org.knime.core.data.DataRow; + +/** + * Implement data tuple with equals by value and hashCode. + * + * @author Andl + */ +public class RaTuple { + private DataCell[] _cells; + + public DataCell[] get_cells() { + return _cells; + } + + /** + * Creates a new RaTuple from an array of cells. + * @param cells The cells comprising the tuple. + */ + public RaTuple(final DataCell[] cells) { + _cells = cells; +// m_cells = new ArrayList(); +// for (DataCell cell : cells) { +// m_cells.add(cell); +// }; + } + + /** + * Creates a new RaTuple from a DataRow + * @param row The DataRow + */ + public RaTuple(final DataRow row) { + _cells = new DataCell[row.getNumCells()]; + for (int i = 0; i < _cells.length; ++i) + _cells[i] = row.getCell(i); +// m_cells = new ArrayList(); +// row.forEach(cell -> { m_cells.add(cell); }); + } + + /** {@inheritDoc} */ + @Override + public int hashCode() { + return Arrays.hashCode(_cells); + } + + /** {@inheritDoc} */ + @Override + public boolean equals(final Object obj) { + if (this == obj) return true; + if (!(obj instanceof RaTuple)) return false; + + RaTuple that = (RaTuple)obj; + for (int i = 0; i < this._cells.length; i++) { + DataCell thisCell = this._cells[i]; + DataCell thatCell = that._cells[i]; + if (!thisCell.equals(thatCell)) return false; + } + return true; + } +} + diff --git a/dev-workspace/andl-ra-set/src/org/andl/ra/set/package.html b/dev-workspace/andl-ra-set/src/org/andl/ra/set/package.html new file mode 100644 index 0000000..e8c417b --- /dev/null +++ b/dev-workspace/andl-ra-set/src/org/andl/ra/set/package.html @@ -0,0 +1,25 @@ + + +This package implements ... (insert package description here) +

+The RaSetModel ... (short comments on the classes) +

+The RaSetDialog ... (short comments on the classes) +

+More comments ... +
+ + diff --git a/dev-workspace/andl-ra-set/src/org/andl/ra/set/set.png b/dev-workspace/andl-ra-set/src/org/andl/ra/set/set.png new file mode 100644 index 0000000000000000000000000000000000000000..23f2aa3c745621c4da45b0e72d015083ec85ec98 GIT binary patch literal 486 zcmV@P)Px#1ZP1_K>z@;j|==^1poj532;bRa{vGi!vFvd!vV){sAK>D0eeYAK~!i%?U~V$ z!ypU=Qx^qMkE@{>it)(_8N?m7r6<`pnP`6jzm*^!JbA32Kv?<_mVSh#A7SZ7So#r` ze&Ck1EIFmen_Oxe*eJP=q%@8JfR=UX7L8om81Z*FEf!JCvg8)t88qtI1SOCqb2!Q7 zO*LpDmQ0dw^BmRWJ#3bO_ONc^%>*o!xvH9Wuvtp>Ff0!U%N@en+WPlDN|n-te$&gyjKYxx+VDN^<|nQkSc&X%1qk+VWnK=zPpUEP3)t ze^@~VNz9UKz8Q5V6AY4| Date: Tue, 25 Feb 2020 17:23:54 +1100 Subject: [PATCH 03/56] Implement Join operation Update various xml etc Minor refactoring --- .../andl-ra-projection/META-INF/MANIFEST.MF | 5 +- dev-workspace/andl-ra-projection/plugin.xml | 4 +- .../src/org/andl/ra/RaTuple.java | 107 ------ .../RaProjectionNodeDialog.java | 2 +- .../RaProjectionNodeFactory.java | 2 +- .../RaProjectionNodeFactory.xml | 2 +- .../RaProjectionNodeModel.java | 4 +- .../RaProjectionNodePlugin.java | 2 +- .../RaProjectionNodeView.java | 2 +- .../org/andl/ra/{ => projection}/package.html | 0 .../andl/ra/{ => projection}/projection.png | Bin dev-workspace/andl-ra-set/plugin.xml | 2 +- .../src/org/andl/ra/set/RaSetNodeFactory.xml | 4 +- .../src/org/andl/ra/set/RaSetNodeModel.java | 14 +- .../src/org/andl/ra/set/RaTuple.java | 69 +--- dev-workspace/andl-ra/.classpath | 7 + dev-workspace/andl-ra/.project | 28 ++ dev-workspace/andl-ra/META-INF/MANIFEST.MF | 16 + dev-workspace/andl-ra/bin/.gitignore | 1 + dev-workspace/andl-ra/build.properties | 4 + dev-workspace/andl-ra/plugin.xml | 25 ++ .../org/andl/ra/join/RaJoinNodeDialog.java | 23 ++ .../org/andl/ra/join/RaJoinNodeFactory.java | 48 +++ .../org/andl/ra/join/RaJoinNodeFactory.xml | 22 ++ .../src/org/andl/ra/join/RaJoinNodeModel.java | 322 ++++++++++++++++++ .../org/andl/ra/join/RaJoinNodePlugin.java | 65 ++++ .../src/org/andl/ra/join/RaJoinNodeView.java | 65 ++++ .../andl-ra/src/org/andl/ra/join/default.png | Bin 0 -> 607 bytes .../andl-ra/src/org/andl/ra/join/package.html | 25 ++ .../andl-try-numberformatter/plugin.xml | 8 +- 30 files changed, 694 insertions(+), 184 deletions(-) delete mode 100644 dev-workspace/andl-ra-projection/src/org/andl/ra/RaTuple.java rename dev-workspace/andl-ra-projection/src/org/andl/ra/{ => projection}/RaProjectionNodeDialog.java (98%) rename dev-workspace/andl-ra-projection/src/org/andl/ra/{ => projection}/RaProjectionNodeFactory.java (96%) rename dev-workspace/andl-ra-projection/src/org/andl/ra/{ => projection}/RaProjectionNodeFactory.xml (94%) rename dev-workspace/andl-ra-projection/src/org/andl/ra/{ => projection}/RaProjectionNodeModel.java (99%) rename dev-workspace/andl-ra-projection/src/org/andl/ra/{ => projection}/RaProjectionNodePlugin.java (98%) rename dev-workspace/andl-ra-projection/src/org/andl/ra/{ => projection}/RaProjectionNodeView.java (96%) rename dev-workspace/andl-ra-projection/src/org/andl/ra/{ => projection}/package.html (100%) rename dev-workspace/andl-ra-projection/src/org/andl/ra/{ => projection}/projection.png (100%) create mode 100644 dev-workspace/andl-ra/.classpath create mode 100644 dev-workspace/andl-ra/.project create mode 100644 dev-workspace/andl-ra/META-INF/MANIFEST.MF create mode 100644 dev-workspace/andl-ra/bin/.gitignore create mode 100644 dev-workspace/andl-ra/build.properties create mode 100644 dev-workspace/andl-ra/plugin.xml create mode 100644 dev-workspace/andl-ra/src/org/andl/ra/join/RaJoinNodeDialog.java create mode 100644 dev-workspace/andl-ra/src/org/andl/ra/join/RaJoinNodeFactory.java create mode 100644 dev-workspace/andl-ra/src/org/andl/ra/join/RaJoinNodeFactory.xml create mode 100644 dev-workspace/andl-ra/src/org/andl/ra/join/RaJoinNodeModel.java create mode 100644 dev-workspace/andl-ra/src/org/andl/ra/join/RaJoinNodePlugin.java create mode 100644 dev-workspace/andl-ra/src/org/andl/ra/join/RaJoinNodeView.java create mode 100644 dev-workspace/andl-ra/src/org/andl/ra/join/default.png create mode 100644 dev-workspace/andl-ra/src/org/andl/ra/join/package.html diff --git a/dev-workspace/andl-ra-projection/META-INF/MANIFEST.MF b/dev-workspace/andl-ra-projection/META-INF/MANIFEST.MF index 2ca3a00..b9f841e 100644 --- a/dev-workspace/andl-ra-projection/META-INF/MANIFEST.MF +++ b/dev-workspace/andl-ra-projection/META-INF/MANIFEST.MF @@ -4,12 +4,13 @@ Bundle-Name: RaProjection-Node extension for KNIME Workbench Bundle-SymbolicName: org.andl.ra; singleton:=true Bundle-Version: 1.0.0.qualifier Bundle-ClassPath: raprojection.jar -Bundle-Activator: org.andl.ra.RaProjectionNodePlugin +Bundle-Activator: org.andl.ra.projection.RaProjectionNodePlugin Bundle-Vendor: andl Require-Bundle: org.eclipse.core.runtime, org.knime.workbench.core, org.knime.workbench.repository, org.knime.base Bundle-ActivationPolicy: lazy -Export-Package: org.andl.ra +Export-Package: org.andl.ra.projection +Import-Package: org.andl.ra.set diff --git a/dev-workspace/andl-ra-projection/plugin.xml b/dev-workspace/andl-ra-projection/plugin.xml index 866aad6..dfb0ed7 100644 --- a/dev-workspace/andl-ra-projection/plugin.xml +++ b/dev-workspace/andl-ra-projection/plugin.xml @@ -17,8 +17,8 @@ diff --git a/dev-workspace/andl-ra-projection/src/org/andl/ra/RaTuple.java b/dev-workspace/andl-ra-projection/src/org/andl/ra/RaTuple.java deleted file mode 100644 index 5f8d535..0000000 --- a/dev-workspace/andl-ra-projection/src/org/andl/ra/RaTuple.java +++ /dev/null @@ -1,107 +0,0 @@ -/* - * ------------------------------------------------------------------------ - * Copyright by KNIME AG, Zurich, Switzerland - * Website: http://www.knime.com; Email: contact@knime.com - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License, Version 3, as - * published by the Free Software Foundation. - * - * 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, see . - * - * Additional permission under GNU GPL version 3 section 7: - * - * KNIME interoperates with ECLIPSE solely via ECLIPSE's plug-in APIs. - * Hence, KNIME and ECLIPSE are both independent programs and are not - * derived from each other. Should, however, the interpretation of the - * GNU GPL Version 3 ("License") under any applicable laws result in - * KNIME and ECLIPSE being a combined program, KNIME AG herewith grants - * you the additional permission to use and propagate KNIME together with - * ECLIPSE with only the license terms in place for ECLIPSE applying to - * ECLIPSE and the GNU GPL Version 3 applying for KNIME, provided the - * license terms of ECLIPSE themselves allow for the respective use and - * propagation of ECLIPSE together with KNIME. - * - * Additional permission relating to nodes for KNIME that extend the Node - * Extension (and in particular that are based on subclasses of NodeModel, - * NodeDialog, and NodeView) and that only interoperate with KNIME through - * standard APIs ("Nodes"): - * Nodes are deemed to be separate and independent programs and to not be - * covered works. Notwithstanding anything to the contrary in the - * License, the License does not apply to Nodes, you are not required to - * license Nodes under the License, and you are granted a license to - * prepare and propagate Nodes, in each case even if such Nodes are - * propagated with or for interoperation with KNIME. The owner of a Node - * may freely choose the license terms applicable to such Node, including - * when such Node is propagated with or for interoperation with KNIME. - * ------------------------------------------------------------------------ - * - * History - * 25.11.2009 (Heiko Hofer): created - */ -package org.andl.ra; - -import java.util.Arrays; -import org.knime.core.data.DataCell; -import org.knime.core.data.DataRow; - -/** - * Implement data tuple with equals by value and hashCode. - * - * @author Andl - */ -public class RaTuple { - private DataCell[] m_cells; - - /** - * Creates a new RaTuple from an array of cells. - * @param cells The cells comprising the tuple. - */ - public RaTuple(final DataCell[] cells) { - m_cells = cells; -// m_cells = new ArrayList(); -// for (DataCell cell : cells) { -// m_cells.add(cell); -// }; - } - - /** - * Creates a new RaTuple from a DataRow - * @param row The DataRow - */ - public RaTuple(final DataRow row) { - m_cells = new DataCell[row.getNumCells()]; - for (int i = 0; i < m_cells.length; ++i) - m_cells[i] = row.getCell(i); -// m_cells = new ArrayList(); -// row.forEach(cell -> { m_cells.add(cell); }); - } - - /** {@inheritDoc} */ - @Override - public int hashCode() { - return Arrays.hashCode(m_cells); - } - - /** {@inheritDoc} */ - @Override - public boolean equals(final Object obj) { - if (this == obj) return true; - if (!(obj instanceof RaTuple)) return false; - - RaTuple that = (RaTuple)obj; - for (int i = 0; i < this.m_cells.length; i++) { - DataCell thisCell = this.m_cells[i]; - DataCell thatCell = that.m_cells[i]; - if (!thisCell.equals(thatCell)) return false; - } - return true; - } -} - diff --git a/dev-workspace/andl-ra-projection/src/org/andl/ra/RaProjectionNodeDialog.java b/dev-workspace/andl-ra-projection/src/org/andl/ra/projection/RaProjectionNodeDialog.java similarity index 98% rename from dev-workspace/andl-ra-projection/src/org/andl/ra/RaProjectionNodeDialog.java rename to dev-workspace/andl-ra-projection/src/org/andl/ra/projection/RaProjectionNodeDialog.java index 51b6f47..e910e80 100644 --- a/dev-workspace/andl-ra-projection/src/org/andl/ra/RaProjectionNodeDialog.java +++ b/dev-workspace/andl-ra-projection/src/org/andl/ra/projection/RaProjectionNodeDialog.java @@ -1,4 +1,4 @@ -package org.andl.ra; +package org.andl.ra.projection; import org.knime.core.node.defaultnodesettings.DefaultNodeSettingsPane; import org.knime.core.node.defaultnodesettings.DialogComponentString; diff --git a/dev-workspace/andl-ra-projection/src/org/andl/ra/RaProjectionNodeFactory.java b/dev-workspace/andl-ra-projection/src/org/andl/ra/projection/RaProjectionNodeFactory.java similarity index 96% rename from dev-workspace/andl-ra-projection/src/org/andl/ra/RaProjectionNodeFactory.java rename to dev-workspace/andl-ra-projection/src/org/andl/ra/projection/RaProjectionNodeFactory.java index 8d3886f..fb9a384 100644 --- a/dev-workspace/andl-ra-projection/src/org/andl/ra/RaProjectionNodeFactory.java +++ b/dev-workspace/andl-ra-projection/src/org/andl/ra/projection/RaProjectionNodeFactory.java @@ -1,4 +1,4 @@ -package org.andl.ra; +package org.andl.ra.projection; import org.knime.core.node.NodeDialogPane; import org.knime.core.node.NodeFactory; diff --git a/dev-workspace/andl-ra-projection/src/org/andl/ra/RaProjectionNodeFactory.xml b/dev-workspace/andl-ra-projection/src/org/andl/ra/projection/RaProjectionNodeFactory.xml similarity index 94% rename from dev-workspace/andl-ra-projection/src/org/andl/ra/RaProjectionNodeFactory.xml rename to dev-workspace/andl-ra-projection/src/org/andl/ra/projection/RaProjectionNodeFactory.xml index 98fec67..672508e 100644 --- a/dev-workspace/andl-ra-projection/src/org/andl/ra/RaProjectionNodeFactory.xml +++ b/dev-workspace/andl-ra-projection/src/org/andl/ra/projection/RaProjectionNodeFactory.xml @@ -3,7 +3,7 @@ RaProjection - RA projection operator + Relational Algebra projection operation. diff --git a/dev-workspace/andl-ra-projection/src/org/andl/ra/RaProjectionNodeModel.java b/dev-workspace/andl-ra-projection/src/org/andl/ra/projection/RaProjectionNodeModel.java similarity index 99% rename from dev-workspace/andl-ra-projection/src/org/andl/ra/RaProjectionNodeModel.java rename to dev-workspace/andl-ra-projection/src/org/andl/ra/projection/RaProjectionNodeModel.java index 1c37c40..1ac9903 100644 --- a/dev-workspace/andl-ra-projection/src/org/andl/ra/RaProjectionNodeModel.java +++ b/dev-workspace/andl-ra-projection/src/org/andl/ra/projection/RaProjectionNodeModel.java @@ -1,4 +1,4 @@ -package org.andl.ra; +package org.andl.ra.projection; import java.io.File; import java.io.IOException; @@ -7,7 +7,7 @@ import java.util.HashSet; import java.util.IllegalFormatException; import java.util.List; - +import org.andl.ra.set.RaTuple; import org.knime.base.node.preproc.filter.row.RowFilterIterator; import org.knime.core.data.DataCell; import org.knime.core.data.DataColumnSpec; diff --git a/dev-workspace/andl-ra-projection/src/org/andl/ra/RaProjectionNodePlugin.java b/dev-workspace/andl-ra-projection/src/org/andl/ra/projection/RaProjectionNodePlugin.java similarity index 98% rename from dev-workspace/andl-ra-projection/src/org/andl/ra/RaProjectionNodePlugin.java rename to dev-workspace/andl-ra-projection/src/org/andl/ra/projection/RaProjectionNodePlugin.java index 303e132..993bc2f 100644 --- a/dev-workspace/andl-ra-projection/src/org/andl/ra/RaProjectionNodePlugin.java +++ b/dev-workspace/andl-ra-projection/src/org/andl/ra/projection/RaProjectionNodePlugin.java @@ -2,7 +2,7 @@ * $Revision$ $Date$ $Author$ * */ -package org.andl.ra; +package org.andl.ra.projection; import org.eclipse.core.runtime.Plugin; import org.osgi.framework.BundleContext; diff --git a/dev-workspace/andl-ra-projection/src/org/andl/ra/RaProjectionNodeView.java b/dev-workspace/andl-ra-projection/src/org/andl/ra/projection/RaProjectionNodeView.java similarity index 96% rename from dev-workspace/andl-ra-projection/src/org/andl/ra/RaProjectionNodeView.java rename to dev-workspace/andl-ra-projection/src/org/andl/ra/projection/RaProjectionNodeView.java index 2c8bc1b..2913ca2 100644 --- a/dev-workspace/andl-ra-projection/src/org/andl/ra/RaProjectionNodeView.java +++ b/dev-workspace/andl-ra-projection/src/org/andl/ra/projection/RaProjectionNodeView.java @@ -1,4 +1,4 @@ -package org.andl.ra; +package org.andl.ra.projection; import org.knime.core.node.NodeView; diff --git a/dev-workspace/andl-ra-projection/src/org/andl/ra/package.html b/dev-workspace/andl-ra-projection/src/org/andl/ra/projection/package.html similarity index 100% rename from dev-workspace/andl-ra-projection/src/org/andl/ra/package.html rename to dev-workspace/andl-ra-projection/src/org/andl/ra/projection/package.html diff --git a/dev-workspace/andl-ra-projection/src/org/andl/ra/projection.png b/dev-workspace/andl-ra-projection/src/org/andl/ra/projection/projection.png similarity index 100% rename from dev-workspace/andl-ra-projection/src/org/andl/ra/projection.png rename to dev-workspace/andl-ra-projection/src/org/andl/ra/projection/projection.png diff --git a/dev-workspace/andl-ra-set/plugin.xml b/dev-workspace/andl-ra-set/plugin.xml index 5d393f8..185ef1e 100644 --- a/dev-workspace/andl-ra-set/plugin.xml +++ b/dev-workspace/andl-ra-set/plugin.xml @@ -17,7 +17,7 @@ diff --git a/dev-workspace/andl-ra-set/src/org/andl/ra/set/RaSetNodeFactory.xml b/dev-workspace/andl-ra-set/src/org/andl/ra/set/RaSetNodeFactory.xml index d4b520a..81900e4 100644 --- a/dev-workspace/andl-ra-set/src/org/andl/ra/set/RaSetNodeFactory.xml +++ b/dev-workspace/andl-ra-set/src/org/andl/ra/set/RaSetNodeFactory.xml @@ -2,7 +2,7 @@ RaSetOperation - Combine two tables using a selected set operation. + Relational Algebra dyadic set operations. Combine two tables using a selected set operation. @@ -10,7 +10,7 @@ - + diff --git a/dev-workspace/andl-ra-set/src/org/andl/ra/set/RaSetNodeModel.java b/dev-workspace/andl-ra-set/src/org/andl/ra/set/RaSetNodeModel.java index 4ee66be..31b7dde 100644 --- a/dev-workspace/andl-ra-set/src/org/andl/ra/set/RaSetNodeModel.java +++ b/dev-workspace/andl-ra-set/src/org/andl/ra/set/RaSetNodeModel.java @@ -36,6 +36,8 @@ /** * Implements the model for the "RaSet" node. * + * The following set operations are supported. + * * Union merges two tables and removes duplicates * Minus outputs rows in the first table but not in the second * Intersect outputs rows found in both tables @@ -51,7 +53,7 @@ public class RaSetNodeModel extends NodeModel { static final String[] ALL_SET_OPERATIONS = { "Union", "Minus", "Intersect", "Difference" }; - private final SettingsModelString m_SetOperationSettings = createSettingsModel(); + private final SettingsModelString _setOperationSettings = createSettingsModel(); /** * Constructor for the node model. @@ -72,7 +74,7 @@ static SettingsModelString createSettingsModel() { protected BufferedDataTable[] execute(final BufferedDataTable[] inData, final ExecutionContext exec) throws Exception { - String operation = m_SetOperationSettings.getStringValue(); + String operation = _setOperationSettings.getStringValue(); LOGGER.debug("Begin setop=" + operation); outputGenerator outgen = new outputGenerator(exec, inData[0].getDataTableSpec()); @@ -88,7 +90,7 @@ protected BufferedDataTable[] execute(final BufferedDataTable[] inData, final Ex /** {@inheritDoc} */ @Override protected DataTableSpec[] configure(final DataTableSpec[] inSpecs) throws InvalidSettingsException { - if (!(Arrays.asList(ALL_SET_OPERATIONS).contains(m_SetOperationSettings.getStringValue()))) + if (!(Arrays.asList(ALL_SET_OPERATIONS).contains(_setOperationSettings.getStringValue()))) throw new InvalidSettingsException("The selection operation is not valid"); return new DataTableSpec[] { createOutputSpec(inSpecs[0]) }; @@ -101,19 +103,19 @@ private DataTableSpec createOutputSpec(DataTableSpec inSpec) { /** {@inheritDoc} */ @Override protected void saveSettingsTo(final NodeSettingsWO settings) { - m_SetOperationSettings.saveSettingsTo(settings); + _setOperationSettings.saveSettingsTo(settings); } /** {@inheritDoc} */ @Override protected void loadValidatedSettingsFrom(final NodeSettingsRO settings) throws InvalidSettingsException { - m_SetOperationSettings.loadSettingsFrom(settings); + _setOperationSettings.loadSettingsFrom(settings); } /** {@inheritDoc} */ @Override protected void validateSettings(final NodeSettingsRO settings) throws InvalidSettingsException { - m_SetOperationSettings.validateSettings(settings); + _setOperationSettings.validateSettings(settings); } /** {@inheritDoc} */ diff --git a/dev-workspace/andl-ra-set/src/org/andl/ra/set/RaTuple.java b/dev-workspace/andl-ra-set/src/org/andl/ra/set/RaTuple.java index e50b004..00391e3 100644 --- a/dev-workspace/andl-ra-set/src/org/andl/ra/set/RaTuple.java +++ b/dev-workspace/andl-ra-set/src/org/andl/ra/set/RaTuple.java @@ -1,65 +1,19 @@ -/* - * ------------------------------------------------------------------------ - * Copyright by KNIME AG, Zurich, Switzerland - * Website: http://www.knime.com; Email: contact@knime.com - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License, Version 3, as - * published by the Free Software Foundation. - * - * 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, see . - * - * Additional permission under GNU GPL version 3 section 7: - * - * KNIME interoperates with ECLIPSE solely via ECLIPSE's plug-in APIs. - * Hence, KNIME and ECLIPSE are both independent programs and are not - * derived from each other. Should, however, the interpretation of the - * GNU GPL Version 3 ("License") under any applicable laws result in - * KNIME and ECLIPSE being a combined program, KNIME AG herewith grants - * you the additional permission to use and propagate KNIME together with - * ECLIPSE with only the license terms in place for ECLIPSE applying to - * ECLIPSE and the GNU GPL Version 3 applying for KNIME, provided the - * license terms of ECLIPSE themselves allow for the respective use and - * propagation of ECLIPSE together with KNIME. - * - * Additional permission relating to nodes for KNIME that extend the Node - * Extension (and in particular that are based on subclasses of NodeModel, - * NodeDialog, and NodeView) and that only interoperate with KNIME through - * standard APIs ("Nodes"): - * Nodes are deemed to be separate and independent programs and to not be - * covered works. Notwithstanding anything to the contrary in the - * License, the License does not apply to Nodes, you are not required to - * license Nodes under the License, and you are granted a license to - * prepare and propagate Nodes, in each case even if such Nodes are - * propagated with or for interoperation with KNIME. The owner of a Node - * may freely choose the license terms applicable to such Node, including - * when such Node is propagated with or for interoperation with KNIME. - * ------------------------------------------------------------------------ +/** + * Implement data tuple with equals by value and hashCode. * - * History - * 25.11.2009 (Heiko Hofer): created + * @author Andl */ + package org.andl.ra.set; import java.util.Arrays; import org.knime.core.data.DataCell; import org.knime.core.data.DataRow; -/** - * Implement data tuple with equals by value and hashCode. - * - * @author Andl - */ public class RaTuple { private DataCell[] _cells; - public DataCell[] get_cells() { + public DataCell[] getCells() { return _cells; } @@ -83,8 +37,17 @@ public RaTuple(final DataRow row) { _cells = new DataCell[row.getNumCells()]; for (int i = 0; i < _cells.length; ++i) _cells[i] = row.getCell(i); -// m_cells = new ArrayList(); -// row.forEach(cell -> { m_cells.add(cell); }); + } + + /** + * Creates a new RaTuple from a DataRow and indexes + * @param row The DataRow + * @param indexes A list of indexes into the row + */ + public RaTuple(final DataRow row, int[] indexes) { + _cells = new DataCell[indexes.length]; + for (int i = 0; i < indexes.length; ++i) + _cells[i] = row.getCell(indexes[i]); } /** {@inheritDoc} */ diff --git a/dev-workspace/andl-ra/.classpath b/dev-workspace/andl-ra/.classpath new file mode 100644 index 0000000..156f8ae --- /dev/null +++ b/dev-workspace/andl-ra/.classpath @@ -0,0 +1,7 @@ + + + + + + + diff --git a/dev-workspace/andl-ra/.project b/dev-workspace/andl-ra/.project new file mode 100644 index 0000000..cc01ab1 --- /dev/null +++ b/dev-workspace/andl-ra/.project @@ -0,0 +1,28 @@ + + + andl-ra + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.pde.ManifestBuilder + + + + + org.eclipse.pde.SchemaBuilder + + + + + + org.eclipse.pde.PluginNature + org.eclipse.jdt.core.javanature + + diff --git a/dev-workspace/andl-ra/META-INF/MANIFEST.MF b/dev-workspace/andl-ra/META-INF/MANIFEST.MF new file mode 100644 index 0000000..b35facb --- /dev/null +++ b/dev-workspace/andl-ra/META-INF/MANIFEST.MF @@ -0,0 +1,16 @@ +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: RaJoin-Node extension for KNIME Workbench +Bundle-SymbolicName: org.andl.ra.join; singleton:=true +Bundle-Version: 1.0.0.qualifier +Bundle-ClassPath: rajoin.jar +Bundle-Activator: org.andl.ra.join.RaJoinNodePlugin +Bundle-Vendor: andl +Require-Bundle: org.eclipse.core.runtime, + org.knime.workbench.core, + org.knime.workbench.repository, + org.knime.base +Bundle-ActivationPolicy: lazy +Export-Package: org.andl.ra.join +Import-Package: org.andl.ra.set + diff --git a/dev-workspace/andl-ra/bin/.gitignore b/dev-workspace/andl-ra/bin/.gitignore new file mode 100644 index 0000000..cf1db2e --- /dev/null +++ b/dev-workspace/andl-ra/bin/.gitignore @@ -0,0 +1 @@ +/org/ diff --git a/dev-workspace/andl-ra/build.properties b/dev-workspace/andl-ra/build.properties new file mode 100644 index 0000000..9d8bd32 --- /dev/null +++ b/dev-workspace/andl-ra/build.properties @@ -0,0 +1,4 @@ +source.rajoin.jar = src/ +bin.includes = plugin.xml,\ + META-INF/,\ + rajoin.jar diff --git a/dev-workspace/andl-ra/plugin.xml b/dev-workspace/andl-ra/plugin.xml new file mode 100644 index 0000000..cb84728 --- /dev/null +++ b/dev-workspace/andl-ra/plugin.xml @@ -0,0 +1,25 @@ + + + + + + + + + + + diff --git a/dev-workspace/andl-ra/src/org/andl/ra/join/RaJoinNodeDialog.java b/dev-workspace/andl-ra/src/org/andl/ra/join/RaJoinNodeDialog.java new file mode 100644 index 0000000..de0f33e --- /dev/null +++ b/dev-workspace/andl-ra/src/org/andl/ra/join/RaJoinNodeDialog.java @@ -0,0 +1,23 @@ +package org.andl.ra.join; + +import org.knime.core.node.defaultnodesettings.DefaultNodeSettingsPane; +import org.knime.core.node.defaultnodesettings.DialogComponentString; +import org.knime.core.node.defaultnodesettings.DialogComponentStringSelection; +import org.knime.core.node.defaultnodesettings.SettingsModelString; + +/** + * Implement dialog for selecting which join operation. + * + * @author andl + */ +public class RaJoinNodeDialog extends DefaultNodeSettingsPane { + + protected RaJoinNodeDialog() { + super(); + + SettingsModelString settings = RaJoinNodeModel.createSettingsModel(); + addDialogComponent(new DialogComponentStringSelection(settings, "Join Operation", + RaJoinNodeModel.ALL_OPERATIONS)); + } +} + diff --git a/dev-workspace/andl-ra/src/org/andl/ra/join/RaJoinNodeFactory.java b/dev-workspace/andl-ra/src/org/andl/ra/join/RaJoinNodeFactory.java new file mode 100644 index 0000000..eb928ec --- /dev/null +++ b/dev-workspace/andl-ra/src/org/andl/ra/join/RaJoinNodeFactory.java @@ -0,0 +1,48 @@ +package org.andl.ra.join; + +import org.knime.core.node.NodeDialogPane; +import org.knime.core.node.NodeFactory; +import org.knime.core.node.NodeView; + +/** + * This is an example implementation of the node factory of the + * "RaJoin" node. + * + * @author andl + */ +public class RaJoinNodeFactory + extends NodeFactory { + + /** {@inheritDoc} */ + @Override + public RaJoinNodeModel createNodeModel() { + return new RaJoinNodeModel(); + } + + /** {@inheritDoc} */ + @Override + public int getNrNodeViews() { + return 0; + } + + /** {@inheritDoc} */ + @Override + public NodeView createNodeView(final int viewIndex, + final RaJoinNodeModel nodeModel) { + return null; + } + + /** {@inheritDoc} */ + @Override + public boolean hasDialog() { + return true; + } + + /** {@inheritDoc} */ + @Override + public NodeDialogPane createNodeDialogPane() { + return new RaJoinNodeDialog(); + } + +} + diff --git a/dev-workspace/andl-ra/src/org/andl/ra/join/RaJoinNodeFactory.xml b/dev-workspace/andl-ra/src/org/andl/ra/join/RaJoinNodeFactory.xml new file mode 100644 index 0000000..c26efd1 --- /dev/null +++ b/dev-workspace/andl-ra/src/org/andl/ra/join/RaJoinNodeFactory.xml @@ -0,0 +1,22 @@ + + + RaJoin + + Relational Algebra join operations. + + + Natural join based on matching columns by name. + Matching columns must be the same type. + There is no outer join, all output values are copied from input rows. + + + + + + + + The left (top) input table. + The right (bottom) input table. + The output table resulting from the join. + + diff --git a/dev-workspace/andl-ra/src/org/andl/ra/join/RaJoinNodeModel.java b/dev-workspace/andl-ra/src/org/andl/ra/join/RaJoinNodeModel.java new file mode 100644 index 0000000..ecedc18 --- /dev/null +++ b/dev-workspace/andl-ra/src/org/andl/ra/join/RaJoinNodeModel.java @@ -0,0 +1,322 @@ +package org.andl.ra.join; + +import java.io.File; +import java.io.IOException; + +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.HashSet; +import java.util.IllegalFormatException; +import java.util.List; +import java.util.Map; +import java.util.stream.Stream; + +import org.andl.ra.set.RaTuple; +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.container.CloseableRowIterator; +import org.knime.core.data.def.DefaultRow; +import org.knime.core.data.def.DoubleCell; +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.SettingsModelString; + + +/** + * This is an example implementation of the node model of the + * "RaJoin" node. + * + * The following join operations are supported. All joins are based on common + * columns matched by name and type. + * + * Join is the natural join. The output includes all columns from both inputs. + * Compose is Join with the join columns removed from the output. + * Semijoin is the left (top) input with only rows that DO match the right (bottom) input included. + * Antijoin is the left (top) input with only rows that DO NOT match the right (bottom) input included. + * + * @author andl + */ +public class RaJoinNodeModel extends NodeModel { + + private static final NodeLogger LOGGER = NodeLogger.getLogger(RaJoinNodeModel.class); + private static final String KEY_OPERATION = "join-operation"; + private static final String DEFAULT_OPERATION = "Join"; + static final String[] ALL_OPERATIONS = { + "Join", "Semijoin", "Antijoin" + }; + private final SettingsModelString _joinOperationSettings = createSettingsModel(); + + /** + * Constructor for the node model. + */ + protected RaJoinNodeModel() { + super(2, 1); + } + + /** + * @return a new SettingsModelString with the key for the set operation String + */ + static SettingsModelString createSettingsModel() { + return new SettingsModelString(KEY_OPERATION, DEFAULT_OPERATION); + } + + /** {@inheritDoc} */ + @Override + protected BufferedDataTable[] execute(final BufferedDataTable[] inData, final ExecutionContext exec) + throws Exception { + + String operation = _joinOperationSettings.getStringValue(); + LOGGER.debug("Begin setop=" + operation); + + outputGenerator outgen = new outputGenerator(exec, inData); + BufferedDataTable out = + operation == ALL_OPERATIONS[0] ? outgen.getJoin(inData) + : operation == ALL_OPERATIONS[1] ? outgen.getSemijoin(inData, true) + : operation == ALL_OPERATIONS[2] ? outgen.getSemijoin(inData, false) + : null; + return new BufferedDataTable[] { out }; + } + + /** {@inheritDoc} */ + @Override + protected DataTableSpec[] configure(final DataTableSpec[] inSpecs) throws InvalidSettingsException { + + String operation = _joinOperationSettings.getStringValue(); + if (!(Arrays.asList(ALL_OPERATIONS).contains(operation))) + throw new InvalidSettingsException("The selection operation is not valid"); + + specGenerator gen = new specGenerator(inSpecs[0], inSpecs[1]); + + DataTableSpec outSpec = + operation == ALL_OPERATIONS[0] ? new DataTableSpec(gen._leftInputSpec, gen._rightSpec) + : operation == ALL_OPERATIONS[1] ? inSpecs[0] + : operation == ALL_OPERATIONS[2] ? inSpecs[0] + : null; + + return new DataTableSpec[] { outSpec }; + } + + private DataTableSpec createOutputSpec(DataTableSpec inSpec) { + return inSpec; + } + + /** {@inheritDoc} */ + @Override + protected void saveSettingsTo(final NodeSettingsWO settings) { + _joinOperationSettings.saveSettingsTo(settings); + } + + /** {@inheritDoc} */ + @Override + protected void loadValidatedSettingsFrom(final NodeSettingsRO settings) throws InvalidSettingsException { + _joinOperationSettings.loadSettingsFrom(settings); + } + + /** {@inheritDoc} */ + @Override + protected void validateSettings(final NodeSettingsRO settings) throws InvalidSettingsException { + _joinOperationSettings.validateSettings(settings); + } + + /** {@inheritDoc} */ + @Override + protected void loadInternals(File nodeInternDir, ExecutionMonitor exec) + throws IOException, CanceledExecutionException { } + + /** {@inheritDoc} */ + @Override + protected void saveInternals(File nodeInternDir, ExecutionMonitor exec) + throws IOException, CanceledExecutionException { } + + /** {@inheritDoc} */ + @Override + protected void reset() { } +} + +/** + * Implement the algorithms to combine two inputs to one output by a Join operation + */ +class outputGenerator { + final ExecutionContext _exec; + specGenerator _specs; + BufferedDataContainer _container; + long _insize = 0; + int _incounter = 0; + int _outcounter = 0; + + outputGenerator(ExecutionContext exec, BufferedDataTable[] inputs) + throws InvalidSettingsException { + _exec = exec; + _specs = new specGenerator(inputs[0].getDataTableSpec(), inputs[1].getDataTableSpec()); + } + + // return the Set Union of the two input tables + BufferedDataTable getJoin(BufferedDataTable[] inputs) throws Exception { + + // output table assumes L + J + R + DataTableSpec outSpec = new DataTableSpec(_specs._leftInputSpec, _specs._rightSpec); + + _container = _exec.createDataContainer(outSpec); + //HashSet hashset = new HashSet<>(); + _insize = inputs[0].size() + inputs[1].size(); + + Map> map = buildIndex(inputs[1], _specs._joinrightcolmap, _specs._rightcolmap); + for (CloseableRowIterator iter = inputs[0].iterator(); iter.hasNext();) { + ++_incounter; + DataRow leftrow = iter.next(); + RaTuple jointuple = new RaTuple(leftrow, _specs._joinleftcolmap); + if (map.containsKey(jointuple)) { + for (RaTuple righttuple : map.get(jointuple)) { + // append right-only columns to left row + DataCell[] newcells = Stream + .concat(leftrow.stream(), Arrays.asList(righttuple.getCells()).stream()) + .toArray(DataCell[]::new); + addRow(newcells); + } + } + } + + // TODO + _container.close(); + return _container.getTable(); + } + + // return the semi join (or anti join) of the two input tables + BufferedDataTable getSemijoin(BufferedDataTable[] inputs, boolean matching) throws Exception { + + DataTableSpec outSpec = _specs._leftInputSpec; + _container = _exec.createDataContainer(outSpec); + HashSet hashset = new HashSet<>(); + _insize = inputs[0].size() + inputs[1].size(); + + // add all the right table join tuples to the hashset + for (CloseableRowIterator iter = inputs[1].iterator(); iter.hasNext(); ) { + ++_incounter; + DataRow row = iter.next(); + RaTuple tuple = new RaTuple(row, _specs._joinrightcolmap); + hashset.add(tuple); + } + + // copy left table rows to the output, remove duplicates + // matching means if join tuple found in the hashset, else the reverse + for (CloseableRowIterator iter = inputs[0].iterator(); iter.hasNext();) { + ++_incounter; + DataRow row = iter.next(); + RaTuple tuple = new RaTuple(row, _specs._joinleftcolmap); + if (hashset.contains(tuple)) { + if (matching) { + addRow(row); + hashset.remove(tuple); + } + } else if (!matching) { + addRow(row); + hashset.add(tuple); + } + } + _container.close(); + return _container.getTable(); + } + + // build an index from join tuple to tuple of remaining columns + private Map> buildIndex(BufferedDataTable input, int[] keycolmap, int[] rowcolmap) + throws CanceledExecutionException { + Map> map = new HashMap<>(); + for (CloseableRowIterator iter = input.iterator(); iter.hasNext();) { + DataRow row = iter.next(); + ++_incounter; + + RaTuple key = new RaTuple(row, keycolmap); + RaTuple value = new RaTuple(row, rowcolmap); + if (!map.containsKey(key)) + map.put(key, new ArrayList<>()); + map.get(key).add(value); + + _exec.checkCanceled(); + _exec.setProgress(_incounter / _insize, "Input row " + _incounter); + } + return map; + } + + private void addRow(DataRow row) throws Exception { + addRow(new RaTuple(row).getCells()); + } + + private void addRow(DataCell[] cells) throws Exception { + DataRow newrow = new DefaultRow("Row" + _outcounter++, cells); + _container.addRowToTable(newrow); + _exec.checkCanceled(); + _exec.setProgress(_incounter / _insize, "Input row " + _incounter); + } + +} + +/** + * internal class to compute various column specs and maps + * + * all pre-calculated because they get used on every row + */ +class specGenerator { + DataTableSpec _leftSpec, _rightSpec, _joinSpec, _leftInputSpec, _rightInputSpec; + int[] _joinleftcolmap, _joinrightcolmap, _leftcolmap, _rightcolmap; + + specGenerator(DataTableSpec leftInputSpec, DataTableSpec rightInputSpec) + throws InvalidSettingsException { + _leftInputSpec = leftInputSpec; + _rightInputSpec = rightInputSpec; + + _joinSpec = getJoinSpec(_leftInputSpec, _rightInputSpec); + _leftSpec = specMinus(_leftInputSpec, _joinSpec); + _rightSpec = specMinus(_rightInputSpec, _joinSpec); + + _leftcolmap = getColMap(_leftSpec, _leftInputSpec); + _joinleftcolmap = getColMap(_joinSpec, _leftInputSpec); + _rightcolmap = getColMap(_rightSpec, _rightInputSpec); + _joinrightcolmap = getColMap(_joinSpec, _rightInputSpec); + + } + + // get a column map for getting required columns from a row + private int[] getColMap(DataTableSpec destSpec, DataTableSpec sourceSpec) { + return destSpec.stream() + .mapToInt(s -> sourceSpec.findColumnIndex(s.getName())) + .toArray(); + } + + private DataTableSpec specMinus(DataTableSpec leftSpec, DataTableSpec rightSpec) { + DataColumnSpec[] cols = leftSpec.stream() + .filter(s -> !rightSpec.containsName(s.getName())) + .toArray(DataColumnSpec[]::new); + return new DataTableSpec(cols); + } + + private DataTableSpec getJoinSpec(DataTableSpec leftSpec, DataTableSpec rightSpec) + throws InvalidSettingsException { + DataColumnSpec[] cols = leftSpec.stream() + .filter(s -> rightSpec.containsName(s.getName())) + .toArray(DataColumnSpec[]::new); + for (DataColumnSpec col : cols) { + DataColumnSpec match = rightSpec.getColumnSpec(col.getName()); + if (match != null && match.getType() != col.getType()) + throw new InvalidSettingsException("Join columns not same type: " + col.getName()); + } + return new DataTableSpec(cols); + } + + +} + diff --git a/dev-workspace/andl-ra/src/org/andl/ra/join/RaJoinNodePlugin.java b/dev-workspace/andl-ra/src/org/andl/ra/join/RaJoinNodePlugin.java new file mode 100644 index 0000000..1be5bb2 --- /dev/null +++ b/dev-workspace/andl-ra/src/org/andl/ra/join/RaJoinNodePlugin.java @@ -0,0 +1,65 @@ +/* @(#)$RCSfile$ + * $Revision$ $Date$ $Author$ + * + */ +package org.andl.ra.join; + +import org.eclipse.core.runtime.Plugin; +import org.osgi.framework.BundleContext; + +/** + * This is the eclipse bundle activator. + * Note: KNIME node developers probably won't have to do anything in here, + * as this class is only needed by the eclipse platform/plugin mechanism. + * If you want to move/rename this file, make sure to change the plugin.xml + * file in the project root directory accordingly. + * + * @author andl + */ +public class RaJoinNodePlugin extends Plugin { + // The shared instance. + private static RaJoinNodePlugin plugin; + + /** + * The constructor. + */ + public RaJoinNodePlugin() { + super(); + plugin = this; + } + + /** + * This method is called upon plug-in activation. + * + * @param context The OSGI bundle context + * @throws Exception If this plugin could not be started + */ + @Override + public void start(final BundleContext context) throws Exception { + super.start(context); + + } + + /** + * This method is called when the plug-in is stopped. + * + * @param context The OSGI bundle context + * @throws Exception If this plugin could not be stopped + */ + @Override + public void stop(final BundleContext context) throws Exception { + super.stop(context); + plugin = null; + } + + /** + * Returns the shared instance. + * + * @return Singleton instance of the Plugin + */ + public static RaJoinNodePlugin getDefault() { + return plugin; + } + +} + diff --git a/dev-workspace/andl-ra/src/org/andl/ra/join/RaJoinNodeView.java b/dev-workspace/andl-ra/src/org/andl/ra/join/RaJoinNodeView.java new file mode 100644 index 0000000..ee21769 --- /dev/null +++ b/dev-workspace/andl-ra/src/org/andl/ra/join/RaJoinNodeView.java @@ -0,0 +1,65 @@ +package org.andl.ra.join; + +import org.knime.core.node.NodeView; + + +/** + * This is an example implementation of the node view of the + * "RaJoin" node. + * + * As this example node does not have a view, this is just an empty stub of the + * NodeView class which not providing a real view pane. + * + * @author andl + */ +public class RaJoinNodeView extends NodeView { + + /** + * Creates a new view. + * + * @param nodeModel The model (class: {@link RaJoinNodeModel}) + */ + protected RaJoinNodeView(final RaJoinNodeModel nodeModel) { + super(nodeModel); + + // TODO instantiate the components of the view here. + + } + + /** + * {@inheritDoc} + */ + @Override + protected void modelChanged() { + + // TODO retrieve the new model from your nodemodel and + // update the view. + RaJoinNodeModel nodeModel = + (RaJoinNodeModel)getNodeModel(); + assert nodeModel != null; + + // be aware of a possibly not executed nodeModel! The data you retrieve + // from your nodemodel could be null, emtpy, or invalid in any kind. + + } + + /** + * {@inheritDoc} + */ + @Override + protected void onClose() { + + // TODO things to do when closing the view + } + + /** + * {@inheritDoc} + */ + @Override + protected void onOpen() { + + // TODO things to do when opening the view + } + +} + diff --git a/dev-workspace/andl-ra/src/org/andl/ra/join/default.png b/dev-workspace/andl-ra/src/org/andl/ra/join/default.png new file mode 100644 index 0000000000000000000000000000000000000000..18c2575f81cc16d413255a046114b81f77cb9a6a GIT binary patch literal 607 zcmV-l0-*hgP)j0xtnv*JZKM*jhH`aAH5w>2xkB+*J6qxv_Do-|zqWYl*|jl0a3}81n$f zxhQa;TrRK2oC8oS7Plv|*=^gl#~sJ{$DrA4=Iu;o1=V>#5V_E3G_t*3@2dk)tJSV5 zj1MQM*X!=y$;k!Vac-cR{0E0T&uasV(rUE|Vp*?&OhWKM;F`iJa4hATKW)o8;fQ6e t4GjbAS9p{%7}uUK4A(?echT)!zX6z`tp*)C$Z!Av002ovPDHLkV1ir~2)_UT literal 0 HcmV?d00001 diff --git a/dev-workspace/andl-ra/src/org/andl/ra/join/package.html b/dev-workspace/andl-ra/src/org/andl/ra/join/package.html new file mode 100644 index 0000000..00df329 --- /dev/null +++ b/dev-workspace/andl-ra/src/org/andl/ra/join/package.html @@ -0,0 +1,25 @@ + + +This package implements ... (insert package description here) +

+The RaJoinModel ... (short comments on the classes) +

+The RaJoinDialog ... (short comments on the classes) +

+More comments ... +
+ + diff --git a/dev-workspace/andl-try-numberformatter/plugin.xml b/dev-workspace/andl-try-numberformatter/plugin.xml index 9ed36ba..d78696c 100644 --- a/dev-workspace/andl-try-numberformatter/plugin.xml +++ b/dev-workspace/andl-try-numberformatter/plugin.xml @@ -5,17 +5,17 @@ From 75dd6a5d80e489bd38e5772074800cf366c8590e Mon Sep 17 00:00:00 2001 From: david Date: Tue, 25 Feb 2020 17:26:30 +1100 Subject: [PATCH 04/56] Heaps of test workspaces and related From 7446e53300f94f242a1fd1c7cafe0944539675f2 Mon Sep 17 00:00:00 2001 From: david Date: Sun, 1 Mar 2020 12:48:35 +1100 Subject: [PATCH 05/56] Re-org nodes into single package --- .../andl-ra-projection/META-INF/MANIFEST.MF | 1 - .../src/org/andl/ra/projection/projection.png | Bin 38702 -> 0 bytes .../andl-ra-set/META-INF/MANIFEST.MF | 1 - .../andl-ra-set/src/org/andl/ra/set/set.png | Bin 486 -> 0 bytes dev-workspace/andl-ra/META-INF/MANIFEST.MF | 21 ++++++++-- .../alpha.png | Bin dev-workspace/andl-ra/build.properties | 6 ++- dev-workspace/andl-ra/plugin.xml | 36 ++++++++---------- .../org/andl/ra/join/RaJoinNodeDialog.java | 1 - .../org/andl/ra/join/RaJoinNodeFactory.xml | 2 +- .../andl-ra/src/org/andl/ra/join/default.png | Bin 607 -> 0 bytes .../andl-ra/src/org/andl/ra/join/join.png | Bin 0 -> 252 bytes .../ra/projection/RaProjectionNodeDialog.java | 0 .../projection/RaProjectionNodeFactory.java | 0 .../ra/projection/RaProjectionNodeFactory.xml | 0 .../ra/projection/RaProjectionNodeModel.java | 0 .../ra/projection/RaProjectionNodePlugin.java | 0 .../ra/projection/RaProjectionNodeView.java | 0 .../src/org/andl/ra/projection/package.html | 0 .../src/org/andl/ra/projection/projection.png | Bin 0 -> 245 bytes .../src/org/andl/ra/set/RaSetNodeDialog.java | 0 .../src/org/andl/ra/set/RaSetNodeFactory.java | 0 .../src/org/andl/ra/set/RaSetNodeFactory.xml | 0 .../src/org/andl/ra/set/RaSetNodeModel.java | 0 .../src/org/andl/ra/set/RaSetNodePlugin.java | 0 .../src/org/andl/ra/set/RaSetNodeView.java | 0 .../src/org/andl/ra/set/RaTuple.java | 4 -- .../src/org/andl/ra/set/package.html | 0 .../andl-ra/src/org/andl/ra/set/set.png | Bin 0 -> 423 bytes .../andl-try-numberformatter/plugin.xml | 18 +++++---- 30 files changed, 50 insertions(+), 40 deletions(-) delete mode 100644 dev-workspace/andl-ra-projection/src/org/andl/ra/projection/projection.png delete mode 100644 dev-workspace/andl-ra-set/src/org/andl/ra/set/set.png rename dev-workspace/{andl-try-numberformatter => andl-ra}/alpha.png (100%) delete mode 100644 dev-workspace/andl-ra/src/org/andl/ra/join/default.png create mode 100644 dev-workspace/andl-ra/src/org/andl/ra/join/join.png rename dev-workspace/{andl-ra-projection => andl-ra}/src/org/andl/ra/projection/RaProjectionNodeDialog.java (100%) rename dev-workspace/{andl-ra-projection => andl-ra}/src/org/andl/ra/projection/RaProjectionNodeFactory.java (100%) rename dev-workspace/{andl-ra-projection => andl-ra}/src/org/andl/ra/projection/RaProjectionNodeFactory.xml (100%) rename dev-workspace/{andl-ra-projection => andl-ra}/src/org/andl/ra/projection/RaProjectionNodeModel.java (100%) rename dev-workspace/{andl-ra-projection => andl-ra}/src/org/andl/ra/projection/RaProjectionNodePlugin.java (100%) rename dev-workspace/{andl-ra-projection => andl-ra}/src/org/andl/ra/projection/RaProjectionNodeView.java (100%) rename dev-workspace/{andl-ra-projection => andl-ra}/src/org/andl/ra/projection/package.html (100%) create mode 100644 dev-workspace/andl-ra/src/org/andl/ra/projection/projection.png rename dev-workspace/{andl-ra-set => andl-ra}/src/org/andl/ra/set/RaSetNodeDialog.java (100%) rename dev-workspace/{andl-ra-set => andl-ra}/src/org/andl/ra/set/RaSetNodeFactory.java (100%) rename dev-workspace/{andl-ra-set => andl-ra}/src/org/andl/ra/set/RaSetNodeFactory.xml (100%) rename dev-workspace/{andl-ra-set => andl-ra}/src/org/andl/ra/set/RaSetNodeModel.java (100%) rename dev-workspace/{andl-ra-set => andl-ra}/src/org/andl/ra/set/RaSetNodePlugin.java (100%) rename dev-workspace/{andl-ra-set => andl-ra}/src/org/andl/ra/set/RaSetNodeView.java (100%) rename dev-workspace/{andl-ra-set => andl-ra}/src/org/andl/ra/set/RaTuple.java (92%) rename dev-workspace/{andl-ra-set => andl-ra}/src/org/andl/ra/set/package.html (100%) create mode 100644 dev-workspace/andl-ra/src/org/andl/ra/set/set.png diff --git a/dev-workspace/andl-ra-projection/META-INF/MANIFEST.MF b/dev-workspace/andl-ra-projection/META-INF/MANIFEST.MF index b9f841e..25bce4b 100644 --- a/dev-workspace/andl-ra-projection/META-INF/MANIFEST.MF +++ b/dev-workspace/andl-ra-projection/META-INF/MANIFEST.MF @@ -11,6 +11,5 @@ Require-Bundle: org.eclipse.core.runtime, org.knime.workbench.repository, org.knime.base Bundle-ActivationPolicy: lazy -Export-Package: org.andl.ra.projection Import-Package: org.andl.ra.set diff --git a/dev-workspace/andl-ra-projection/src/org/andl/ra/projection/projection.png b/dev-workspace/andl-ra-projection/src/org/andl/ra/projection/projection.png deleted file mode 100644 index 774e67b4d3d0952701fe5d2c9688389246a7becc..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 38702 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 diff --git a/dev-workspace/andl-ra-set/META-INF/MANIFEST.MF b/dev-workspace/andl-ra-set/META-INF/MANIFEST.MF index 7882788..e0db395 100644 --- a/dev-workspace/andl-ra-set/META-INF/MANIFEST.MF +++ b/dev-workspace/andl-ra-set/META-INF/MANIFEST.MF @@ -11,5 +11,4 @@ Require-Bundle: org.eclipse.core.runtime, org.knime.workbench.repository, org.knime.base Bundle-ActivationPolicy: lazy -Export-Package: org.andl.ra.set diff --git a/dev-workspace/andl-ra-set/src/org/andl/ra/set/set.png b/dev-workspace/andl-ra-set/src/org/andl/ra/set/set.png deleted file mode 100644 index 23f2aa3c745621c4da45b0e72d015083ec85ec98..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 486 zcmV@P)Px#1ZP1_K>z@;j|==^1poj532;bRa{vGi!vFvd!vV){sAK>D0eeYAK~!i%?U~V$ z!ypU=Qx^qMkE@{>it)(_8N?m7r6<`pnP`6jzm*^!JbA32Kv?<_mVSh#A7SZ7So#r` ze&Ck1EIFmen_Oxe*eJP=q%@8JfR=UX7L8om81Z*FEf!JCvg8)t88qtI1SOCqb2!Q7 zO*LpDmQ0dw^BmRWJ#3bO_ONc^%>*o!xvH9Wuvtp>Ff0!U%N@en+WPlDN|n-te$&gyjKYxx+VDN^<|nQkSc&X%1qk+VWnK=zPpUEP3)t ze^@~VNz9UKz8Q5V6AY4| - - + + - - - - + + + + + + diff --git a/dev-workspace/andl-ra/src/org/andl/ra/join/RaJoinNodeDialog.java b/dev-workspace/andl-ra/src/org/andl/ra/join/RaJoinNodeDialog.java index de0f33e..11d94a9 100644 --- a/dev-workspace/andl-ra/src/org/andl/ra/join/RaJoinNodeDialog.java +++ b/dev-workspace/andl-ra/src/org/andl/ra/join/RaJoinNodeDialog.java @@ -1,7 +1,6 @@ package org.andl.ra.join; import org.knime.core.node.defaultnodesettings.DefaultNodeSettingsPane; -import org.knime.core.node.defaultnodesettings.DialogComponentString; import org.knime.core.node.defaultnodesettings.DialogComponentStringSelection; import org.knime.core.node.defaultnodesettings.SettingsModelString; diff --git a/dev-workspace/andl-ra/src/org/andl/ra/join/RaJoinNodeFactory.xml b/dev-workspace/andl-ra/src/org/andl/ra/join/RaJoinNodeFactory.xml index c26efd1..a938f6b 100644 --- a/dev-workspace/andl-ra/src/org/andl/ra/join/RaJoinNodeFactory.xml +++ b/dev-workspace/andl-ra/src/org/andl/ra/join/RaJoinNodeFactory.xml @@ -1,5 +1,5 @@ - + RaJoin Relational Algebra join operations. diff --git a/dev-workspace/andl-ra/src/org/andl/ra/join/default.png b/dev-workspace/andl-ra/src/org/andl/ra/join/default.png deleted file mode 100644 index 18c2575f81cc16d413255a046114b81f77cb9a6a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 607 zcmV-l0-*hgP)j0xtnv*JZKM*jhH`aAH5w>2xkB+*J6qxv_Do-|zqWYl*|jl0a3}81n$f zxhQa;TrRK2oC8oS7Plv|*=^gl#~sJ{$DrA4=Iu;o1=V>#5V_E3G_t*3@2dk)tJSV5 zj1MQM*X!=y$;k!Vac-cR{0E0T&uasV(rUE|Vp*?&OhWKM;F`iJa4hATKW)o8;fQ6e t4GjbAS9p{%7}uUK4A(?echT)!zX6z`tp*)C$Z!Av002ovPDHLkV1ir~2)_UT diff --git a/dev-workspace/andl-ra/src/org/andl/ra/join/join.png b/dev-workspace/andl-ra/src/org/andl/ra/join/join.png new file mode 100644 index 0000000000000000000000000000000000000000..009f0fec5b1bbf8c32db892e332b964b8defe687 GIT binary patch literal 252 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`EX7WqAsj$Z!;#Vf2?p zUk71ECym(^Ktah8*NBqf{Irtt#G+J&^73-M%)IR4*hH2ygfw#S zet^fNTfTu|=Un3nJcU8FmzcX2z4lzQdl6&YVs qm0P9c)y-2?p zUk71ECym(^Ktah8*NBqf{Irtt#G+J&^73-M%)IR4}HPQCJrweYQ*_Ce=2%J?0k@?HnZ~k+h;B6 zavFvUHlO1a-%{a!nu&A0{H7C23g#r=%oiyBRe3P4uW9jv{aovA#w$b=JA(); -// for (DataCell cell : cells) { -// m_cells.add(cell); -// }; } /** diff --git a/dev-workspace/andl-ra-set/src/org/andl/ra/set/package.html b/dev-workspace/andl-ra/src/org/andl/ra/set/package.html similarity index 100% rename from dev-workspace/andl-ra-set/src/org/andl/ra/set/package.html rename to dev-workspace/andl-ra/src/org/andl/ra/set/package.html diff --git a/dev-workspace/andl-ra/src/org/andl/ra/set/set.png b/dev-workspace/andl-ra/src/org/andl/ra/set/set.png new file mode 100644 index 0000000000000000000000000000000000000000..6e2194942870303c3fb73991bc475b8d8394e229 GIT binary patch literal 423 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`EX7WqAsj$Z!;#Vf2?p zUk71ECym(^Ktah8*NBqf{Irtt#G+J&^73-M%)IR4HkbOb}XGE{*ON-i0QUs zCcCquS;Ja^`?^d|CzuFT@aiATd#rF{v1a4J1Ja#*^33vnoIb2|lLdD0)+n+4+Su2Z zv#;Bwu(A05_YIwPH@MFgpZTL~(7Sm;y#DEHK@Wbm{}qre?)I$bP0l+XkKZNsj) literal 0 HcmV?d00001 diff --git a/dev-workspace/andl-try-numberformatter/plugin.xml b/dev-workspace/andl-try-numberformatter/plugin.xml index d78696c..629333d 100644 --- a/dev-workspace/andl-try-numberformatter/plugin.xml +++ b/dev-workspace/andl-try-numberformatter/plugin.xml @@ -2,15 +2,17 @@ - - + From 031bcb26657e94acbcc6702112d2b718dc4285b5 Mon Sep 17 00:00:00 2001 From: david Date: Sun, 1 Mar 2020 12:49:33 +1100 Subject: [PATCH 06/56] Try out JEXL --- dev-workspace/try-jexl/.classpath | 12 +++++ dev-workspace/try-jexl/.gitignore | 1 + dev-workspace/try-jexl/.project | 17 +++++++ .../.settings/org.eclipse.jdt.core.prefs | 11 +++++ dev-workspace/try-jexl/src/try_jexl.java | 44 +++++++++++++++++++ 5 files changed, 85 insertions(+) create mode 100644 dev-workspace/try-jexl/.classpath create mode 100644 dev-workspace/try-jexl/.gitignore create mode 100644 dev-workspace/try-jexl/.project create mode 100644 dev-workspace/try-jexl/.settings/org.eclipse.jdt.core.prefs create mode 100644 dev-workspace/try-jexl/src/try_jexl.java diff --git a/dev-workspace/try-jexl/.classpath b/dev-workspace/try-jexl/.classpath new file mode 100644 index 0000000..47f2529 --- /dev/null +++ b/dev-workspace/try-jexl/.classpath @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/dev-workspace/try-jexl/.gitignore b/dev-workspace/try-jexl/.gitignore new file mode 100644 index 0000000..ae3c172 --- /dev/null +++ b/dev-workspace/try-jexl/.gitignore @@ -0,0 +1 @@ +/bin/ diff --git a/dev-workspace/try-jexl/.project b/dev-workspace/try-jexl/.project new file mode 100644 index 0000000..429b48f --- /dev/null +++ b/dev-workspace/try-jexl/.project @@ -0,0 +1,17 @@ + + + try-jexl + + + + + + org.eclipse.jdt.core.javabuilder + + + + + + org.eclipse.jdt.core.javanature + + diff --git a/dev-workspace/try-jexl/.settings/org.eclipse.jdt.core.prefs b/dev-workspace/try-jexl/.settings/org.eclipse.jdt.core.prefs new file mode 100644 index 0000000..3a21537 --- /dev/null +++ b/dev-workspace/try-jexl/.settings/org.eclipse.jdt.core.prefs @@ -0,0 +1,11 @@ +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8 +org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve +org.eclipse.jdt.core.compiler.compliance=1.8 +org.eclipse.jdt.core.compiler.debug.lineNumber=generate +org.eclipse.jdt.core.compiler.debug.localVariable=generate +org.eclipse.jdt.core.compiler.debug.sourceFile=generate +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.source=1.8 diff --git a/dev-workspace/try-jexl/src/try_jexl.java b/dev-workspace/try-jexl/src/try_jexl.java new file mode 100644 index 0000000..a0d0198 --- /dev/null +++ b/dev-workspace/try-jexl/src/try_jexl.java @@ -0,0 +1,44 @@ +import org.apache.commons.jexl3.JexlBuilder; +import org.apache.commons.jexl3.JexlContext; +import org.apache.commons.jexl3.JexlEngine; +import org.apache.commons.jexl3.JexlExpression; +import org.apache.commons.jexl3.MapContext; + +/** + * + */ + +/** + * @author david + * + */ +public class try_jexl { + + /** + * @param args + */ + public static void main(String[] args) { + System.out.println("Hello, World"); + + final JexlEngine jexl = new JexlBuilder().cache(512).strict(true).silent(false).create(); + + // Assuming we have a JexlEngine instance initialized in our class named 'jexl': + // Create an expression object for our calculation + String calculateTax = "((G1 + G2 + G3) * 0.1) + G4"; // taxManager.getTaxCalc(); //e.g. + JexlExpression e = jexl.createExpression( calculateTax ); + + // populate the context + JexlContext context = new MapContext(); + + context.set("G1", 100000.0); + context.set("G2", 5555.0); + context.set("G3", 4444.0); + context.set("G4", -3333.33); + // ... + + // work it out + Number result = (Number) e.evaluate(context); + System.out.println("Result = " + result); + } + +} From e0e057c65199f74b8d865d182c5e3397f46abe23 Mon Sep 17 00:00:00 2001 From: david Date: Sun, 1 Mar 2020 12:51:51 +1100 Subject: [PATCH 07/56] Add extension. WIP. With swing dialog, not working --- .../src/org/andl/ra/RaExtensionConfig.java | 111 ++++++++++ .../org/andl/ra/RaExtensionNodeDialog.java | 118 ++++++++++ .../org/andl/ra/RaExtensionNodeFactory.java | 63 ++++++ .../org/andl/ra/RaExtensionNodeFactory.xml | 37 ++++ .../src/org/andl/ra/RaExtensionNodeModel.java | 148 +++++++++++++ .../src/org/andl/ra/RaExtensionNodeView.java | 47 ++++ .../src/org/andl/ra/TypeCellFactory.java | 208 ++++++++++++++++++ .../andl-ra/src/org/andl/ra/default.png | Bin 0 -> 607 bytes .../andl-ra/src/org/andl/ra/package.html | 25 +++ 9 files changed, 757 insertions(+) create mode 100644 dev-workspace/andl-ra/src/org/andl/ra/RaExtensionConfig.java create mode 100644 dev-workspace/andl-ra/src/org/andl/ra/RaExtensionNodeDialog.java create mode 100644 dev-workspace/andl-ra/src/org/andl/ra/RaExtensionNodeFactory.java create mode 100644 dev-workspace/andl-ra/src/org/andl/ra/RaExtensionNodeFactory.xml create mode 100644 dev-workspace/andl-ra/src/org/andl/ra/RaExtensionNodeModel.java create mode 100644 dev-workspace/andl-ra/src/org/andl/ra/RaExtensionNodeView.java create mode 100644 dev-workspace/andl-ra/src/org/andl/ra/TypeCellFactory.java create mode 100644 dev-workspace/andl-ra/src/org/andl/ra/default.png create mode 100644 dev-workspace/andl-ra/src/org/andl/ra/package.html diff --git a/dev-workspace/andl-ra/src/org/andl/ra/RaExtensionConfig.java b/dev-workspace/andl-ra/src/org/andl/ra/RaExtensionConfig.java new file mode 100644 index 0000000..f0ef8e5 --- /dev/null +++ b/dev-workspace/andl-ra/src/org/andl/ra/RaExtensionConfig.java @@ -0,0 +1,111 @@ +package org.andl.ra; + +import org.knime.core.data.DataTableSpec; +import org.knime.core.node.InvalidSettingsException; +import org.knime.core.node.NodeSettingsRO; +import org.knime.core.node.NodeSettingsWO; + +final class RaExtensionConfig { + private static final String NEW_COLUMN_NAME = "new-column-name"; + private static final String TYPE = "column-type"; + static final String VALUE = "column-value"; + + private String m_newColumnName; + private String m_value; + private TypeCellFactory m_cellFactory; + + /** + * @return the newColumnName + */ + public String getNewColumnName() { + return m_newColumnName; + } + + /** + * @param newColumnName the newColumnName to set + */ + public void setNewColumnName(final String newColumnName) { + m_newColumnName = newColumnName; + } + + /** + * @return the value + */ + public String getValue() { + return m_value; + } + + /** + * @param value the value to set + */ + public void setValue(final String value) { + m_value = value; + } + + /** + * @return the cellFactory + */ + public TypeCellFactory getCellFactory() { + return m_cellFactory; + } + + /** + * @param cellFactory the cellFactory to set + */ + public void setCellFactory(final TypeCellFactory cellFactory) { + m_cellFactory = cellFactory; + } + + /** + * Save current configuration. + * + * @param settings To save to. + */ + void save(final NodeSettingsWO settings) { + settings.addString(NEW_COLUMN_NAME, m_newColumnName); + settings.addString(VALUE, m_value); + settings.addString(TYPE, m_cellFactory.toString()); + } + + /** + * Load config in node model. + * + * @param settings To load from. + * @throws InvalidSettingsException If invalid. + */ + void loadInModel(final NodeSettingsRO settings) throws InvalidSettingsException { + m_newColumnName = settings.getString(NEW_COLUMN_NAME); + m_value = settings.getString(VALUE); + m_cellFactory = getEnum(settings.getString(TYPE)); + } + + /** + * Load config in dialog. + * + * @param settings To load from + * @param in Current input spec + */ + void loadInDialog(final NodeSettingsRO settings, final DataTableSpec in) { + m_newColumnName = settings.getString(NEW_COLUMN_NAME, null); + m_value = settings.getString(VALUE, null); + try { + m_cellFactory = getEnum(settings.getString(TYPE, TypeCellFactory.STRING.toString())); + } catch (InvalidSettingsException e) { + m_cellFactory = TypeCellFactory.STRING; + } + } + + /** + * @param string + * @param b + * @return + */ + private TypeCellFactory getEnum(final String string) throws InvalidSettingsException { + try { + return TypeCellFactory.valueOf(string); + } catch (IllegalArgumentException e) { + // NOOP + } + throw new InvalidSettingsException("invalid type: " + string); + } +} diff --git a/dev-workspace/andl-ra/src/org/andl/ra/RaExtensionNodeDialog.java b/dev-workspace/andl-ra/src/org/andl/ra/RaExtensionNodeDialog.java new file mode 100644 index 0000000..5488134 --- /dev/null +++ b/dev-workspace/andl-ra/src/org/andl/ra/RaExtensionNodeDialog.java @@ -0,0 +1,118 @@ +package org.andl.ra; + +import static org.knime.core.node.util.CheckUtils.checkSetting; + +import java.awt.BorderLayout; + +import javax.swing.JComboBox; +import javax.swing.JPanel; +import javax.swing.JTextField; + +import org.knime.core.data.DataTableSpec; +import org.knime.core.data.DataType; +import org.knime.core.node.InvalidSettingsException; +import org.knime.core.node.NodeDialogPane; +import org.knime.core.node.NodeSettingsRO; +import org.knime.core.node.NodeSettingsWO; +import org.knime.core.node.NotConfigurableException; +import org.knime.core.node.util.DataTypeListCellRenderer; + +/** + * NodeDialog for the "RaExtension" node. + * + * @author andl + */ +//public class RaExtensionNodeDialog extends DefaultNodeSettingsPane { +// +// /** +// * New pane for configuring the RaExtension node. +// */ +// protected RaExtensionNodeDialog() { +// addDialogComponent(new DialogComponentString(RaExtensionNodeModel.createSettingsColumnName(), "New column name")); +// addDialogComponent(new DialogComponentStringSelection(RaExtensionNodeModel.createSettingsColumnType(), "Column type")); +// addDialogComponent(new DialogComponentString(RaExtensionNodeModel.createSettingsExpression(), "Expression")); +// } +//} + +final class RaExtensionNodeDialog extends NodeDialogPane { + + private static final int DEFAULT_TEXT_SIZE = 25; + private static final int HORIZONTAL_VERTICAL_GAB = 5; + + private final JTextField m_columnName; + private final JComboBox m_fieldType; + private final JTextField m_value; + + private DataTableSpec m_dataTableSpec; + + /** Create new dialog. */ + @SuppressWarnings("unchecked") + RaExtensionNodeDialog() { + m_columnName = new JTextField(DEFAULT_TEXT_SIZE); + m_value = new JTextField(DEFAULT_TEXT_SIZE); + + m_fieldType = new JComboBox(); + m_fieldType.setRenderer(new DataTypeListCellRenderer()); + + for (TypeCellFactory factory : TypeCellFactory.values()) { + m_fieldType.addItem(factory.getDataType()); + } + m_fieldType.setSelectedIndex(0); + + final JPanel northValuePanel = new JPanel(new BorderLayout(5, 5)); + northValuePanel.add(m_columnName, BorderLayout.NORTH); + northValuePanel.add(m_fieldType, BorderLayout.NORTH); + northValuePanel.add(m_value, BorderLayout.NORTH); + + JPanel tabPanel = new JPanel(new BorderLayout()); + tabPanel.add(northValuePanel, BorderLayout.CENTER); + + addTab("Settings", tabPanel); + } + + /** {@inheritDoc} */ + @Override + protected void loadSettingsFrom(final NodeSettingsRO settings, final DataTableSpec[] specs) + throws NotConfigurableException { + RaExtensionConfig config = new RaExtensionConfig(); + config.loadInDialog(settings, specs[0]); + m_dataTableSpec = specs[0]; + m_value.setText(config.getValue()); + m_fieldType.setSelectedItem(config.getCellFactory().getDataType()); + setText(m_columnName, config.getNewColumnName()); + } + + /** {@inheritDoc} */ + @Override + protected void saveSettingsTo(final NodeSettingsWO settings) throws InvalidSettingsException { + RaExtensionConfig config = new RaExtensionConfig(); + TypeCellFactory forDataType = TypeCellFactory.forDataType((DataType)m_fieldType.getSelectedItem()); + config.setValue(m_value.getText()); + + config.setCellFactory(forDataType); + config.setNewColumnName(getText(m_columnName, "New column name must not be empty.")); + config.save(settings); + } + + @Override + public void onClose() { + m_dataTableSpec = null; + } + + private static void setText(final JTextField appendColumnField, final String newColumnName) { + appendColumnField.setEnabled(false); + if (newColumnName != null) { + appendColumnField.setText(newColumnName); + appendColumnField.setEnabled(true); + } + } + + private static String getText(final JTextField field, final String messageIfNotExist) + throws InvalidSettingsException { + String text = field.getText(); + checkSetting(text != null, messageIfNotExist); + return text; + } + +} + diff --git a/dev-workspace/andl-ra/src/org/andl/ra/RaExtensionNodeFactory.java b/dev-workspace/andl-ra/src/org/andl/ra/RaExtensionNodeFactory.java new file mode 100644 index 0000000..de6a324 --- /dev/null +++ b/dev-workspace/andl-ra/src/org/andl/ra/RaExtensionNodeFactory.java @@ -0,0 +1,63 @@ +package org.andl.ra; + +import org.knime.core.node.NodeDialogPane; +import org.knime.core.node.NodeFactory; +import org.knime.core.node.NodeView; + +/** + * This is an example implementation of the node factory of the + * "RaExtension" node. + * + * @author andl + */ +public class RaExtensionNodeFactory + extends NodeFactory { + + /** + * {@inheritDoc} + */ + @Override + public RaExtensionNodeModel createNodeModel() { + // Create and return a new node model. + return new RaExtensionNodeModel(); + } + + /** + * {@inheritDoc} + */ + @Override + public int getNrNodeViews() { + // The number of views the node should have, in this cases there is none. + return 0; + } + + /** + * {@inheritDoc} + */ + @Override + public NodeView createNodeView(final int viewIndex, + final RaExtensionNodeModel nodeModel) { + // We return null as this example node does not provide a view. Also see "getNrNodeViews()". + return null; + } + + /** + * {@inheritDoc} + */ + @Override + public boolean hasDialog() { + // Indication whether the node has a dialog or not. + return true; + } + + /** + * {@inheritDoc} + */ + @Override + public NodeDialogPane createNodeDialogPane() { + // This example node has a dialog, hence we create and return it here. Also see "hasDialog()". + return new RaExtensionNodeDialog(); + } + +} + diff --git a/dev-workspace/andl-ra/src/org/andl/ra/RaExtensionNodeFactory.xml b/dev-workspace/andl-ra/src/org/andl/ra/RaExtensionNodeFactory.xml new file mode 100644 index 0000000..8b8f762 --- /dev/null +++ b/dev-workspace/andl-ra/src/org/andl/ra/RaExtensionNodeFactory.xml @@ -0,0 +1,37 @@ + + + RaExtension + + + RA Extension node + + + + Insert long description here... + + + + + + + + + + Description of first input port... + + Description of first output port... + + + + Description of first view... + + + diff --git a/dev-workspace/andl-ra/src/org/andl/ra/RaExtensionNodeModel.java b/dev-workspace/andl-ra/src/org/andl/ra/RaExtensionNodeModel.java new file mode 100644 index 0000000..eb2ac3f --- /dev/null +++ b/dev-workspace/andl-ra/src/org/andl/ra/RaExtensionNodeModel.java @@ -0,0 +1,148 @@ +package org.andl.ra; + +import java.io.File; +import java.io.IOException; +import java.util.List; + +import org.knime.core.data.DataColumnSpec; +import org.knime.core.data.DataTableSpec; +import org.knime.core.data.DataType; +import org.knime.core.data.DataTypeRegistry; +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.SettingsModelString; + +/** + * NodeModel for the "RaExtension" node. + * + * @author andl + */ +public class RaExtensionNodeModel extends NodeModel { + + private static final NodeLogger LOGGER = NodeLogger.getLogger(RaExtensionNodeModel.class); + private static final String KEY_NAME = "column-name"; + private static final String KEY_TYPE = "column-type"; + private static final String KEY_EXPRESSION = "column-expression"; + private static final String DEFAULT_TYPE = "string"; + static final String[] ALL_TYPES = { + "sring", "int", "double", "date" + }; + + private final SettingsModelString _nameSettings = createSettingsColumnName(); + private final SettingsModelString _typeSettings = createSettingsColumnType(); + private final SettingsModelString _expressionSettings = createSettingsExpression(); + + /** + * Constructor for the node model. + */ + protected RaExtensionNodeModel() { + super(1, 1); + LOGGER.info("Extension node created"); + } + + static SettingsModelString createSettingsColumnName() { + return new SettingsModelString(KEY_NAME, "new column"); + } + + static SettingsModelString createSettingsColumnType() { + return new SettingsModelString(KEY_TYPE, "string"); + } + + static SettingsModelString createSettingsExpression() { + return new SettingsModelString(KEY_EXPRESSION, ""); + } + + /** + * {@inheritDoc} + */ + @Override + protected BufferedDataTable[] execute(final BufferedDataTable[] inData, + final ExecutionContext exec) throws Exception { + + // TODO: Return a BufferedDataTable for each output port + return new BufferedDataTable[]{}; + } + + /** + * {@inheritDoc} + */ + @Override + protected void reset() { + // TODO: generated method stub + } + + /** + * {@inheritDoc} + */ + @Override + protected DataTableSpec[] configure(final DataTableSpec[] inSpecs) + throws InvalidSettingsException { + +// DataType newtype = DataTypeRegistry +// DataColumnSpec newcol = DataColumnSpecCreator( +// _nameSettings.getStringValue(), _); +// List specs = new ArrayList<>(); +// specs.addAll(inSpecs[0].stream()); +// specs.add(e) + DataTableSpec newspec = inSpecs[0]; + + // TODO: generated method stub + return new DataTableSpec[]{ newspec}; + } + + /** + * {@inheritDoc} + */ + @Override + protected void saveSettingsTo(final NodeSettingsWO settings) { + // TODO: generated method stub + } + + /** + * {@inheritDoc} + */ + @Override + protected void loadValidatedSettingsFrom(final NodeSettingsRO settings) + throws InvalidSettingsException { + // TODO: generated method stub + } + + /** + * {@inheritDoc} + */ + @Override + protected void validateSettings(final NodeSettingsRO settings) + throws InvalidSettingsException { + // TODO: generated method stub + } + + /** + * {@inheritDoc} + */ + @Override + protected void loadInternals(final File internDir, + final ExecutionMonitor exec) throws IOException, + CanceledExecutionException { + // TODO: generated method stub + } + + /** + * {@inheritDoc} + */ + @Override + protected void saveInternals(final File internDir, + final ExecutionMonitor exec) throws IOException, + CanceledExecutionException { + // TODO: generated method stub + } + + +} + diff --git a/dev-workspace/andl-ra/src/org/andl/ra/RaExtensionNodeView.java b/dev-workspace/andl-ra/src/org/andl/ra/RaExtensionNodeView.java new file mode 100644 index 0000000..12fd98d --- /dev/null +++ b/dev-workspace/andl-ra/src/org/andl/ra/RaExtensionNodeView.java @@ -0,0 +1,47 @@ +package org.andl.ra; + +import org.knime.core.node.NodeView; + +/** + * NodeView for the "RaExtension" node. + * + * @author andl + */ +public class RaExtensionNodeView extends NodeView { + + /** + * Creates a new view. + * + * @param nodeModel The model (class: {@link RaExtensionNodeModel}) + */ + protected RaExtensionNodeView(final RaExtensionNodeModel nodeModel) { + super(nodeModel); + // TODO: generated method stub + } + + /** + * {@inheritDoc} + */ + @Override + protected void modelChanged() { + // TODO: generated method stub + } + + /** + * {@inheritDoc} + */ + @Override + protected void onClose() { + // TODO: generated method stub + } + + /** + * {@inheritDoc} + */ + @Override + protected void onOpen() { + // TODO: generated method stub + } + +} + diff --git a/dev-workspace/andl-ra/src/org/andl/ra/TypeCellFactory.java b/dev-workspace/andl-ra/src/org/andl/ra/TypeCellFactory.java new file mode 100644 index 0000000..3547ac3 --- /dev/null +++ b/dev-workspace/andl-ra/src/org/andl/ra/TypeCellFactory.java @@ -0,0 +1,208 @@ +/* + * ------------------------------------------------------------------------ + * Copyright by KNIME AG, Zurich, Switzerland + * Website: http://www.knime.com; Email: contact@knime.com + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License, Version 3, as + * published by the Free Software Foundation. + * + * 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + * + * Additional permission under GNU GPL version 3 section 7: + * + * KNIME interoperates with ECLIPSE solely via ECLIPSE's plug-in APIs. + * Hence, KNIME and ECLIPSE are both independent programs and are not + * derived from each other. Should, however, the interpretation of the + * GNU GPL Version 3 ("License") under any applicable laws result in + * KNIME and ECLIPSE being a combined program, KNIME AG herewith grants + * you the additional permission to use and propagate KNIME together with + * ECLIPSE with only the license terms in place for ECLIPSE applying to + * ECLIPSE and the GNU GPL Version 3 applying for KNIME, provided the + * license terms of ECLIPSE themselves allow for the respective use and + * propagation of ECLIPSE together with KNIME. + * + * Additional permission relating to nodes for KNIME that extend the Node + * Extension (and in particular that are based on subclasses of NodeModel, + * NodeDialog, and NodeView) and that only interoperate with KNIME through + * standard APIs ("Nodes"): + * Nodes are deemed to be separate and independent programs and to not be + * covered works. Notwithstanding anything to the contrary in the + * License, the License does not apply to Nodes, you are not required to + * license Nodes under the License, and you are granted a license to + * prepare and propagate Nodes, in each case even if such Nodes are + * propagated with or for interoperation with KNIME. The owner of a Node + * may freely choose the license terms applicable to such Node, including + * when such Node is propagated with or for interoperation with KNIME. + * --------------------------------------------------------------------- + * + * Created on 25.11.2013 by NanoTec + */ +package org.andl.ra; + +import java.io.IOException; +import java.text.SimpleDateFormat; +import java.util.Calendar; +import java.util.Date; + +import javax.xml.parsers.ParserConfigurationException; +import javax.xml.stream.XMLStreamException; + +import org.knime.core.data.DataCell; +import org.knime.core.data.DataType; +import org.knime.core.data.date.DateAndTimeCell; +import org.knime.core.data.def.BooleanCell; +import org.knime.core.data.def.DoubleCell; +import org.knime.core.data.def.IntCell; +import org.knime.core.data.def.LongCell; +import org.knime.core.data.def.StringCell; +import org.knime.core.data.xml.XMLCell; +import org.knime.core.data.xml.XMLCellFactory; +import org.knime.core.node.NodeLogger; +import org.osgi.framework.InvalidSyntaxException; +import org.xml.sax.SAXException; + +import com.sun.corba.se.impl.io.TypeMismatchException; + +/** + * A TypeCellFactory creates for a string and an optional additional parameter a new cell. + * + * @author Marcel Hanser + */ +enum TypeCellFactory { + /** + * Creates a {@link LongCell} for the given String. + */ + LONG(LongCell.TYPE) { + @Override + public DataCell innerCreateCell(final String toConvert, final String otherArgument) // + throws IllegalArgumentException { + return new LongCell(Long.valueOf(toConvert)); + } + }, + /** + * Creates a {@link IntCell} from the given String. + */ + INT(IntCell.TYPE) { + @Override + public DataCell innerCreateCell(final String toConvert, final String otherArgument) { + return new IntCell(Integer.valueOf(toConvert)); + } + }, + /** + * Creates a {@link DoubleCell} from the given String. + */ + DOUBLE(DoubleCell.TYPE) { + @Override + public DataCell innerCreateCell(final String toConvert, final String otherArgument) { + return new DoubleCell(Double.valueOf(toConvert)); + } + }, + /** + * Creates a {@link XMLCell} from the given String. + */ + XML(XMLCell.TYPE) { + @Override + public DataCell innerCreateCell(final String toConvert, final String otherArgument) throws IOException, + ParserConfigurationException, SAXException, XMLStreamException { + return XMLCellFactory.create(toConvert); + } + }, + /** + * Creates a {@link StringCell} from the given String. + */ + STRING(StringCell.TYPE) { + @Override + public DataCell innerCreateCell(final String toConvert, final String otherArgument) { + return new StringCell(toConvert.toString()); + } + }, + /** + * Creates a {@link DateAndTimeCell} from the given String and the additional SimpleDateFormat conform pattern. + */ + DATE(DateAndTimeCell.TYPE) { + @Override + public DataCell innerCreateCell(final String toConvert, final String otherArgument) throws Exception { + + Date parsed = new SimpleDateFormat(otherArgument).parse(toConvert); + Calendar cal = Calendar.getInstance(); + cal.setTime(parsed); + return new DateAndTimeCell(cal.get(Calendar.YEAR), cal.get(Calendar.MONTH), cal.get(Calendar.DAY_OF_MONTH)); + } + }, + /** + * Creates a {@link BooleanCell} from the given String. + */ + BOOLEAN(BooleanCell.TYPE) { + @Override + public DataCell innerCreateCell(final String toConvert, final String otherArgument) { + String lowerCase = toConvert.toLowerCase(); + if (!("false".equals(lowerCase) || "true".equals(lowerCase))) { + throw new IllegalArgumentException(); + } + return BooleanCell.get(Boolean.valueOf(lowerCase)); + } + }; + + private static final NodeLogger LOGGER = NodeLogger.getLogger(TypeCellFactory.class); + + private final DataType m_dataType; + + private TypeCellFactory(final DataType dataType) { + this.m_dataType = dataType; + } + + /** + * @return the dataType + */ + public DataType getDataType() { + return m_dataType; + } + + /** + * Should not be called. Call {@link #createCell(String, String)} instead. + * + * @param toConvert the string to convert + * @param pattern an additional argument, semantic definition is done by the concrete {@link TypeCellFactory} + * @return the data cell + * @throws Exception if the toConvert string is not parseable to the DataCell to create + */ + abstract DataCell innerCreateCell(final String toConvert, String pattern) throws Exception; + + /** + * Creates a cell from the given String and the additional argument, which is sometimes necessary (e.g.for creating + * a DataAndTimeCell). + * + * @param toConvert the string to convert + * @param otherArgument an additional argument, semantic definition is done by the concrete {@link TypeCellFactory} + * @return a new data cell from the given value + * @throws TypeParsingException if an error occurred during conversion + */ + final DataCell createCell(final String toConvert, final String otherArgument) throws IllegalArgumentException { + try { + return innerCreateCell(toConvert, otherArgument); + } catch (Exception e) { + LOGGER.info("error on parsing value: " + toConvert, e); + throw new IllegalArgumentException(e); + } + } + + /** + * @param dataType the data type top receive the {@link TypeCellFactory} for + * @return the the {@link TypeCellFactory} responsible for creating {@link DataCell}s of the given {@link DataType} + */ + static final TypeCellFactory forDataType(final DataType dataType) { + for (TypeCellFactory factory : values()) { + if (factory.getDataType().equals(dataType)) { + return factory; + } + } + throw new IllegalArgumentException("no factory found for type: " + dataType); + } +} diff --git a/dev-workspace/andl-ra/src/org/andl/ra/default.png b/dev-workspace/andl-ra/src/org/andl/ra/default.png new file mode 100644 index 0000000000000000000000000000000000000000..18c2575f81cc16d413255a046114b81f77cb9a6a GIT binary patch literal 607 zcmV-l0-*hgP)j0xtnv*JZKM*jhH`aAH5w>2xkB+*J6qxv_Do-|zqWYl*|jl0a3}81n$f zxhQa;TrRK2oC8oS7Plv|*=^gl#~sJ{$DrA4=Iu;o1=V>#5V_E3G_t*3@2dk)tJSV5 zj1MQM*X!=y$;k!Vac-cR{0E0T&uasV(rUE|Vp*?&OhWKM;F`iJa4hATKW)o8;fQ6e t4GjbAS9p{%7}uUK4A(?echT)!zX6z`tp*)C$Z!Av002ovPDHLkV1ir~2)_UT literal 0 HcmV?d00001 diff --git a/dev-workspace/andl-ra/src/org/andl/ra/package.html b/dev-workspace/andl-ra/src/org/andl/ra/package.html new file mode 100644 index 0000000..e3d974a --- /dev/null +++ b/dev-workspace/andl-ra/src/org/andl/ra/package.html @@ -0,0 +1,25 @@ + + +This package implements ... (insert package description here) +

+The RaExtensionModel ... (short comments on the classes) +

+The RaExtensionDialog ... (short comments on the classes) +

+More comments ... +
+ + From 9f6f3fd2346172e214d7a676a7ae62da4fba458d Mon Sep 17 00:00:00 2001 From: david Date: Mon, 2 Mar 2020 15:42:04 +1100 Subject: [PATCH 08/56] Config working, exec not WIP --- .../org/andl/ra/RaExtensionNodeDialog.java | 124 ++++-------------- .../src/org/andl/ra/RaExtensionNodeModel.java | 98 +++++++++----- .../src/org/andl/ra/TypeCellFactory.java | 3 - 3 files changed, 85 insertions(+), 140 deletions(-) diff --git a/dev-workspace/andl-ra/src/org/andl/ra/RaExtensionNodeDialog.java b/dev-workspace/andl-ra/src/org/andl/ra/RaExtensionNodeDialog.java index 5488134..6a0cc0b 100644 --- a/dev-workspace/andl-ra/src/org/andl/ra/RaExtensionNodeDialog.java +++ b/dev-workspace/andl-ra/src/org/andl/ra/RaExtensionNodeDialog.java @@ -1,118 +1,40 @@ package org.andl.ra; -import static org.knime.core.node.util.CheckUtils.checkSetting; +import java.util.ArrayList; -import java.awt.BorderLayout; - -import javax.swing.JComboBox; -import javax.swing.JPanel; -import javax.swing.JTextField; - -import org.knime.core.data.DataTableSpec; import org.knime.core.data.DataType; -import org.knime.core.node.InvalidSettingsException; -import org.knime.core.node.NodeDialogPane; -import org.knime.core.node.NodeSettingsRO; -import org.knime.core.node.NodeSettingsWO; -import org.knime.core.node.NotConfigurableException; -import org.knime.core.node.util.DataTypeListCellRenderer; +import org.knime.core.node.defaultnodesettings.DefaultNodeSettingsPane; +import org.knime.core.node.defaultnodesettings.DialogComponentMultiLineString; +import org.knime.core.node.defaultnodesettings.DialogComponentString; +import org.knime.core.node.defaultnodesettings.DialogComponentStringSelection; +import org.knime.core.node.util.DefaultStringIconOption; +import org.knime.core.node.util.StringIconOption; /** * NodeDialog for the "RaExtension" node. * * @author andl */ -//public class RaExtensionNodeDialog extends DefaultNodeSettingsPane { -// -// /** -// * New pane for configuring the RaExtension node. -// */ -// protected RaExtensionNodeDialog() { -// addDialogComponent(new DialogComponentString(RaExtensionNodeModel.createSettingsColumnName(), "New column name")); -// addDialogComponent(new DialogComponentStringSelection(RaExtensionNodeModel.createSettingsColumnType(), "Column type")); -// addDialogComponent(new DialogComponentString(RaExtensionNodeModel.createSettingsExpression(), "Expression")); -// } -//} - -final class RaExtensionNodeDialog extends NodeDialogPane { - - private static final int DEFAULT_TEXT_SIZE = 25; - private static final int HORIZONTAL_VERTICAL_GAB = 5; - - private final JTextField m_columnName; - private final JComboBox m_fieldType; - private final JTextField m_value; - - private DataTableSpec m_dataTableSpec; - - /** Create new dialog. */ - @SuppressWarnings("unchecked") - RaExtensionNodeDialog() { - m_columnName = new JTextField(DEFAULT_TEXT_SIZE); - m_value = new JTextField(DEFAULT_TEXT_SIZE); - - m_fieldType = new JComboBox(); - m_fieldType.setRenderer(new DataTypeListCellRenderer()); +public class RaExtensionNodeDialog extends DefaultNodeSettingsPane { + /** + * New pane for configuring the RaExtension node. + */ + protected RaExtensionNodeDialog() { + ArrayList options = new ArrayList<>(); for (TypeCellFactory factory : TypeCellFactory.values()) { - m_fieldType.addItem(factory.getDataType()); - } - m_fieldType.setSelectedIndex(0); - - final JPanel northValuePanel = new JPanel(new BorderLayout(5, 5)); - northValuePanel.add(m_columnName, BorderLayout.NORTH); - northValuePanel.add(m_fieldType, BorderLayout.NORTH); - northValuePanel.add(m_value, BorderLayout.NORTH); - - JPanel tabPanel = new JPanel(new BorderLayout()); - tabPanel.add(northValuePanel, BorderLayout.CENTER); - - addTab("Settings", tabPanel); - } - - /** {@inheritDoc} */ - @Override - protected void loadSettingsFrom(final NodeSettingsRO settings, final DataTableSpec[] specs) - throws NotConfigurableException { - RaExtensionConfig config = new RaExtensionConfig(); - config.loadInDialog(settings, specs[0]); - m_dataTableSpec = specs[0]; - m_value.setText(config.getValue()); - m_fieldType.setSelectedItem(config.getCellFactory().getDataType()); - setText(m_columnName, config.getNewColumnName()); - } - - /** {@inheritDoc} */ - @Override - protected void saveSettingsTo(final NodeSettingsWO settings) throws InvalidSettingsException { - RaExtensionConfig config = new RaExtensionConfig(); - TypeCellFactory forDataType = TypeCellFactory.forDataType((DataType)m_fieldType.getSelectedItem()); - config.setValue(m_value.getText()); - - config.setCellFactory(forDataType); - config.setNewColumnName(getText(m_columnName, "New column name must not be empty.")); - config.save(settings); - } - - @Override - public void onClose() { - m_dataTableSpec = null; - } - - private static void setText(final JTextField appendColumnField, final String newColumnName) { - appendColumnField.setEnabled(false); - if (newColumnName != null) { - appendColumnField.setText(newColumnName); - appendColumnField.setEnabled(true); + DataType type = factory.getDataType(); + options.add(new DefaultStringIconOption(type.getName(), type.getIcon())); } + addDialogComponent(new DialogComponentString( + RaExtensionNodeModel.createSettingsColumnName(), "New column name")); + addDialogComponent(new DialogComponentStringSelection( + RaExtensionNodeModel.createSettingsColumnTypeName(), "Column type", + options.toArray(new StringIconOption[options.size()]))); + addDialogComponent(new DialogComponentMultiLineString( + RaExtensionNodeModel.createSettingsExpression(), "Expression")); } +} - private static String getText(final JTextField field, final String messageIfNotExist) - throws InvalidSettingsException { - String text = field.getText(); - checkSetting(text != null, messageIfNotExist); - return text; - } -} diff --git a/dev-workspace/andl-ra/src/org/andl/ra/RaExtensionNodeModel.java b/dev-workspace/andl-ra/src/org/andl/ra/RaExtensionNodeModel.java index eb2ac3f..14ccb88 100644 --- a/dev-workspace/andl-ra/src/org/andl/ra/RaExtensionNodeModel.java +++ b/dev-workspace/andl-ra/src/org/andl/ra/RaExtensionNodeModel.java @@ -2,61 +2,63 @@ import java.io.File; import java.io.IOException; -import java.util.List; +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.DataType; -import org.knime.core.data.DataTypeRegistry; +import org.knime.core.data.container.CellFactory; +import org.knime.core.data.container.ColumnRearranger; +import org.knime.core.data.container.SingleCellFactory; 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.SettingsModelString; +import org.knime.core.node.streamable.simple.SimpleStreamableFunctionNodeModel; /** * NodeModel for the "RaExtension" node. * * @author andl */ -public class RaExtensionNodeModel extends NodeModel { +public class RaExtensionNodeModel extends SimpleStreamableFunctionNodeModel { private static final NodeLogger LOGGER = NodeLogger.getLogger(RaExtensionNodeModel.class); - private static final String KEY_NAME = "column-name"; - private static final String KEY_TYPE = "column-type"; - private static final String KEY_EXPRESSION = "column-expression"; - private static final String DEFAULT_TYPE = "string"; - static final String[] ALL_TYPES = { - "sring", "int", "double", "date" - }; - - private final SettingsModelString _nameSettings = createSettingsColumnName(); - private final SettingsModelString _typeSettings = createSettingsColumnType(); + private static final String KEY_COLUMN_NAME = "column-name"; + private static final String KEY_TYPE_NAME = "column-type-name"; + private static final String KEY_EXPRESSION = "column-value-expression"; + private static final String DEFAULT_COLUMN_NAME = "new column"; + private static final String DEFAULT_TYPE_NAME = "STRING"; + private static final String DEFAULT_EXPRESSION = ""; + + private final SettingsModelString _columnNameSettings = createSettingsColumnName(); + private final SettingsModelString _columnTypeNameSettings = createSettingsColumnTypeName(); private final SettingsModelString _expressionSettings = createSettingsExpression(); /** * Constructor for the node model. */ protected RaExtensionNodeModel() { - super(1, 1); + super(); LOGGER.info("Extension node created"); } static SettingsModelString createSettingsColumnName() { - return new SettingsModelString(KEY_NAME, "new column"); + return new SettingsModelString(KEY_COLUMN_NAME, DEFAULT_COLUMN_NAME); } - static SettingsModelString createSettingsColumnType() { - return new SettingsModelString(KEY_TYPE, "string"); + static SettingsModelString createSettingsColumnTypeName() { + return new SettingsModelString(KEY_TYPE_NAME, DEFAULT_TYPE_NAME); } static SettingsModelString createSettingsExpression() { - return new SettingsModelString(KEY_EXPRESSION, ""); + return new SettingsModelString(KEY_EXPRESSION, DEFAULT_EXPRESSION); } /** @@ -66,8 +68,10 @@ static SettingsModelString createSettingsExpression() { protected BufferedDataTable[] execute(final BufferedDataTable[] inData, final ExecutionContext exec) throws Exception { - // TODO: Return a BufferedDataTable for each output port - return new BufferedDataTable[]{}; + DataTableSpec spec = inData[0].getDataTableSpec(); + ColumnRearranger rearranger = createColumnRearranger(spec); + BufferedDataTable out = exec.createColumnRearrangeTable(inData[0], rearranger, exec); + return new BufferedDataTable[]{out}; } /** @@ -85,24 +89,42 @@ protected void reset() { protected DataTableSpec[] configure(final DataTableSpec[] inSpecs) throws InvalidSettingsException { -// DataType newtype = DataTypeRegistry -// DataColumnSpec newcol = DataColumnSpecCreator( -// _nameSettings.getStringValue(), _); -// List specs = new ArrayList<>(); -// specs.addAll(inSpecs[0].stream()); -// specs.add(e) - DataTableSpec newspec = inSpecs[0]; - - // TODO: generated method stub - return new DataTableSpec[]{ newspec}; + ColumnRearranger rearranger = createColumnRearranger(inSpecs[0]); + DataTableSpec out = rearranger.createSpec(); + return new DataTableSpec[]{out}; } - + + /** {@inheritDoc} */ + @Override + protected ColumnRearranger createColumnRearranger(final DataTableSpec in) throws InvalidSettingsException { + String colname = createSettingsColumnName().getStringValue(); + String typename = createSettingsColumnTypeName().getStringValue(); + String expression = createSettingsExpression().getStringValue(); + TypeCellFactory tcf = TypeCellFactory.valueOf(typename); + + DataColumnSpec outcolspec = new DataColumnSpecCreator(colname, tcf.getDataType()).createSpec(); + final DataCell constantCell = tcf.createCell(expression, ""); + + ColumnRearranger rearranger = new ColumnRearranger(in); + CellFactory fac = new SingleCellFactory(outcolspec) { + @Override + public DataCell getCell(final DataRow row) { + return constantCell; + } + }; + + rearranger.append(fac); + return rearranger; + } + /** * {@inheritDoc} */ @Override protected void saveSettingsTo(final NodeSettingsWO settings) { - // TODO: generated method stub + _columnNameSettings.saveSettingsTo(settings); + _columnTypeNameSettings.saveSettingsTo(settings); + _expressionSettings.saveSettingsTo(settings); } /** @@ -111,7 +133,9 @@ protected void saveSettingsTo(final NodeSettingsWO settings) { @Override protected void loadValidatedSettingsFrom(final NodeSettingsRO settings) throws InvalidSettingsException { - // TODO: generated method stub + _columnNameSettings.loadSettingsFrom(settings); + _columnTypeNameSettings.loadSettingsFrom(settings); + _expressionSettings.loadSettingsFrom(settings); } /** @@ -120,7 +144,9 @@ protected void loadValidatedSettingsFrom(final NodeSettingsRO settings) @Override protected void validateSettings(final NodeSettingsRO settings) throws InvalidSettingsException { - // TODO: generated method stub + _columnNameSettings.validateSettings(settings); + _columnTypeNameSettings.validateSettings(settings); + _expressionSettings.validateSettings(settings); } /** diff --git a/dev-workspace/andl-ra/src/org/andl/ra/TypeCellFactory.java b/dev-workspace/andl-ra/src/org/andl/ra/TypeCellFactory.java index 3547ac3..9ab7091 100644 --- a/dev-workspace/andl-ra/src/org/andl/ra/TypeCellFactory.java +++ b/dev-workspace/andl-ra/src/org/andl/ra/TypeCellFactory.java @@ -65,11 +65,8 @@ import org.knime.core.data.xml.XMLCell; import org.knime.core.data.xml.XMLCellFactory; import org.knime.core.node.NodeLogger; -import org.osgi.framework.InvalidSyntaxException; import org.xml.sax.SAXException; -import com.sun.corba.se.impl.io.TypeMismatchException; - /** * A TypeCellFactory creates for a string and an optional additional parameter a new cell. * From 8ea7b5e57529016777c0f800b8f209ebd7301da0 Mon Sep 17 00:00:00 2001 From: david Date: Mon, 2 Mar 2020 15:45:50 +1100 Subject: [PATCH 09/56] Move try group elsewhere From b273b14336be46184e2880be84b64810b5705967 Mon Sep 17 00:00:00 2001 From: david Date: Mon, 2 Mar 2020 15:46:53 +1100 Subject: [PATCH 10/56] Updates to ra_group and Inkscape --- Inkscape/braces.png | Bin 0 -> 423 bytes Inkscape/join.png | Bin 0 -> 252 bytes Inkscape/knime.svg | 162 ++++++++++++++++++++++++++++++++++++++++++++ Inkscape/pi.png | Bin 0 -> 245 bytes Inkscape/rho.png | Bin 0 -> 390 bytes Inkscape/sigma.png | Bin 0 -> 422 bytes 6 files changed, 162 insertions(+) create mode 100644 Inkscape/braces.png create mode 100644 Inkscape/join.png create mode 100644 Inkscape/knime.svg create mode 100644 Inkscape/pi.png create mode 100644 Inkscape/rho.png create mode 100644 Inkscape/sigma.png diff --git a/Inkscape/braces.png b/Inkscape/braces.png new file mode 100644 index 0000000000000000000000000000000000000000..6e2194942870303c3fb73991bc475b8d8394e229 GIT binary patch literal 423 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`EX7WqAsj$Z!;#Vf2?p zUk71ECym(^Ktah8*NBqf{Irtt#G+J&^73-M%)IR4HkbOb}XGE{*ON-i0QUs zCcCquS;Ja^`?^d|CzuFT@aiATd#rF{v1a4J1Ja#*^33vnoIb2|lLdD0)+n+4+Su2Z zv#;Bwu(A05_YIwPH@MFgpZTL~(7Sm;y#DEHK@Wbm{}qre?)I$bP0l+XkKZNsj) literal 0 HcmV?d00001 diff --git a/Inkscape/join.png b/Inkscape/join.png new file mode 100644 index 0000000000000000000000000000000000000000..009f0fec5b1bbf8c32db892e332b964b8defe687 GIT binary patch literal 252 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`EX7WqAsj$Z!;#Vf2?p zUk71ECym(^Ktah8*NBqf{Irtt#G+J&^73-M%)IR4*hH2ygfw#S zet^fNTfTu|=Un3nJcU8FmzcX2z4lzQdl6&YVs qm0P9c)y- + + +image/svg+xml{} + \ No newline at end of file diff --git a/Inkscape/pi.png b/Inkscape/pi.png new file mode 100644 index 0000000000000000000000000000000000000000..ddeccb16ead15e08b67b363fa78c6312e1c2f20c GIT binary patch literal 245 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`EX7WqAsj$Z!;#Vf2?p zUk71ECym(^Ktah8*NBqf{Irtt#G+J&^73-M%)IR4}HPQCJrweYQ*_Ce=2%J?0k@?HnZ~k+h;B6 zavFvUHlO1a-%{a!nu&A0{H7C23g#r=%oiyBRe3P4uW9jv{aovA#w$b=JA2?p zUk71ECym(^Ktah8*NBqf{Irtt#G+J&^73-M%)IR4uf1L-*(bq0Z0~THJ_`)S5@9@Z3BScHyVXbhhN8G{*7cx{#JpQcS z;^JMg@Sxq%cl*q5>cqWPnSAHW9LwVObDhO&BMykI``F^Y=b>PG#K9F(J&&2*D$U#2 z?`u-nyk^DTWZul1cMjBM+&d6(b^_-dmV10c5&S39?tW!rE0Ftfy6g4S&YSiu35Fm1 z7m5n?%CQ_{`mcJlKx13AfQOR(S`qbXff;}rR!`*&<$0v_Vfrej+?^9&oiS?O zeBk!GJ&QYh%9Z7J9AWJHAW)&ZMyqGai@KP$x-*G#!4ear|A>}b99ws1rR@2^n@9iv literal 0 HcmV?d00001 diff --git a/Inkscape/sigma.png b/Inkscape/sigma.png new file mode 100644 index 0000000000000000000000000000000000000000..c0e57410fffd1c7bdc42a51055ac99a26c0d56b8 GIT binary patch literal 422 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`EX7WqAsj$Z!;#Vf2?p zUk71ECym(^Ktah8*NBqf{Irtt#G+J&^73-M%)IR4!PO>F{P+(i#@HK2LP9q8REM}|@;|I-5B#}t(i@w}YS$(o36eFOB6P28 zmPOCe=q+Xj0&}#!ZEjUkW19cqGk^2y8P&nf^A4ETcRW-*uTb5YCCnzdUDdRLCnoDq zg2FSO#T}my1fS%qyx2YQK>Esqfe#YTm>OuX$1h_1TM@du*_-EChx$jEIou~@Q#L+( zJ~<{?^l_H|o~a%72C?gp^eSA*p2PJ_T1K!ZQU6p;X!e@mHw*OrKk!QL4pd{E9T)-( OQwC30KbLh*2~7Yr!L1$u literal 0 HcmV?d00001 From 2746f81c67f49a0042a9ef478c9bb13792503039 Mon Sep 17 00:00:00 2001 From: david Date: Mon, 2 Mar 2020 22:55:57 +1100 Subject: [PATCH 11/56] Fix so it works as a constant column. WIP --- .../org/andl/ra/RaExtensionNodeDialog.java | 2 +- .../src/org/andl/ra/RaExtensionNodeModel.java | 38 +++++++++++-------- 2 files changed, 23 insertions(+), 17 deletions(-) diff --git a/dev-workspace/andl-ra/src/org/andl/ra/RaExtensionNodeDialog.java b/dev-workspace/andl-ra/src/org/andl/ra/RaExtensionNodeDialog.java index 6a0cc0b..bad7f38 100644 --- a/dev-workspace/andl-ra/src/org/andl/ra/RaExtensionNodeDialog.java +++ b/dev-workspace/andl-ra/src/org/andl/ra/RaExtensionNodeDialog.java @@ -24,7 +24,7 @@ protected RaExtensionNodeDialog() { ArrayList options = new ArrayList<>(); for (TypeCellFactory factory : TypeCellFactory.values()) { DataType type = factory.getDataType(); - options.add(new DefaultStringIconOption(type.getName(), type.getIcon())); + options.add(new DefaultStringIconOption(factory.name(), type.getIcon())); } addDialogComponent(new DialogComponentString( RaExtensionNodeModel.createSettingsColumnName(), "New column name")); diff --git a/dev-workspace/andl-ra/src/org/andl/ra/RaExtensionNodeModel.java b/dev-workspace/andl-ra/src/org/andl/ra/RaExtensionNodeModel.java index 14ccb88..6b6a33d 100644 --- a/dev-workspace/andl-ra/src/org/andl/ra/RaExtensionNodeModel.java +++ b/dev-workspace/andl-ra/src/org/andl/ra/RaExtensionNodeModel.java @@ -2,6 +2,7 @@ import java.io.File; import java.io.IOException; +import java.util.IllegalFormatException; import org.knime.core.data.DataCell; import org.knime.core.data.DataColumnSpec; @@ -97,24 +98,29 @@ protected DataTableSpec[] configure(final DataTableSpec[] inSpecs) /** {@inheritDoc} */ @Override protected ColumnRearranger createColumnRearranger(final DataTableSpec in) throws InvalidSettingsException { - String colname = createSettingsColumnName().getStringValue(); - String typename = createSettingsColumnTypeName().getStringValue(); - String expression = createSettingsExpression().getStringValue(); + String colname = _columnNameSettings.getStringValue(); + String typename = _columnTypeNameSettings.getStringValue(); + String expression = _expressionSettings.getStringValue(); TypeCellFactory tcf = TypeCellFactory.valueOf(typename); - DataColumnSpec outcolspec = new DataColumnSpecCreator(colname, tcf.getDataType()).createSpec(); - final DataCell constantCell = tcf.createCell(expression, ""); - - ColumnRearranger rearranger = new ColumnRearranger(in); - CellFactory fac = new SingleCellFactory(outcolspec) { - @Override - public DataCell getCell(final DataRow row) { - return constantCell; - } - }; - - rearranger.append(fac); - return rearranger; + try { + DataColumnSpec outcolspec = new DataColumnSpecCreator(colname, tcf.getDataType()).createSpec(); + final DataCell constantCell = tcf.createCell(expression, "yyyy-MM-dd"); + + ColumnRearranger rearranger = new ColumnRearranger(in); + CellFactory fac = new SingleCellFactory(outcolspec) { + @Override + public DataCell getCell(final DataRow row) { + return constantCell; + } + }; + + rearranger.append(fac); + return rearranger; + } catch (Exception e) { + throw new InvalidSettingsException( + "Not a valid expression for the type: " + e.getMessage(), e); + } } /** From d250dfe897ef05c68c8e334df449211f946f82f2 Mon Sep 17 00:00:00 2001 From: david Date: Fri, 6 Mar 2020 13:12:17 +1100 Subject: [PATCH 12/56] Add RaExtensionJexl Code complete, problems with jexl config WIP --- dev-workspace/andl-ra/.classpath | 14 ++- dev-workspace/andl-ra/META-INF/MANIFEST.MF | 18 ++- dev-workspace/andl-ra/bin/.gitignore | 1 - dev-workspace/andl-ra/build.properties | 17 ++- dev-workspace/andl-ra/plugin.xml | 10 +- .../org/andl/ra/RaExtensionNodeFactory.xml | 37 ------ .../ra/{ => extension}/RaExtensionConfig.java | 2 +- .../andl/ra/extension/RaExtensionJexl.java | 107 ++++++++++++++++++ .../RaExtensionNodeDialog.java | 2 +- .../RaExtensionNodeFactory.java | 2 +- .../ra/extension/RaExtensionNodeFactory.xml | 20 ++++ .../{ => extension}/RaExtensionNodeModel.java | 11 +- .../{ => extension}/RaExtensionNodeView.java | 2 +- .../ra/{ => extension}/TypeCellFactory.java | 2 +- .../org/andl/ra/{ => extension}/default.png | Bin .../org/andl/ra/{ => extension}/package.html | 0 .../org/andl/ra/join/RaJoinNodeFactory.xml | 4 +- .../src/org/andl/ra/join/RaJoinNodeModel.java | 12 -- .../ra/projection/RaProjectionNodeDialog.java | 4 - .../ra/projection/RaProjectionNodeFactory.xml | 4 +- .../ra/projection/RaProjectionNodeModel.java | 15 +-- .../src/org/andl/ra/set/RaSetNodeDialog.java | 1 - .../src/org/andl/ra/set/RaSetNodeFactory.xml | 2 +- .../src/org/andl/ra/set/RaSetNodeModel.java | 12 -- 24 files changed, 185 insertions(+), 114 deletions(-) delete mode 100644 dev-workspace/andl-ra/bin/.gitignore delete mode 100644 dev-workspace/andl-ra/src/org/andl/ra/RaExtensionNodeFactory.xml rename dev-workspace/andl-ra/src/org/andl/ra/{ => extension}/RaExtensionConfig.java (98%) create mode 100644 dev-workspace/andl-ra/src/org/andl/ra/extension/RaExtensionJexl.java rename dev-workspace/andl-ra/src/org/andl/ra/{ => extension}/RaExtensionNodeDialog.java (97%) rename dev-workspace/andl-ra/src/org/andl/ra/{ => extension}/RaExtensionNodeFactory.java (97%) create mode 100644 dev-workspace/andl-ra/src/org/andl/ra/extension/RaExtensionNodeFactory.xml rename dev-workspace/andl-ra/src/org/andl/ra/{ => extension}/RaExtensionNodeModel.java (95%) rename dev-workspace/andl-ra/src/org/andl/ra/{ => extension}/RaExtensionNodeView.java (96%) rename dev-workspace/andl-ra/src/org/andl/ra/{ => extension}/TypeCellFactory.java (99%) rename dev-workspace/andl-ra/src/org/andl/ra/{ => extension}/default.png (100%) rename dev-workspace/andl-ra/src/org/andl/ra/{ => extension}/package.html (100%) diff --git a/dev-workspace/andl-ra/.classpath b/dev-workspace/andl-ra/.classpath index 156f8ae..8de8989 100644 --- a/dev-workspace/andl-ra/.classpath +++ b/dev-workspace/andl-ra/.classpath @@ -1,7 +1,13 @@ - - - - + + + + + + + + + + diff --git a/dev-workspace/andl-ra/META-INF/MANIFEST.MF b/dev-workspace/andl-ra/META-INF/MANIFEST.MF index d820246..52491a6 100644 --- a/dev-workspace/andl-ra/META-INF/MANIFEST.MF +++ b/dev-workspace/andl-ra/META-INF/MANIFEST.MF @@ -1,19 +1,25 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 -Bundle-Name: RaJoin-Node extension for KNIME Workbench -Bundle-SymbolicName: org.andl.ra.join; singleton:=true +Bundle-Name: Relational Algebra extensions for KNIME Workbench +Bundle-SymbolicName: org.andl.ra;singleton:=true Bundle-Version: 1.0.0.qualifier Bundle-ClassPath: rajoin.jar, raprojection.jar, - raset.jar + raset.jar, + raextension.jar, + d:/mydocs/dev/commons-jexl3-3.1.jar Bundle-Activator: org.andl.ra.join.RaJoinNodePlugin Bundle-Vendor: andl Require-Bundle: org.eclipse.core.runtime, org.knime.workbench.core, org.knime.workbench.repository, - org.knime.base + org.knime.base, + org.knime.core, + org.apache.commons.logging;bundle-version="1.2.0" Bundle-ActivationPolicy: lazy -Export-Package: org.andl.ra.join; +Export-Package: org.andl.ra.extension; + uses:=org.apache.commons.jexl, + org.andl.ra.join; uses:="org.osgi.framework, org.eclipse.core.runtime, org.knime.core.node.defaultnodesettings, @@ -28,4 +34,6 @@ Export-Package: org.andl.ra.join; org.knime.core.node.streamable, org.knime.core.node", org.andl.ra.set +Import-Package: org.knime.core.data.def +Bundle-RequiredExecutionEnvironment: JavaSE-1.8 diff --git a/dev-workspace/andl-ra/bin/.gitignore b/dev-workspace/andl-ra/bin/.gitignore deleted file mode 100644 index cf1db2e..0000000 --- a/dev-workspace/andl-ra/bin/.gitignore +++ /dev/null @@ -1 +0,0 @@ -/org/ diff --git a/dev-workspace/andl-ra/build.properties b/dev-workspace/andl-ra/build.properties index 5f630ef..b649478 100644 --- a/dev-workspace/andl-ra/build.properties +++ b/dev-workspace/andl-ra/build.properties @@ -1,8 +1,19 @@ source.rajoin.jar = src/ +source.raprojection.jar = src/ +source.raset.jar = src/ +source.raextension.jar = src/ bin.includes = plugin.xml,\ META-INF/,\ rajoin.jar,\ raprojection.jar,\ - raset.jar -source.raprojection.jar = src/ -source.raset.jar = src/ + raset.jar,\ + raextension.jar +source.raextension.jar = src/ +jars.compile.order = rajoin.jar,\ + raprojection.jar,\ + raset.jar,\ + raextension.jar +output.raextension.jar = bin/ +output.rajoin.jar = bin/ +output.raprojection.jar = bin/ +output.raset.jar = bin/ diff --git a/dev-workspace/andl-ra/plugin.xml b/dev-workspace/andl-ra/plugin.xml index 73b93aa..6b81f29 100644 --- a/dev-workspace/andl-ra/plugin.xml +++ b/dev-workspace/andl-ra/plugin.xml @@ -7,15 +7,15 @@ icon="/alpha.png" level-id="Andl" name="Andl nodes" - after="DB" + after="/DB" path="/"/> - - - - + + + + diff --git a/dev-workspace/andl-ra/src/org/andl/ra/RaExtensionNodeFactory.xml b/dev-workspace/andl-ra/src/org/andl/ra/RaExtensionNodeFactory.xml deleted file mode 100644 index 8b8f762..0000000 --- a/dev-workspace/andl-ra/src/org/andl/ra/RaExtensionNodeFactory.xml +++ /dev/null @@ -1,37 +0,0 @@ - - - RaExtension - - - RA Extension node - - - - Insert long description here... - - - - - - - - - - Description of first input port... - - Description of first output port... - - - - Description of first view... - - - diff --git a/dev-workspace/andl-ra/src/org/andl/ra/RaExtensionConfig.java b/dev-workspace/andl-ra/src/org/andl/ra/extension/RaExtensionConfig.java similarity index 98% rename from dev-workspace/andl-ra/src/org/andl/ra/RaExtensionConfig.java rename to dev-workspace/andl-ra/src/org/andl/ra/extension/RaExtensionConfig.java index f0ef8e5..c279653 100644 --- a/dev-workspace/andl-ra/src/org/andl/ra/RaExtensionConfig.java +++ b/dev-workspace/andl-ra/src/org/andl/ra/extension/RaExtensionConfig.java @@ -1,4 +1,4 @@ -package org.andl.ra; +package org.andl.ra.extension; import org.knime.core.data.DataTableSpec; import org.knime.core.node.InvalidSettingsException; diff --git a/dev-workspace/andl-ra/src/org/andl/ra/extension/RaExtensionJexl.java b/dev-workspace/andl-ra/src/org/andl/ra/extension/RaExtensionJexl.java new file mode 100644 index 0000000..39c46aa --- /dev/null +++ b/dev-workspace/andl-ra/src/org/andl/ra/extension/RaExtensionJexl.java @@ -0,0 +1,107 @@ +package org.andl.ra.extension; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Map; + +import org.apache.commons.jexl3.JexlBuilder; +import org.apache.commons.jexl3.JexlContext; +import org.apache.commons.jexl3.JexlEngine; +import org.apache.commons.jexl3.JexlExpression; +import org.knime.core.data.BooleanValue; +import org.knime.core.data.DataCell; +import org.knime.core.data.DataColumnSpec; +import org.knime.core.data.DataRow; +import org.knime.core.data.DataTableSpec; +import org.knime.core.data.DataType; +import org.knime.core.data.DoubleValue; +import org.knime.core.data.IntValue; +import org.knime.core.data.StringValue; +//import org.knime.core.data.date.DateAndTimeCell; +//import org.knime.core.data.date.DateAndTimeValue; +import org.knime.core.data.def.BooleanCell; +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.InvalidSettingsException; + +class RaExtensionJexl { + private DataTableSpec _intablespec; + private DataType _outcoltype; + private JexlEngine _jexl = new JexlBuilder().cache(512).strict(true).silent(false).create(); + private RaContext _context; + private ArrayList _colspecs = new ArrayList<>(); + private JexlExpression _expr; + + // create Jexl wrapper from specs and settings + RaExtensionJexl(DataTableSpec intablespec, DataColumnSpec outcolspec, String expression) + throws InvalidSettingsException { + _intablespec = intablespec; + _outcoltype = outcolspec.getType(); + HashMap map = new HashMap<>(); + for (DataColumnSpec colspec : _intablespec) { + map.put(colspec.getName(), _colspecs.size()); + _colspecs.add(colspec); + } + _context = new RaContext(map); + try { + _expr = _jexl.createExpression(expression); + } catch (Exception e) { + throw new InvalidSettingsException("The expression is not valid: " + e.getMessage(), e); + } + + } + + // evaluate the expression on a row and return a cell value + DataCell evaluate(DataRow row) { + _context._currentrow = row; + return getCell(_expr.evaluate(_context)); + } + + // convert object value to cell value + DataCell getCell(Object value) { + if (_outcoltype.equals(BooleanCell.TYPE)) return (boolean)value ? BooleanCell.TRUE : BooleanCell.FALSE; + if (_outcoltype.equals(IntCell.TYPE)) return IntCell.IntCellFactory.create((int)value); + if (_outcoltype.equals(DoubleCell.TYPE)) return DoubleCell.DoubleCellFactory.create((double)value); + if (_outcoltype.equals(StringCell.TYPE)) return StringCell.StringCellFactory.create((String)value); + //if (cell instanceof DateAndTimeValue) return DateAndTimeCell.UTILITY.create((int)value); + return null; + } + +} + +// Dynamic context for use by expression evaluator +class RaContext implements JexlContext { + final Map _map; + DataRow _currentrow; + + public RaContext(Map map) { + _map = map; + } + + @Override + public boolean has(String name) { + return _map.containsKey(name); + } + + // get an object value from the row by index + @Override + public Object get(String name) { + return getValue(_currentrow.getCell(_map.get(name))); + } + + @Override + public void set(String name, Object value) { + //throw new InvalidDataException(); + } + + Object getValue(DataCell cell) { + if (cell instanceof BooleanValue) return ((BooleanValue)cell).getBooleanValue(); + if (cell instanceof IntValue) return ((IntValue)cell).getIntValue(); + if (cell instanceof DoubleValue) return ((DoubleValue)cell).getDoubleValue(); + if (cell instanceof StringValue) return ((StringValue)cell).getStringValue(); + //if (cell instanceof DateAndTimeValue) return ((DateAndTimeValue)cell).getUTCTimeInMillis(); //BUG + return null; + } +} + \ No newline at end of file diff --git a/dev-workspace/andl-ra/src/org/andl/ra/RaExtensionNodeDialog.java b/dev-workspace/andl-ra/src/org/andl/ra/extension/RaExtensionNodeDialog.java similarity index 97% rename from dev-workspace/andl-ra/src/org/andl/ra/RaExtensionNodeDialog.java rename to dev-workspace/andl-ra/src/org/andl/ra/extension/RaExtensionNodeDialog.java index bad7f38..145c9f0 100644 --- a/dev-workspace/andl-ra/src/org/andl/ra/RaExtensionNodeDialog.java +++ b/dev-workspace/andl-ra/src/org/andl/ra/extension/RaExtensionNodeDialog.java @@ -1,4 +1,4 @@ -package org.andl.ra; +package org.andl.ra.extension; import java.util.ArrayList; diff --git a/dev-workspace/andl-ra/src/org/andl/ra/RaExtensionNodeFactory.java b/dev-workspace/andl-ra/src/org/andl/ra/extension/RaExtensionNodeFactory.java similarity index 97% rename from dev-workspace/andl-ra/src/org/andl/ra/RaExtensionNodeFactory.java rename to dev-workspace/andl-ra/src/org/andl/ra/extension/RaExtensionNodeFactory.java index de6a324..3fef7f3 100644 --- a/dev-workspace/andl-ra/src/org/andl/ra/RaExtensionNodeFactory.java +++ b/dev-workspace/andl-ra/src/org/andl/ra/extension/RaExtensionNodeFactory.java @@ -1,4 +1,4 @@ -package org.andl.ra; +package org.andl.ra.extension; import org.knime.core.node.NodeDialogPane; import org.knime.core.node.NodeFactory; diff --git a/dev-workspace/andl-ra/src/org/andl/ra/extension/RaExtensionNodeFactory.xml b/dev-workspace/andl-ra/src/org/andl/ra/extension/RaExtensionNodeFactory.xml new file mode 100644 index 0000000..bdfd2e3 --- /dev/null +++ b/dev-workspace/andl-ra/src/org/andl/ra/extension/RaExtensionNodeFactory.xml @@ -0,0 +1,20 @@ + + + RaExtension + + Relational Algebra Extend operation. + + + Extends a relation (table) by adding a single attribute (column). + The value of the column is defined by an arbitrary expression. + + + + + + + + The input table. + The output table. + + diff --git a/dev-workspace/andl-ra/src/org/andl/ra/RaExtensionNodeModel.java b/dev-workspace/andl-ra/src/org/andl/ra/extension/RaExtensionNodeModel.java similarity index 95% rename from dev-workspace/andl-ra/src/org/andl/ra/RaExtensionNodeModel.java rename to dev-workspace/andl-ra/src/org/andl/ra/extension/RaExtensionNodeModel.java index 6b6a33d..eb9fc8c 100644 --- a/dev-workspace/andl-ra/src/org/andl/ra/RaExtensionNodeModel.java +++ b/dev-workspace/andl-ra/src/org/andl/ra/extension/RaExtensionNodeModel.java @@ -1,8 +1,7 @@ -package org.andl.ra; +package org.andl.ra.extension; import java.io.File; import java.io.IOException; -import java.util.IllegalFormatException; import org.knime.core.data.DataCell; import org.knime.core.data.DataColumnSpec; @@ -97,7 +96,7 @@ protected DataTableSpec[] configure(final DataTableSpec[] inSpecs) /** {@inheritDoc} */ @Override - protected ColumnRearranger createColumnRearranger(final DataTableSpec in) throws InvalidSettingsException { + protected ColumnRearranger createColumnRearranger(final DataTableSpec inspec) throws InvalidSettingsException { String colname = _columnNameSettings.getStringValue(); String typename = _columnTypeNameSettings.getStringValue(); String expression = _expressionSettings.getStringValue(); @@ -105,13 +104,13 @@ protected ColumnRearranger createColumnRearranger(final DataTableSpec in) throws try { DataColumnSpec outcolspec = new DataColumnSpecCreator(colname, tcf.getDataType()).createSpec(); - final DataCell constantCell = tcf.createCell(expression, "yyyy-MM-dd"); + RaExtensionJexl jexl = new RaExtensionJexl(inspec, outcolspec, expression); - ColumnRearranger rearranger = new ColumnRearranger(in); + ColumnRearranger rearranger = new ColumnRearranger(inspec); CellFactory fac = new SingleCellFactory(outcolspec) { @Override public DataCell getCell(final DataRow row) { - return constantCell; + return jexl.evaluate(row); } }; diff --git a/dev-workspace/andl-ra/src/org/andl/ra/RaExtensionNodeView.java b/dev-workspace/andl-ra/src/org/andl/ra/extension/RaExtensionNodeView.java similarity index 96% rename from dev-workspace/andl-ra/src/org/andl/ra/RaExtensionNodeView.java rename to dev-workspace/andl-ra/src/org/andl/ra/extension/RaExtensionNodeView.java index 12fd98d..5e9f3c6 100644 --- a/dev-workspace/andl-ra/src/org/andl/ra/RaExtensionNodeView.java +++ b/dev-workspace/andl-ra/src/org/andl/ra/extension/RaExtensionNodeView.java @@ -1,4 +1,4 @@ -package org.andl.ra; +package org.andl.ra.extension; import org.knime.core.node.NodeView; diff --git a/dev-workspace/andl-ra/src/org/andl/ra/TypeCellFactory.java b/dev-workspace/andl-ra/src/org/andl/ra/extension/TypeCellFactory.java similarity index 99% rename from dev-workspace/andl-ra/src/org/andl/ra/TypeCellFactory.java rename to dev-workspace/andl-ra/src/org/andl/ra/extension/TypeCellFactory.java index 9ab7091..9ddb321 100644 --- a/dev-workspace/andl-ra/src/org/andl/ra/TypeCellFactory.java +++ b/dev-workspace/andl-ra/src/org/andl/ra/extension/TypeCellFactory.java @@ -44,7 +44,7 @@ * * Created on 25.11.2013 by NanoTec */ -package org.andl.ra; +package org.andl.ra.extension; import java.io.IOException; import java.text.SimpleDateFormat; diff --git a/dev-workspace/andl-ra/src/org/andl/ra/default.png b/dev-workspace/andl-ra/src/org/andl/ra/extension/default.png similarity index 100% rename from dev-workspace/andl-ra/src/org/andl/ra/default.png rename to dev-workspace/andl-ra/src/org/andl/ra/extension/default.png diff --git a/dev-workspace/andl-ra/src/org/andl/ra/package.html b/dev-workspace/andl-ra/src/org/andl/ra/extension/package.html similarity index 100% rename from dev-workspace/andl-ra/src/org/andl/ra/package.html rename to dev-workspace/andl-ra/src/org/andl/ra/extension/package.html diff --git a/dev-workspace/andl-ra/src/org/andl/ra/join/RaJoinNodeFactory.xml b/dev-workspace/andl-ra/src/org/andl/ra/join/RaJoinNodeFactory.xml index a938f6b..5f3e1e5 100644 --- a/dev-workspace/andl-ra/src/org/andl/ra/join/RaJoinNodeFactory.xml +++ b/dev-workspace/andl-ra/src/org/andl/ra/join/RaJoinNodeFactory.xml @@ -2,10 +2,10 @@ RaJoin - Relational Algebra join operations. + Relational Algebra Join operations. - Natural join based on matching columns by name. + Performs natural join of two relations (tables) based on matching attributes (columns) by name. Matching columns must be the same type. There is no outer join, all output values are copied from input rows. diff --git a/dev-workspace/andl-ra/src/org/andl/ra/join/RaJoinNodeModel.java b/dev-workspace/andl-ra/src/org/andl/ra/join/RaJoinNodeModel.java index ecedc18..fb64b05 100644 --- a/dev-workspace/andl-ra/src/org/andl/ra/join/RaJoinNodeModel.java +++ b/dev-workspace/andl-ra/src/org/andl/ra/join/RaJoinNodeModel.java @@ -1,29 +1,21 @@ package org.andl.ra.join; -import java.io.File; -import java.io.IOException; - import java.io.File; import java.io.IOException; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; import java.util.HashSet; -import java.util.IllegalFormatException; -import java.util.List; import java.util.Map; import java.util.stream.Stream; import org.andl.ra.set.RaTuple; 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.container.CloseableRowIterator; import org.knime.core.data.def.DefaultRow; -import org.knime.core.data.def.DoubleCell; -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; @@ -111,10 +103,6 @@ protected DataTableSpec[] configure(final DataTableSpec[] inSpecs) throws Invali return new DataTableSpec[] { outSpec }; } - private DataTableSpec createOutputSpec(DataTableSpec inSpec) { - return inSpec; - } - /** {@inheritDoc} */ @Override protected void saveSettingsTo(final NodeSettingsWO settings) { diff --git a/dev-workspace/andl-ra/src/org/andl/ra/projection/RaProjectionNodeDialog.java b/dev-workspace/andl-ra/src/org/andl/ra/projection/RaProjectionNodeDialog.java index e910e80..8b3b05b 100644 --- a/dev-workspace/andl-ra/src/org/andl/ra/projection/RaProjectionNodeDialog.java +++ b/dev-workspace/andl-ra/src/org/andl/ra/projection/RaProjectionNodeDialog.java @@ -1,9 +1,5 @@ package org.andl.ra.projection; -import org.knime.core.node.defaultnodesettings.DefaultNodeSettingsPane; -import org.knime.core.node.defaultnodesettings.DialogComponentString; -import org.knime.core.node.defaultnodesettings.SettingsModelString; - import org.knime.core.data.DataTableSpec; import org.knime.core.node.InvalidSettingsException; import org.knime.core.node.NodeDialogPane; diff --git a/dev-workspace/andl-ra/src/org/andl/ra/projection/RaProjectionNodeFactory.xml b/dev-workspace/andl-ra/src/org/andl/ra/projection/RaProjectionNodeFactory.xml index 672508e..e9920c8 100644 --- a/dev-workspace/andl-ra/src/org/andl/ra/projection/RaProjectionNodeFactory.xml +++ b/dev-workspace/andl-ra/src/org/andl/ra/projection/RaProjectionNodeFactory.xml @@ -7,8 +7,8 @@ - This is the projection operator defined for the relational algebra. - It is equivalent to removing some columns and then copying the table removing duplicates. + Projects relation (table) onto a reduced set of attributes (columns). + Equivalent to removing some columns and then copying the table removing duplicates. diff --git a/dev-workspace/andl-ra/src/org/andl/ra/projection/RaProjectionNodeModel.java b/dev-workspace/andl-ra/src/org/andl/ra/projection/RaProjectionNodeModel.java index 1ac9903..7b0804a 100644 --- a/dev-workspace/andl-ra/src/org/andl/ra/projection/RaProjectionNodeModel.java +++ b/dev-workspace/andl-ra/src/org/andl/ra/projection/RaProjectionNodeModel.java @@ -2,36 +2,23 @@ import java.io.File; import java.io.IOException; - -import java.util.ArrayList; import java.util.HashSet; -import java.util.IllegalFormatException; -import java.util.List; + import org.andl.ra.set.RaTuple; import org.knime.base.node.preproc.filter.row.RowFilterIterator; -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.RowIterator; -import org.knime.core.data.container.CloseableRowIterator; import org.knime.core.data.container.ColumnRearranger; -import org.knime.core.data.container.JoinedTable; -import org.knime.core.data.def.DefaultRow; -import org.knime.core.data.def.DoubleCell; -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.SettingsModelString; import org.knime.core.node.port.PortObjectSpec; import org.knime.core.node.port.PortType; import org.knime.core.node.streamable.InputPortRole; diff --git a/dev-workspace/andl-ra/src/org/andl/ra/set/RaSetNodeDialog.java b/dev-workspace/andl-ra/src/org/andl/ra/set/RaSetNodeDialog.java index b8e069e..9c63f41 100644 --- a/dev-workspace/andl-ra/src/org/andl/ra/set/RaSetNodeDialog.java +++ b/dev-workspace/andl-ra/src/org/andl/ra/set/RaSetNodeDialog.java @@ -2,7 +2,6 @@ import org.knime.core.node.defaultnodesettings.DefaultNodeSettingsPane; import org.knime.core.node.defaultnodesettings.DialogComponentStringSelection; -import org.knime.core.node.defaultnodesettings.SettingsModel; import org.knime.core.node.defaultnodesettings.SettingsModelString; /** diff --git a/dev-workspace/andl-ra/src/org/andl/ra/set/RaSetNodeFactory.xml b/dev-workspace/andl-ra/src/org/andl/ra/set/RaSetNodeFactory.xml index 81900e4..f38d1a2 100644 --- a/dev-workspace/andl-ra/src/org/andl/ra/set/RaSetNodeFactory.xml +++ b/dev-workspace/andl-ra/src/org/andl/ra/set/RaSetNodeFactory.xml @@ -5,7 +5,7 @@ Relational Algebra dyadic set operations. - Combine two tables using a selected set operation. + Combines two relations (tables) by performing a selected set operation on their tuples (rows). Duplicates if any are removed from the output. diff --git a/dev-workspace/andl-ra/src/org/andl/ra/set/RaSetNodeModel.java b/dev-workspace/andl-ra/src/org/andl/ra/set/RaSetNodeModel.java index 31b7dde..7463353 100644 --- a/dev-workspace/andl-ra/src/org/andl/ra/set/RaSetNodeModel.java +++ b/dev-workspace/andl-ra/src/org/andl/ra/set/RaSetNodeModel.java @@ -2,25 +2,13 @@ import java.io.File; import java.io.IOException; -import java.nio.channels.CancelledKeyException; -import java.io.File; -import java.io.IOException; -import java.util.ArrayList; import java.util.Arrays; import java.util.HashSet; -import java.util.IllegalFormatException; -import java.util.Iterator; -import java.util.List; -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.container.CloseableRowIterator; import org.knime.core.data.def.DefaultRow; -import org.knime.core.data.def.DoubleCell; -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; From 4b2b5311d27eea02c4f26ef312e972c42d5f4310 Mon Sep 17 00:00:00 2001 From: david Date: Fri, 6 Mar 2020 13:17:32 +1100 Subject: [PATCH 13/56] try_extend From c1b420536a24015bf0a4741ffaa5e852f8b510e3 Mon Sep 17 00:00:00 2001 From: david Date: Fri, 6 Mar 2020 13:21:17 +1100 Subject: [PATCH 14/56] Attempt at fx icon --- Inkscape/fx.png | Bin 0 -> 298 bytes Inkscape/knime.svg | 55 +++++++++++++++++++++++++++++++++++++-------- 2 files changed, 46 insertions(+), 9 deletions(-) create mode 100644 Inkscape/fx.png diff --git a/Inkscape/fx.png b/Inkscape/fx.png new file mode 100644 index 0000000000000000000000000000000000000000..ae317e16305cb7373d1f66c23d4ea9a4e220e0e1 GIT binary patch literal 298 zcmeAS@N?(olHy`uVBq!ia0vp^AhrMp8<5nmf9C+CSc;uILpXq-h9ji|$mcBZh%5%G zzYfBTP8zc-fP#`Gt`Q}{`DrEPiAAXl<>lpinR(g8$%zH2dih1^v)|cB0TnIxba4#P znAm#3u+K43