voruby 1.1.1 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
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
+