import { IClass } from "../../matching/IClass" ; import { ICommand } from "../api/ICommand" ; import { ICommandExecutor } from "../api/ICommandExecutor" ; import { ICommandMapping } from "../api/ICommandMapping" ; import { CommandPayload } from "../api/CommandPayload" ; import { IInjector } from "../../../framework/api/IInjector" ; import { applyHooks } from "../../../framework/impl/applyHooks" ; import { guardsApprove } from "../../../framework/impl/guardsApprove" ; import { instantiateUnmapped } from "../../../framework/impl/instantiateUnmapped" ; private export class CommandExecutor implements ICommandExecutor { private _injector : IInjector ; private _removeMapping : Function ; private _handleResult : Function ; param injector param removeMapping param handleResult constructor ( injector , removeMapping ? , handleResult ? ) { this . _injector = injector . createChild ( ) ; this . _removeMapping = removeMapping ; this . _handleResult = handleResult ; } inheritDoc public executeCommands ( mappings , payload ? ) { let length = mappings . length ; for ( let i = 0 ; i < length ; i ++ ) { this . executeCommand ( mappings [ i ] , payload ) ; } } inheritDoc public executeCommand ( mapping , payload ? ) { let hasPayload = payload && payload . hasPayload ( ) ; let injectionEnabled = hasPayload && mapping . payloadInjectionEnabled ; let command = null ; if ( injectionEnabled ) { this . mapPayload ( payload ) ; } if ( mapping . guards . length === 0 || guardsApprove ( mapping . guards , this . _injector ) ) { let commandClass = mapping . commandClass ; if ( mapping . fireOnce && this . _removeMapping ) { this . _removeMapping ( mapping ) ; } command = instantiateUnmapped < ICommand > ( this . _injector , commandClass ) ; if ( mapping . hooks . length > 0 ) { this . _injector . bind ( commandClass ) . toConstantValue ( command ) ; applyHooks ( mapping . hooks , this . _injector ) ; this . _injector . unbind ( commandClass ) ; } } if ( injectionEnabled ) { this . unmapPayload ( payload ) ; } if ( command ) { let executeMethod = command . execute . bind ( command ) ; let result = hasPayload && executeMethod . length > 0 ? executeMethod . apply ( command , payload . values ) : executeMethod ( ) ; if ( this . _handleResult ) { this . _handleResult ( result , command , mapping ) ; } } } private mapPayload ( payload ) { let i = payload . length ; while ( i -- ) { this . _injector . bind ( payload . classes [ i ] ) . toConstantValue ( payload . values [ i ] ) ; } } private unmapPayload ( payload ) { let i = payload . length ; while ( i -- ) { this . _injector . unbind ( payload . classes [ i ] ) ; } } }