Class: Plist4r::Backend
- Defined in:
-
lib/plist4r/backend.rb,
lib/plist4r/backend_base.rb,
lib/plist4r/backend/test/output.rb,
lib/plist4r/backend/test/harness.rb,
lib/plist4r/backend/test/data_types.rb
Direct Known Subclasses
Modules
Instance Methods
Overview
This class is the Backend broker. The purpose of this object is to manage and handle API calls, passing them over to the appropriate Plist4r backends. Also see the Backends Rdoc page.
Constant Summary
- ApiMethods =
The list backend API methods. A Plist4r::Backend should implement 1 or more of these methods
%w[ from_xml from_binary from_gnustep to_xml to_binary to_gnustep ]
- PrivateApiMethods =
The set of Plist4r API methods which are generated by the #generic_call method These methods don’t need to be implemented by a Plist4r::Backend
%w[ from_string open save ]
- PlistCacheApiMethods =
The set of Plist4r API methods with are invoked by Plist4r::PlistCache
%w[from_string to_xml to_binary to_gnustep open save]
Constructor Details
- (Backend) initialize(plist, *args, &blk)
A new instance of Backend. A single Backend will exist for the the life of the Plist object. The attribute @plist is set during initialization and refers back to the plist instance object.
25 26 27 |
# File 'lib/plist4r/backend.rb', line 25 def initialize plist, *args, &blk @plist = plist end |
Instance Method Details
- (Object) call(method_sym)
Call a Plist4r API Method. Here, we usually pass a Plist4r::Plist object as one of the parameters, which will also contain all the input data to work on.
This function loops through the array of available backends, and calls the first backend found to implement the appropriate fullfilment request.
If the request fails, the call is re-executed on the next available backend.
The plist object is updated in-place and also usually placed as the return argument.
91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 |
# File 'lib/plist4r/backend.rb', line 91 def call method_sym raise "Unsupported api call #{method_sym.inspect}" unless PlistCacheApiMethods.include? method_sym.to_s exceptions = [] generic_call_exception = nil @plist.backends.each do |b_sym| backend = eval "Plist4r::Backend::#{b_sym.to_s.camelcase}" begin if backend.respond_to?(method_sym) && method_sym != :from_string Timeout::timeout(Plist4r::Config[:backend_timeout]) do return eval("#{backend}.#{method_sym} @plist") end elsif PrivateApiMethods.include? method_sym.to_s result = generic_call backend, method_sym if result.is_a? Exception generic_call_exception = result else return result end end rescue LoadError exceptions << $! rescue RuntimeError exceptions << $! rescue SyntaxError exceptions << $! rescue Exception exceptions << $! rescue Timeout::Error exceptions << $! rescue exceptions << $! end if Config[:raise_any_failure] && exceptions.first raise exceptions.first end end if exceptions.empty? if generic_call_exception raise generic_call_exception else raise "Plist4r: No backend found to handle method #{method_sym.inspect}. Could not execute method #{method_sym.inspect} on plist #{@plist.inspect}" end else # $stderr.puts "Failure(s) while executing method #{method_sym.inspect} on plist #{@plist}." exceptions.each do |e| $stderr.puts e.inspect $stderr.puts e.backtrace.collect { |l| "\tfrom #{l}"}.join "\n" end # raise exceptions.first raise "Failure(s) while executing method #{method_sym.inspect} on plist #{@plist}." end end |
- (Object) generic_call(backend, method_sym)
Implements a generic version of each of the Plist4r Private API Calls.
32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 |
# File 'lib/plist4r/backend.rb', line 32 def generic_call backend, method_sym case method_sym when :save fmt = @plist.file_format || Plist4r::Config[:default_format] unless backend.respond_to? "to_#{fmt}" return Exception.new "Plist4r: No backend found to handle method :to_#{fmt}. Could not execute method :save on plist #{@plist.inspect}" end File.open(@plist.filename_path,'w') do |out| out << @plist.instance_eval { @plist_cache.send("to_#{fmt}".to_sym) } end when :open unless @open_fmt @plist.instance_eval "@from_string = File.read(filename_path)" @open_fmt = Plist4r.string_detect_format @plist.from_string end fmt = @open_fmt if backend.respond_to? "from_#{fmt}" @from_string_fmt = @open_fmt @open_fmt = nil @plist.instance_eval { @plist_cache.send :from_string } else return Exception.new "Plist4r: No backend found to handle method :from_#{fmt}. Could not execute method :open on plist #{@plist.inspect}" end when :from_string unless @from_string_fmt @from_string_fmt = Plist4r.string_detect_format @plist.from_string end fmt = @from_string_fmt if backend.respond_to? "from_#{fmt}" @from_string_fmt = nil Timeout::timeout(Plist4r::Config[:backend_timeout]) do backend.send("from_#{fmt}".to_sym, @plist) end @plist.file_format fmt @plist else return Exception.new "Plist4r: No backend found to handle method :from_#{fmt}. Could not execute method :from_string on plist #{@plist.inspect}" end end end |