rhodes 2.0.0.beta1 → 2.0.0.beta2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (104) hide show
  1. data/CHANGELOG +5 -0
  2. data/LICENSE +19 -674
  3. data/Manifest.txt +21 -4
  4. data/README.textile +5 -36
  5. data/Rakefile +5 -0
  6. data/lib/build/jake.rb +3 -1
  7. data/lib/extensions/rexml/rexml/document.rb +2 -0
  8. data/lib/extensions/rexml/rexml/parsers/baseparser.rb +0 -6
  9. data/lib/extensions/rhoxml/rexml/child.rb +96 -0
  10. data/lib/extensions/rhoxml/rexml/document.rb +527 -0
  11. data/lib/extensions/rhoxml/rexml/element.rb +987 -0
  12. data/lib/extensions/rhoxml/rexml/encoding.rb +71 -0
  13. data/lib/extensions/rhoxml/rexml/encodings/US-ASCII.rb +30 -0
  14. data/lib/extensions/rhoxml/rexml/encodings/UTF-16.rb +35 -0
  15. data/lib/extensions/rhoxml/rexml/encodings/UTF-8.rb +18 -0
  16. data/lib/extensions/rhoxml/rexml/namespace.rb +47 -0
  17. data/lib/extensions/rhoxml/rexml/node.rb +76 -0
  18. data/lib/extensions/rhoxml/rexml/parent.rb +166 -0
  19. data/lib/extensions/rhoxml/rexml/parseexception.rb +51 -0
  20. data/lib/extensions/rhoxml/rexml/parsers/baseparser.rb +531 -0
  21. data/lib/extensions/rhoxml/rexml/parsers/treeparser.rb +100 -0
  22. data/lib/extensions/rhoxml/rexml/parsers/xpathparser.rb +698 -0
  23. data/lib/extensions/rhoxml/rexml/set.rb +1274 -0
  24. data/lib/extensions/rhoxml/rexml/source.rb +258 -0
  25. data/lib/extensions/rhoxml/rexml/xmltokens.rb +18 -0
  26. data/lib/extensions/rhoxml/rexml/xpath.rb +77 -0
  27. data/lib/extensions/rhoxml/rexml/xpath_parser.rb +806 -0
  28. data/lib/framework/builtinME.rb +2 -0
  29. data/lib/framework/dateME.rb +5 -1
  30. data/lib/framework/rho/render.rb +10 -2
  31. data/lib/framework/rhom/rhom_object_factory.rb +2 -1
  32. data/lib/framework/singleton.rb +1 -1
  33. data/platform/android/Rhodes/jni/src/rhodes.cpp +2 -4
  34. data/platform/android/Rhodes/src/com/rhomobile/rhodes/NativeBar.java +23 -18
  35. data/platform/android/Rhodes/src/com/rhomobile/rhodes/Rhodes.java +42 -69
  36. data/platform/android/Rhodes/src/com/rhomobile/rhodes/SplashScreen.java +59 -7
  37. data/platform/android/Rhodes/src/com/rhomobile/rhodes/camera/Camera.java +1 -1
  38. data/platform/android/Rhodes/src/com/rhomobile/rhodes/mapview/Annotation.java +1 -0
  39. data/platform/android/Rhodes/src/com/rhomobile/rhodes/mapview/MapView.java +97 -85
  40. data/platform/android/Rhodes/src/com/rhomobile/rhodes/uri/SmsUriHandler.java +52 -0
  41. data/platform/android/build/RhodesSRC_build.files +1 -0
  42. data/platform/android/build/android.rake +38 -14
  43. data/platform/bb/RubyVM/RubyVM.jdp +1 -0
  44. data/platform/bb/build/RubyVM_build.files +1 -0
  45. data/platform/bb/build/bb.rake +44 -2
  46. data/platform/bb/rhodes/platform/5.0/com/rho/BrowserAdapter5.java +1 -1
  47. data/platform/bb/rhodes/rhodes.jdp +4 -4
  48. data/platform/bb/rhodes/src/com/rho/BrowserAdapter.java +8 -4
  49. data/platform/bb/rhodes/src/com/rho/rubyext/Alert.java +149 -17
  50. data/platform/bb/rhodes/src/rhomobile/PushListeningThread.java +20 -17
  51. data/platform/bb/rhodes/src/rhomobile/RhodesApplication.java +54 -28
  52. data/platform/bb/rhodes/src/rhomobile/mapview/Annotation.java +1 -0
  53. data/platform/bb/rhodes/src/rhomobile/mapview/GoogleMapField.java +37 -11
  54. data/platform/bb/rhodes/src/rhomobile/mapview/MapView.java +49 -19
  55. data/platform/bb/rhodes/src/rhomobile/mapview/MapViewScreen.java +6 -0
  56. data/platform/iphone/Classes/MapView/GoogleGeocoder.h +6 -7
  57. data/platform/iphone/Classes/MapView/GoogleGeocoder.m +70 -70
  58. data/platform/iphone/Classes/MapView/MapAnnotation.h +5 -3
  59. data/platform/iphone/Classes/MapView/MapAnnotation.m +10 -8
  60. data/platform/iphone/Classes/MapView/MapViewController.h +13 -10
  61. data/platform/iphone/Classes/MapView/MapViewController.m +131 -72
  62. data/platform/iphone/Classes/Rhodes.h +2 -0
  63. data/platform/iphone/Classes/Rhodes.m +13 -1
  64. data/platform/iphone/Classes/SimpleMainView.m +0 -1
  65. data/platform/iphone/Classes/TabbedMainView.m +5 -6
  66. data/platform/shared/common/RhoTime.h +2 -2
  67. data/platform/shared/common/RhodesApp.cpp +1 -1
  68. data/platform/shared/db/DBAdapter.cpp +6 -0
  69. data/platform/shared/net/CURLNetRequest.cpp +23 -1
  70. data/platform/shared/ruby/thread_win32.c +9 -1
  71. data/platform/shared/rubyJVM/src/com/rho/Capabilities.java +6 -0
  72. data/platform/shared/rubyJVM/src/com/rho/RhodesApp.java +1 -1
  73. data/platform/shared/rubyJVM/src/com/rho/sync/ClientRegister.java +1 -1
  74. data/platform/shared/rubyJVM/src/com/xruby/GeneratedMethods/RubySymbol_Methods.java +6 -1
  75. data/platform/shared/rubyJVM/src/com/xruby/GeneratedMethods/RubyTime_Methods.java +3 -3
  76. data/platform/shared/rubyJVM/src/com/xruby/runtime/builtin/InputStreamExecutor.java +1 -1
  77. data/platform/shared/rubyJVM/src/com/xruby/runtime/builtin/RubyArray.java +15 -3
  78. data/platform/shared/rubyJVM/src/com/xruby/runtime/builtin/RubyString.java +10 -2
  79. data/platform/shared/rubyJVM/src/com/xruby/runtime/builtin/RubyTime.java +12 -1
  80. data/platform/shared/rubyJVM/src/com/xruby/runtime/lang/RubyKernelModule.java +18 -9
  81. data/platform/shared/rubyJVM/src/com/xruby/runtime/lang/RubySymbol.java +5 -0
  82. data/platform/shared/rubyJVM/src/org/json/me/JSONArray.java +2 -1
  83. data/platform/shared/unzip/unzip.cpp +1 -1
  84. data/platform/wm/build/wm.rake +27 -6
  85. data/platform/wm/rhodes/Alert.cpp +335 -5
  86. data/platform/wm/rhodes/Alert.h +84 -1
  87. data/platform/wm/rhodes/MainWindow.cpp +28 -6
  88. data/platform/wm/rhodes/MainWindow.h +7 -2
  89. data/platform/wm/rhodes/Rhodes.cpp +23 -0
  90. data/platform/wm/rhodes/rho/rubyext/SystemImpl.cpp +2 -1
  91. data/platform/wm/rhodes/stdafx.h +1 -0
  92. data/platform/wm/tools/detool/detool.cpp +405 -14
  93. data/rakefile.rb +5 -0
  94. data/res/build-tools/detool.exe +0 -0
  95. data/res/generators/rhogen.rb +2 -0
  96. data/rhodes.gemspec +1 -1
  97. data/spec/framework_spec/app/spec/fixtures/object_values.txt +1 -1
  98. data/spec/framework_spec/app/spec/pagination/fixtures/object_values.txt +1 -1
  99. data/spec/framework_spec/app/spec/rhom_object_spec.rb +12 -12
  100. metadata +23 -6
  101. data/LICENSING_OPTIONS +0 -1
  102. data/platform/bb/build/rhodesApp.rapc +0 -9
  103. data/res/generators/templates/source/source_adapter.rb +0 -48
  104. data/rhobuild.yml +0 -37
data/Manifest.txt CHANGED
@@ -164,6 +164,25 @@ lib/extensions/rholang/lang_se.rb
164
164
  lib/extensions/rholang/lang_sr.rb
165
165
  lib/extensions/rholang/rhoerror_ru.rb
166
166
  lib/extensions/rholang/rhomsg_ru.rb
167
+ lib/extensions/rhoxml/rexml/child.rb
168
+ lib/extensions/rhoxml/rexml/document.rb
169
+ lib/extensions/rhoxml/rexml/element.rb
170
+ lib/extensions/rhoxml/rexml/encoding.rb
171
+ lib/extensions/rhoxml/rexml/encodings/US-ASCII.rb
172
+ lib/extensions/rhoxml/rexml/encodings/UTF-16.rb
173
+ lib/extensions/rhoxml/rexml/encodings/UTF-8.rb
174
+ lib/extensions/rhoxml/rexml/namespace.rb
175
+ lib/extensions/rhoxml/rexml/node.rb
176
+ lib/extensions/rhoxml/rexml/parent.rb
177
+ lib/extensions/rhoxml/rexml/parseexception.rb
178
+ lib/extensions/rhoxml/rexml/parsers/baseparser.rb
179
+ lib/extensions/rhoxml/rexml/parsers/treeparser.rb
180
+ lib/extensions/rhoxml/rexml/parsers/xpathparser.rb
181
+ lib/extensions/rhoxml/rexml/set.rb
182
+ lib/extensions/rhoxml/rexml/source.rb
183
+ lib/extensions/rhoxml/rexml/xmltokens.rb
184
+ lib/extensions/rhoxml/rexml/xpath.rb
185
+ lib/extensions/rhoxml/rexml/xpath_parser.rb
167
186
  lib/extensions/set/set.rb
168
187
  lib/extensions/uri/uri/common.rb
169
188
  lib/extensions/uri/uri/ftp.rb
@@ -221,7 +240,6 @@ lib/test/framework_test.rb
221
240
  lib/test/rho_stubs.rb
222
241
  lib/test/syncdb.sqlite
223
242
  LICENSE
224
- LICENSING_OPTIONS
225
243
  Manifest.txt
226
244
  platform/android/build/android.rake
227
245
  platform/android/build/androidcommon.rb
@@ -341,6 +359,7 @@ platform/android/Rhodes/src/com/rhomobile/rhodes/ui/AboutDialog.java
341
359
  platform/android/Rhodes/src/com/rhomobile/rhodes/ui/LogOptionsDialog.java
342
360
  platform/android/Rhodes/src/com/rhomobile/rhodes/ui/LogViewDialog.java
343
361
  platform/android/Rhodes/src/com/rhomobile/rhodes/uri/MailUriHandler.java
362
+ platform/android/Rhodes/src/com/rhomobile/rhodes/uri/SmsUriHandler.java
344
363
  platform/android/Rhodes/src/com/rhomobile/rhodes/uri/TelUriHandler.java
345
364
  platform/android/Rhodes/src/com/rhomobile/rhodes/uri/UriHandler.java
346
365
  platform/android/Rhodes/src/com/rhomobile/rhodes/uri/VideoUriHandler.java
@@ -352,7 +371,6 @@ platform/bb/build/MANIFEST.MF
352
371
  platform/bb/build/RhoBundleAlx.erb
353
372
  platform/bb/build/rhodes_build.files
354
373
  platform/bb/build/rhodesApp.csl
355
- platform/bb/build/rhodesApp.rapc
356
374
  platform/bb/build/rhodesAppAlx.erb
357
375
  platform/bb/build/RubyVM_build.files
358
376
  platform/bb/build/RubyVM_MANIFEST.MF
@@ -1412,6 +1430,7 @@ platform/shared/rubyext/RhoRuby.cpp
1412
1430
  platform/shared/rubyext/RhoRuby.h
1413
1431
  platform/shared/rubyext/System.cpp
1414
1432
  platform/shared/rubyext/WebView.h
1433
+ platform/shared/rubyJVM/src/com/rho/Capabilities.java
1415
1434
  platform/shared/rubyJVM/src/com/rho/Convert.java
1416
1435
  platform/shared/rubyJVM/src/com/rho/DateTimeTokenizer.java
1417
1436
  platform/shared/rubyJVM/src/com/rho/db/DBAdapter.java
@@ -3522,7 +3541,6 @@ res/generators/templates/model/new.erb
3522
3541
  res/generators/templates/model/show.bb.erb
3523
3542
  res/generators/templates/model/show.erb
3524
3543
  res/generators/templates/model/spec.rb
3525
- res/generators/templates/source/source_adapter.rb
3526
3544
  res/generators/templates/spec/app/fileutils.rb
3527
3545
  res/generators/templates/spec/app/mspec/expectations/expectations.rb
3528
3546
  res/generators/templates/spec/app/mspec/expectations/should.rb
@@ -3641,7 +3659,6 @@ res/generators/templates/spec/app/spec/webview_spec.rb
3641
3659
  res/generators/templates/spec/app/spec_runner.rb
3642
3660
  res/generators/templates/spec/app/SpecRunner/controller.rb
3643
3661
  res/generators/templates/spec/app/SpecRunner/index.erb
3644
- rhobuild.yml
3645
3662
  rhobuild.yml.example
3646
3663
  rhodes.gemspec
3647
3664
  spec/framework_spec/app/Account/config.rb
data/README.textile CHANGED
@@ -1,8 +1,8 @@
1
1
  h1. Rhodes
2
2
 
3
- The "Rhodes framework":http://github.com/rhomobile/rhodes/tree/master is a framework for building locally executing, device-optimized mobile applications for smartphone devices. These applications are optimized for interacting with transactional enterprise application backends (with synced local data via "RhoSync":http://github.com/rhomobile/rhosync/tree/master). Rhodes is now available for iPhone, Windows Mobile, Research in Motion (Blackberry) and Symbian smartphones.
3
+ The "Rhodes framework":http://github.com/rhomobile/rhodes is a framework for building locally executing, device-optimized mobile applications for smartphone devices. These applications are optimized for interacting with transactional enterprise application backends (with synced local data via "RhoSync":http://github.com/rhomobile/rhosync). Rhodes is now available for iPhone, Windows Mobile, Research in Motion (Blackberry) and Symbian smartphones.
4
4
 
5
- Rhodes is available as an open source product under the "GNU Public License": http://gplv3.fsf.org/ for developers prepared to abide by the GPL and open source their own application. For developers building closed source applications (either within an enterprise or as independent software vendors selling to other companies) we offer a "commercial license":http://rhomobile.com/products/licensing. Contact sales@rhomobile.com for details
5
+ Rhodes is available as an open source product under the MIT license. For developers interested a commercial license is still "available":http://rhomobile.com/products/rhodes/license/.
6
6
 
7
7
  h2. INTRODUCTION
8
8
 
@@ -20,7 +20,7 @@ Rhodes features an application generator called rhogen that generates a control
20
20
 
21
21
  rhogen app appname
22
22
 
23
- This will generate a config.rb and an index.html file. Currently config.rb is focused on describing what source to sync with. Modify the URL that you see in this file with whatever your RhoSync server URL and source ID are for this particular "source" or data model. It is assumed that you've already set up a RhoSync "source adapter" as described by the RhoSync README.
23
+ This will generate a config.rb and an index.html file. Currently config.rb is focused on describing what source to sync with. Modify the URL that you see in this file with whatever your RhoSync server URL and source ID are for this particular "source" or data model. It is assumed that you've already set up a RhoSync "source adapter" as described by the "RhoSync docs":http://wiki.rhomobile.com/index.php/RhoSync_2.0.
24
24
 
25
25
  h3. Generate a Model and Associated Controller and Templates
26
26
 
@@ -33,43 +33,12 @@ This will generate a controller as the file controller.rb and several views as a
33
33
  * edit - to edit the actual object
34
34
  * show - to show the object attributes
35
35
 
36
- h2. DIRECTORY STRUCTURE
37
-
38
- The Rhodes directory structure is outlined below. In a default Rhodes application, there are several subdirectories inside of an app directory, one for each model or synced data object. For example, there might be subdirectories called Account, Employee, and Case. Each model subdirectory contains a controller in the file controller.rb. These subdirectories each contain a set of template files as Embedded Ruby (ERB) files. These control how data from the model is displayed and what links are available to other actions. Note that this structure is reminiscent of Rails and MERB's structure, but is a bit simpler by design.
39
-
40
- /appname
41
- build.yml (contains the settings for running builds)
42
- rhoconfig.txt (contains settings for setting the default start and options path)
43
- Rakefile
44
- /public (contains static resources for the generated objects)
45
- /css
46
- /images
47
- /js
48
- /app
49
- index.erb
50
- layout.erb
51
- loading.html
52
- /modelname (for example Account)
53
- config.rb
54
- index.erb
55
- new.erb
56
- edit.erb
57
- show.erb
58
- controller.rb
59
- /modelname (for example Case)
60
- config.rb
61
- index.erb
62
- new.erb
63
- edit.erb
64
- show.erb
65
- controller.rb
66
-
67
36
 
68
37
  h2. MORE RESOURCES
69
38
 
70
- There is a "tutorial available":http://rhomobile.com/wiki/index.php?title=Mobilizing_Your_Application_with_Rhomobile on the "Rhomobile site":http://www.rhomobile.com. This includes thorough and current platform by platform build instructions.
39
+ There is a "tutorial available":http://rhomobile.com/wiki/index.php/Mobilizing_Your_Application_with_Rhomobile on the "Rhomobile site":http://www.rhomobile.com. This includes thorough and current platform by platform build instructions.
71
40
 
72
- The "Rhodes spec":http://rhomobile.com/wiki/index.php?title=Rhodes is also available on the "Rhomobile documentation wiki":http://rhomobile.com/wiki/index.php?title=Rhomobile.
41
+ The "Rhodes spec":http://rhomobile.com/wiki/index.php/Rhodes is also available on the "Rhomobile documentation wiki":http://rhomobile.com/wiki/index.php?title=Rhomobile.
73
42
 
74
43
  For further questions "email us":mailto:info@rhomobile.com or join the "Google Group":http://groups.google.com/group/rhomobile.
75
44
 
data/Rakefile CHANGED
@@ -275,6 +275,11 @@ def common_bundle_start(startdir, dest)
275
275
  end
276
276
  end
277
277
 
278
+ if $excludeextlib
279
+ chdir dest
280
+ $excludeextlib.each {|e| Dir.glob(e).each {|f| rm f}}
281
+ end
282
+
278
283
  chdir startdir
279
284
  #throw "ME"
280
285
  cp_r app + '/app',File.join($srcdir,'apps')
data/lib/build/jake.rb CHANGED
@@ -241,7 +241,9 @@ class Jake
241
241
 
242
242
  if cldc and icon
243
243
  f.write "MIDlet-1: " + title + "," + icon + ",\n"
244
- f.write "RIM-MIDlet-Flags-1: 1\n"
244
+ puts "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! service_enabled: #{$service_enabled}"
245
+ $stdout.flush
246
+ f.write "RIM-MIDlet-Flags-1: 1\n" if $service_enabled
245
247
  end
246
248
 
247
249
  f.close
@@ -7,7 +7,9 @@ require "rexml/instruction"
7
7
  require "rexml/rexml"
8
8
  require "rexml/parseexception"
9
9
  require "rexml/output"
10
+ if !defined? RHO_ME
10
11
  require "rexml/parsers/baseparser"
12
+ end
11
13
  require "rexml/parsers/streamparser"
12
14
  require "rexml/parsers/treeparser"
13
15
 
@@ -1,7 +1,3 @@
1
- if defined? RHO_ME
2
-
3
- else
4
-
5
1
  require 'rexml/parseexception'
6
2
  require 'rexml/undefinednamespaceexception'
7
3
  require 'rexml/source'
@@ -533,5 +529,3 @@ end
533
529
  when :end_doctype
534
530
  end
535
531
  =end
536
-
537
- end
@@ -0,0 +1,96 @@
1
+ require "rexml/node"
2
+
3
+ module REXML
4
+ ##
5
+ # A Child object is something contained by a parent, and this class
6
+ # contains methods to support that. Most user code will not use this
7
+ # class directly.
8
+ class Child
9
+ include Node
10
+ attr_reader :parent # The Parent of this object
11
+
12
+ # Constructor. Any inheritors of this class should call super to make
13
+ # sure this method is called.
14
+ # parent::
15
+ # if supplied, the parent of this child will be set to the
16
+ # supplied value, and self will be added to the parent
17
+ def initialize( parent = nil )
18
+ @parent = nil
19
+ # Declare @parent, but don't define it. The next line sets the
20
+ # parent.
21
+ parent.add( self ) if parent
22
+ end
23
+
24
+ # Replaces this object with another object. Basically, calls
25
+ # Parent.replace_child
26
+ #
27
+ # Returns:: self
28
+ def replace_with( child )
29
+ @parent.replace_child( self, child )
30
+ self
31
+ end
32
+
33
+ # Removes this child from the parent.
34
+ #
35
+ # Returns:: self
36
+ def remove
37
+ unless @parent.nil?
38
+ @parent.delete self
39
+ end
40
+ self
41
+ end
42
+
43
+ # Sets the parent of this child to the supplied argument.
44
+ #
45
+ # other::
46
+ # Must be a Parent object. If this object is the same object as the
47
+ # existing parent of this child, no action is taken. Otherwise, this
48
+ # child is removed from the current parent (if one exists), and is added
49
+ # to the new parent.
50
+ # Returns:: The parent added
51
+ def parent=( other )
52
+ return @parent if @parent == other
53
+ @parent.delete self if defined?( @parent ) and @parent
54
+ @parent = other
55
+ end
56
+
57
+ alias :next_sibling :next_sibling_node
58
+ alias :previous_sibling :previous_sibling_node
59
+
60
+ # Sets the next sibling of this child. This can be used to insert a child
61
+ # after some other child.
62
+ # a = Element.new("a")
63
+ # b = a.add_element("b")
64
+ # c = Element.new("c")
65
+ # b.next_sibling = c
66
+ # # => <a><b/><c/></a>
67
+ def next_sibling=( other )
68
+ parent.insert_after self, other
69
+ end
70
+
71
+ # Sets the previous sibling of this child. This can be used to insert a
72
+ # child before some other child.
73
+ # a = Element.new("a")
74
+ # b = a.add_element("b")
75
+ # c = Element.new("c")
76
+ # b.previous_sibling = c
77
+ # # => <a><b/><c/></a>
78
+ def previous_sibling=(other)
79
+ parent.insert_before self, other
80
+ end
81
+
82
+ # Returns:: the document this child belongs to, or nil if this child
83
+ # belongs to no document
84
+ def document
85
+ return parent.document unless parent.nil?
86
+ nil
87
+ end
88
+
89
+ # This doesn't yet handle encodings
90
+ def bytes
91
+ encoding = document.encoding
92
+
93
+ to_s
94
+ end
95
+ end
96
+ end
@@ -0,0 +1,527 @@
1
+ require "rexml/element"
2
+ #require "rexml/xmldecl"
3
+ #require 'rexml/text'
4
+ require "rexml/source"
5
+ #require "rexml/doctype"
6
+ =begin
7
+ require "rexml/comment"
8
+
9
+ require "rexml/instruction"
10
+ require "rexml/rexml"
11
+ require "rexml/parseexception"
12
+ require "rexml/output"
13
+ =end
14
+ if !defined? RHO_ME
15
+ require "rexml/parsers/baseparser"
16
+ end
17
+ #require "rexml/parsers/streamparser"
18
+
19
+ require "rexml/parsers/treeparser"
20
+
21
+ module REXML
22
+ class Comment < Child
23
+ include Comparable
24
+ START = "<!--"
25
+ STOP = "-->"
26
+
27
+ # The content text
28
+
29
+ attr_accessor :string
30
+
31
+ ##
32
+ # Constructor. The first argument can be one of three types:
33
+ # @param first If String, the contents of this comment are set to the
34
+ # argument. If Comment, the argument is duplicated. If
35
+ # Source, the argument is scanned for a comment.
36
+ # @param second If the first argument is a Source, this argument
37
+ # should be nil, not supplied, or a Parent to be set as the parent
38
+ # of this object
39
+ def initialize( first, second = nil )
40
+ #puts "IN COMMENT CONSTRUCTOR; SECOND IS #{second.type}"
41
+ super(second)
42
+ if first.kind_of? String
43
+ @string = first
44
+ elsif first.kind_of? Comment
45
+ @string = first.string
46
+ end
47
+ end
48
+
49
+ def clone
50
+ Comment.new self
51
+ end
52
+
53
+ alias :to_s :string
54
+
55
+ ##
56
+ # Compares this Comment to another; the contents of the comment are used
57
+ # in the comparison.
58
+ def <=>(other)
59
+ other.to_s <=> @string
60
+ end
61
+
62
+ ##
63
+ # Compares this Comment to another; the contents of the comment are used
64
+ # in the comparison.
65
+ def ==( other )
66
+ other.kind_of?( Comment ) and
67
+ (other <=> self) == 0
68
+ end
69
+
70
+ def node_type
71
+ :comment
72
+ end
73
+ end
74
+
75
+ # Represents an XML DOCTYPE declaration; that is, the contents of <!DOCTYPE
76
+ # ... >. DOCTYPES can be used to declare the DTD of a document, as well as
77
+ # being used to declare entities used in the document.
78
+ class DocType < Parent
79
+ include XMLTokens
80
+ end
81
+
82
+ class XMLDecl < Child
83
+ include Encoding
84
+
85
+ DEFAULT_VERSION = "1.0";
86
+ DEFAULT_ENCODING = "UTF-8";
87
+ DEFAULT_STANDALONE = "no";
88
+ START = '<\?xml';
89
+ STOP = '\?>';
90
+
91
+ attr_accessor :version, :standalone
92
+ attr_reader :writeencoding, :writethis
93
+
94
+ def initialize(version=DEFAULT_VERSION, encoding=nil, standalone=nil)
95
+ @writethis = true
96
+ @writeencoding = !encoding.nil?
97
+ if version.kind_of? XMLDecl
98
+ super()
99
+ @version = version.version
100
+ self.encoding = version.encoding
101
+ @writeencoding = version.writeencoding
102
+ @standalone = version.standalone
103
+ else
104
+ super()
105
+ @version = version
106
+ self.encoding = encoding
107
+ @standalone = standalone
108
+ end
109
+ @version = DEFAULT_VERSION if @version.nil?
110
+ end
111
+
112
+ def clone
113
+ XMLDecl.new(self)
114
+ end
115
+
116
+ # indent::
117
+ # Ignored. There must be no whitespace before an XML declaration
118
+ # transitive::
119
+ # Ignored
120
+ # ie_hack::
121
+ # Ignored
122
+ def write(writer, indent=-1, transitive=false, ie_hack=false)
123
+ return nil unless @writethis or writer.kind_of? Output
124
+ writer << START.sub(/\\/u, '')
125
+ if writer.kind_of? Output
126
+ writer << " #{content writer.encoding}"
127
+ else
128
+ writer << " #{content encoding}"
129
+ end
130
+ writer << STOP.sub(/\\/u, '')
131
+ end
132
+
133
+ def ==( other )
134
+ other.kind_of?(XMLDecl) and
135
+ other.version == @version and
136
+ other.encoding == self.encoding and
137
+ other.standalone == @standalone
138
+ end
139
+
140
+ def xmldecl version, encoding, standalone
141
+ @version = version
142
+ self.encoding = encoding
143
+ @standalone = standalone
144
+ end
145
+
146
+ def node_type
147
+ :xmldecl
148
+ end
149
+
150
+ alias :stand_alone? :standalone
151
+ alias :old_enc= :encoding=
152
+
153
+ def encoding=( enc )
154
+ if enc.nil?
155
+ @@old_enc = "UTF-8"
156
+ @writeencoding = false
157
+ else
158
+ @@old_enc = enc
159
+ @writeencoding = true
160
+ end
161
+ self.dowrite
162
+ end
163
+
164
+ # Only use this if you do not want the XML declaration to be written;
165
+ # this object is ignored by the XML writer. Otherwise, instantiate your
166
+ # own XMLDecl and add it to the document.
167
+ #
168
+ # Note that XML 1.1 documents *must* include an XML declaration
169
+ def XMLDecl.default
170
+ rv = XMLDecl.new( "1.0" )
171
+ rv.nowrite
172
+ rv
173
+ end
174
+
175
+ def nowrite
176
+ @writethis = false
177
+ end
178
+
179
+ def dowrite
180
+ @writethis = true
181
+ end
182
+
183
+ def inspect
184
+ START.sub(/\\/u, '') + " ... " + STOP.sub(/\\/u, '')
185
+ end
186
+
187
+ private
188
+ def content(enc)
189
+ rv = "version='#@version'"
190
+ rv << " encoding='#{enc}'" if @writeencoding || enc !~ /utf-8/i
191
+ rv << " standalone='#@standalone'" if @standalone
192
+ rv
193
+ end
194
+ end
195
+
196
+ # Represents a full XML document, including PIs, a doctype, etc. A
197
+ # Document has a single child that can be accessed by root().
198
+ # Note that if you want to have an XML declaration written for a document
199
+ # you create, you must add one; REXML documents do not write a default
200
+ # declaration for you. See |DECLARATION| and |write|.
201
+ class Document < Element
202
+ # A convenient default XML declaration. If you want an XML declaration,
203
+ # the easiest way to add one is mydoc << Document::DECLARATION
204
+ # +DEPRECATED+
205
+ # Use: mydoc << XMLDecl.default
206
+ DECLARATION = XMLDecl.default
207
+
208
+ # Constructor
209
+ # @param source if supplied, must be a Document, String, or IO.
210
+ # Documents have their context and Element attributes cloned.
211
+ # Strings are expected to be valid XML documents. IOs are expected
212
+ # to be sources of valid XML documents.
213
+ # @param context if supplied, contains the context of the document;
214
+ # this should be a Hash.
215
+ def initialize( source = nil, context = {} )
216
+ @entity_expansion_count = 0
217
+ super()
218
+ @context = context
219
+ return if source.nil?
220
+ if source.kind_of? Document
221
+ @context = source.context
222
+ super source
223
+ else
224
+ build( source )
225
+ end
226
+ end
227
+
228
+ def node_type
229
+ :document
230
+ end
231
+
232
+ # Should be obvious
233
+ def clone
234
+ Document.new self
235
+ end
236
+
237
+ # According to the XML spec, a root node has no expanded name
238
+ def expanded_name
239
+ ''
240
+ #d = doc_type
241
+ #d ? d.name : "UNDEFINED"
242
+ end
243
+
244
+ alias :name :expanded_name
245
+
246
+ # We override this, because XMLDecls and DocTypes must go at the start
247
+ # of the document
248
+ def add( child )
249
+ #puts "document.add: #{child}"
250
+ if child.kind_of? XMLDecl
251
+ @children.unshift child
252
+ child.parent = self
253
+ elsif child.kind_of? DocType
254
+ # Find first Element or DocType node and insert the decl right
255
+ # before it. If there is no such node, just insert the child at the
256
+ # end. If there is a child and it is an DocType, then replace it.
257
+ insert_before_index = 0
258
+ @children.find { |x|
259
+ insert_before_index += 1
260
+ x.kind_of?(Element) || x.kind_of?(DocType)
261
+ }
262
+ if @children[ insert_before_index ] # Not null = not end of list
263
+ if @children[ insert_before_index ].kind_of DocType
264
+ @children[ insert_before_index ] = child
265
+ else
266
+ @children[ index_before_index-1, 0 ] = child
267
+ end
268
+ else # Insert at end of list
269
+ @children[insert_before_index] = child
270
+ end
271
+ child.parent = self
272
+ else
273
+ rv = super
274
+ raise "attempted adding second root element to document" if @elements.size > 1
275
+ rv
276
+ end
277
+ end
278
+ alias :<< :add
279
+
280
+ def add_element(arg=nil, arg2=nil)
281
+ #puts "document.add_element: #{arg}; #{arg2}"
282
+ rv = super
283
+ raise "attempted adding second root element to document" if @elements.size > 1
284
+ rv
285
+ end
286
+
287
+ # @return the root Element of the document, or nil if this document
288
+ # has no children.
289
+ def root
290
+ elements[1]
291
+ #self
292
+ #@children.find { |item| item.kind_of? Element }
293
+ end
294
+
295
+ # @return the DocType child of the document, if one exists,
296
+ # and nil otherwise.
297
+ def doctype
298
+ @children.find { |item| item.kind_of? DocType }
299
+ end
300
+
301
+ # @return the XMLDecl of this document; if no XMLDecl has been
302
+ # set, the default declaration is returned.
303
+ def xml_decl
304
+ rv = @children[0]
305
+ return rv if rv.kind_of? XMLDecl
306
+ rv = @children.unshift(XMLDecl.default)[0]
307
+ end
308
+
309
+ # @return the XMLDecl version of this document as a String.
310
+ # If no XMLDecl has been set, returns the default version.
311
+ def version
312
+ xml_decl().version
313
+ end
314
+
315
+ # @return the XMLDecl encoding of this document as a String.
316
+ # If no XMLDecl has been set, returns the default encoding.
317
+ def encoding
318
+ xml_decl().encoding
319
+ end
320
+
321
+ # @return the XMLDecl standalone value of this document as a String.
322
+ # If no XMLDecl has been set, returns the default setting.
323
+ def stand_alone?
324
+ xml_decl().stand_alone?
325
+ end
326
+
327
+ # Write the XML tree out, optionally with indent. This writes out the
328
+ # entire XML document, including XML declarations, doctype declarations,
329
+ # and processing instructions (if any are given).
330
+ #
331
+ # A controversial point is whether Document should always write the XML
332
+ # declaration (<?xml version='1.0'?>) whether or not one is given by the
333
+ # user (or source document). REXML does not write one if one was not
334
+ # specified, because it adds unnecessary bandwidth to applications such
335
+ # as XML-RPC.
336
+ #
337
+ # See also the classes in the rexml/formatters package for the proper way
338
+ # to change the default formatting of XML output
339
+ #
340
+ # _Examples_
341
+ # Document.new("<a><b/></a>").serialize
342
+ #
343
+ # output_string = ""
344
+ # tr = Transitive.new( output_string )
345
+ # Document.new("<a><b/></a>").serialize( tr )
346
+ #
347
+ # output::
348
+ # output an object which supports '<< string'; this is where the
349
+ # document will be written.
350
+ # indent::
351
+ # An integer. If -1, no indenting will be used; otherwise, the
352
+ # indentation will be twice this number of spaces, and children will be
353
+ # indented an additional amount. For a value of 3, every item will be
354
+ # indented 3 more levels, or 6 more spaces (2 * 3). Defaults to -1
355
+ # transitive::
356
+ # If transitive is true and indent is >= 0, then the output will be
357
+ # pretty-printed in such a way that the added whitespace does not affect
358
+ # the absolute *value* of the document -- that is, it leaves the value
359
+ # and number of Text nodes in the document unchanged.
360
+ # ie_hack::
361
+ # Internet Explorer is the worst piece of crap to have ever been
362
+ # written, with the possible exception of Windows itself. Since IE is
363
+ # unable to parse proper XML, we have to provide a hack to generate XML
364
+ # that IE's limited abilities can handle. This hack inserts a space
365
+ # before the /> on empty tags. Defaults to false
366
+ def write( output=$stdout, indent=-1, transitive=false, ie_hack=false )
367
+ if xml_decl.encoding != "UTF-8" && !output.kind_of?(Output)
368
+ output = Output.new( output, xml_decl.encoding )
369
+ end
370
+ formatter = if indent > -1
371
+ if transitive
372
+ require "rexml/formatters/transitive"
373
+ REXML::Formatters::Transitive.new( indent, ie_hack )
374
+ else
375
+ REXML::Formatters::Pretty.new( indent, ie_hack )
376
+ end
377
+ else
378
+ REXML::Formatters::Default.new( ie_hack )
379
+ end
380
+ formatter.write( self, output )
381
+ end
382
+
383
+
384
+ def Document::parse_stream( source, listener )
385
+ Parsers::StreamParser.new( source, listener ).parse
386
+ end
387
+
388
+ @@entity_expansion_limit = 10_000
389
+
390
+ # Set the entity expansion limit. By default the limit is set to 10000.
391
+ def Document::entity_expansion_limit=( val )
392
+ @@entity_expansion_limit = val
393
+ end
394
+
395
+ # Get the entity expansion limit. By default the limit is set to 10000.
396
+ def Document::entity_expansion_limit
397
+ return @@entity_expansion_limit
398
+ end
399
+
400
+ attr_reader :entity_expansion_count
401
+
402
+ def record_entity_expansion
403
+ @entity_expansion_count += 1
404
+ if @entity_expansion_count > @@entity_expansion_limit
405
+ raise "number of entity expansions exceeded, processing aborted."
406
+ end
407
+ end
408
+
409
+ private
410
+ def build( source )
411
+ Parsers::TreeParser.new( source, self ).parse
412
+ end
413
+ end
414
+
415
+ class Text < Child
416
+ include Comparable
417
+
418
+ attr_accessor :raw
419
+
420
+ def initialize(arg, respect_whitespace=false, parent=nil, raw=nil,
421
+ entity_filter=nil )
422
+
423
+ @raw = false
424
+
425
+ if parent
426
+ super( parent )
427
+ @raw = parent.raw
428
+ else
429
+ @parent = nil
430
+ end
431
+
432
+ @raw = raw unless raw.nil?
433
+ @entity_filter = entity_filter
434
+ @normalized = @unnormalized = nil
435
+
436
+ if arg.kind_of? String
437
+ @string = arg.clone
438
+ @string.squeeze!(" \n\t") unless respect_whitespace
439
+ else
440
+ if arg.kind_of? Text
441
+ @string = arg.to_s
442
+ @raw = arg.raw
443
+ else
444
+ raise "Illegal argument of type #{arg.type} for Text constructor (#{arg})"
445
+ end
446
+ end
447
+
448
+ @string.gsub!( /\r\n?/, "\n" )
449
+ end
450
+
451
+ def node_type
452
+ :text
453
+ end
454
+
455
+ def empty?
456
+ @string.size==0
457
+ end
458
+
459
+
460
+ def clone
461
+ return Text.new(self)
462
+ end
463
+
464
+
465
+ # Appends text to this text node. The text is appended in the +raw+ mode
466
+ # of this text node.
467
+ def <<( to_append )
468
+ @string << to_append.gsub( /\r\n?/, "\n" )
469
+ end
470
+
471
+
472
+ # +other+ a String or a Text
473
+ # +returns+ the result of (to_s <=> arg.to_s)
474
+ def <=>( other )
475
+ to_s() <=> other.to_s
476
+ end
477
+
478
+ def doctype
479
+ if @parent
480
+ doc = @parent.document
481
+ doc.doctype if doc
482
+ end
483
+ end
484
+
485
+ def to_s
486
+ @string
487
+ end
488
+
489
+ def inspect
490
+ @string.inspect
491
+ end
492
+
493
+ def value
494
+ #TODO:
495
+ #return @unnormalized if @unnormalized
496
+ #@unnormalized = Text::unnormalize( @string, doctype )
497
+
498
+ @string
499
+ end
500
+
501
+ #TODO optimize it - regular expressions is slow on BB
502
+ =begin
503
+ def Text::unnormalize( string, doctype=nil, filter=nil, illegal=nil )
504
+ string.gsub( /\r\n?/, "\n" ).gsub( REFERENCE ) {
505
+ ref = $&
506
+ if ref[1] == ?#
507
+ if ref[2] == ?x
508
+ [ref[3...-1].to_i(16)].pack('U*')
509
+ else
510
+ [ref[2...-1].to_i].pack('U*')
511
+ end
512
+ elsif ref == '&amp;'
513
+ '&'
514
+ elsif filter and filter.include?( ref[1...-1] )
515
+ ref
516
+ elsif doctype
517
+ doctype.entity( ref[1...-1] ) or ref
518
+ else
519
+ entity_value = DocType::DEFAULT_ENTITIES[ ref[1...-1] ]
520
+ entity_value ? entity_value.value : ref
521
+ end
522
+ }
523
+ end
524
+ =end
525
+ end
526
+
527
+ end