public Object evaluate ( Input input ) { if ( noInput ( input ) ) { return NO_INPUT ; } String line = input . words ( ) . stream ( ) . collect ( Collectors . joining ( " " ) ) . trim ( ) ; String command = findLongestCommand ( line ) ; List < String > words = input . words ( ) ; if ( command != null ) { MethodTarget methodTarget = methodTargets . get ( command ) ; Availability availability = methodTarget . getAvailability ( ) ; if ( availability . isAvailable ( ) ) { List < String > wordsForArgs = wordsForArguments ( command , words ) ; Method method = methodTarget . getMethod ( ) ; Thread commandThread = Thread . currentThread ( ) ; Object sh = Signals . register ( "INT" , ( ) -> commandThread . interrupt ( ) ) ; try { Object [ ] args = resolveArgs ( method , wordsForArgs ) ; validateArgs ( args , methodTarget ) ; return ReflectionUtils . invokeMethod ( method , methodTarget . getBean ( ) , args ) ; } catch ( UndeclaredThrowableException e ) { if ( e . getCause ( ) instanceof InterruptedException || e . getCause ( ) instanceof ClosedByInterruptException ) { Thread . interrupted ( ) ; // to reset interrupted flag } return e . getCause ( ) ; } catch ( Exception e ) { return e ; } finally { Signals . unregister ( "INT" , sh ) ; } } else { return new CommandNotCurrentlyAvailable ( command , availability ) ; } } else { return new CommandNotFound ( words ) ; } }
Evaluate a single line of input from the user by trying to map words to a command and arguments .