1010import java .util .ArrayList ;
1111import java .util .Arrays ;
1212import java .util .Collection ;
13+ import java .util .HashMap ;
1314import java .util .LinkedList ;
1415import java .util .List ;
16+ import java .util .Map ;
1517import java .util .Set ;
1618import java .util .TreeSet ;
1719
@@ -78,14 +80,17 @@ public Job convert(final NativeNodeContainer nativeNodeContainer, final Workflow
7880
7981 // input/output ports are also handled as parameters in GKN, so we need to keep track of
8082 // the ports that we've processed
81- final Set <String > processedPortNames = new TreeSet <String >();
83+ final Set <String > processedPortNames = new TreeSet <>();
84+ // since we will name converted job inputs using extensions, we need a map to relate GKN port names to converted
85+ // inputs
86+ final Map <String , com .workflowconversion .knime2grid .model .Port > gknPortToConvertedPort = new HashMap <>();
8287
8388 // all inputs and outputs of GKNs are URIs, so this simplifies the conversion
8489 // we need to know how to actually execute this job on a command line environment
8590 // so we need to access the command generator... however, at this point, there
8691 // is no guarantee that all jobs have been converted so we need to use the WorkflowManager to
8792 // gather information about other nodes
88- createInputsAndOutputsFromKnimeWorkflow (nativeNodeContainer , workflowManager , nodeConfiguration , job , processedPortNames );
93+ createInputsAndOutputsFromKnimeWorkflow (nativeNodeContainer , workflowManager , nodeConfiguration , job , processedPortNames , gknPortToConvertedPort );
8994
9095 // process all non-input/non-output parameters AND the CTD, if any.
9196 // this must be AFTER inputs/outputs have been processed, because we are adding
@@ -98,7 +103,7 @@ public Job convert(final NativeNodeContainer nativeNodeContainer, final Workflow
98103 throw new ApplicationException (
99104 "This job already has a CTD file. Only one CTD file per job is allowed. This is probably a bug and should be reported." );
100105 }
101- addCTDInputPort (workflowManager , (CommandLineCTDFile ) element , job , nodeConfiguration , nativeNodeContainer );
106+ addCTDInputPort (workflowManager , (CommandLineCTDFile ) element , job , nodeConfiguration , nativeNodeContainer , gknPortToConvertedPort );
102107 ctdFound = true ;
103108 } else if (element instanceof ParametrizedCommandLineElement && !processedPortNames .contains (element .getKey ())) {
104109 // we need to process only true parameters, not flags or option identifiers
@@ -124,18 +129,20 @@ public Job convert(final NativeNodeContainer nativeNodeContainer, final Workflow
124129 }
125130
126131 private void createInputsAndOutputsFromKnimeWorkflow (final NativeNodeContainer nativeNodeContainer , final WorkflowManager workflowManager ,
127- final INodeConfiguration nodeConfiguration , final Job job , final Set <String > processedPortNames ) {
132+ final INodeConfiguration nodeConfiguration , final Job job , final Set <String > processedPortNames ,
133+ final Map <String , com .workflowconversion .knime2grid .model .Port > gknPortToConvertedPort ) {
128134 for (final ConnectionContainer connectionContainer : workflowManager .getIncomingConnectionsFor (nativeNodeContainer .getID ())) {
129135 final NodeID sourceNodeId = connectionContainer .getSource ();
130136 final Node sourceNode = ((NativeNodeContainer ) workflowManager .getNodeContainer (connectionContainer .getSource ())).getNode ();
131137 final int destPortNr = connectionContainer .getDestPort ();
132138 final Port destPort = nodeConfiguration .getInputPorts ().get (ConverterUtils .convertFromKnimePort (destPortNr ));
133- final Input input = new Input ();
134- input .setSourceId (sourceNodeId );
135- input .setOriginalPortNr (destPortNr );
136- input .setName (destPort .getName () + getExtensionForPort (sourceNode , connectionContainer .getSourcePort ()));
139+ final Input convertedInput = new Input ();
140+ convertedInput .setSourceId (sourceNodeId );
141+ convertedInput .setOriginalPortNr (destPortNr );
142+ convertedInput .setName (destPort .getName () + getExtensionForPort (sourceNode , connectionContainer .getSourcePort ()));
143+ gknPortToConvertedPort .put (destPort .getName (), convertedInput );
137144 // input.setMultiFile(destPort.isMultiFile());
138- job .addInput (input );
145+ job .addInput (convertedInput );
139146
140147 processedPortNames .add (destPort .getName ());
141148 }
@@ -144,12 +151,13 @@ private void createInputsAndOutputsFromKnimeWorkflow(final NativeNodeContainer n
144151 if (job .getOutputByOriginalPortNr (sourcePortNr ) == null ) {
145152 // first time we see the output, we need to add it
146153 final Port sourcePort = nodeConfiguration .getOutputPorts ().get (ConverterUtils .convertFromKnimePort (sourcePortNr ));
147- final Output newOutput = new Output ();
154+ final Output convertedOutput = new Output ();
148155 final Node sourceNode = ((NativeNodeContainer ) workflowManager .getNodeContainer (connectionContainer .getSource ())).getNode ();
149156 // newOutput.setMultiFile(sourcePort.isMultiFile());
150- newOutput .setName (sourcePort .getName () + getExtensionForPort (sourceNode , connectionContainer .getSourcePort ()));
151- newOutput .setOriginalPortNr (sourcePortNr );
152- job .addOutput (newOutput );
157+ convertedOutput .setName (sourcePort .getName () + getExtensionForPort (sourceNode , connectionContainer .getSourcePort ()));
158+ convertedOutput .setOriginalPortNr (sourcePortNr );
159+ gknPortToConvertedPort .put (sourcePort .getName (), convertedOutput );
160+ job .addOutput (convertedOutput );
153161 processedPortNames .add (sourcePort .getName ());
154162 }
155163 }
@@ -158,7 +166,8 @@ private void createInputsAndOutputsFromKnimeWorkflow(final NativeNodeContainer n
158166 // when executing GKN in KNIME, each GKN generates an "on the fly" CTD file and uses it to
159167 // execute the associated binary, but what we need here is to add a new input containing a CTD
160168 private void addCTDInputPort (final WorkflowManager workflowManager , final CommandLineCTDFile element , final Job job ,
161- final INodeConfiguration nodeConfiguration , final NativeNodeContainer nativeNodeContainer ) throws IOException , InvalidCTDFileException {
169+ final INodeConfiguration nodeConfiguration , final NativeNodeContainer nativeNodeContainer ,
170+ final Map <String , com .workflowconversion .knime2grid .model .Port > gknPortToConvertedPort ) throws IOException , InvalidCTDFileException {
162171 final Input ctdInput = new Input ();
163172 ctdInput .setName (CommandLineCTDFile .CTD_FILE_KEY );
164173 ctdInput .setConnectionType (ConnectionType .UserProvided );
@@ -171,8 +180,21 @@ private void addCTDInputPort(final WorkflowManager workflowManager, final Comman
171180 dumpConfiguration (clonedNodeConfiguration ).getCanonicalPath ());
172181 ctdInput .setAssociatedFileParameter (ctdFileParameter );
173182 job .addInput (ctdInput );
174- // fix the command line element!
183+ // fix the command line element
175184 element .setValue (ctdFileParameter );
185+ // fix converted Input/Outputs
186+ transferToConvertedPorts (clonedNodeConfiguration , gknPortToConvertedPort );
187+ }
188+
189+ private void transferToConvertedPorts (final INodeConfiguration clonedNodeConfiguration ,
190+ final Map <String , com .workflowconversion .knime2grid .model .Port > gknPortToConvertedPort ) {
191+ for (final Map .Entry <String , com .workflowconversion .knime2grid .model .Port > entry : gknPortToConvertedPort .entrySet ()) {
192+ final Parameter <?> parameter = clonedNodeConfiguration .getParameter (entry .getKey ());
193+ if (parameter == null || !(parameter instanceof IFileParameter )) {
194+ throw new ApplicationException ("Invalid contents of map relating GKN ports to converted inputs. This is a bug and should be reported." );
195+ }
196+ entry .getValue ().setAssociatedFileParameter ((IFileParameter ) parameter );
197+ }
176198 }
177199
178200 private File dumpConfiguration (final INodeConfiguration nodeConfiguration ) throws IOException {
@@ -270,21 +292,18 @@ private void fixFilePathsFromAssociatedParameters(final WorkflowManager workflow
270292 processedPorts .add (parameterName );
271293 }
272294 } else if (fileNames .size () > 1 ) {
273- if (associatedParameter .getValue () != null ) {
274- // multifile
275- final List <String > fixedFilenames = new LinkedList <String >();
276- int fileNumber = 0 ;
277- for (final String fileName : fileNames ) {
278- final String extension = FilenameUtils .getExtension (fileName );
279- fixedFilenames .add (ConverterUtils .generateFileNameForExport (parameterName , extension , fileNumber ));
280- fileNumber ++;
281- }
282- ((FileListParameter ) associatedParameter ).setValue (fixedFilenames );
283- processedPorts .add (parameterName );
295+ final List <String > fixedFilenames = new LinkedList <String >();
296+ int fileNumber = 0 ;
297+ for (final String fileName : fileNames ) {
298+ final String extension = FilenameUtils .getExtension (fileName );
299+ fixedFilenames .add (ConverterUtils .generateFileNameForExport (parameterName , extension , fileNumber ));
300+ fileNumber ++;
284301 }
302+ ((FileListParameter ) associatedParameter ).setValue (fixedFilenames );
303+ processedPorts .add (parameterName );
285304 } else {
286- // 0 inputs?
287- throw new RuntimeException ( "Invalid association between parameters and input files. This is probably a bug, please report it." );
305+ // 0 inputs!
306+ // TODO: what does this mean???
288307 }
289308 }
290309 }
0 commit comments