Class: Xap::XapMessage

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

Overview

Base class for all xAP message types. Registered subclasses must implement a parse method that accepts the message hash as its first parameter.

Direct Known Subclasses

XapHeartbeat, XapUnsupportedMessage

Constant Summary collapse

@@msgtypes =
{}

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(msgclass, src_addr, src_uid, target_addr = nil) ⇒ XapMessage

msgclass - the message’s class src_addr - the message’s source address src_uid - the message’s source UID (TODO: merge with XapAddress?) target_addr - the message’s target address, or nil for no target



57
58
59
60
61
62
63
64
65
66
67
68
69
70
# File 'lib/xap/xap_msg.rb', line 57

def initialize msgclass, src_addr, src_uid, target_addr = nil
	raise 'Do not instantiate XapMessage directly (use a subclass)' if self.class == XapMessage
	raise 'src_addr must be an XapAddress' unless src_addr.is_a? XapAddress
	raise 'target_addr must be nil or an XapAddress' unless target_addr.nil? || target_addr.is_a?(XapAddress)

	@src_addr = src_addr
	@target_addr = target_addr
	@version = 12
	@hop = 1
	@uid = src_uid
	@msgclass = msgclass
	@blocks = {}
	@headers = {}
end

Instance Attribute Details

#headernameObject

Returns the value of attribute headername.



10
11
12
# File 'lib/xap/xap_msg.rb', line 10

def headername
  @headername
end

#hopObject

Returns the value of attribute hop.



10
11
12
# File 'lib/xap/xap_msg.rb', line 10

def hop
  @hop
end

#msgclassObject

Returns the value of attribute msgclass.



10
11
12
# File 'lib/xap/xap_msg.rb', line 10

def msgclass
  @msgclass
end

#src_addrObject

Returns the value of attribute src_addr.



10
11
12
# File 'lib/xap/xap_msg.rb', line 10

def src_addr
  @src_addr
end

#target_addrObject

Returns the value of attribute target_addr.



10
11
12
# File 'lib/xap/xap_msg.rb', line 10

def target_addr
  @target_addr
end

#uidObject

Returns the value of attribute uid.



10
11
12
# File 'lib/xap/xap_msg.rb', line 10

def uid
  @uid
end

#versionObject

Returns the value of attribute version.



10
11
12
# File 'lib/xap/xap_msg.rb', line 10

def version
  @version
end

Class Method Details

.parse(data) ⇒ Object

Parses the given data as an xAP message. If the message type does not have a registered handler, an exception will be raised



14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
# File 'lib/xap/xap_msg.rb', line 14

def self.parse data
	raise 'data must be (convertible to) a String' unless data.respond_to? :to_s

	msghash = Xap::Parser::ParseXap.simple_parse data.to_s

	headername = msghash.keys[0].downcase
	raise "No handlers defined for #{headername} message headers." unless @@msgtypes[headername]

	classname = msghash[headername]['class']
	raise 'Message lacks a class field in its header.' unless classname || @@msgtypes[headername][nil]
	classname.downcase!

	handler = @@msgtypes[headername][classname] || @@msgtypes[headername][nil]
	raise "No handler defined for #{headername}/#{classname} messages." unless handler

	handler.parse msghash
end

.register_class(klass, msgclass, headername = 'xap-header') ⇒ Object

Registers the given klass as the handler for msgclass messages, with the header block called headername (‘xap-header’ by default).

Specify nil for msgclass to register a fallback handler for messages with the given header name that don’t have a specific class handler registered.



38
39
40
41
42
43
44
45
46
47
48
49
50
51
# File 'lib/xap/xap_msg.rb', line 38

def self.register_class klass, msgclass, headername='xap-header'
	unless klass.is_a?(Class) && klass < XapMessage
		raise "klass must be a Class that inherits XapMessage, not #{klass.inspect}"
	end
	raise 'msgclass must be nil or a String' unless msgclass.nil? || msgclass.is_a?(String)

	Xap.log "Registered support for #{headername}/#{msgclass} messages via #{klass.name}"

	# TODO: Support regex for msgclass?
	headername.downcase!
	msgclass.downcase! if msgclass.is_a? String
	@@msgtypes[headername] = @@msgtypes[headername] || {}
	@@msgtypes[headername][msgclass] = klass
end

Instance Method Details

#to_sObject

Returns a string representation of the message suitable for transmission on the network.



74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
# File 'lib/xap/xap_msg.rb', line 74

def to_s
	s = "#{headername}\n" +
		"{\n" +
		"v=#{@version}\n" +
	"hop=#{@hop}\n" +
	"uid=#{@uid}\n" +
	"class=#{@msgclass}\n" +
	"source=#{@src_addr}\n"

	s << "target=#{@target_addr}\n" if @target_addr

	if @headers
		@headers.each do |k, v|
			s << "#{k}=#{v}\n"
		end
	end

	s << "}\n"

	if @blocks
		@blocks.each do |name, block|
			s << "#{name}\n{\n"
			block.each do |k, v|
				s << "#{k}=#{v}\n"
			end
			s << "}\n"
		end
	end

	s
end

#uid_endpointObject

Returns the last two digits of the UID



107
108
109
# File 'lib/xap/xap_msg.rb', line 107

def uid_endpoint
	@uid[-2, 2]
end