Class: A4Tools::TalkConsumer

Inherits:
Object
  • Object
show all
Defined in:
lib/talk_consumer.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(defn = nil) ⇒ TalkConsumer

Returns a new instance of TalkConsumer.



7
8
9
10
11
12
# File 'lib/talk_consumer.rb', line 7

def initialize(defn=nil)
  self.definition = translate_definition(defn)
  @constants = {}

  setup_constants
end

Instance Attribute Details

#definitionObject

Returns the value of attribute definition.



5
6
7
# File 'lib/talk_consumer.rb', line 5

def definition
  @definition
end

Instance Method Details

#[](key) ⇒ Object



228
229
230
# File 'lib/talk_consumer.rb', line 228

def [](key)
  return @constants[key.to_sym][:constant][:value]
end

#class_fields_match?(cls, obj) ⇒ Boolean

Returns:

  • (Boolean)


172
173
174
175
176
177
# File 'lib/talk_consumer.rb', line 172

def class_fields_match?(cls, obj)
  return false unless obj.is_a? Hash
  obj.keys.each { |key| return false if field_named(cls, key).nil? }
  cls[:field].each { |field| return false unless obj.has_key?(field[:name].to_sym) }
  true
end

#class_named(name) ⇒ Object



85
86
87
88
# File 'lib/talk_consumer.rb', line 85

def class_named(name)
  @definition[:class].each { |cls| return cls if name_matches?(cls[:name], name) }
  nil
end

#constant_named(name, collection = nil) ⇒ Object



121
122
123
124
125
126
127
128
129
130
131
132
133
# File 'lib/talk_consumer.rb', line 121

def constant_named(name, collection=nil)
  if collection.nil? then
    constant = @constants[name.to_sym]
    return constant[:constant], constant[:container] unless constant.nil?
    return nil, nil
  end

  collection = glossary_named(collection) || enumeration_named(collection) if collection.is_a? String
  return nil if collection.nil?

  set = collection[:term] || collection[:constant]
  return (set.select { |item| (item[:name] == name or item[:value] == name or item[:value] == name.to_f) }).first, collection
end

#enumeration_named(name) ⇒ Object



116
117
118
119
# File 'lib/talk_consumer.rb', line 116

def enumeration_named(name)
  @definition[:enumeration].select { |enum| return enum if name_matches?(enum[:name], name) }
  nil
end

#expand_name(name) ⇒ Object



218
219
220
221
222
223
224
225
226
# File 'lib/talk_consumer.rb', line 218

def expand_name(name)
  return nil if name.nil?
  [ :class_named, :glossary_named, :enumeration_named ].each do |method|
    thing = send(method, name)
    return thing[:name] unless thing.nil?
  end

  nil
end

#field_named(cls, name) ⇒ Object



80
81
82
83
# File 'lib/talk_consumer.rb', line 80

def field_named(cls, name)
  cls[:field].each { |field| return field if field[:name] == name.to_s }
  nil
end

#get_field_from_object(object, field_name) ⇒ Object



188
189
190
191
192
193
194
195
196
197
# File 'lib/talk_consumer.rb', line 188

def get_field_from_object(object, field_name)
  m = field_name.to_s.match(/^([a-zA-Z0-9_]+)\[([0-9]+)\]$/)
  if m.nil? then
    return field_name, (object[field_name.to_sym] rescue nil)
  else
    name = m[1]
    value = object[name.to_sym][m[2].to_i] rescue nil
    return name, value
  end
end

#glossary_named(name) ⇒ Object



111
112
113
114
# File 'lib/talk_consumer.rb', line 111

def glossary_named(name)
  @definition[:glossary].select { |glossary| return glossary if name_matches?(glossary[:name], name) }
  nil
end

#guess_class(obj) ⇒ Object



179
180
181
182
183
184
185
186
# File 'lib/talk_consumer.rb', line 179

def guess_class(obj)
  return obj[:__class] if obj.has_key? :__class
  return "com.acres4.common.info.NamedObjectWrapper" if obj.has_key? :className
  return "com.acres4.common.info.JSONRPCResponse" if obj.has_key? :result and obj.has_key? :jsonrpc
  return "com.acres4.common.info.JSONRPCRequest" if obj.has_key? :request and obj.has_key? :jsonrpc
  @definition[:class].each { |cls| return cls[:name] if class_fields_match?(cls, obj) }
  nil
end

#locate_data(object, path, classhint = nil) ⇒ Object



199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
# File 'lib/talk_consumer.rb', line 199

def locate_data(object, path, classhint=nil)
  path = path.split(".") if path.is_a? String
  path = [] if path.nil?

  type = classhint || guess_class(object)
  return object, type if type.nil? or path.empty?

  cls = class_named(type)
  return nil if cls.nil?

  field_name, value = get_field_from_object(object, path.first)
  return nil if field_name.nil? or value.nil?

  field = field_named(cls, field_name)
  return nil if field.nil?

  locate_data(value, path[1..-1], field[:type].first)
end

#method_named(name, protocol = nil) ⇒ Object



95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
# File 'lib/talk_consumer.rb', line 95

def method_named(name, protocol=nil)
  protocol = protocol_named(protocol) if(protocol.is_a? String)
  if protocol.nil? then
    @definition[:protocol].each do |proto|
      next if proto[:method].nil?
      proto[:method].each do |m|
        next if !m.is_a? Hash || m[:name].nil?
        return m, proto if m[:name] == name
      end
    end

    return nil
  end
  return (protocol[:method].select { |method| method[:name] == name }).first, protocol
end

#methods_in_protocol(protocol) ⇒ Object



158
159
160
161
# File 'lib/talk_consumer.rb', line 158

def methods_in_protocol(protocol)
  protocol = protocol_named(name) if(protocol.is_a? String)
  protocol[:method]
end

#name_matches?(cls_name, name) ⇒ Boolean

Returns:

  • (Boolean)


57
58
59
# File 'lib/talk_consumer.rb', line 57

def name_matches?(cls_name, name)
  cls_name[-name.length .. -1] == name
end

#name_similar?(item_name, name) ⇒ Boolean

Returns:

  • (Boolean)


61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
# File 'lib/talk_consumer.rb', line 61

def name_similar?(item_name, name)
  item_name = item_name[:name] if item_name.is_a? Hash
  return false if item_name.nil?

  item_comps = item_name.split(".")
  comps = name.split(".")
  return true if name == item_name
  return true if item_name.end_with? name
  if item_comps.last.start_with? comps.last then
    return false if comps.length > item_comps.length
    comps[0..-2].reverse.each_index do |idx|
      return false unless item_comps[-1 - idx] == comps[idx]
    end
    return true
  end

  return false
end

#primitive?(type) ⇒ Boolean

Returns:

  • (Boolean)


47
48
49
50
51
52
53
54
55
# File 'lib/talk_consumer.rb', line 47

def primitive?(type)
  type = type[:type] if type.is_a? Hash
  type = type.first if type.is_a? Array
  primitives = [
    "uint8", "uint16", "uint32", "uint64",
    "int8", "int16", "int32", "int64",
    "string", "real", "bool", "object", "talkobject" ]
  primitives.include? type
end

#protocol_named(name) ⇒ Object



90
91
92
93
# File 'lib/talk_consumer.rb', line 90

def protocol_named(name)
  @definition[:protocol].each { |proto| return proto if proto[:name] == name }
  nil
end

#setup_constantsObject



163
164
165
166
167
168
169
170
# File 'lib/talk_consumer.rb', line 163

def setup_constants
  @definition[:enumeration].each do |enum|
    enum[:constant].each { |constant| @constants[constant[:name].to_sym] = { constant:constant, container:enum } }
  end
  @definition[:glossary].each do |glossary|
    glossary[:term].each { |term| @constants[term[:name].to_sym] = { constant:term, container:glossary } }
  end
end

#things_named_like(name, allowed = nil, exclude = [:field]) ⇒ Object



152
153
154
155
156
# File 'lib/talk_consumer.rb', line 152

def things_named_like(name, allowed=nil, exclude=[:field])
  allowed ||= @definition.keys
  allowed = [allowed] unless allowed.is_a? Array
  allowed.inject([]) { |total, key| total + things_named_recursive(name, @definition[key], exclude) }
end

#things_named_recursive(name, collection, exclude) ⇒ Object



135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
# File 'lib/talk_consumer.rb', line 135

def things_named_recursive(name, collection, exclude)
  total = []
  if collection.is_a? Array then
    collection.each do |item|
      next if item.nil?
      total += things_named_recursive(name, item, exclude)
    end
  elsif collection.is_a? Hash then
    total.push(collection) if name_similar?(collection, name)
    collection.each do |key, item|
      total += things_named_recursive(name, item, exclude) unless (item.nil? or exclude.include? key)
    end
  end

  total
end

#translate_definition(defn) ⇒ Object



27
28
29
30
31
32
33
34
35
36
37
38
39
40
# File 'lib/talk_consumer.rb', line 27

def translate_definition(defn)
  # Accept the definition if it's already a hash or nil
  return defn if defn.is_a? Hash or defn.nil?

  # Try to parse the definition as a JSON string, then try to treat it as a path to a file
  [ lambda { JSON.parse(defn) }, lambda { JSON.parse(IO.read(defn)) } ].each do |func|
    begin
      return func.call
    rescue JSON::ParserError
    end
  end

  nil
end

#truncated_name(name) ⇒ Object



42
43
44
45
# File 'lib/talk_consumer.rb', line 42

def truncated_name(name)
  name = name[:name] if name.is_a? Hash
  name.to_s.split(".").last
end