jabber4r-revive 0.9.0 → 0.10.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (45) hide show
  1. data/.gitignore +5 -4
  2. data/.rspec +3 -3
  3. data/.travis.yml +7 -7
  4. data/CHANGELOG +11 -1
  5. data/Gemfile +3 -3
  6. data/README.md +29 -29
  7. data/Rakefile +70 -70
  8. data/jabber4r-revive.gemspec +25 -25
  9. data/lib/jabber4r.rb +38 -33
  10. data/lib/jabber4r/bosh.rb +21 -0
  11. data/lib/jabber4r/bosh/authentication.rb +13 -0
  12. data/lib/jabber4r/bosh/authentication/non_sasl.rb +219 -0
  13. data/lib/jabber4r/bosh/authentication/sasl.rb +239 -0
  14. data/lib/jabber4r/bosh/session.rb +144 -0
  15. data/lib/jabber4r/connection.rb +259 -258
  16. data/lib/jabber4r/debugger.rb +60 -60
  17. data/lib/jabber4r/jid.rb +20 -19
  18. data/lib/jabber4r/protocol.rb +249 -257
  19. data/lib/jabber4r/protocol/authentication.rb +14 -0
  20. data/lib/jabber4r/protocol/authentication/non_sasl.rb +138 -0
  21. data/lib/jabber4r/protocol/authentication/sasl.rb +88 -0
  22. data/lib/jabber4r/protocol/iq.rb +259 -259
  23. data/lib/jabber4r/protocol/message.rb +245 -245
  24. data/lib/jabber4r/protocol/parsed_xml_element.rb +207 -207
  25. data/lib/jabber4r/protocol/presence.rb +160 -160
  26. data/lib/jabber4r/protocol/xml_element.rb +143 -143
  27. data/lib/jabber4r/rexml_1.8_patch.rb +15 -15
  28. data/lib/jabber4r/roster.rb +38 -38
  29. data/lib/jabber4r/session.rb +615 -615
  30. data/lib/jabber4r/version.rb +10 -3
  31. data/spec/lib/jabber4r/bosh/authentication/non_sasl_spec.rb +79 -0
  32. data/spec/lib/jabber4r/bosh/authentication/sasl_spec.rb +42 -0
  33. data/spec/lib/jabber4r/bosh/session_spec.rb +406 -0
  34. data/spec/lib/jabber4r/bosh_spec.rb +0 -0
  35. data/spec/lib/jabber4r/connection_spec.rb +174 -174
  36. data/spec/lib/jabber4r/debugger_spec.rb +35 -35
  37. data/spec/lib/jabber4r/jid_spec.rb +197 -197
  38. data/spec/lib/jabber4r/protocol/authentication/non_sasl_spec.rb +79 -0
  39. data/spec/lib/jabber4r/protocol/authentication/sasl_spec.rb +42 -0
  40. data/spec/spec_helper.rb +11 -11
  41. data/spec/support/mocks/tcp_socket_mock.rb +8 -8
  42. metadata +61 -45
  43. data/Gemfile.lock +0 -45
  44. data/lib/jabber4r/bosh_session.rb +0 -224
  45. data/spec/lib/jabber4r/bosh_session_spec.rb +0 -150
@@ -1,61 +1,61 @@
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
- # Copyright (C) 2013 Sergey Fedorov <strech_ftf@mail.ru>
7
-
8
- require "singleton"
9
- require "logger"
10
-
11
- module Jabber
12
- # Produces debug methods
13
- #
14
- # Example
15
- #
16
- # def warn(message)
17
- # Debug.instance.send(:warn, message)
18
- # end
19
- # module_function m
20
- [:warn, :debug, :info].each do |m|
21
- define_method(m) do |message|
22
- Debugger.send(m, message)
23
- end
24
- module_function m
25
- end
26
-
27
- class Debugger
28
- include Singleton
29
-
30
- attr_accessor :enabled, :logger
31
-
32
- def initialize
33
- @logger = Logger.new(STDOUT)
34
- @enabled = false
35
- end
36
-
37
- class << self
38
- def logger=(logger)
39
- instance.logger = logger
40
- end
41
-
42
- def enable!
43
- instance.enabled = true
44
- end
45
-
46
- def disable!
47
- instance.enabled = false
48
- end
49
-
50
- def enabled?
51
- instance.enabled
52
- end
53
-
54
- [:warn, :debug, :info].each do |m|
55
- define_method(m) do |message|
56
- enabled? && instance.logger.send(m, message)
57
- end
58
- end
59
- end # class << self
60
- end
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
+ # Copyright (C) 2013 Sergey Fedorov <strech_ftf@mail.ru>
7
+
8
+ require "singleton"
9
+ require "logger"
10
+
11
+ module Jabber
12
+ # Produces debug methods
13
+ #
14
+ # Example
15
+ #
16
+ # def warn(message)
17
+ # Debug.instance.send(:warn, message)
18
+ # end
19
+ # module_function m
20
+ [:warn, :debug, :info].each do |m|
21
+ define_method(m) do |message|
22
+ Debugger.send(m, message)
23
+ end
24
+ module_function m
25
+ end
26
+
27
+ class Debugger
28
+ include Singleton
29
+
30
+ attr_accessor :enabled, :logger
31
+
32
+ def initialize
33
+ @logger = Logger.new(STDOUT)
34
+ @enabled = false
35
+ end
36
+
37
+ class << self
38
+ def logger=(logger)
39
+ instance.logger = logger
40
+ end
41
+
42
+ def enable!
43
+ instance.enabled = true
44
+ end
45
+
46
+ def disable!
47
+ instance.enabled = false
48
+ end
49
+
50
+ def enabled?
51
+ instance.enabled
52
+ end
53
+
54
+ [:warn, :debug, :info].each do |m|
55
+ define_method(m) do |message|
56
+ enabled? && instance.logger.send(m, message)
57
+ end
58
+ end
59
+ end # class << self
60
+ end
61
61
  end
data/lib/jabber4r/jid.rb CHANGED
@@ -3,20 +3,21 @@
3
3
  # License: see LICENSE
4
4
  # Jabber4R - Jabber Instant Messaging Library for Ruby
5
5
  # Copyright (C) 2002 Rich Kilmer <rich@infoether.com>
6
+ # Copyright (C) 2013 Sergey Fedorov <strech_ftf@mail.ru>
6
7
 
7
8
  module Jabber
8
- # The Jabber ID class is used to hold a parsed jabber identifier (account+host+resource)
9
+ # The Jabber ID class is used to hold a parsed jabber identifier (account+domain+resource)
9
10
  class JID
10
- PATTERN = /^(?:(?<node>[^@]*)@)??(?<host>[^@\/]*)(?:\/(?<resource>.*?))?$/.freeze
11
+ PATTERN = /^(?:(?<node>[^@]*)@)??(?<domain>[^@\/]*)(?:\/(?<resource>.*?))?$/.freeze
11
12
 
12
- # The node (account)
13
+ # Public: The node (account)
13
14
  attr_accessor :node
14
15
 
15
- # The resource id
16
+ # Public: The resource id
16
17
  attr_accessor :resource
17
18
 
18
- # The host name (or IP address)
19
- attr_accessor :host
19
+ # Public: The domain indentificator (or IP address)
20
+ attr_accessor :domain
20
21
 
21
22
  # Public: Convert something to Jabber::JID
22
23
  #
@@ -30,34 +31,34 @@ module Jabber
30
31
  end
31
32
 
32
33
  # Constructs a JID from the supplied string of the format:
33
- # node@host[/resource] (e.g. "rich_kilmer@jabber.com/laptop")
34
+ # node@domain[/resource] (e.g. "rich_kilmer@jabber.com/laptop")
34
35
  #
35
36
  # jid - String the jabber id string to parse
36
- # host - String the host of jabber server (optional)
37
+ # domain - String the domain of jabber server (optional)
37
38
  # resource - String the resource of jabber id (optional)
38
39
  #
39
40
  # Examples
40
41
  #
41
42
  # jid = Jabber::JID.new("strech@localhost/attach")
42
43
  # jid.node # => "strech"
43
- # jid.host # => "localhost"
44
+ # jid.domain # => "localhost"
44
45
  # jid.resource # => "attach"
45
46
  #
46
47
  # Raises ArgumentError
47
48
  # Returns nothing
48
- def initialize(jid, host = nil, resource = nil)
49
+ def initialize(jid, domain = nil, resource = nil)
49
50
  raise ArgumentError, "Node can't be empty" if jid.to_s.empty?
50
51
 
51
- @node, @host, @resource = self.class.parse(jid)
52
- @node, @host = @host, nil if @node.nil? && @host
52
+ @node, @domain, @resource = self.class.parse(jid)
53
+ @node, @domain = @domain, nil if @node.nil? && @domain
53
54
 
54
- @host = host unless host.nil?
55
+ @domain = domain unless domain.nil?
55
56
  @resource = resource unless resource.nil?
56
57
 
57
- raise ArgumentError, "Couldn't create JID without host" if @host.to_s.empty?
58
+ raise ArgumentError, "Couldn't create JID without domain" if @domain.to_s.empty?
58
59
  end
59
60
 
60
- # Public: Evalutes whether the node, resource and host are the same
61
+ # Public: Evalutes whether the node, resource and domain are the same
61
62
  #
62
63
  # jid - Jabber::JID the other jabber id
63
64
  #
@@ -74,14 +75,14 @@ module Jabber
74
75
  def same?(jid)
75
76
  other_jid = self.class.to_jid(jid)
76
77
 
77
- other_jid.node == node && other_jid.host == host
78
+ other_jid.node == node && other_jid.domain == domain
78
79
  end
79
80
 
80
81
  # Public: Strip resource from jid and return new object
81
82
  #
82
83
  # Returns Jabber::JID
83
84
  def strip
84
- self.class.new(node, host)
85
+ self.class.new(node, domain)
85
86
  end
86
87
 
87
88
  # Public: Strip resource from jid and return the same object
@@ -97,7 +98,7 @@ module Jabber
97
98
  #
98
99
  # Returns String
99
100
  def to_s
100
- ["#{node}@#{host}", resource].compact.join "/"
101
+ ["#{node}@#{domain}", resource].compact.join "/"
101
102
  end
102
103
 
103
104
  # Public: Override #hash to hash based on the to_s method
@@ -108,7 +109,7 @@ module Jabber
108
109
  end
109
110
 
110
111
  private
111
- # Internal: Parse jid string for node, host, resource
112
+ # Internal: Parse jid string for node, domain, resource
112
113
  #
113
114
  # jid - String jabber id
114
115
  #
@@ -1,257 +1,249 @@
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
-
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
+ # domain:: [String] The domain being connected to
54
+ # return:: [String] The XML data to send
55
+ #
56
+ def self.gen_open_stream(domain)
57
+ return ('<?xml version="1.0" encoding="UTF-8" ?><stream:stream to="'+domain+'" xmlns="jabber:client" xmlns:stream="http://etherx.jabber.org/streams" version="1.0">')
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
+ case qname
209
+ when "stream:stream"
210
+ openstream = ParsedXMLElement.new(qname)
211
+ attributes.each { |attr, value| openstream.add_attribute(attr, value) }
212
+ @listener.receive(openstream)
213
+ @started = true
214
+ else
215
+ if @current.nil?
216
+ @current = ParsedXMLElement.new(qname)
217
+ else
218
+ @current = @current.add_child(qname)
219
+ end
220
+ attributes.each { |attr, value| @current.add_attribute(attr, value) }
221
+ end
222
+ end
223
+ parser.listen( :end_element ) do |uri, localname, qname|
224
+ case qname
225
+ when "stream:stream"
226
+ @started = false
227
+ else
228
+ @listener.receive(@current) unless @current.element_parent
229
+ @current = @current.element_parent
230
+ end
231
+ end
232
+ parser.listen( :characters ) do | text |
233
+ @current.append_data(text) if @current
234
+ end
235
+ parser.listen( :cdata ) do | text |
236
+ @current.append_data(text) if @current
237
+ end
238
+ parser.parse
239
+ rescue REXML::ParseException => e
240
+ @listener.parse_failure
241
+ rescue Jabber::ConnectionForceCloseError => e
242
+ @listener.parse_failure(e)
243
+ end
244
+ end
245
+ end
246
+ end # USE_PARSER
247
+ end
248
+ end
249
+