module Sbuilder # Facade to Sbuilder for api loaders. # # Class implements following service groups # # - for controller to configure the facade (this part is not visible for api) # # - for api loader to read/cache api configuration, to create # model objects, and build sbuilder model # class ApiLoaderFacade extend Forwardable # for easy delegation # @attr [Boolean] infrastructureServices generate response, default 'false' attr_reader :infrastructureServices # @attr [Boolean] interfaceService genarate interface process, default 'true' attr_reader :interfaceServices # string to prefix to all definitions (default 'nil' ie. no # prefix). Allow homonymous API definition names ie. same # name in separata definitions. attr_reader :namespace attr_reader :cacheFile # controller sets before # loader called # facade collaborators attr_reader :factory # to create stuff attr_accessor :controller # get sets when load starts def_delegators :controller, :modelDefinition, # :modelInterface def_delegators :factory, :createParamSet, # @return[Sbuilder::ParamSet] :createParameter # @return[Sbuilder::Parameter] # ------------------------------------------------------------------ # progname for logger PROGNAME = nil # progname for logger default class name include Sbuilder::Utils::MyLogger # mix logger # ------------------------------------------------------------------ # @!group Construtor def initialize( factory, options = {} ) @logger = getLogger( PROGNAME, options ) @logger.info( "#{__method__} initialized" ) # collaborators init setFactory( factory ) @controller = nil # configuration init configureInfrastructureService( false ) configureInterfaceService( true ) @namespace = nil @cacheFile = nil @options = options end # @!endgroup # ------------------------------------------------------------------ # @!group Prepare Facade # Allow facade to access controller services # @param controller [Sbuilder::Controller] controller sets self def setController( controller ) @controller = controller end # Facade delagates the task to create new objects to `factory # @param factory [Sbuilder::Factory] to create new obejcts def setFactory( factory ) @factory = factory end ## # Tag all interfaces created using this facadate with property 'infrastructureServices' # # @param [Boolean] infrastructureServices true/false set on all interfaces # def configureInfrastructureService( infrastructureServices ) @infrastructureServices = infrastructureServices end ## # Tag all interfaces created using this facadate with property 'interfaceService' def configureInterfaceService( interfaceServices ) @interfaceServices = interfaceServices end # Prefix all definititions with "#{namespace}." string # # @param [String] namespace to prefix to all definitions # def configureNamespace( namespace ) @namespace = namespace end # Cache string read into 'cacheFile' # # @param [String] cacheFile name of file to cache content in this facade # def setInterfaceCacheFilePath( cacheFile ) @cacheFile = cacheFile end # @!endgroup # ------------------------------------------------------------------ # @!group Cache API Metadata # Reader service: read String of interface definitions from # 'location'. The string is cached in '@cacheFile', which # controller has configured. # # @param [String] location uri/file/block parameter from which to # read the string # # @param [yield] blk yield block to read if no block given use # 'Sbuilder::Utils::NetIo.read_lines'. Block should return a # string. # # @return [String] read from 'location' (or from @cacheFile) def read_cached( location, &blk ) # return cached line = get_cached return line if line if block_given? line = yield( location ) else line = Sbuilder::Utils::NetIo.read_lines( location ) end cache_line( line ) return line end # Read previously cached content (@see cache_line) # @param what [String] sub-content in cache # @return [String] cached content (nil if no cached content def get_cached( what=nil ) Sbuilder::Utils::FileIo.cache_read( get_cachefile(what) ) if doCache? end # Service for loader to save 'line' into cache # @param line [String] content to store # @param what [String] sub-content in cache def cache_line( line, what=nil ) Sbuilder::Utils::FileIo.cache_write( get_cachefile(what), line ) if doCache? && line end # @return [Boolean] true if cache i.e. when cacheFile defined def doCache? !cacheFile.nil? end # Return cache directory location from opitions # # @return [String] path to cache -directory def getCacheDir controller.getCacheDir end # @!endgroup # ------------------------------------------------------------------ # @!group Add to Sbuilder # Add 'newDefinition' to model # @param [Sbuilder::ParamSetDef] newDefinition definition to add def modelDefinition( newDefinition ) controller.modelDefinition( newDefinition ) end # Add 'newInterface' to model # @param [Sbuilder::ParamSet_If] newInterface interface to add def modelInterface( newInterface ) controller.modelInterface( newInterface ) end # @!endgroup # ------------------------------------------------------------------ # @!group Construct Model Objects # # @param [String] definitionName name of defintition to create # @param [Boolean] isArray true if array defined # # @return [Sbuilder::ParamSetDef] New definition object created def newDefinition( definitionName, isArray=false ) paramSet = createParamSet( Sbuilder::Constants::DEFINITION ) # optionally prefix within namespace definitionName = namespacedReferenceName( definitionName ) paramSet.setDefinition( definitionName ) paramSet.setIsArray( isArray ) return paramSet end # Create a function definition (parameter set) # # @param [String] definitionName name of defintition to create # @param [Boolean] isArray true if array defined # # @return [Sbuilder::ParamSetDefFunc] New definition object created def newFunctionDefinition( definitionName, isArray=false ) paramSet = createParamSet( Sbuilder::Constants::DEFINITION_FUNCTION ) # optionally prefix within namespace definitionName = namespacedReferenceName( definitionName ) paramSet.setDefinition( definitionName ) paramSet.setIsArray( isArray ) return paramSet end # Create new interface paramtereter set (and a response parameter # set) # # @param [String] path of restfull interface operation # # @param [String] op rest operation (get, put, post,...), defaults # to 'response' (ie. definiting return from a operation) # # @return [Sbuilder::ParamSet_If] New interface param set createds # for request. Use #response to access response object. def newInterface( path, op ) interfaceParamSet = newParamset( path, op ) paramSetResponse = newParamset( path ) interfaceParamSet.setResponse( paramSetResponse ) return interfaceParamSet end # Cretate new pojo for a simple paramter # @param [String] name of the simple paramter to create # @param [Boolean] isArray true if array # @return [Sbuilder::Parameter_Dom] new parmater created def newParameter( name, isArray=false ) swagger_parameter = createParameter( Sbuilder::Constants::PARAMETER ) swagger_parameter.setName( name ) # default for parameter 'not array' - set exlicitely array swagger_parameter.setIsArray( isArray ) return swagger_parameter end ## # Add +paramter+ to +parameterSet+ # # @param [ParamSet|ParamSetDef|ParamSet_If] paramSet where to add to # # @param [Parameter] parameter to add # # @param [String] name of domain to assign to +parameter+ def addParameter( paramSet, parameter, domain_name=nil ) paramSet.addParameter( parameter ) configParameterDomain( parameter, domain_name ) if domain_name end ## # Add +paramter+ to +parameterSet+ response # # @param [ParamSet_If] paramSet of the response where to add to # # @param [Parameter] parameter to add # # @param [String] name of domain to assign to +parameter+ def addResponseParameter( paramSet, parameter, domain_name=nil ) responseParamSet = paramSet.response responseParamSet.addParameter( parameter ) configParameterDomain( parameter, domain_name ) if domain_name end ## # Set +domain_name+ to +parameter+ # # @param [Parameter] parameter to add # # @param [String] name of domain to assign to +parameter+ private def configParameterDomain( parameter, domain_name ) if !parameter.is_a?(Parameter_Dom) then msg = <<-EOS Only domain parameters can assgined domain In this case domain '#{domain_name}' was assigned to #{parameter.class} EOS @logger.error "#{__method__}, msg" raise PluginException, msg end # call static busines rule to set 'domain' on 'parameter' in model context ResolverRuleMatch.setDomain( parameter, domain_name, controller.model ) end # Create new pojo for a reference to a definition # # @param [String] name of the simple paramter to create # @param [String] referenceName definition name referenced # @param [Boolean] isArray true if array # @return [Sbuilder::Parameter_Ref] new parmater created def newParameterReference( name, referenceName, isArray ) refParameter = createParameter( Sbuilder::Constants::PARAMETER_REF ) refParameter.setName( name ) # namespace.name referenceName = namespacedReferenceName( referenceName ) refParameter.setReference( referenceName ) refParameter.setIsArray( isArray ) return refParameter end # @!endgroup # ------------------------------------------------------------------ # @!group domain ## # Add +domainName+ to sbuilder. Pass +domainValues+ to controller # using +setApplicationDomainValues+ api if defined. # # @param [String] domainName to define # # @param [String:Array] domainValues e.g. literals in application # def defineDomain( domainName, domainValues = nil ) controller.domainEncountered( domainName ) controller.setApplicationDomainValues( domainName, domainValues ) if domainValues && domainValues.is_a?( Array ) && domainValues.any? end # @!endgroup # ------------------------------------------------------------------ # @!group Access framework context ## # Return array of base metatypes in sbuilder context # # @return [Hash] baseMetatypes # @option baseMetatype [Symbol] :name of metatype # @option baseMetatype [Symbol] :desc metatype description def baseMetatypes controller.baseMetatypes end # @!endgroup # ------------------------------------------------------------------ # @!group Miscellaneous Operations # # @return [String] semver number def version Sbuilder::version end # @param logname [String] progname to set on logger # @return [Logger] new logger object def createLogger( logname ) getLogger( logname, @options ) end # @!endgroup # ------------------------------------------------------------------ # Private private # @return [Sbuilder::ParamSet_If] New interface param set created def newParamset( path, op ='response' ) interfaceParamSet = createParamSet( Sbuilder::Constants::INTERFACE_OPERATION ) interfaceParamSet.setIdentity( path, op ) # infrastructureService (capability to return response), and # infrastructureService (interface process) use values set using # configure* -methods interfaceParamSet.setInfrastructureService( infrastructureServices ) interfaceParamSet.setInterfaceService( interfaceServices ) return interfaceParamSet end # @return [String] path to cachefile def get_cachefile( what ) "#{cacheFile}#{ what ? '.' + what : '' }" end # @return [String] 'definitionName' possible prefixed with 'namespace' def namespacedReferenceName( definitionName ) if namespace definitionName = "#{namespace}.#{definitionName}" end return definitionName end end # class ApiLoaderFacade end # module