3535import java .lang .reflect .TypeVariable ;
3636import java .util .ArrayList ;
3737import java .util .Arrays ;
38+ import java .util .Collections ;
3839import java .util .Comparator ;
3940import java .util .EnumSet ;
4041import java .util .HashMap ;
4344import java .util .List ;
4445import java .util .Map ;
4546import java .util .Map .Entry ;
46- import java .util .PriorityQueue ;
47- import java .util .Queue ;
4847import java .util .function .Function ;
4948import java .util .stream .Collectors ;
5049
6160import org .scijava .ops .matcher .OpMatcher ;
6261import org .scijava .ops .matcher .OpMatchingException ;
6362import org .scijava .ops .matcher .OpRef ;
64- import org .scijava .ops .transform .AdaptedOp ;
6563import org .scijava .ops .transform .OpRunner ;
6664import org .scijava .ops .transform .OpTransformationMatcher ;
6765import org .scijava .ops .transform .OpTransformer ;
66+ import org .scijava .ops .types .Any ;
6867import org .scijava .ops .types .Nil ;
6968import org .scijava .ops .types .TypeService ;
7069import org .scijava .ops .util .OpWrapper ;
@@ -269,7 +268,7 @@ public <T> T findOpInstance(final String opName, final Nil<T> specialType, final
269268 public Object findOpInstance (final String opName , final OpRef ref , boolean adaptable ) {
270269 Object op = null ;
271270 OpCandidate match = null ;
272- AdaptedOp adaptation = null ;
271+ OpAdaptor adaptation = null ;
273272 try {
274273 // Find single match which matches the specified types
275274 match = getOpMatcher ().findSingleMatch (this , ref );
@@ -282,8 +281,8 @@ public Object findOpInstance(final String opName, final OpRef ref, boolean adapt
282281 }
283282 log .debug ("Attempting Op adaptation..." );
284283 try {
285- adaptation = adaptOp (opName , ref );
286- op = adaptation .op ();
284+ adaptation = adaptOp (ref );
285+ op = adaptation .getAdaptedOp ();
287286 } catch (OpMatchingException e1 ) {
288287 log .debug ("No suitable Op adaptation found" );
289288 throw new IllegalArgumentException (e1 );
@@ -305,82 +304,73 @@ public Object findOpInstance(final String opName, final OpRef ref, boolean adapt
305304 return wrappedOp ;
306305 }
307306
308- public AdaptedOp adaptOp (String opName , OpRef ref ) throws OpMatchingException {
309-
307+ public OpAdaptor adaptOp (OpRef ref ) throws OpMatchingException {
308+
310309 // TODO: support all types of ref
311310 // TODO: multi-stage adaptations (do we need this if we are not doing OpRunners
312311 // anymore?)
313312 // TODO: prevent searching for Op types that have already been searched for
314313 // TODO: export code to helper method.
315- Type opType = ref .getTypes ()[0 ];
316- List <OpInfo > adaptors = opCache .get ("adapt" );
317-
318- // create a priority queue to store suitable transformations.
319- Comparator <OpAdaptor > comp = (OpAdaptor i1 ,
320- OpAdaptor i2 ) -> i1 .adaptorInfo ().priority () < i2 .adaptorInfo ().priority () ? -1
321- : i1 .adaptorInfo ().priority () == i2 .adaptorInfo ().priority () ? 0 : 1 ;
322- Queue <OpAdaptor > suitableAdaptors = new PriorityQueue <>(comp );
323-
314+
324315 // create an OpCandidate list of suitable adaptors
325- for (OpInfo adaptor : adaptors ) {
326- Type adaptTo = adaptor .output ().getType ();
327- Map <TypeVariable <?>, Type > map = new HashMap <>();
328- // make sure that the adaptor outputs the correct type
329- if (opType instanceof ParameterizedType ) {
330- try {
331- if (!MatchingUtils .checkGenericAssignability (adaptTo , (ParameterizedType ) opType , map , true ))
332- continue ;
333- } catch (IllegalArgumentException e ) {continue ; }
334- }
335- else if (!Types .isAssignable (opType , adaptTo , map )) {
336- continue ;
337- }
338- // make sure that the adaptor is a Function (so we can cast it later)
339- if (Types .isInstance (adaptor .opType (), Function .class )) {
340- log .debug (adaptor + " is an illegal adaptor Op: must be a Function" );
341- continue ;
342- }
343- // make an OpCandidate
344- suitableAdaptors .add (new OpAdaptor (ref , adaptor , map , this , log ));
345- }
316+ Type blahadaptTo = ref .getTypes ()[0 ];
317+ Type adaptFrom = new Any ();
318+ Type refType = Types .parameterize (Function .class , new Type [] {adaptFrom , blahadaptTo });
319+ OpRef adaptorRef = new OpRef ("adapt" , new Type [] {refType }, blahadaptTo , new Type [] {adaptFrom });
320+ List <OpCandidate > adaptorCandidates = getOpMatcher ().findCandidates (this , adaptorRef );
321+ Comparator <OpCandidate > comp = (OpCandidate i1 ,
322+ OpCandidate i2 ) -> i1 .opInfo ().priority () < i2 .opInfo ().priority () ? -1
323+ : i1 .opInfo ().priority () == i2 .opInfo ().priority () ? 0 : 1 ;
324+ Collections .sort (adaptorCandidates , comp );
325+ // Queue<OpAdaptor> suitableAdaptors = new PriorityQueue<>(comp);
326+
327+ // // create an OpCandidate list of suitable adaptors
328+ // for (OpInfo adaptor : adaptors) {
329+ // Type adaptTo = adaptor.output().getType();
330+ // Map<TypeVariable<?>, Type> map = new HashMap<>();
331+ // // make sure that the adaptor outputs the correct type
332+ // if(opType instanceof ParameterizedType) {
333+ // try {
334+ // if(!MatchingUtils.checkGenericAssignability(adaptTo, (ParameterizedType) opType, map, true))
335+ // continue;
336+ // } catch(IllegalArgumentException e) {continue; }
337+ // }
338+ // else if (!Types.isAssignable(opType, adaptTo, map)) {
339+ // continue;
340+ // }
341+ // // make sure that the adaptor is a Function (so we can cast it later)
342+ // if (Types.isInstance(adaptor.opType(), Function.class)) {
343+ // log.debug(adaptor + " is an illegal adaptor Op: must be a Function");
344+ // continue;
345+ // }
346+ // // make an OpCandidate
347+ // suitableAdaptors.add(new OpAdaptor(ref, adaptor, map, this, log));
348+ // }
346349
347- while (suitableAdaptors .size () > 0 ) {
348- OpAdaptor adaptor = suitableAdaptors . remove ();
349- Object adaptorOp ;
350+ while (adaptorCandidates .size () > 0 ) {
351+
352+ OpAdaptor adaptor = new OpAdaptor ( ref , suitableAdaptors . remove (). opInfo (), ;
350353 // attempt to construct the adaptor
351354 // (N.B. we fail here if, for example, the adaptor cannot resolve its OpDependencies).
352355 try {
353- adaptorOp = adaptor .constructAdaptor ();
356+ adaptor .constructAdaptor ();
354357 } catch (OpMatchingException e ) {
355358 continue ;
356359 }
357360 try {
358-
359- // grab the first type parameter (from the OpCandidate?) and search for an Op
360- // that will then be adapted (this will be the first (only) type in the args of
361- // the adaptor)
362- Type adaptFrom = adaptor .adaptorCandidate ().paddedArgs ()[0 ];
363- final OpRef inferredRef = inferOpRef (adaptFrom , opName , adaptor .adaptorCandidate ().typeVarAssigns ());
364- // TODO: export this to another function (also done in findOpInstance).
365- // We need this here because we need to grab the OpInfo.
366- // TODO: is there a better way to do this?
367- final OpCandidate srcCandidate = getOpMatcher ().findSingleMatch (this , inferredRef );
368- final List <Object > srcDependencies = resolveOpDependencies (srcCandidate );
369- final Object fromOp = srcCandidate .opInfo ().createOpInstance (srcDependencies ).object ();
370-
371361 // get adapted Op by applying adaptor on unadapted Op, then return
372- // TODO: can we make this safer?
373- @ SuppressWarnings ("unchecked" )
374- Object toOp = ((Function <Object , Object >) adaptorOp ).apply (fromOp );
375- return new AdaptedOp (toOp , srcCandidate .opInfo (), adaptor .adaptorCandidate ().opInfo ());
362+ final Object fromOp = adaptor .constructSrcOp (ref .getName (), this );
363+ adaptor .executeAdaptation (fromOp );
364+ return adaptor ;
376365 } catch (OpMatchingException e1 ) {
377- // TODO: chain adaptations
378- continue ;
366+ //TODO: this should probably be safer.
367+ OpRef srcOpRef = adaptor .srcOpRef ;
368+
379369 }
380370
381371 }
382372 // no adaptors available.
383- throw new OpMatchingException ("Op adaptation failed: no adaptable Ops of type " + opName );
373+ throw new OpMatchingException ("Op adaptation failed: no adaptable Ops of type " + ref . getName () );
384374 }
385375
386376 /**
@@ -813,10 +803,13 @@ private class OpAdaptor {
813803
814804 //TODO: do we actually need all of these things?
815805 private Object adaptor ;
806+ private Object srcOp ;
807+ private Object adaptedOp ;
816808 private OpInfo adaptorInfo ;
809+ private OpInfo srcOpInfo ;
817810 private OpCandidate adaptorCandidate ;
818811 private OpRef adaptorRef ;
819- private OpRef srcRef ;
812+ private OpRef srcOpRef ;
820813 private OpRef targetRef ;
821814 private OpRef child ;
822815 private Map <TypeVariable <?>, Type > typeVarAssigns ;
@@ -847,15 +840,39 @@ public Object constructAdaptor() throws OpMatchingException {
847840 return adaptor ;
848841 }
849842
843+ public Object constructSrcOp (String opName , OpService ops ) throws OpMatchingException {
844+ // grab the first type parameter (from the OpCandidate?) and search for an Op
845+ // that will then be adapted (this will be the first (only) type in the args of
846+ // the adaptor)
847+ Type adaptFrom = adaptorCandidate .paddedArgs ()[0 ];
848+ srcOpRef = inferOpRef (adaptFrom , opName , typeVarAssigns );
849+ // TODO: export this to another function (also done in findOpInstance).
850+ // We need this here because we need to grab the OpInfo.
851+ // TODO: is there a better way to do this?
852+ final OpCandidate srcCandidate = getOpMatcher ().findSingleMatch (ops , srcOpRef );
853+ final List <Object > srcDependencies = resolveOpDependencies (srcCandidate );
854+ srcOp = srcCandidate .opInfo ().createOpInstance (srcDependencies ).object ();
855+ srcOpInfo = srcCandidate .opInfo ();
856+ return srcOp ;
857+ }
858+
850859 public OpInfo adaptorInfo () {return adaptorInfo ; }
860+
861+ public OpInfo srcInfo () {return srcOpInfo ; }
862+
863+ public OpRef srcRef () {return srcOpRef ; }
851864
852865 public OpCandidate adaptorCandidate () {return adaptorCandidate ; }
853866
854- public Object executeAdaptation (Object fromOp ) {
855- Object toOp = ((Function <Object , Object >) adaptor ).apply (fromOp );
867+ public void executeAdaptation (Object fromOp ) {
868+ //TODO: can we make this safer?
869+ @ SuppressWarnings ("unchecked" )
870+ Object op = ((Function <Object , Object >) adaptor ).apply (fromOp );
871+ adaptedOp = op ;
856872 // TODO: child adaptor support.
857- return toOp ;
858873 }
874+
875+ public Object getAdaptedOp () {return adaptedOp ; }
859876
860877 }
861878}
0 commit comments