@@ -328,4 +328,116 @@ private static void outputYamlDoc(String opYaml) throws IOException {
328328 os .write (opYaml .getBytes (UTF_8 ));
329329 }
330330 }
331+
332+ /**
333+ * A data structure containing all the metadata needed to define an Op
334+ *
335+ * @author Gabriel Selzer
336+ * @author Mark Hiner
337+ */
338+ private static class OpData {
339+
340+ /**
341+ * A {@link Map} used to store any implementation-specific and/or nullable
342+ * tags.
343+ */
344+ private final Map <String , Object > tags ;
345+
346+ /**
347+ * A {@link List} of {@link String}s describing the name(s) of the Op. There
348+ * must be at least one.
349+ */
350+ private final List <String > names ;
351+
352+ /**
353+ * A {@link List} of {@link OpParameter}, describing the input and output
354+ * parameters of this Op.
355+ */
356+ private final List <OpParameter > params ;
357+
358+ /**
359+ * A {@link String} identifying the code providing an Op's functionality.
360+ */
361+ private final String source ;
362+
363+ /**
364+ * The version of this Op.
365+ */
366+ private final String version ;
367+
368+ /**
369+ * The priority of this Op.
370+ */
371+ private final double priority ;
372+
373+ /**
374+ * A description of the functionality provided by this Op.
375+ */
376+ private final String description ;
377+
378+ /**
379+ * A {@link List} of the authors of this Op
380+ */
381+ private final List <String > authors ;
382+
383+ public OpData (final String source , final String version ,
384+ final List <String > names , final List <OpParameter > params ,
385+ final Map <String , Object > tags , List <String > authors , double priority ,
386+ String description )
387+ {
388+ this .source = source ;
389+ this .version = version ;
390+ this .names = names ;
391+ this .params = params ;
392+ this .tags = tags ;
393+ this .authors = authors ;
394+ this .priority = priority ;
395+ this .description = description ;
396+
397+ validateOpData ();
398+ }
399+
400+ /**
401+ * Helper method to ensure this OpImpl is valid. Throws
402+ * {@link InvalidOpException} if problems are detected. Parallel
403+ * implementation of org.scijava.ops.engine.util.Infos#validate in
404+ * scijava-ops-engine
405+ */
406+ private void validateOpData () {
407+ if (Objects .isNull (names ) || names .isEmpty ()) {
408+ throw new InvalidOpException ("Invalid Op defined in : " + source +
409+ ". Op names cannot be empty!" );
410+ }
411+
412+ int outputs = 0 ;
413+ for (OpParameter p : params ) {
414+ if (p .ioType .equals (OpParameter .IO_TYPE .OUTPUT )) outputs ++;
415+ }
416+ if (outputs > 1 ) {
417+ throw new InvalidOpException ("Invalid Op defined in : " + source +
418+ ". Ops cannot have more than one output!" );
419+ }
420+ }
421+
422+ /**
423+ * Returns a {@link Map} storing the needed Op data hierarchically.
424+ *
425+ * @return the {@link Map} of data.
426+ */
427+ public Map <String , Object > dumpData () {
428+ Map <String , Object > map = new HashMap <>();
429+ map .put ("source" , source );
430+ map .put ("version" , version );
431+ map .put ("names" , names .toArray (String []::new ));
432+ map .put ("description" , description );
433+ map .put ("priority" , priority );
434+ map .put ("authors" , authors .toArray (String []::new ));
435+ List <Map <String , Object >> foo = params .stream () //
436+ .map (OpParameter ::data ) //
437+ .collect (Collectors .toList ());
438+ map .put ("parameters" , foo .toArray (Map []::new ));
439+ map .put ("tags" , tags );
440+ return Collections .singletonMap ("op" , map );
441+ }
442+ }
331443}
0 commit comments