jabber4r-revive 0.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.gitignore +4 -0
- data/.rspec +3 -0
- data/.travis.yml +8 -0
- data/CHANGELOG +45 -0
- data/Gemfile +3 -0
- data/Gemfile.lock +45 -0
- data/LICENSE +12 -0
- data/README.md +29 -0
- data/Rakefile +71 -0
- data/jabber4r-revive.gemspec +25 -0
- data/lib/jabber4r/bosh_session.rb +224 -0
- data/lib/jabber4r/connection.rb +258 -0
- data/lib/jabber4r/debugger.rb +61 -0
- data/lib/jabber4r/jid.rb +125 -0
- data/lib/jabber4r/protocol/iq.rb +260 -0
- data/lib/jabber4r/protocol/message.rb +246 -0
- data/lib/jabber4r/protocol/parsed_xml_element.rb +208 -0
- data/lib/jabber4r/protocol/presence.rb +160 -0
- data/lib/jabber4r/protocol/xml_element.rb +144 -0
- data/lib/jabber4r/protocol.rb +257 -0
- data/lib/jabber4r/rexml_1.8_patch.rb +16 -0
- data/lib/jabber4r/roster.rb +322 -0
- data/lib/jabber4r/session.rb +615 -0
- data/lib/jabber4r/vcard.rb +42 -0
- data/lib/jabber4r/version.rb +3 -0
- data/lib/jabber4r.rb +33 -0
- data/spec/lib/jabber4r/bosh_session_spec.rb +150 -0
- data/spec/lib/jabber4r/connection_spec.rb +174 -0
- data/spec/lib/jabber4r/debugger_spec.rb +36 -0
- data/spec/lib/jabber4r/jid_spec.rb +198 -0
- data/spec/spec_helper.rb +11 -0
- data/spec/support/mocks/tcp_socket_mock.rb +8 -0
- metadata +151 -0
@@ -0,0 +1,160 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
|
3
|
+
# License: see LICENSE
|
4
|
+
# Jabber4R - Jabber Instant Messaging Library for Ruby
|
5
|
+
# Copyright (C) 2002 Rich Kilmer <rich@infoether.com>
|
6
|
+
|
7
|
+
module Jabber::Protocol
|
8
|
+
##
|
9
|
+
# The presence class is used to construct presence messages to
|
10
|
+
# send to the Jabber service.
|
11
|
+
#
|
12
|
+
class Presence
|
13
|
+
attr_accessor :to, :from, :id, :type
|
14
|
+
|
15
|
+
# The state to show (chat, xa, dnd, away)
|
16
|
+
attr_accessor :show
|
17
|
+
|
18
|
+
# The status message
|
19
|
+
attr_accessor :status
|
20
|
+
attr_accessor :priority
|
21
|
+
|
22
|
+
##
|
23
|
+
# Constructs a Presence object w/the supplied id
|
24
|
+
#
|
25
|
+
# id:: [String] The message ID
|
26
|
+
# show:: [String] The state to show
|
27
|
+
# status:: [String] The status message
|
28
|
+
#
|
29
|
+
def initialize(id, show=nil, status=nil)
|
30
|
+
@id = id
|
31
|
+
@show = show if show
|
32
|
+
@status = status if status
|
33
|
+
end
|
34
|
+
|
35
|
+
##
|
36
|
+
# Generate a presence object for initial presence notification
|
37
|
+
#
|
38
|
+
# id:: [String] The message ID
|
39
|
+
# show:: [String] The state to show
|
40
|
+
# status:: [String] The status message
|
41
|
+
# return:: [Jabber::Protocol::Presence] The newly created Presence object
|
42
|
+
#
|
43
|
+
def self.gen_initial(id, show=nil, status=nil)
|
44
|
+
Presence.new(id, show, status)
|
45
|
+
end
|
46
|
+
|
47
|
+
##
|
48
|
+
# Generate a presence object w/show="normal" (normal availability)
|
49
|
+
#
|
50
|
+
# id:: [String] The message ID
|
51
|
+
# status:: [String=nil] The status message
|
52
|
+
# return:: [Jabber::Protocol::Presence] The newly created Presence object
|
53
|
+
#
|
54
|
+
def self.gen_normal(id, status=nil)
|
55
|
+
Presence.new(id, "normal", status)
|
56
|
+
end
|
57
|
+
|
58
|
+
##
|
59
|
+
# Generate a presence object w/show="chat" (free for chat)
|
60
|
+
#
|
61
|
+
# id:: [String] The message ID
|
62
|
+
# status:: [String=nil] The status message
|
63
|
+
# return:: [Jabber::Protocol::Presence] The newly created Presence object
|
64
|
+
#
|
65
|
+
def self.gen_chat(id, status=nil)
|
66
|
+
Presence.new(id, "chat", status)
|
67
|
+
end
|
68
|
+
|
69
|
+
##
|
70
|
+
# Generate a presence object w/show="xa" (extended away)
|
71
|
+
#
|
72
|
+
# id:: [String] The message ID
|
73
|
+
# status:: [String=nil] The status message
|
74
|
+
# return:: [Jabber::Protocol::Presence] The newly created Presence object
|
75
|
+
#
|
76
|
+
def self.gen_xa(id, status=nil)
|
77
|
+
Presence.new(id, "xa", status)
|
78
|
+
end
|
79
|
+
|
80
|
+
##
|
81
|
+
# Generate a presence object w/show="dnd" (do not disturb)
|
82
|
+
#
|
83
|
+
# id:: [String] The message ID
|
84
|
+
# status:: [String=nil] The status message
|
85
|
+
# return:: [Jabber::Protocol::Presence] The newly created Presence object
|
86
|
+
#
|
87
|
+
def self.gen_dnd(id, status=nil)
|
88
|
+
Presence.new(id, "dnd", status)
|
89
|
+
end
|
90
|
+
|
91
|
+
##
|
92
|
+
# Generate a presence object w/show="away" (away from resource)
|
93
|
+
#
|
94
|
+
# id:: [String] The message ID
|
95
|
+
# status:: [String=nil] The status message
|
96
|
+
# return:: [Jabber::Protocol::Presence] The newly created Presence object
|
97
|
+
#
|
98
|
+
def self.gen_away(id, status=nil)
|
99
|
+
Presence.new(id, "away", status)
|
100
|
+
end
|
101
|
+
|
102
|
+
##
|
103
|
+
# Generate a presence object w/show="unavailable" (not free for chat)
|
104
|
+
#
|
105
|
+
# id:: [String] The message ID
|
106
|
+
# status:: [String=nil] The status message
|
107
|
+
# return:: [Jabber::Protocol::Presence] The newly created Presence object
|
108
|
+
#
|
109
|
+
def self.gen_unavailable(id, status=nil)
|
110
|
+
p = Presence.new(id)
|
111
|
+
p.type="unavailable"
|
112
|
+
p
|
113
|
+
end
|
114
|
+
|
115
|
+
def self.gen_new_subscription(to)
|
116
|
+
p = Presence.new(Jabber.gen_random_id)
|
117
|
+
p.type = "subscribe"
|
118
|
+
p.to = to
|
119
|
+
p
|
120
|
+
end
|
121
|
+
|
122
|
+
def self.gen_accept_subscription(id, jid)
|
123
|
+
p = Presence.new(id)
|
124
|
+
p.type = "subscribed"
|
125
|
+
p.to = jid
|
126
|
+
p
|
127
|
+
end
|
128
|
+
|
129
|
+
def self.gen_accept_unsubscription(id, jid)
|
130
|
+
p = Presence.new(id)
|
131
|
+
p.type = "unsubscribed"
|
132
|
+
p.to = jid
|
133
|
+
p
|
134
|
+
end
|
135
|
+
|
136
|
+
##
|
137
|
+
# Generates the xml representation of this Presence object
|
138
|
+
#
|
139
|
+
# return:: [String] The presence XML message to send the Jabber service
|
140
|
+
#
|
141
|
+
def to_xml
|
142
|
+
e = XMLElement.new("presence")
|
143
|
+
e.add_attribute("id", @id) if @id
|
144
|
+
e.add_attribute("from", @from) if @from
|
145
|
+
e.add_attribute("to", @to) if @to
|
146
|
+
e.add_attribute("type", @type) if @type
|
147
|
+
e.add_child("show").add_data(@show) if @show
|
148
|
+
e.add_child("status").add_data(@status) if @status
|
149
|
+
e.add_child("priority") if @priority
|
150
|
+
e.to_s
|
151
|
+
end
|
152
|
+
|
153
|
+
##
|
154
|
+
# see _to_xml
|
155
|
+
#
|
156
|
+
def to_s
|
157
|
+
to_xml
|
158
|
+
end
|
159
|
+
end
|
160
|
+
end
|
@@ -0,0 +1,144 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
|
3
|
+
# License: see LICENSE
|
4
|
+
# Jabber4R - Jabber Instant Messaging Library for Ruby
|
5
|
+
# Copyright (C) 2002 Rich Kilmer <rich@infoether.com>
|
6
|
+
|
7
|
+
module Jabber::Protocol
|
8
|
+
##
|
9
|
+
# Utility class to create valid XML strings
|
10
|
+
#
|
11
|
+
class XMLElement
|
12
|
+
|
13
|
+
# The parent XMLElement
|
14
|
+
attr_accessor :parent
|
15
|
+
|
16
|
+
##
|
17
|
+
# Construct an XMLElement for the supplied tag and attributes
|
18
|
+
#
|
19
|
+
# tag:: [String] XML tag
|
20
|
+
# attributes:: [Hash = {}] The attribute hash[attribute]=value
|
21
|
+
def initialize(tag, attributes={})
|
22
|
+
@tag = tag
|
23
|
+
@elements = []
|
24
|
+
@attributes = attributes
|
25
|
+
@data = ""
|
26
|
+
end
|
27
|
+
|
28
|
+
##
|
29
|
+
# Adds an attribute to this element
|
30
|
+
#
|
31
|
+
# attrib:: [String] The attribute name
|
32
|
+
# value:: [String] The attribute value
|
33
|
+
# return:: [Jabber::Protocol::XMLElement] self for chaining
|
34
|
+
#
|
35
|
+
def add_attribute(attrib, value)
|
36
|
+
@attributes[attrib]=value
|
37
|
+
self
|
38
|
+
end
|
39
|
+
|
40
|
+
##
|
41
|
+
# Adds data to this element
|
42
|
+
#
|
43
|
+
# data:: [String] The data to add
|
44
|
+
# return:: [Jabber::Protocol::XMLElement] self for chaining
|
45
|
+
#
|
46
|
+
def add_data(data)
|
47
|
+
@data += data.to_s
|
48
|
+
self
|
49
|
+
end
|
50
|
+
|
51
|
+
##
|
52
|
+
# Sets the namespace for this tag
|
53
|
+
#
|
54
|
+
# ns:: [String] The namespace
|
55
|
+
# return:: [Jabber::Protocol::XMLElement] self for chaining
|
56
|
+
#
|
57
|
+
def set_namespace(ns)
|
58
|
+
@tag+=":#{ns}"
|
59
|
+
self
|
60
|
+
end
|
61
|
+
|
62
|
+
##
|
63
|
+
# Adds cdata to this element
|
64
|
+
#
|
65
|
+
# cdata:: [String] The cdata to add
|
66
|
+
# return:: [Jabber::Protocol::XMLElement] self for chaining
|
67
|
+
#
|
68
|
+
def add_cdata(cdata)
|
69
|
+
@data += "<![CDATA[#{cdata.to_s}]]>"
|
70
|
+
self
|
71
|
+
end
|
72
|
+
|
73
|
+
##
|
74
|
+
# Returns the parent element
|
75
|
+
#
|
76
|
+
# return:: [Jabber::Protocol::XMLElement] The parent XMLElement
|
77
|
+
#
|
78
|
+
def to_parent
|
79
|
+
@parent
|
80
|
+
end
|
81
|
+
|
82
|
+
##
|
83
|
+
# Adds a child to this element of the supplied tag
|
84
|
+
#
|
85
|
+
# tag:: [String] The element tag
|
86
|
+
# attributes:: [Hash = {}] The attributes hash[attribute]=value
|
87
|
+
# return:: [Jabber::Protocol::XMLElement] newly created child element
|
88
|
+
#
|
89
|
+
def add_child(tag, attributes={})
|
90
|
+
child = XMLElement.new(tag, attributes)
|
91
|
+
child.parent = self
|
92
|
+
@elements << child
|
93
|
+
return child
|
94
|
+
end
|
95
|
+
|
96
|
+
##
|
97
|
+
# Adds arbitrary XML data to this object
|
98
|
+
#
|
99
|
+
# xml:: [String] the xml to add
|
100
|
+
#
|
101
|
+
def add_xml(xml)
|
102
|
+
@xml = xml
|
103
|
+
end
|
104
|
+
|
105
|
+
##
|
106
|
+
# Recursively builds the XML string by traversing this element's
|
107
|
+
# children.
|
108
|
+
#
|
109
|
+
# format:: [Boolean] True to pretty-print (format) the output string
|
110
|
+
# indent:: [Integer = 0] The indent level (recursively more)
|
111
|
+
#
|
112
|
+
def to_xml(format, indent=0)
|
113
|
+
result = ""
|
114
|
+
result += " "*indent if format
|
115
|
+
result += "<#{@tag}"
|
116
|
+
@attributes.each {|attrib, value| result += (' '+attrib.to_s+'="'+value.to_s+'"') }
|
117
|
+
if @data=="" and @elements.size==0
|
118
|
+
result +="/>"
|
119
|
+
result +="\n" if format
|
120
|
+
return result
|
121
|
+
end
|
122
|
+
result += ">"
|
123
|
+
result += "\n" if format and @data==""
|
124
|
+
result += @data if @data!=""
|
125
|
+
@elements.each {|element| result+=element.to_xml(format, indent+4)}
|
126
|
+
result += @xml if not @xml.nil?
|
127
|
+
result += " "*indent if format and @data==""
|
128
|
+
result+="</#{@tag}>"
|
129
|
+
result+="\n" if format
|
130
|
+
return result
|
131
|
+
end
|
132
|
+
|
133
|
+
##
|
134
|
+
# Climbs to the top of this elements parent tree and then returns
|
135
|
+
# the to_xml XML string.
|
136
|
+
#
|
137
|
+
# return:: [String] The XML string of this element (from the topmost parent).
|
138
|
+
#
|
139
|
+
def to_s
|
140
|
+
return @parent.to_s if @parent
|
141
|
+
return to_xml(true)
|
142
|
+
end
|
143
|
+
end
|
144
|
+
end
|
@@ -0,0 +1,257 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
|
3
|
+
# License: see LICENSE
|
4
|
+
# Jabber4R - Jabber Instant Messaging Library for Ruby
|
5
|
+
# Copyright (C) 2002 Rich Kilmer <rich@infoether.com>
|
6
|
+
|
7
|
+
require "singleton"
|
8
|
+
require "socket"
|
9
|
+
|
10
|
+
module Jabber
|
11
|
+
class JabberConnectionException < RuntimeError
|
12
|
+
attr_reader :data
|
13
|
+
|
14
|
+
def initialize(writing, data)
|
15
|
+
@writing = writing
|
16
|
+
@data = data
|
17
|
+
end
|
18
|
+
|
19
|
+
def writing?
|
20
|
+
@writing
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
##
|
25
|
+
# The Protocol module contains helper methods for constructing
|
26
|
+
# Jabber protocol elements and classes that implement protocol
|
27
|
+
# elements.
|
28
|
+
#
|
29
|
+
module Protocol
|
30
|
+
|
31
|
+
USE_PARSER = :rexml # either :rexml or :xmlparser
|
32
|
+
|
33
|
+
##
|
34
|
+
# The parser to use for stream processing. The current
|
35
|
+
# available parsers are:
|
36
|
+
#
|
37
|
+
# * Jabber::Protocol::ExpatJabberParser uses XMLParser
|
38
|
+
# * Jabber::Protocol::REXMLJabberParser uses REXML
|
39
|
+
#
|
40
|
+
# return:: [Class] The parser class
|
41
|
+
#
|
42
|
+
def Protocol.Parser
|
43
|
+
if USE_PARSER==:xmlparser
|
44
|
+
Jabber::Protocol::ExpatJabberParser
|
45
|
+
else
|
46
|
+
Jabber::Protocol::REXMLJabberParser
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
##
|
51
|
+
# Generates an open stream XML element
|
52
|
+
#
|
53
|
+
# host:: [String] The host being connected to
|
54
|
+
# return:: [String] The XML data to send
|
55
|
+
#
|
56
|
+
def self.gen_open_stream(host)
|
57
|
+
return ('<?xml version="1.0" encoding="UTF-8" ?><stream:stream to="'+host+'" xmlns="jabber:client" xmlns:stream="http://etherx.jabber.org/streams">')
|
58
|
+
end
|
59
|
+
|
60
|
+
##
|
61
|
+
# Generates an close stream XML element
|
62
|
+
#
|
63
|
+
# return:: [String] The XML data to send
|
64
|
+
#
|
65
|
+
def self.gen_close_stream
|
66
|
+
return "</stream:stream>"
|
67
|
+
end
|
68
|
+
|
69
|
+
if USE_PARSER == :xmlparser
|
70
|
+
require 'xmlparser'
|
71
|
+
##
|
72
|
+
# The ExpatJabberParser uses XMLParser (expat) to parse the incoming XML stream
|
73
|
+
# of the Jabber protocol and fires ParsedXMLElements at the Connection
|
74
|
+
# instance.
|
75
|
+
#
|
76
|
+
class ExpatJabberParser
|
77
|
+
|
78
|
+
# status if the parser is started
|
79
|
+
attr_reader :started
|
80
|
+
|
81
|
+
##
|
82
|
+
# Constructs a parser for the supplied stream (socket input)
|
83
|
+
#
|
84
|
+
# stream:: [IO] Socket input stream
|
85
|
+
# listener:: [#receive(ParsedXMLElement)] The listener (usually a Jabber::Protocol::Connection instance
|
86
|
+
#
|
87
|
+
def initialize(stream, listener)
|
88
|
+
@stream = stream
|
89
|
+
def @stream.gets
|
90
|
+
super(">")
|
91
|
+
end
|
92
|
+
@listener = listener
|
93
|
+
end
|
94
|
+
|
95
|
+
##
|
96
|
+
# Begins parsing the XML stream and does not return until
|
97
|
+
# the stream closes.
|
98
|
+
#
|
99
|
+
def parse
|
100
|
+
@started = false
|
101
|
+
|
102
|
+
parser = XMLParser.new("UTF-8")
|
103
|
+
def parser.unknownEncoding(e)
|
104
|
+
raise "Unknown encoding #{e.to_s}"
|
105
|
+
end
|
106
|
+
def parser.default
|
107
|
+
end
|
108
|
+
|
109
|
+
begin
|
110
|
+
parser.parse(@stream) do |type, name, data|
|
111
|
+
begin
|
112
|
+
case type
|
113
|
+
when XMLParser::START_ELEM
|
114
|
+
case name
|
115
|
+
when "stream:stream"
|
116
|
+
openstream = ParsedXMLElement.new(name)
|
117
|
+
data.each {|key, value| openstream.add_attribute(key, value)}
|
118
|
+
@listener.receive(openstream)
|
119
|
+
@started = true
|
120
|
+
else
|
121
|
+
if @current.nil?
|
122
|
+
@current = ParsedXMLElement.new(name.clone)
|
123
|
+
else
|
124
|
+
@current = @current.add_child(name.clone)
|
125
|
+
end
|
126
|
+
data.each {|key, value| @current.add_attribute(key.clone, value.clone)}
|
127
|
+
end
|
128
|
+
when XMLParser::CDATA
|
129
|
+
@current.append_data(data.clone) if @current
|
130
|
+
when XMLParser::END_ELEM
|
131
|
+
case name
|
132
|
+
when "stream:stream"
|
133
|
+
@started = false
|
134
|
+
else
|
135
|
+
@listener.receive(@current) unless @current.element_parent
|
136
|
+
@current = @current.element_parent
|
137
|
+
end
|
138
|
+
end
|
139
|
+
rescue
|
140
|
+
puts "Error #{$!}"
|
141
|
+
end
|
142
|
+
end
|
143
|
+
rescue XMLParserError
|
144
|
+
line = parser.line
|
145
|
+
print "XML Parsing error(#{line}): #{$!}\n"
|
146
|
+
end
|
147
|
+
end
|
148
|
+
end
|
149
|
+
else # USE REXML
|
150
|
+
require 'rexml/document'
|
151
|
+
require 'rexml/parsers/sax2parser'
|
152
|
+
require 'rexml/source'
|
153
|
+
|
154
|
+
##
|
155
|
+
# The REXMLJabberParser uses REXML to parse the incoming XML stream
|
156
|
+
# of the Jabber protocol and fires ParsedXMLElements at the Connection
|
157
|
+
# instance.
|
158
|
+
#
|
159
|
+
class REXMLJabberParser
|
160
|
+
# status if the parser is started
|
161
|
+
attr_reader :started
|
162
|
+
|
163
|
+
##
|
164
|
+
# Constructs a parser for the supplied stream (socket input)
|
165
|
+
#
|
166
|
+
# stream:: [IO] Socket input stream
|
167
|
+
# listener:: [Object.receive(ParsedXMLElement)] The listener (usually a Jabber::Protocol::Connection instance
|
168
|
+
#
|
169
|
+
def initialize(stream, listener)
|
170
|
+
@stream = stream
|
171
|
+
|
172
|
+
# this hack fixes REXML version "2.7.3" and "2.7.4"
|
173
|
+
if REXML::Version=="2.7.3" || REXML::Version=="2.7.4"
|
174
|
+
def @stream.read(len=nil)
|
175
|
+
len = 100 unless len
|
176
|
+
super(len)
|
177
|
+
end
|
178
|
+
def @stream.gets(char=nil)
|
179
|
+
super(">")
|
180
|
+
end
|
181
|
+
def @stream.readline(char=nil)
|
182
|
+
super(">")
|
183
|
+
end
|
184
|
+
def @stream.readlines(char=nil)
|
185
|
+
super(">")
|
186
|
+
end
|
187
|
+
end
|
188
|
+
|
189
|
+
@listener = listener
|
190
|
+
@current = nil
|
191
|
+
end
|
192
|
+
|
193
|
+
##
|
194
|
+
# Begins parsing the XML stream and does not return until
|
195
|
+
# the stream closes.
|
196
|
+
#
|
197
|
+
def parse
|
198
|
+
#puts "PARSE"
|
199
|
+
@started = false
|
200
|
+
begin
|
201
|
+
parser = REXML::Parsers::SAX2Parser.new @stream
|
202
|
+
|
203
|
+
parser.listen(:end_document) do
|
204
|
+
raise Jabber::ConnectionForceCloseError
|
205
|
+
end
|
206
|
+
|
207
|
+
parser.listen( :start_element ) do |uri, localname, qname, attributes|
|
208
|
+
puts "START ELEMENT"
|
209
|
+
case qname
|
210
|
+
when "stream:stream"
|
211
|
+
openstream = ParsedXMLElement.new(qname)
|
212
|
+
attributes.each { |attr, value| openstream.add_attribute(attr, value) }
|
213
|
+
@listener.receive(openstream)
|
214
|
+
@started = true
|
215
|
+
else
|
216
|
+
if @current.nil?
|
217
|
+
@current = ParsedXMLElement.new(qname)
|
218
|
+
else
|
219
|
+
@current = @current.add_child(qname)
|
220
|
+
end
|
221
|
+
attributes.each { |attr, value| @current.add_attribute(attr, value) }
|
222
|
+
end
|
223
|
+
end
|
224
|
+
parser.listen( :end_element ) do |uri, localname, qname|
|
225
|
+
puts "END ELEMENT"
|
226
|
+
case qname
|
227
|
+
when "stream:stream"
|
228
|
+
@started = false
|
229
|
+
else
|
230
|
+
@listener.receive(@current) unless @current.element_parent
|
231
|
+
@current = @current.element_parent
|
232
|
+
end
|
233
|
+
end
|
234
|
+
parser.listen( :characters ) do | text |
|
235
|
+
puts "CHARACTERS"
|
236
|
+
@current.append_data(text) if @current
|
237
|
+
end
|
238
|
+
parser.listen( :cdata ) do | text |
|
239
|
+
puts "CDATA"
|
240
|
+
@current.append_data(text) if @current
|
241
|
+
end
|
242
|
+
parser.parse
|
243
|
+
rescue REXML::ParseException => e
|
244
|
+
puts "FAIL"
|
245
|
+
|
246
|
+
puts e.backtrace.join "\n"
|
247
|
+
puts e.message
|
248
|
+
@listener.parse_failure
|
249
|
+
rescue Jabber::ConnectionForceCloseError => e
|
250
|
+
@listener.parse_failure(e)
|
251
|
+
end
|
252
|
+
end
|
253
|
+
end
|
254
|
+
end # USE_PARSER
|
255
|
+
end
|
256
|
+
end
|
257
|
+
|