blob: 902c05c29737d24e93055893a2a7332d041b76eb [file] [log] [blame]
#
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
#
require "qpid/spec"
module Qpid08
module Spec
include Qpid::Spec
# XXX: workaround for ruby bug/missfeature
Reference = Reference
class Root
fields(:major, :minor, :classes, :constants, :domains)
def find_method(name)
classes.each do |c|
c.methods.each do |m|
if name == m.qname
return m
end
end
end
return nil
end
end
class Constant
fields(:name, :id, :type, :docs)
end
class Domain
fields(:name, :type)
end
class Class
fields(:name, :id, :handler, :fields, :methods, :docs)
end
class Method
fields(:name, :id, :content?, :responses, :synchronous?, :fields,
:docs)
def init()
@response = false
end
attr :parent, true
def response?; @response end
def response=(b); @response = b end
def qname
:"#{parent.name}_#{name}"
end
end
class Field
fields(:name, :id, :type, :docs)
def default
case type
when :bit then false
when :octet, :short, :long, :longlong then 0
when :shortstr, :longstr then ""
when :table then {}
end
end
end
class Doc
fields(:type, :text)
end
class Container08 < Container
def do_lookup(key)
case key
when Integer
return find {|x| x.id == key}
else
return super(key)
end
end
end
class Loader08 < Loader
def container()
return Container08.new()
end
def load_amqp()
Root.new(attr("major", :int), attr("minor", :int), load("class"),
load("constant"), load("domain"))
end
def load_class()
Class.new(attr("name", :name), attr("index", :int), attr("handler", :name),
load("field"), load("method"), load("doc"))
end
def load_method()
Method.new(attr("name", :name), attr("index", :int),
attr("content", :bool), load("response"),
attr("synchronous", :bool), load("field"), load("docs"))
end
def load_response()
name = attr("name", :name)
Reference.new {|spec, klass|
response = klass.methods[name]
if response.nil?
raise Exception.new("no such method: #{name}")
end
response
}
end
def load_field()
type = attr("type", :name)
if type.nil?
domain = attr("domain", :name)
type = Reference.new {|spec, klass|
spec.domains[domain].type
}
end
Field.new(attr("name", :name), @index, type, load("docs"))
end
def load_constant()
Constant.new(attr("name", :name), attr("value", :int), attr("class", :name),
load("doc"))
end
def load_domain()
Domain.new(attr("name", :name), attr("type", :name))
end
def load_doc()
Doc.new(attr("type", :symbol), text)
end
end
def self.load(spec)
case spec
when String
spec = File.new(spec)
end
doc = Document.new(spec)
spec = Loader08.new().load(doc.root)
spec.classes.each do |klass|
klass.traverse! do |o|
case o
when Reference
o.resolve(spec, klass)
else
o
end
end
klass.methods.each do |m|
m.parent = klass
m.responses.each do |r|
r.response = true
end
end
end
return spec
end
end
end