voruby 1.1.1 → 2.0.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.
Files changed (257) hide show
  1. data/Rakefile.rb +107 -224
  2. data/lib/misc.rb +1 -0
  3. data/lib/misc/misc.rb +60 -0
  4. data/lib/misc/propertyfile.rb +31 -0
  5. data/lib/symphony.rb +1 -0
  6. data/lib/symphony/symphony.rb +247 -0
  7. data/lib/voruby.rb +186 -0
  8. data/lib/voruby/active_votable/active_votable.rb +468 -347
  9. data/lib/voruby/adql/1.0/adql.rb +2418 -0
  10. data/lib/voruby/adql/support.rb +2 -0
  11. data/lib/voruby/misc.rb +351 -0
  12. data/lib/voruby/misc/connection_monitor.rb +97 -0
  13. data/lib/voruby/misc/libxml_ext.rb +121 -0
  14. data/lib/voruby/misc/rexml_ext.rb +223 -0
  15. data/lib/voruby/resolver/resolver.rb +12 -0
  16. data/lib/voruby/resolver/sesame.rb +299 -0
  17. data/lib/voruby/sky_query/sky_query.rb +192 -0
  18. data/lib/voruby/stc/1.10/coords.rb +2272 -0
  19. data/lib/voruby/stc/1.10/region.rb +892 -0
  20. data/lib/voruby/stc/1.10/stc.rb +3271 -0
  21. data/lib/voruby/stc/1.30/stc.rb +8666 -0
  22. data/lib/voruby/stc/support.rb +2 -0
  23. data/lib/voruby/ucd/ucd.rb +173 -0
  24. data/lib/voruby/voevent/1.1/voevent.rb +1124 -0
  25. data/lib/voruby/voevent/support.rb +5 -0
  26. data/lib/voruby/votable/1.0/votable.rb +1807 -0
  27. data/lib/voruby/votable/1.1/votable.rb +2100 -0
  28. data/lib/voruby/votable/votable.rb +305 -0
  29. data/lib/voruby/wesix/wesix.rb +491 -0
  30. data/lib/voruby/xlink/1.2/xlink.rb +21 -0
  31. data/test/voruby/active_votable/complex.vot +60 -0
  32. data/test/voruby/active_votable/error.vot +6 -0
  33. data/test/voruby/active_votable/large.vot +130040 -0
  34. data/test/voruby/active_votable/simple1.vot +38 -0
  35. data/test/voruby/active_votable/simple2.vot +38 -0
  36. data/test/voruby/active_votable/test.rb +193 -0
  37. data/test/voruby/adql/1.0/adql-alias.sql +1 -0
  38. data/test/voruby/adql/1.0/adql-alias.xml +26 -0
  39. data/test/voruby/adql/1.0/adql-avg.sql +1 -0
  40. data/test/voruby/adql/1.0/adql-avg.xml +31 -0
  41. data/test/voruby/adql/1.0/adql-circle.sql +1 -0
  42. data/test/voruby/adql/1.0/adql-circle.xml +46 -0
  43. data/test/voruby/adql/1.0/adql-expr.sql +1 -0
  44. data/test/voruby/adql/1.0/adql-expr.xml +34 -0
  45. data/test/voruby/adql/1.0/adql-function.sql +1 -0
  46. data/test/voruby/adql/1.0/adql-function.xml +41 -0
  47. data/test/voruby/adql/1.0/adql-group.sql +1 -0
  48. data/test/voruby/adql/1.0/adql-group.xml +51 -0
  49. data/test/voruby/adql/1.0/adql-having.sql +1 -0
  50. data/test/voruby/adql/1.0/adql-having.xml +25 -0
  51. data/test/voruby/adql/1.0/adql-like.sql +1 -0
  52. data/test/voruby/adql/1.0/adql-like.xml +17 -0
  53. data/test/voruby/adql/1.0/adql-order.sql +1 -0
  54. data/test/voruby/adql/1.0/adql-order.xml +37 -0
  55. data/test/voruby/adql/1.0/adql-simple.sql +1 -0
  56. data/test/voruby/adql/1.0/adql-simple.xml +12 -0
  57. data/test/voruby/adql/1.0/adql-top.sql +1 -0
  58. data/test/voruby/adql/1.0/adql-top.xml +33 -0
  59. data/test/voruby/adql/1.0/test.rb +2220 -0
  60. data/test/voruby/misc/test.rb +32 -0
  61. data/test/voruby/resolver/sesame/test.rb +56 -0
  62. data/test/voruby/sky_query/test.rb +107 -0
  63. data/test/voruby/stc/1.10/coords_test.rb +3704 -0
  64. data/test/voruby/stc/1.10/region_test.rb +993 -0
  65. data/test/voruby/stc/1.10/stc-catalog-entry-location.xml +112 -0
  66. data/test/voruby/stc/1.10/stc-obs-data-location.xml +126 -0
  67. data/test/voruby/stc/1.10/stc-region-circle.xml +5 -0
  68. data/test/voruby/stc/1.10/stc-region-convex.xml +11 -0
  69. data/test/voruby/stc/1.10/stc-region-convexhull.xml +5 -0
  70. data/test/voruby/stc/1.10/stc-region-ellipse.xml +7 -0
  71. data/test/voruby/stc/1.10/stc-region-intersection.xml +25 -0
  72. data/test/voruby/stc/1.10/stc-region-negation.xml +7 -0
  73. data/test/voruby/stc/1.10/stc-region-polygon.xml +13 -0
  74. data/test/voruby/stc/1.10/stc-region-sector.xml +6 -0
  75. data/test/voruby/stc/1.10/stc-region-union.xml +25 -0
  76. data/test/voruby/stc/1.10/stc-resource-profile.xml +60 -0
  77. data/test/voruby/stc/1.10/stc-search-location.xml +54 -0
  78. data/test/voruby/stc/1.10/stc_test.rb +4626 -0
  79. data/test/voruby/stc/1.30/stc-catalog-entry-location.xml +210 -0
  80. data/test/voruby/stc/1.30/stc-obs-data-location-arecibo.xml +353 -0
  81. data/test/voruby/stc/1.30/stc-obs-data-location-fits.xml +250 -0
  82. data/test/voruby/stc/1.30/stc-obs-data-location-xlink.xml +63 -0
  83. data/test/voruby/stc/1.30/stc-obs-data-location.xml +216 -0
  84. data/test/voruby/stc/1.30/stc-resource-profile-unusual-ref-pos.xml +39 -0
  85. data/test/voruby/stc/1.30/stc-resource-profile.xml +129 -0
  86. data/test/voruby/stc/1.30/stc-search-location-arecibo.xml +86 -0
  87. data/test/voruby/stc/1.30/stc-search-location.xml +101 -0
  88. data/test/voruby/stc/1.30/test.rb +6274 -0
  89. data/test/voruby/ucd/test.rb +48 -0
  90. data/test/voruby/voevent/1.1/test.rb +812 -0
  91. data/test/{voevent/voevent_v1_1.xml → voruby/voevent/1.1/voevent.xml} +2 -2
  92. data/test/voruby/voregistry/0.3/test.rb +137 -0
  93. data/test/voruby/votable/1.0/test.rb +714 -0
  94. data/test/voruby/votable/1.0/votable.basic.xml +660 -0
  95. data/test/voruby/votable/1.0/votable.html +86 -0
  96. data/test/voruby/votable/1.0/votable.ns.xml +56 -0
  97. data/test/voruby/votable/1.1/test.rb +785 -0
  98. data/test/voruby/votable/1.1/votable.basic.xml +38 -0
  99. data/test/voruby/votable/1.1/votable.html +86 -0
  100. data/test/voruby/votable/1.1/votable.ns.xml +56 -0
  101. data/test/voruby/votable/test.rb +15 -0
  102. data/test/voruby/wesix/test.rb +268 -0
  103. data/test/voruby/wesix/testr.fits +28 -0
  104. metadata +234 -247
  105. data/REQUIREMENTS +0 -6
  106. data/lib/voruby/active_votable/loader.rb +0 -5
  107. data/lib/voruby/adql/adql.rb +0 -2787
  108. data/lib/voruby/adql/ext.rb +0 -14
  109. data/lib/voruby/adql/loader.rb +0 -6
  110. data/lib/voruby/adql/operations.rb +0 -54
  111. data/lib/voruby/adql/parser.rb +0 -160
  112. data/lib/voruby/adql/transforms.rb +0 -573
  113. data/lib/voruby/ext.rb +0 -17
  114. data/lib/voruby/loader.rb +0 -4
  115. data/lib/voruby/misc/propertyfile.rb +0 -36
  116. data/lib/voruby/plastic/applications.rb +0 -174
  117. data/lib/voruby/plastic/constants.rb +0 -30
  118. data/lib/voruby/plastic/loader.rb +0 -10
  119. data/lib/voruby/plastic/plastic.rb +0 -1
  120. data/lib/voruby/resources/conesearch/conesearch.rb +0 -9
  121. data/lib/voruby/resources/conesearch/conesearch_v0_2.rb +0 -55
  122. data/lib/voruby/resources/conesearch/conesearch_v0_3.rb +0 -50
  123. data/lib/voruby/resources/conesearch/conesearch_v1_0.rb +0 -72
  124. data/lib/voruby/resources/conesearch/loader.rb +0 -4
  125. data/lib/voruby/resources/loader.rb +0 -50
  126. data/lib/voruby/resources/nodes.rb +0 -190
  127. data/lib/voruby/resources/openskynode/loader.rb +0 -4
  128. data/lib/voruby/resources/openskynode/openskynode.rb +0 -9
  129. data/lib/voruby/resources/openskynode/openskynode_v0_1.rb +0 -54
  130. data/lib/voruby/resources/sia/loader.rb +0 -5
  131. data/lib/voruby/resources/sia/sia.rb +0 -9
  132. data/lib/voruby/resources/sia/sia_v0_6.rb +0 -90
  133. data/lib/voruby/resources/sia/sia_v0_7.rb +0 -89
  134. data/lib/voruby/resources/sia/sia_v1_0.rb +0 -122
  135. data/lib/voruby/resources/stsci.rb +0 -59
  136. data/lib/voruby/resources/vodataservice/coverage_v0_2.rb +0 -195
  137. data/lib/voruby/resources/vodataservice/coverage_v0_3.rb +0 -158
  138. data/lib/voruby/resources/vodataservice/loader.rb +0 -5
  139. data/lib/voruby/resources/vodataservice/vodataservice.rb +0 -9
  140. data/lib/voruby/resources/vodataservice/vodataservice_v0_4.rb +0 -189
  141. data/lib/voruby/resources/vodataservice/vodataservice_v0_5.rb +0 -163
  142. data/lib/voruby/resources/vodataservice/vodataservice_v1_0.rb +0 -221
  143. data/lib/voruby/resources/voregistry/loader.rb +0 -4
  144. data/lib/voruby/resources/voregistry/voregistry.rb +0 -9
  145. data/lib/voruby/resources/voregistry/voregistry_v0_2.rb +0 -40
  146. data/lib/voruby/resources/voregistry/voregistry_v0_3.rb +0 -30
  147. data/lib/voruby/resources/voregistry/voregistry_v1_0.rb +0 -86
  148. data/lib/voruby/resources/voresource/loader.rb +0 -17
  149. data/lib/voruby/resources/voresource/voresource.rb +0 -9
  150. data/lib/voruby/resources/voresource/voresource_v0_10.rb +0 -327
  151. data/lib/voruby/resources/voresource/voresource_v0_9.rb +0 -405
  152. data/lib/voruby/resources/voresource/voresource_v1_0.rb +0 -230
  153. data/lib/voruby/services/ext.rb +0 -11
  154. data/lib/voruby/services/gestalt/footprint.rb +0 -95
  155. data/lib/voruby/services/gestalt/wcs_fixer.rb +0 -105
  156. data/lib/voruby/services/gestalt/wesix.rb +0 -155
  157. data/lib/voruby/services/loader.rb +0 -7
  158. data/lib/voruby/services/registry/registry.rb +0 -53
  159. data/lib/voruby/services/resolver/resolver.rb +0 -35
  160. data/lib/voruby/services/schema/schema.rb +0 -644
  161. data/lib/voruby/sesame/loader.rb +0 -6
  162. data/lib/voruby/sesame/sesame_v1_0.rb +0 -64
  163. data/lib/voruby/simple/loader.rb +0 -6
  164. data/lib/voruby/simple/parameters.rb +0 -196
  165. data/lib/voruby/simple/sap.rb +0 -446
  166. data/lib/voruby/spacetime/loader.rb +0 -3
  167. data/lib/voruby/spacetime/spacetime.rb +0 -607
  168. data/lib/voruby/stc/coords_v1_20.rb +0 -900
  169. data/lib/voruby/stc/loader.rb +0 -55
  170. data/lib/voruby/stc/region_v1_20.rb +0 -274
  171. data/lib/voruby/stc/stc_v1_20.rb +0 -1196
  172. data/lib/voruby/util.rb +0 -27
  173. data/lib/voruby/voevent/loader.rb +0 -7
  174. data/lib/voruby/voevent/voevent_v1_0.rb +0 -213
  175. data/lib/voruby/voevent/voevent_v1_1.rb +0 -196
  176. data/lib/voruby/votables/chandra.rb +0 -373
  177. data/lib/voruby/votables/data.rb +0 -179
  178. data/lib/voruby/votables/galex.rb +0 -377
  179. data/lib/voruby/votables/int.rb +0 -354
  180. data/lib/voruby/votables/libxml_parser.rb +0 -411
  181. data/lib/voruby/votables/libxml_votable.rb +0 -67
  182. data/lib/voruby/votables/loader.rb +0 -10
  183. data/lib/voruby/votables/meta.rb +0 -763
  184. data/lib/voruby/votables/misc.rb +0 -51
  185. data/lib/voruby/votables/nsa.rb +0 -410
  186. data/lib/voruby/votables/rexml_parser.rb +0 -408
  187. data/lib/voruby/votables/rexml_votable.rb +0 -67
  188. data/lib/voruby/votables/sdss.rb +0 -356
  189. data/lib/voruby/votables/transforms.rb +0 -388
  190. data/lib/voruby/votables/tree.rb +0 -45
  191. data/lib/voruby/votables/types.rb +0 -391
  192. data/lib/voruby/votables/votable.rb +0 -687
  193. data/test/active_votable/database.yml +0 -6
  194. data/test/active_votable/test.vot +0 -168492
  195. data/test/active_votable/unittest.rb +0 -41
  196. data/test/adql/test1.adql +0 -49
  197. data/test/adql/test2.adql +0 -51
  198. data/test/adql/test3.adql +0 -81
  199. data/test/adql/test4.adql +0 -53
  200. data/test/adql/test5.adql +0 -55
  201. data/test/adql/test6.adql +0 -18
  202. data/test/adql/test7.adql +0 -48
  203. data/test/adql/unittest.rb +0 -1672
  204. data/test/plastic/test.rb +0 -44
  205. data/test/plastic/test.vot +0 -5385
  206. data/test/plastic/unittest.rb +0 -66
  207. data/test/resources/conesearch/conesearch_v0_3.xml +0 -31
  208. data/test/resources/conesearch/conesearch_v1_0.xml +0 -86
  209. data/test/resources/conesearch/unittest_v0_3.rb +0 -22
  210. data/test/resources/conesearch/unittest_v1_0.rb +0 -24
  211. data/test/resources/openskynode/open_sky_node_v0_1.xml +0 -32
  212. data/test/resources/openskynode/unittest_v0_1.rb +0 -31
  213. data/test/resources/sia/simple_image_access_v0_7.xml +0 -36
  214. data/test/resources/sia/simple_image_access_v1_0.xml +0 -122
  215. data/test/resources/sia/unittest_v0_7.rb +0 -24
  216. data/test/resources/sia/unittest_v1_0.rb +0 -29
  217. data/test/resources/stsci.xml +0 -336
  218. data/test/resources/unittest_stsci.rb +0 -25
  219. data/test/resources/vodataservice/catalog_service_resource_v1_0.xml +0 -128
  220. data/test/resources/vodataservice/data_collection_resource_v0_5.xml +0 -54
  221. data/test/resources/vodataservice/data_collection_resource_v1_0.xml +0 -117
  222. data/test/resources/vodataservice/data_service_resource_v1_0.xml +0 -115
  223. data/test/resources/vodataservice/sky_service_resource_v0_10.xml +0 -45
  224. data/test/resources/vodataservice/table_service_resource_v1_0.xml +0 -122
  225. data/test/resources/vodataservice/tabular_sky_service_resource_v0_10.xml +0 -60
  226. data/test/resources/vodataservice/unittest_v0_5.rb +0 -126
  227. data/test/resources/vodataservice/unittest_v1_0.rb +0 -151
  228. data/test/resources/voregistry/authority_resource_v0_3.xml +0 -20
  229. data/test/resources/voregistry/authority_resource_v1_0.xml +0 -82
  230. data/test/resources/voregistry/registry_service_v0_3.xml +0 -20
  231. data/test/resources/voregistry/registry_service_v1_0.xml +0 -107
  232. data/test/resources/voregistry/unittest_v0_3.rb +0 -31
  233. data/test/resources/voregistry/unittest_v1_0.rb +0 -34
  234. data/test/resources/voresource/organisation_resource_v1_0.xml +0 -90
  235. data/test/resources/voresource/resource_organisation_v0_10.xml +0 -22
  236. data/test/resources/voresource/resource_service_v0_10.xml +0 -19
  237. data/test/resources/voresource/resource_v0_10.xml +0 -19
  238. data/test/resources/voresource/resource_v1_0.xml +0 -79
  239. data/test/resources/voresource/service_resource_v1_0.xml +0 -91
  240. data/test/resources/voresource/unittest_v0_10.rb +0 -61
  241. data/test/resources/voresource/unittest_v0_9.rb +0 -4
  242. data/test/resources/voresource/unittest_v1_0.rb +0 -190
  243. data/test/services/gestalt/unittest.rb +0 -74
  244. data/test/services/registry/unittest.rb +0 -34
  245. data/test/services/resolver/unittest.rb +0 -38
  246. data/test/simple/unittest.rb +0 -46
  247. data/test/spacetime/unittest.rb +0 -39
  248. data/test/stc/catalog_entry_location_v1_20.xml +0 -112
  249. data/test/stc/obs_data_location_v1_20.xml +0 -108
  250. data/test/stc/search_location_v1_20.xml +0 -54
  251. data/test/stc/stc_resource_profile_v1_20.xml +0 -60
  252. data/test/stc/unittest_v1_20.rb +0 -620
  253. data/test/voevent/unittest_v1_0.rb +0 -79
  254. data/test/voevent/unittest_v1_1.rb +0 -70
  255. data/test/voevent/voevent_v1_0.xml +0 -96
  256. data/test/votables/test.vot +0 -366
  257. data/test/votables/unittest.rb +0 -54
@@ -0,0 +1,2 @@
1
+ require 'rexml/document'
2
+ require 'voruby/misc'
@@ -0,0 +1,351 @@
1
+ require 'ostruct'
2
+
3
+ XSI_NAMESPACE = OpenStruct.new(:uri => 'http://www.w3.org/2001/XMLSchema-instance', :prefix => 'xsi')
4
+
5
+ # A hash mapping module names to XML namespaces.
6
+ NAMESPACES = {
7
+ 'VORuby::STC::V1_10::Coords' => OpenStruct.new(:uri => 'http://www.ivoa.net/xml/STC/STCcoords/v1.10', :prefix => 'crd'),
8
+ 'VORuby::STC::V1_10::Region' => OpenStruct.new(:uri => 'http://www.ivoa.net/xml/STC/STCregion/v1.10', :prefix => 'reg'),
9
+ 'VORuby::STC::V1_10::STC' => OpenStruct.new(:uri => 'http://www.ivoa.net/xml/STC/stc-v1.10.xsd', :prefix => 'stc'),
10
+ 'VORuby::STC::V1_30' => OpenStruct.new(:uri => 'http://www.ivoa.net/xml/STC/stc-v1.30.xsd', :prefix => 'stc'),
11
+ 'VORuby::XLink::V1_2' => OpenStruct.new(:uri => 'http://www.w3.org/1999/xlink', :prefix => 'xlink'),
12
+ 'VORuby::ADQL::V1_0' => OpenStruct.new(:uri => 'http://www.ivoa.net/xml/ADQL/v1.0', :prefix => 'adq'),
13
+ 'VORuby::VOEvent::V1_1' => OpenStruct.new(:uri => 'http://www.ivoa.net/xml/VOEvent/v1.1', :prefix => 'voe'),
14
+ 'VORuby::VOResource::V0_10' => OpenStruct.new(:uri => 'http://www.ivoa.net/xml/VOResource/v0.10', :prefix => 'vr'),
15
+ 'VORuby::VORegistry::V0_3' => OpenStruct.new(:uri => 'http://www.ivoa.net/xml/VORegistry/v0.3', :prefix => 'vg'),
16
+ 'VORuby::VODataService::V0_5' => OpenStruct.new(:uri => 'http://www.ivoa.net/xml/VODataService/v0.5', :prefix => 'vs'),
17
+ 'VORuby::ConeSearch::V0_3' => OpenStruct.new(:uri => 'http://www.ivoa.net/xml/ConeSearch/v0.3', :prefix => 'cs')
18
+ }
19
+
20
+ # Raises an ArgumentError with the specified root message.
21
+ def raise_argument_required_error(msg)
22
+ raise ArgumentError, "#{msg} required"
23
+ end
24
+
25
+ # Raises a TypeError if the given variable isn't of the expected class.
26
+ def raise_type_mismatch_error(var, expected_klass)
27
+ raise TypeError, "invalid type #{var.class} for #{var.inspect}, expected #{expected_klass}" if !var.is_a?(expected_klass)
28
+ end
29
+
30
+ # An astract array which will only accept objects of a specified type,
31
+ # and optionally enforce a size range.
32
+ class TypedArray < Array
33
+ def self.restricted_to; nil end
34
+ def self.maximum_length; nil end
35
+
36
+ def initialize(args)
37
+ check_members(args)
38
+ super(args)
39
+ check_length
40
+ end
41
+
42
+ def []=(i, item)
43
+ check_members(item)
44
+ super(i, item)
45
+ check_length
46
+ end
47
+
48
+ def <<(item)
49
+ check_members(item)
50
+ super(item)
51
+ check_length
52
+ end
53
+
54
+ def replace(items)
55
+ check_members(items)
56
+ super(items)
57
+ check_length
58
+ end
59
+
60
+ def insert(index, *items)
61
+ check_members(items)
62
+ super(index, *items)
63
+ check_length
64
+ end
65
+
66
+ def clear
67
+ super
68
+ check_length
69
+ end
70
+
71
+ def to_s
72
+ self.collect{ |item| item.to_s }.join(' ')
73
+ end
74
+
75
+ protected
76
+
77
+ def check_length
78
+ if self.class.respond_to?(:maximum_length) and self.class.maximum_length
79
+ raise "#{self.size} > maximum length of #{self.class.maximum_length}" if self.size > self.class.maximum_length
80
+ end
81
+
82
+ if self.class.respond_to?(:minimum_length) and self.class.minimum_length
83
+ raise "#{self.size} < minimum length of #{self.class.minimum_length}" if self.size < self.class.minimum_length
84
+ end
85
+ end
86
+
87
+ def check_members(list)
88
+ list = [list] if !list.is_a?(Array)
89
+
90
+ if self.class.respond_to?(:restricted_to) and self.class.restricted_to
91
+ list.each do |l|
92
+ raise TypeError, "invalid type #{l.class} for #{l.inspect}, expected #{self.class.restricted_to}" if !self.class.restricted_to.find{ |klass| l.is_a?(klass) }
93
+ end
94
+ end
95
+ end
96
+ end
97
+
98
+ # An abstract class that represents a set of possible choices.
99
+ class Enumeration
100
+ def self.choices; nil end
101
+
102
+ attr_reader :value
103
+
104
+ def initialize(v)
105
+ self.value = v
106
+ end
107
+
108
+ def value=(v)
109
+ if self.class.respond_to?(:choices) and self.class.choices and !self.class.choices.include?(v)
110
+ raise ArgumentError, "value was #{v}, but #{self.class.to_s.split('::').last} must be one of: #{self.class.choices.join(', ')}"
111
+ end
112
+
113
+ @value = v
114
+ end
115
+
116
+ def to_s
117
+ self.value.to_s
118
+ end
119
+
120
+ def ==(v)
121
+ self.value == v.value
122
+ end
123
+ end
124
+
125
+ # Various utilities for dealing with Ruby classes and XML mappings.
126
+ # Normally included in an existing module.
127
+ module XMLUtilities
128
+ def element_from(xml)
129
+ xml.is_a?(REXML::Element) ? xml : REXML::Document.new(xml).root
130
+ end
131
+
132
+ def element_name_from(klass)
133
+ klass.respond_to?(:element_name) ? klass.element_name : klass.to_s.split('::').last
134
+ end
135
+
136
+ def current_module
137
+ target = self.is_a?(Class) ? self : self.class
138
+ target.to_s.split('::')[0..-2].inject(Object){ |x, y| x.const_get(y) }
139
+ end
140
+
141
+ def find_classes_of_type(type, mod=nil)
142
+ mod ||= current_module
143
+ mod.constants.find_all{ |c|
144
+ obj = mod.const_get(c)
145
+ obj.is_a?(Class) and obj.allocate().is_a?(type)
146
+ }
147
+ end
148
+
149
+ def find_class_with_name(name, mod=nil)
150
+ mod ||= current_module
151
+ mod.const_get(
152
+ mod.constants.find { |c|
153
+ obj = mod.const_get(c)
154
+ obj.is_a?(Class) and name == element_name_from(obj)
155
+ }
156
+ )
157
+ end
158
+
159
+ def xpath_for(type, mod=nil)
160
+ mod ||= current_module
161
+ find_classes_of_type(type, mod).collect { |klass_name|
162
+ element_name_from(
163
+ klass_name.split('::').inject(Object){ |x, y| x.const_get(y) }
164
+ )
165
+ }
166
+ end
167
+
168
+ def obj_ns(mod_name=nil)
169
+ mod_name ||= current_module.to_s
170
+ NAMESPACES[mod_name]
171
+ end
172
+
173
+ def find_elements(root, path, ns=nil)
174
+ ns ||= obj_ns
175
+ root.children.find_all{ |n|
176
+ n.respond_to?(:name) and path.include?(n.name) and n.namespace == ns.uri
177
+ }
178
+ end
179
+
180
+ def xml_to_obj(node, klass=nil, first_only=false, mod=nil)
181
+ raise 'xml node is required' if !node
182
+
183
+ if klass # style 1 (as in STC): element name + substitution groups determines object
184
+ mod ||= current_module
185
+ objects = find_elements(node, xpath_for(klass, mod), obj_ns(mod.to_s)).collect{ |n| find_class_with_name(n.name, mod).from_xml(n) }
186
+ first_only ? objects.first : objects
187
+ else # style 2 (as in ADQL): xsi:type determines object
188
+ # find the xsi:type attribute
189
+ xsi_type_def = node.attributes.get_attribute_ns(XSI_NAMESPACE.uri, 'type')
190
+ raise "unable to find xsi:type attribute for #{node}" if !xsi_type_def
191
+
192
+ # extract its namespace prefix (if none is present, use the default)
193
+ # and the type name.
194
+ type_def = xsi_type_def.value.split(':')
195
+ type_ns_prefix = type_def.size == 2 ? type_def.first : nil
196
+ type_ns_uri = node.namespace(type_ns_prefix)
197
+ type_name = type_def.size == 2 ? type_def.last : type_def.first
198
+
199
+ # find the module that corresponds to the namespace prefix
200
+ ns_info = NAMESPACES.find { |key, value| value.uri == type_ns_uri }
201
+ raise "unable to find module corresponding to #{type_ns_uri}" if !ns_info
202
+ mod = ns_info.first.to_s.split('::').inject(Object){ |x, y| x.const_get(y) }
203
+
204
+ # search through the module for the class who's xml_type is equal
205
+ # to the type name
206
+ klass = mod.constants.find { |c|
207
+ obj = mod.const_get(c)
208
+ obj.is_a?(Class) and obj.respond_to?(:xml_type) and obj.respond_to?(:from_xml) and obj.xml_type == type_name
209
+ }.split('::').inject(Object){ |x, y| x.const_get(y) }
210
+ raise "unable to find class with an xml_type of #{type_name}" if !klass
211
+
212
+ # instantiate the class
213
+ klass.from_xml(node)
214
+ end
215
+ end
216
+
217
+ def collapse_namespaces(el, existing_namespaces=nil)
218
+ return if !el or !el.has_elements?
219
+
220
+ existing_namespaces ||= el.namespaces
221
+
222
+ el.children.each do |child|
223
+ child.namespaces.each do |prefix, uri|
224
+ child.delete_namespace(prefix) if existing_namespaces.has_key?(prefix)
225
+ end
226
+
227
+ collapse_namespaces(child, existing_namespaces.merge(child.namespaces))
228
+ end
229
+ end
230
+ end
231
+
232
+ # A mix-in that adds to a classes the ability to serialize
233
+ # themselves to very basic XML.
234
+ module SerializableToXml
235
+ def element(name=nil, ns=nil, options={})
236
+ name ||= element_name_from(self.class)
237
+ ns ||= obj_ns
238
+
239
+ el = REXML::Element.new("#{ns.prefix}:#{name}")
240
+ el.add_namespace(ns.prefix, ns.uri)
241
+
242
+ el.add_namespace(XSI_NAMESPACE.prefix, XSI_NAMESPACE.uri) if options[:include_xsi]
243
+ el.attributes["#{XSI_NAMESPACE.prefix}:type"] = "#{options[:prefix] || ns.prefix}:#{options[:type]}" if options[:type]
244
+
245
+ el
246
+ end
247
+ end
248
+
249
+ # Basic IDREF
250
+ class IdRef
251
+ include SerializableToXml
252
+
253
+ attr_reader :value
254
+
255
+ def initialize(ref)
256
+ self.value = ref
257
+ end
258
+
259
+ def value=(ref)
260
+ raise ArgumentError, "reference can't be blank" if !ref or ref.to_s.strip == ''
261
+ @value = ref.to_s
262
+ end
263
+
264
+ def to_s
265
+ self.value.to_s
266
+ end
267
+
268
+ def ==(id)
269
+ self.value == id.value
270
+ end
271
+
272
+ def to_xml(name=nil)
273
+ el = element(name)
274
+ el.text = self.value.to_s
275
+ el
276
+ end
277
+
278
+ def self.from_xml(xml)
279
+ self.new(element_from(xml).text)
280
+ end
281
+ end
282
+
283
+ # Basic ID
284
+ class Id
285
+ attr_reader :value
286
+
287
+ include SerializableToXml
288
+
289
+ def initialize(ref)
290
+ self.value = ref
291
+ end
292
+
293
+ def value=(i)
294
+ raise ArgumentError, "ID can't be blank" if !i or i.to_s.strip == ''
295
+ @value = i.to_s
296
+ end
297
+
298
+ def to_s
299
+ self.value.to_s
300
+ end
301
+
302
+ def ==(id)
303
+ self.value == id.value
304
+ end
305
+
306
+ def to_xml(name=nil)
307
+ el = element(name)
308
+ el.text = self.value.to_s
309
+ el
310
+ end
311
+
312
+ def self.from_xml(xml)
313
+ self.new(element_from(xml).text)
314
+ end
315
+ end
316
+
317
+ # Regex-restricted string
318
+ class RegexRestrictedString
319
+ attr_reader :value
320
+
321
+ include SerializableToXml
322
+
323
+ def initialize(s)
324
+ self.value = s
325
+ end
326
+
327
+ def regex; /.*/ end
328
+
329
+ def value=(s)
330
+ raise_argument_required_error('value') if !s
331
+ raise "#{s} does not match /#{self.regex.source}/" if !s.match(self.regex)
332
+ @value = s
333
+ end
334
+
335
+ def ==(s)
336
+ self.value == s.value
337
+ end
338
+
339
+ def to_s; self.value.to_s end
340
+
341
+ def to_xml(name=nil, ns=nil)
342
+ el = element(name, ns)
343
+ el.text = self.value
344
+ el
345
+ end
346
+
347
+ def self.from_xml(xml)
348
+ root = element_from(xml)
349
+ self.new(root.text)
350
+ end
351
+ end
@@ -0,0 +1,97 @@
1
+ module VORuby
2
+ module Misc
3
+
4
+ # Monitors (by way of "pinging") a URL.
5
+ # monitor = ConnectionMonitor.new('http://www.noao.edu/')
6
+ # monitor.on_success = Proc.new{ |pinger, monitor|
7
+ # puts "#{monitor.url} is awake!"
8
+ # }
9
+ # monitor.on_failure = Proc.new{ |pinger, monitor|
10
+ # puts "Connection to #{monitor.url} failed: #{pinger.exception}"
11
+ # }
12
+ #
13
+ # monitor.start
14
+ # => http://www.noao.edu/ is awake! # Wait 10 minutes...
15
+ # => http://www.noao.edu/ is awake! # Wait 10 minutes...
16
+ # => Connection to http://www.noao.edu/ failed: some error message # Uh oh! Something happened...
17
+ class ConnectionMonitor
18
+ require 'loader'
19
+ require 'net/ping'
20
+
21
+ # The Net::PingHTTP object doing the actual pinging.
22
+ attr_reader :pinger
23
+ # The URL being pinged.
24
+ attr_reader :url
25
+ # The amount of time to wait (in seconds) before timing out a connection.
26
+ attr_reader :timeout
27
+
28
+ # The frequency (in seconds) at which to poll.
29
+ attr_accessor :polling_freq
30
+ # A Proc triggered when a ping fails. Takes the Net::PingHTTP object and the monitor itself.
31
+ attr_accessor :on_failure
32
+ # A Proc triggered when a ping succeeds. Takes the Net::PingHTTP object and the monitor itself.
33
+ attr_accessor :on_success
34
+ # A Proc triggered when the monitor is interrupted (i.e via Ctrl-C)
35
+ attr_accessor :on_interrupt
36
+
37
+ # Place a monitor on the specified URL.
38
+ # By default the URL will be "pinged" every 600 seconds
39
+ # and will timeout if it doesn't receive a response
40
+ # within 5 seconds.
41
+ def initialize(url, polling_freq=600, timeout=5)
42
+ @pinger = Net::Ping::HTTP.new(url)
43
+
44
+ self.polling_freq = polling_freq
45
+ self.url = url
46
+ self.timeout = timeout
47
+
48
+ @interrupted = false
49
+
50
+ self.on_failure = Proc.new{ |pinger, monitor|
51
+ puts "Connection to #{monitor.url} failed: #{pinger.exception}."
52
+ }
53
+ self.on_success = Proc.new{ |pinger, monitor| }
54
+ self.on_interrupt = Proc.new{ @interrupted = true }
55
+
56
+ trap("INT"){ self.on_interrupt.call }
57
+ end
58
+
59
+ # Set the URL to monitor.
60
+ def url=(url)
61
+ @url = url
62
+ @pinger.host = url
63
+ @pinger.port = URI.parse(url).port
64
+ end
65
+
66
+ # Set the timeout for the monitor.
67
+ def timeout=(s)
68
+ @timeout = s
69
+ @pinger.timeout = s
70
+ end
71
+
72
+ # Start monitoring, but do so in a thread.
73
+ def start_threaded
74
+ @t = Thread.new { start }
75
+ @t.run
76
+ end
77
+
78
+ # Start monitoring.
79
+ def start
80
+ while true
81
+ return if @interrupted
82
+
83
+ pinger.ping ? on_success.call(pinger, self): on_failure.call(pinger, self)
84
+ sleep(polling_freq)
85
+ end
86
+ end
87
+
88
+ # Stop monitoring.
89
+ def stop
90
+ self.on_interrupt.call
91
+ end
92
+
93
+ end
94
+
95
+ end
96
+ end
97
+