A singleton factory class offering convenient access to all available renderer classes. Factory can be customized using the `required_methods` and `namespace` attributes.
@attr ::required_methods [Array] list of required renderer methods @attr namespace [Module] module containing renderer candidates
@author Boris Parak <parak@cesnet.cz>
Parent namespace of all supported renderer classes
Methods expected on supported renderer classes
Returns all classes from the given namespace.
@param namespace [Module] base namespace @return [Array] list of classes
# File lib/occi/core/renderer_factory.rb, line 187 def classes_from(namespace) constants_from(namespace).select { |const| const.is_a? Class } end
Returns all constants from the given namespace. The list may contain constants other than classes, from the given namespace and needs to be refined further.
@param namespace [Module] base namespace @return [Array] list of constants
# File lib/occi/core/renderer_factory.rb, line 174 def constants_from(namespace) unless namespace.is_a? Module raise Occi::Core::Errors::RendererError, "#{namespace.inspect} " 'is not a Module' end logger.debug "RendererFactory looking for renderers in #{namespace}" namespace.constants.collect { |const| namespace.const_get(const) } end
Returns the default renderer namespace.
@return [Module] base namespace
# File lib/occi/core/renderer_factory.rb, line 164 def namespace NAMESPACE end
Constructs an instance of the `RendererFactory` class. Since this class is a singleton, `new` (or `initialize`) are not supposed to be called directly. Use attribute accessors to change settings on existing factories.
@param args [Hash] hash with factory settings @option args [Array] :required_methods (`REQUIRED_METHODS`) list of required renderer methods @option args [Module] :namespace (`NAMESPACE`) module containing renderer candidates
# File lib/occi/core/renderer_factory.rb, line 31 def initialize(args = {}) default_args! args logger.debug "Initializing RendererFactory with #{args.inspect}" @required_methods = args.fetch(:required_methods) @namespace = args.fetch(:namespace) reload! end
Lists default methods required from any supported renderer.
@return [Array] list of method symbols
# File lib/occi/core/renderer_factory.rb, line 157 def required_methods REQUIRED_METHODS end
Lists available rendering `format`s.
@example
formats # => ['text', 'json', 'headers']
@return [Array] list of formats, as Strings
# File lib/occi/core/renderer_factory.rb, line 53 def formats renderers.keys end
# File lib/occi/core/renderer_factory.rb, line 42 def reload! logger.debug 'Clearing RendererFactory cache for renderer reload' @ravail_cache = nil end
Checks whether the given object can act as a renderer.
@example
renderer? TextRenderer # => true renderer? NilClass # => false
@param candidate [Object, Class] object or class to check @return [TrueClass, FalseClass] result (`true` for renderer, else `false`)
# File lib/occi/core/renderer_factory.rb, line 111 def renderer?(candidate) begin renderer_with_methods! candidate renderer_with_formats! candidate rescue Occi::Core::Errors::RendererError => ex logger.debug "Renderer validation failed with #{ex.message}" return false end candidate.renderer? end
Lists available renderers as an Array of renderer classes.
@example
renderer_classes #=> [Occi::Core::Renderers::TextRenderer]
@return [Array] list of renderer classes
# File lib/occi/core/renderer_factory.rb, line 99 def renderer_classes self.class.classes_from(namespace).select { |cand| renderer? cand } end
Returns a renderer corresponding with the given `format`. If no such renderer exists, `Occi::Core::Errors::RenderingError` error is raised.
@example
renderer_for 'text' # => Occi::Core::Renderers::TextRenderer renderer_for 'tewat?' # => !Error: Occi::Core::Errors::RenderingError!
@param format [String] over-the-wire format @return [Class] factory renderer corresponding to `format`
# File lib/occi/core/renderer_factory.rb, line 85 def renderer_for(format) if format.blank? raise Occi::Core::Errors::RenderingError, 'Cannot return a renderer for an unspecified format' end renderers[format] || raise(Occi::Core::Errors::RenderingError, "No renderer for #{format.inspect}") end
Ensures that the renderer candidate passed as an argument exposes supported formats. If that is not the case, an `Occi::Core::Errors::RendererError` error is raised.
@param candidate [Object, Class] object or class to check
# File lib/occi/core/renderer_factory.rb, line 142 def renderer_with_formats!(candidate) unless candidate.respond_to?(:formats) raise Occi::Core::Errors::RendererError, "#{candidate.inspect} " "does not respond to 'formats'" end return unless candidate.formats.blank? raise Occi::Core::Errors::RendererError, "#{candidate.inspect} " 'does not expose any supported formats' end
Ensures that the renderer candidate passed as an argument exposes all required methods. If that is not the case, an `Occi::Core::Errors::RendererError` error is raised.
@param candidate [Object, Class] object or class to check
# File lib/occi/core/renderer_factory.rb, line 128 def renderer_with_methods!(candidate) required_methods.each do |method| unless candidate.respond_to?(method) raise Occi::Core::Errors::RendererError, "#{candidate.inspect} " "does not respond to #{method.inspect}" end end end
Lists available renderers as a Hash mapping `format` to `Renderer` class.
@example
renderers # => { 'text' => TextRenderer }
@return [Hash] map of available renderers, keyed by `format`
# File lib/occi/core/renderer_factory.rb, line 63 def renderers return @ravail_cache if @ravail_cache @ravail_cache = {} renderer_classes.each do |rndr_klass| logger.debug "RendererFactory registering #{rndr_klass} for #{rndr_klass.formats}" rndr_klass.formats.each { |rndr_klass_f| @ravail_cache[rndr_klass_f] = rndr_klass } end @ravail_cache end