@ SuppressWarnings ( "unchecked" ) public < Input , Output > Adapter < Input , Output > findAdapter ( Object in , Class < Input > input , Class < Output > output ) { ArrayList < Adapter > acceptInput = new ArrayList <> ( ) ; ArrayList < Adapter > matching = new ArrayList <> ( ) ; for ( Adapter a : adapters ) { if ( ! a . getInputType ( ) . isAssignableFrom ( input ) ) continue ; if ( ! a . canAdapt ( in ) ) continue ; acceptInput . add ( a ) ; if ( output . equals ( a . getOutputType ( ) ) ) return a ; if ( output . isAssignableFrom ( a . getOutputType ( ) ) ) matching . add ( a ) ; } if ( acceptInput . isEmpty ( ) ) return null ; if ( matching . size ( ) == 1 ) return matching . get ( 0 ) ; if ( ! matching . isEmpty ( ) ) return getBest ( matching ) ; LinkedList < LinkedList < Adapter > > paths = findPathsTo ( input , acceptInput , output ) ; LinkedList < Adapter > best = null ; while ( ! paths . isEmpty ( ) ) { LinkedList < Adapter > path = paths . removeFirst ( ) ; if ( best != null && best . size ( ) <= path . size ( ) ) continue ; Object o = in ; boolean valid = true ; int i = 0 ; for ( Adapter a : path ) { if ( ! a . canAdapt ( o ) ) { valid = false ; break ; } if ( i == path . size ( ) - 1 ) break ; // we are on the last, so no need to do it i ++ ; try { o = a . adapt ( o ) ; } catch ( Exception e ) { valid = false ; break ; } } if ( valid ) best = path ; } if ( best == null ) return null ; return new LinkedAdapter ( best ) ; }
Search for an adapter .