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.
- data/Rakefile.rb +107 -224
- data/lib/misc.rb +1 -0
- data/lib/misc/misc.rb +60 -0
- data/lib/misc/propertyfile.rb +31 -0
- data/lib/symphony.rb +1 -0
- data/lib/symphony/symphony.rb +247 -0
- data/lib/voruby.rb +186 -0
- data/lib/voruby/active_votable/active_votable.rb +468 -347
- data/lib/voruby/adql/1.0/adql.rb +2418 -0
- data/lib/voruby/adql/support.rb +2 -0
- data/lib/voruby/misc.rb +351 -0
- data/lib/voruby/misc/connection_monitor.rb +97 -0
- data/lib/voruby/misc/libxml_ext.rb +121 -0
- data/lib/voruby/misc/rexml_ext.rb +223 -0
- data/lib/voruby/resolver/resolver.rb +12 -0
- data/lib/voruby/resolver/sesame.rb +299 -0
- data/lib/voruby/sky_query/sky_query.rb +192 -0
- data/lib/voruby/stc/1.10/coords.rb +2272 -0
- data/lib/voruby/stc/1.10/region.rb +892 -0
- data/lib/voruby/stc/1.10/stc.rb +3271 -0
- data/lib/voruby/stc/1.30/stc.rb +8666 -0
- data/lib/voruby/stc/support.rb +2 -0
- data/lib/voruby/ucd/ucd.rb +173 -0
- data/lib/voruby/voevent/1.1/voevent.rb +1124 -0
- data/lib/voruby/voevent/support.rb +5 -0
- data/lib/voruby/votable/1.0/votable.rb +1807 -0
- data/lib/voruby/votable/1.1/votable.rb +2100 -0
- data/lib/voruby/votable/votable.rb +305 -0
- data/lib/voruby/wesix/wesix.rb +491 -0
- data/lib/voruby/xlink/1.2/xlink.rb +21 -0
- data/test/voruby/active_votable/complex.vot +60 -0
- data/test/voruby/active_votable/error.vot +6 -0
- data/test/voruby/active_votable/large.vot +130040 -0
- data/test/voruby/active_votable/simple1.vot +38 -0
- data/test/voruby/active_votable/simple2.vot +38 -0
- data/test/voruby/active_votable/test.rb +193 -0
- data/test/voruby/adql/1.0/adql-alias.sql +1 -0
- data/test/voruby/adql/1.0/adql-alias.xml +26 -0
- data/test/voruby/adql/1.0/adql-avg.sql +1 -0
- data/test/voruby/adql/1.0/adql-avg.xml +31 -0
- data/test/voruby/adql/1.0/adql-circle.sql +1 -0
- data/test/voruby/adql/1.0/adql-circle.xml +46 -0
- data/test/voruby/adql/1.0/adql-expr.sql +1 -0
- data/test/voruby/adql/1.0/adql-expr.xml +34 -0
- data/test/voruby/adql/1.0/adql-function.sql +1 -0
- data/test/voruby/adql/1.0/adql-function.xml +41 -0
- data/test/voruby/adql/1.0/adql-group.sql +1 -0
- data/test/voruby/adql/1.0/adql-group.xml +51 -0
- data/test/voruby/adql/1.0/adql-having.sql +1 -0
- data/test/voruby/adql/1.0/adql-having.xml +25 -0
- data/test/voruby/adql/1.0/adql-like.sql +1 -0
- data/test/voruby/adql/1.0/adql-like.xml +17 -0
- data/test/voruby/adql/1.0/adql-order.sql +1 -0
- data/test/voruby/adql/1.0/adql-order.xml +37 -0
- data/test/voruby/adql/1.0/adql-simple.sql +1 -0
- data/test/voruby/adql/1.0/adql-simple.xml +12 -0
- data/test/voruby/adql/1.0/adql-top.sql +1 -0
- data/test/voruby/adql/1.0/adql-top.xml +33 -0
- data/test/voruby/adql/1.0/test.rb +2220 -0
- data/test/voruby/misc/test.rb +32 -0
- data/test/voruby/resolver/sesame/test.rb +56 -0
- data/test/voruby/sky_query/test.rb +107 -0
- data/test/voruby/stc/1.10/coords_test.rb +3704 -0
- data/test/voruby/stc/1.10/region_test.rb +993 -0
- data/test/voruby/stc/1.10/stc-catalog-entry-location.xml +112 -0
- data/test/voruby/stc/1.10/stc-obs-data-location.xml +126 -0
- data/test/voruby/stc/1.10/stc-region-circle.xml +5 -0
- data/test/voruby/stc/1.10/stc-region-convex.xml +11 -0
- data/test/voruby/stc/1.10/stc-region-convexhull.xml +5 -0
- data/test/voruby/stc/1.10/stc-region-ellipse.xml +7 -0
- data/test/voruby/stc/1.10/stc-region-intersection.xml +25 -0
- data/test/voruby/stc/1.10/stc-region-negation.xml +7 -0
- data/test/voruby/stc/1.10/stc-region-polygon.xml +13 -0
- data/test/voruby/stc/1.10/stc-region-sector.xml +6 -0
- data/test/voruby/stc/1.10/stc-region-union.xml +25 -0
- data/test/voruby/stc/1.10/stc-resource-profile.xml +60 -0
- data/test/voruby/stc/1.10/stc-search-location.xml +54 -0
- data/test/voruby/stc/1.10/stc_test.rb +4626 -0
- data/test/voruby/stc/1.30/stc-catalog-entry-location.xml +210 -0
- data/test/voruby/stc/1.30/stc-obs-data-location-arecibo.xml +353 -0
- data/test/voruby/stc/1.30/stc-obs-data-location-fits.xml +250 -0
- data/test/voruby/stc/1.30/stc-obs-data-location-xlink.xml +63 -0
- data/test/voruby/stc/1.30/stc-obs-data-location.xml +216 -0
- data/test/voruby/stc/1.30/stc-resource-profile-unusual-ref-pos.xml +39 -0
- data/test/voruby/stc/1.30/stc-resource-profile.xml +129 -0
- data/test/voruby/stc/1.30/stc-search-location-arecibo.xml +86 -0
- data/test/voruby/stc/1.30/stc-search-location.xml +101 -0
- data/test/voruby/stc/1.30/test.rb +6274 -0
- data/test/voruby/ucd/test.rb +48 -0
- data/test/voruby/voevent/1.1/test.rb +812 -0
- data/test/{voevent/voevent_v1_1.xml → voruby/voevent/1.1/voevent.xml} +2 -2
- data/test/voruby/voregistry/0.3/test.rb +137 -0
- data/test/voruby/votable/1.0/test.rb +714 -0
- data/test/voruby/votable/1.0/votable.basic.xml +660 -0
- data/test/voruby/votable/1.0/votable.html +86 -0
- data/test/voruby/votable/1.0/votable.ns.xml +56 -0
- data/test/voruby/votable/1.1/test.rb +785 -0
- data/test/voruby/votable/1.1/votable.basic.xml +38 -0
- data/test/voruby/votable/1.1/votable.html +86 -0
- data/test/voruby/votable/1.1/votable.ns.xml +56 -0
- data/test/voruby/votable/test.rb +15 -0
- data/test/voruby/wesix/test.rb +268 -0
- data/test/voruby/wesix/testr.fits +28 -0
- metadata +234 -247
- data/REQUIREMENTS +0 -6
- data/lib/voruby/active_votable/loader.rb +0 -5
- data/lib/voruby/adql/adql.rb +0 -2787
- data/lib/voruby/adql/ext.rb +0 -14
- data/lib/voruby/adql/loader.rb +0 -6
- data/lib/voruby/adql/operations.rb +0 -54
- data/lib/voruby/adql/parser.rb +0 -160
- data/lib/voruby/adql/transforms.rb +0 -573
- data/lib/voruby/ext.rb +0 -17
- data/lib/voruby/loader.rb +0 -4
- data/lib/voruby/misc/propertyfile.rb +0 -36
- data/lib/voruby/plastic/applications.rb +0 -174
- data/lib/voruby/plastic/constants.rb +0 -30
- data/lib/voruby/plastic/loader.rb +0 -10
- data/lib/voruby/plastic/plastic.rb +0 -1
- data/lib/voruby/resources/conesearch/conesearch.rb +0 -9
- data/lib/voruby/resources/conesearch/conesearch_v0_2.rb +0 -55
- data/lib/voruby/resources/conesearch/conesearch_v0_3.rb +0 -50
- data/lib/voruby/resources/conesearch/conesearch_v1_0.rb +0 -72
- data/lib/voruby/resources/conesearch/loader.rb +0 -4
- data/lib/voruby/resources/loader.rb +0 -50
- data/lib/voruby/resources/nodes.rb +0 -190
- data/lib/voruby/resources/openskynode/loader.rb +0 -4
- data/lib/voruby/resources/openskynode/openskynode.rb +0 -9
- data/lib/voruby/resources/openskynode/openskynode_v0_1.rb +0 -54
- data/lib/voruby/resources/sia/loader.rb +0 -5
- data/lib/voruby/resources/sia/sia.rb +0 -9
- data/lib/voruby/resources/sia/sia_v0_6.rb +0 -90
- data/lib/voruby/resources/sia/sia_v0_7.rb +0 -89
- data/lib/voruby/resources/sia/sia_v1_0.rb +0 -122
- data/lib/voruby/resources/stsci.rb +0 -59
- data/lib/voruby/resources/vodataservice/coverage_v0_2.rb +0 -195
- data/lib/voruby/resources/vodataservice/coverage_v0_3.rb +0 -158
- data/lib/voruby/resources/vodataservice/loader.rb +0 -5
- data/lib/voruby/resources/vodataservice/vodataservice.rb +0 -9
- data/lib/voruby/resources/vodataservice/vodataservice_v0_4.rb +0 -189
- data/lib/voruby/resources/vodataservice/vodataservice_v0_5.rb +0 -163
- data/lib/voruby/resources/vodataservice/vodataservice_v1_0.rb +0 -221
- data/lib/voruby/resources/voregistry/loader.rb +0 -4
- data/lib/voruby/resources/voregistry/voregistry.rb +0 -9
- data/lib/voruby/resources/voregistry/voregistry_v0_2.rb +0 -40
- data/lib/voruby/resources/voregistry/voregistry_v0_3.rb +0 -30
- data/lib/voruby/resources/voregistry/voregistry_v1_0.rb +0 -86
- data/lib/voruby/resources/voresource/loader.rb +0 -17
- data/lib/voruby/resources/voresource/voresource.rb +0 -9
- data/lib/voruby/resources/voresource/voresource_v0_10.rb +0 -327
- data/lib/voruby/resources/voresource/voresource_v0_9.rb +0 -405
- data/lib/voruby/resources/voresource/voresource_v1_0.rb +0 -230
- data/lib/voruby/services/ext.rb +0 -11
- data/lib/voruby/services/gestalt/footprint.rb +0 -95
- data/lib/voruby/services/gestalt/wcs_fixer.rb +0 -105
- data/lib/voruby/services/gestalt/wesix.rb +0 -155
- data/lib/voruby/services/loader.rb +0 -7
- data/lib/voruby/services/registry/registry.rb +0 -53
- data/lib/voruby/services/resolver/resolver.rb +0 -35
- data/lib/voruby/services/schema/schema.rb +0 -644
- data/lib/voruby/sesame/loader.rb +0 -6
- data/lib/voruby/sesame/sesame_v1_0.rb +0 -64
- data/lib/voruby/simple/loader.rb +0 -6
- data/lib/voruby/simple/parameters.rb +0 -196
- data/lib/voruby/simple/sap.rb +0 -446
- data/lib/voruby/spacetime/loader.rb +0 -3
- data/lib/voruby/spacetime/spacetime.rb +0 -607
- data/lib/voruby/stc/coords_v1_20.rb +0 -900
- data/lib/voruby/stc/loader.rb +0 -55
- data/lib/voruby/stc/region_v1_20.rb +0 -274
- data/lib/voruby/stc/stc_v1_20.rb +0 -1196
- data/lib/voruby/util.rb +0 -27
- data/lib/voruby/voevent/loader.rb +0 -7
- data/lib/voruby/voevent/voevent_v1_0.rb +0 -213
- data/lib/voruby/voevent/voevent_v1_1.rb +0 -196
- data/lib/voruby/votables/chandra.rb +0 -373
- data/lib/voruby/votables/data.rb +0 -179
- data/lib/voruby/votables/galex.rb +0 -377
- data/lib/voruby/votables/int.rb +0 -354
- data/lib/voruby/votables/libxml_parser.rb +0 -411
- data/lib/voruby/votables/libxml_votable.rb +0 -67
- data/lib/voruby/votables/loader.rb +0 -10
- data/lib/voruby/votables/meta.rb +0 -763
- data/lib/voruby/votables/misc.rb +0 -51
- data/lib/voruby/votables/nsa.rb +0 -410
- data/lib/voruby/votables/rexml_parser.rb +0 -408
- data/lib/voruby/votables/rexml_votable.rb +0 -67
- data/lib/voruby/votables/sdss.rb +0 -356
- data/lib/voruby/votables/transforms.rb +0 -388
- data/lib/voruby/votables/tree.rb +0 -45
- data/lib/voruby/votables/types.rb +0 -391
- data/lib/voruby/votables/votable.rb +0 -687
- data/test/active_votable/database.yml +0 -6
- data/test/active_votable/test.vot +0 -168492
- data/test/active_votable/unittest.rb +0 -41
- data/test/adql/test1.adql +0 -49
- data/test/adql/test2.adql +0 -51
- data/test/adql/test3.adql +0 -81
- data/test/adql/test4.adql +0 -53
- data/test/adql/test5.adql +0 -55
- data/test/adql/test6.adql +0 -18
- data/test/adql/test7.adql +0 -48
- data/test/adql/unittest.rb +0 -1672
- data/test/plastic/test.rb +0 -44
- data/test/plastic/test.vot +0 -5385
- data/test/plastic/unittest.rb +0 -66
- data/test/resources/conesearch/conesearch_v0_3.xml +0 -31
- data/test/resources/conesearch/conesearch_v1_0.xml +0 -86
- data/test/resources/conesearch/unittest_v0_3.rb +0 -22
- data/test/resources/conesearch/unittest_v1_0.rb +0 -24
- data/test/resources/openskynode/open_sky_node_v0_1.xml +0 -32
- data/test/resources/openskynode/unittest_v0_1.rb +0 -31
- data/test/resources/sia/simple_image_access_v0_7.xml +0 -36
- data/test/resources/sia/simple_image_access_v1_0.xml +0 -122
- data/test/resources/sia/unittest_v0_7.rb +0 -24
- data/test/resources/sia/unittest_v1_0.rb +0 -29
- data/test/resources/stsci.xml +0 -336
- data/test/resources/unittest_stsci.rb +0 -25
- data/test/resources/vodataservice/catalog_service_resource_v1_0.xml +0 -128
- data/test/resources/vodataservice/data_collection_resource_v0_5.xml +0 -54
- data/test/resources/vodataservice/data_collection_resource_v1_0.xml +0 -117
- data/test/resources/vodataservice/data_service_resource_v1_0.xml +0 -115
- data/test/resources/vodataservice/sky_service_resource_v0_10.xml +0 -45
- data/test/resources/vodataservice/table_service_resource_v1_0.xml +0 -122
- data/test/resources/vodataservice/tabular_sky_service_resource_v0_10.xml +0 -60
- data/test/resources/vodataservice/unittest_v0_5.rb +0 -126
- data/test/resources/vodataservice/unittest_v1_0.rb +0 -151
- data/test/resources/voregistry/authority_resource_v0_3.xml +0 -20
- data/test/resources/voregistry/authority_resource_v1_0.xml +0 -82
- data/test/resources/voregistry/registry_service_v0_3.xml +0 -20
- data/test/resources/voregistry/registry_service_v1_0.xml +0 -107
- data/test/resources/voregistry/unittest_v0_3.rb +0 -31
- data/test/resources/voregistry/unittest_v1_0.rb +0 -34
- data/test/resources/voresource/organisation_resource_v1_0.xml +0 -90
- data/test/resources/voresource/resource_organisation_v0_10.xml +0 -22
- data/test/resources/voresource/resource_service_v0_10.xml +0 -19
- data/test/resources/voresource/resource_v0_10.xml +0 -19
- data/test/resources/voresource/resource_v1_0.xml +0 -79
- data/test/resources/voresource/service_resource_v1_0.xml +0 -91
- data/test/resources/voresource/unittest_v0_10.rb +0 -61
- data/test/resources/voresource/unittest_v0_9.rb +0 -4
- data/test/resources/voresource/unittest_v1_0.rb +0 -190
- data/test/services/gestalt/unittest.rb +0 -74
- data/test/services/registry/unittest.rb +0 -34
- data/test/services/resolver/unittest.rb +0 -38
- data/test/simple/unittest.rb +0 -46
- data/test/spacetime/unittest.rb +0 -39
- data/test/stc/catalog_entry_location_v1_20.xml +0 -112
- data/test/stc/obs_data_location_v1_20.xml +0 -108
- data/test/stc/search_location_v1_20.xml +0 -54
- data/test/stc/stc_resource_profile_v1_20.xml +0 -60
- data/test/stc/unittest_v1_20.rb +0 -620
- data/test/voevent/unittest_v1_0.rb +0 -79
- data/test/voevent/unittest_v1_1.rb +0 -70
- data/test/voevent/voevent_v1_0.xml +0 -96
- data/test/votables/test.vot +0 -366
- data/test/votables/unittest.rb +0 -54
@@ -0,0 +1,1807 @@
|
|
1
|
+
require 'voruby/votable/votable'
|
2
|
+
|
3
|
+
module VORuby
|
4
|
+
module VOTable
|
5
|
+
|
6
|
+
# Classes that represent the domain objects in the VOTable 1.0 specification
|
7
|
+
# (http://www.ivoa.net/Documents/PR/VOTable/VOTable-20031017.html).
|
8
|
+
module V1_0
|
9
|
+
|
10
|
+
# The root element of the votable.
|
11
|
+
class VOTable < VORuby::VOTable::Base
|
12
|
+
ELEMENT_NAME = 'VOTABLE'
|
13
|
+
|
14
|
+
def self.serialization_order
|
15
|
+
[
|
16
|
+
:description, :definitions, :infos, :resources,
|
17
|
+
:version, :id
|
18
|
+
]
|
19
|
+
end
|
20
|
+
|
21
|
+
# Create a votable.
|
22
|
+
# To parse an existing votable one would normally do this:
|
23
|
+
# votable = VOTable.from_file('my_file.xml')
|
24
|
+
# but any of the other methods described in VOTable::Base#new are also acceptable:
|
25
|
+
# votable = VOTable.new(
|
26
|
+
# :version => '1.0',
|
27
|
+
# :id => 'votable1',
|
28
|
+
# :description => Description.new(:text => 'A test votable'),
|
29
|
+
# :resources => [Resource.new(...)]
|
30
|
+
# ) # etc.
|
31
|
+
#
|
32
|
+
# or to create a blank VOTable that you'll build up later:
|
33
|
+
# votable = VOTable.new()
|
34
|
+
def initialize(defn=nil)
|
35
|
+
super(defn)
|
36
|
+
self.version = '1.0' if !self.version
|
37
|
+
end
|
38
|
+
|
39
|
+
# Retrieve the version. By default this is '1.0'.
|
40
|
+
def version
|
41
|
+
self.node['version']
|
42
|
+
end
|
43
|
+
|
44
|
+
# Set the version. Normally you should leave
|
45
|
+
# this as 1.0.
|
46
|
+
def version=(v)
|
47
|
+
@node['version'] = v.to_s
|
48
|
+
end
|
49
|
+
|
50
|
+
def id
|
51
|
+
self.node['ID']
|
52
|
+
end
|
53
|
+
|
54
|
+
def id=(i)
|
55
|
+
@node['ID'] = i.to_s
|
56
|
+
end
|
57
|
+
|
58
|
+
# Retrieve the description (Description).
|
59
|
+
def description
|
60
|
+
get_element(Description)
|
61
|
+
end
|
62
|
+
|
63
|
+
# Set the description (Description).
|
64
|
+
# votable.description = Description.new(:text => 'A fascinating votable')
|
65
|
+
def description=(d)
|
66
|
+
set_element(Description, d)
|
67
|
+
end
|
68
|
+
|
69
|
+
# Retrieve the definitions (Definitions).
|
70
|
+
def definitions
|
71
|
+
get_element(Definitions)
|
72
|
+
end
|
73
|
+
|
74
|
+
# Set the definitions (Definitions).
|
75
|
+
def definitions=(d)
|
76
|
+
set_element(Definitions, d)
|
77
|
+
end
|
78
|
+
|
79
|
+
# Retrieve the coordinate systems (Coosys).
|
80
|
+
def coordinate_systems
|
81
|
+
HomogeneousNodeList.new(self.node, xpath_for(Coosys), Coosys)
|
82
|
+
end
|
83
|
+
|
84
|
+
# Set the coordinate systems.
|
85
|
+
# Takes an array of Coosys objects.
|
86
|
+
# votable.coordinate_systems = [Coosys.new(), ...]
|
87
|
+
def coordinate_systems=(systems)
|
88
|
+
self.coordinate_systems.replace(systems)
|
89
|
+
end
|
90
|
+
|
91
|
+
# Retrieve the parameters (Param).
|
92
|
+
# Returns a HomogeneousNodeList.
|
93
|
+
def params
|
94
|
+
HomogeneousNodeList.new(self.node, xpath_for(Param), Param)
|
95
|
+
end
|
96
|
+
|
97
|
+
# Set the parameters.
|
98
|
+
# Takes an array of Param objects.
|
99
|
+
# votable.params = [Param.new(), ...]
|
100
|
+
def params=(parameters)
|
101
|
+
self.params.replace(parameters)
|
102
|
+
end
|
103
|
+
|
104
|
+
# Retrieve the information list (Info).
|
105
|
+
# Returns a HomogeneousNodeList.
|
106
|
+
def infos
|
107
|
+
HomogeneousNodeList.new(self.node, xpath_for(Info), Info)
|
108
|
+
end
|
109
|
+
|
110
|
+
# Set the information list.
|
111
|
+
# Takes an array of Info objects.
|
112
|
+
# votable.infos = [Info.new(), ...]
|
113
|
+
def infos=(is)
|
114
|
+
self.infos.replace(is)
|
115
|
+
end
|
116
|
+
|
117
|
+
# Retrieve the resources (Resource).
|
118
|
+
# Returns a HomogeneousNodeList.
|
119
|
+
def resources
|
120
|
+
HomogeneousNodeList.new(self.node, xpath_for(Resource), Resource)
|
121
|
+
end
|
122
|
+
|
123
|
+
# Set the resources.
|
124
|
+
# Takes an array of Resource objects.
|
125
|
+
# votable.resources = [Resource.new(), ...]
|
126
|
+
def resources=(res)
|
127
|
+
self.resources.replace(res)
|
128
|
+
end
|
129
|
+
|
130
|
+
# Convert a VOTable to HTML.
|
131
|
+
# Not all attributes are converted.
|
132
|
+
# See test/voruby/votable/1.1/votable.html for an example of the output.
|
133
|
+
def to_html
|
134
|
+
builder = Builder::XmlMarkup.new(:indent => 2)
|
135
|
+
|
136
|
+
votable_opts = {:class => 'votable'}
|
137
|
+
votable_opts[:id] = self.id if self.id
|
138
|
+
|
139
|
+
builder.div(votable_opts){ |votable|
|
140
|
+
votable.div(self.description.text, :class => 'description') if self.description
|
141
|
+
|
142
|
+
self.resources.each do |res|
|
143
|
+
votable << res.to_html
|
144
|
+
end
|
145
|
+
}
|
146
|
+
end
|
147
|
+
|
148
|
+
protected
|
149
|
+
|
150
|
+
def methods_to_test_for_equality
|
151
|
+
[
|
152
|
+
:version, :id, :description,
|
153
|
+
:definitions, :infos, :resources
|
154
|
+
]
|
155
|
+
end
|
156
|
+
end
|
157
|
+
|
158
|
+
# A simple description of something.
|
159
|
+
class Description < VORuby::VOTable::Base
|
160
|
+
ELEMENT_NAME = 'DESCRIPTION'
|
161
|
+
|
162
|
+
# Create a description.
|
163
|
+
# descr = Description.new(:text => 'Hello, world!')
|
164
|
+
def initialize(defn=nil)
|
165
|
+
super(defn)
|
166
|
+
end
|
167
|
+
|
168
|
+
# Retrieve the actual text of the description.
|
169
|
+
def text
|
170
|
+
self.node.content
|
171
|
+
end
|
172
|
+
|
173
|
+
# Set the text of the description.
|
174
|
+
# descr.text = 'Hello, world!'
|
175
|
+
def text=(text)
|
176
|
+
@node.content = text
|
177
|
+
end
|
178
|
+
|
179
|
+
protected
|
180
|
+
|
181
|
+
def methods_to_test_for_equality; [:text] end
|
182
|
+
end
|
183
|
+
|
184
|
+
# Definitions of various values appropriate to the votable.
|
185
|
+
class Definitions < VORuby::VOTable::Base
|
186
|
+
ELEMENT_NAME = 'DEFINITIONS'
|
187
|
+
|
188
|
+
# Create a set of definitions.
|
189
|
+
# definitions = Definitions.new(
|
190
|
+
# :coordinate_systems => [Coosys.new]
|
191
|
+
# :params => [Param.new]
|
192
|
+
# )
|
193
|
+
def initialize(defn=nil)
|
194
|
+
super(defn)
|
195
|
+
end
|
196
|
+
|
197
|
+
# Retrieve the coordinate systems (Coosys).
|
198
|
+
# Returns a HomogeneousNodeList.
|
199
|
+
def coordinate_systems
|
200
|
+
HomogeneousNodeList.new(self.node, xpath_for(Coosys), Coosys)
|
201
|
+
end
|
202
|
+
|
203
|
+
# Retrieve the parameters (Param).
|
204
|
+
# Returns a HomogeneousNodeList.
|
205
|
+
def coordinate_systems=(systems)
|
206
|
+
self.coordinate_systems.replace(systems)
|
207
|
+
end
|
208
|
+
|
209
|
+
# Retrieve the parameters (Param).
|
210
|
+
# Returns a HomogeneousNodeList.
|
211
|
+
def params
|
212
|
+
HomogeneousNodeList.new(self.node, xpath_for(Param), Param)
|
213
|
+
end
|
214
|
+
|
215
|
+
# Set the parameter list.
|
216
|
+
# Takes an array of Param objects.
|
217
|
+
# definitions.params = [Param.new(), ...]
|
218
|
+
def params=(parameters)
|
219
|
+
self.params.replace(parameters)
|
220
|
+
end
|
221
|
+
|
222
|
+
protected
|
223
|
+
|
224
|
+
def methods_to_test_for_equality
|
225
|
+
[:coordinate_systems, :params]
|
226
|
+
end
|
227
|
+
end
|
228
|
+
|
229
|
+
# A celestial coordinate system, to which the components of a position on the celestial sphere refer.
|
230
|
+
class Coosys < VORuby::VOTable::Base
|
231
|
+
ELEMENT_NAME = 'COOSYS'
|
232
|
+
|
233
|
+
# Create a new coordinate system.
|
234
|
+
# coosys = Coosys.new(
|
235
|
+
# :id => 'J2000',
|
236
|
+
# :equinox => 'J2000.',
|
237
|
+
# :epoch => 'J2000.',
|
238
|
+
# :system => 'eq_FK5'
|
239
|
+
# )
|
240
|
+
# The default system is eq_FK5.
|
241
|
+
def initialize(defn=nil)
|
242
|
+
super(defn)
|
243
|
+
self.system = 'eq_FK5' if !self.system
|
244
|
+
end
|
245
|
+
|
246
|
+
def id
|
247
|
+
self.node['ID']
|
248
|
+
end
|
249
|
+
|
250
|
+
def id=(i)
|
251
|
+
@node['ID'] = i.to_s
|
252
|
+
end
|
253
|
+
|
254
|
+
def equinox
|
255
|
+
self.node['equinox']
|
256
|
+
end
|
257
|
+
|
258
|
+
def equinox=(e)
|
259
|
+
@node['equinox'] = e.to_s
|
260
|
+
end
|
261
|
+
|
262
|
+
def epoch
|
263
|
+
self.node['epoch']
|
264
|
+
end
|
265
|
+
|
266
|
+
def epoch=(e)
|
267
|
+
@node['epoch'] = e.to_s
|
268
|
+
end
|
269
|
+
|
270
|
+
def system
|
271
|
+
self.node['system']
|
272
|
+
end
|
273
|
+
|
274
|
+
# Set the system.
|
275
|
+
# May be one of: eq_FK4, eq_FK5, ICRS,
|
276
|
+
# ecl_FK4, ecl_FK5, galactic, supergalactic, xy,
|
277
|
+
# barycentric or geo_app.
|
278
|
+
def system=(s)
|
279
|
+
@node['system'] = s.to_s
|
280
|
+
end
|
281
|
+
|
282
|
+
protected
|
283
|
+
|
284
|
+
def methods_to_test_for_equality
|
285
|
+
[:id, :equinox, :epoch, :system]
|
286
|
+
end
|
287
|
+
end
|
288
|
+
|
289
|
+
# A global value associated with (usually) a table.
|
290
|
+
class Param < VORuby::VOTable::Base
|
291
|
+
include Castable
|
292
|
+
|
293
|
+
ELEMENT_NAME = 'PARAM'
|
294
|
+
|
295
|
+
def self.serialization_order
|
296
|
+
[
|
297
|
+
:description, :values, :links,
|
298
|
+
:id, :unit, :datatype, :arraysize, :precision, :width, :ref, :name,
|
299
|
+
:ucd, :value
|
300
|
+
]
|
301
|
+
end
|
302
|
+
|
303
|
+
# Create a new parameter.
|
304
|
+
# param = Param.new(
|
305
|
+
# :name => 'Telescope',
|
306
|
+
# :datatype => 'float',
|
307
|
+
# :ucd => 'phys.size;instr.tel',
|
308
|
+
# :unit => 'm',
|
309
|
+
# :value => '3.6'
|
310
|
+
# )
|
311
|
+
def initialize(defn=nil)
|
312
|
+
super(defn)
|
313
|
+
end
|
314
|
+
|
315
|
+
def id
|
316
|
+
self.node['ID']
|
317
|
+
end
|
318
|
+
|
319
|
+
def id=(i)
|
320
|
+
@node['ID'] = i.to_s
|
321
|
+
end
|
322
|
+
|
323
|
+
def unit
|
324
|
+
self.node['unit']
|
325
|
+
end
|
326
|
+
|
327
|
+
# Set the unit.
|
328
|
+
# Units should be of the form outlined by Vizier[http://vizier.u-strasbg.fr/doc/catstd-3.2.htx].
|
329
|
+
def unit=(u)
|
330
|
+
@node['unit'] = u.to_s
|
331
|
+
end
|
332
|
+
|
333
|
+
def datatype
|
334
|
+
self.node['datatype']
|
335
|
+
end
|
336
|
+
|
337
|
+
# Set the datatype.
|
338
|
+
# Should be one of: boolean, bit, unsignedByte, short, int, long,
|
339
|
+
# char, unicodeChar, float, double, floatComplex, doubleComplex.
|
340
|
+
def datatype=(d)
|
341
|
+
@node['datatype'] = d.to_s
|
342
|
+
end
|
343
|
+
|
344
|
+
def precision
|
345
|
+
self.node['precision']
|
346
|
+
end
|
347
|
+
|
348
|
+
# Set the precision of the value.
|
349
|
+
# Should match [EF]?[1-9][0-9]*
|
350
|
+
# param.precision = '1'
|
351
|
+
def precision=(p)
|
352
|
+
@node['precision'] = p.to_s
|
353
|
+
end
|
354
|
+
|
355
|
+
def width
|
356
|
+
self.node['width'].to_i
|
357
|
+
end
|
358
|
+
|
359
|
+
def width=(w)
|
360
|
+
@node['width'] = w.to_s
|
361
|
+
end
|
362
|
+
|
363
|
+
def ref
|
364
|
+
self.node['ref']
|
365
|
+
end
|
366
|
+
|
367
|
+
def ref=(r)
|
368
|
+
@node['ref'] = r.to_s
|
369
|
+
end
|
370
|
+
|
371
|
+
def name
|
372
|
+
self.node['name']
|
373
|
+
end
|
374
|
+
|
375
|
+
def name=(n)
|
376
|
+
@node['name'] = n.to_s
|
377
|
+
end
|
378
|
+
|
379
|
+
def ucd
|
380
|
+
self.node['ucd']
|
381
|
+
end
|
382
|
+
|
383
|
+
# Set the unified content descriptor or UCD[http://vizier.u-strasbg.fr/doc/UCD.htx].
|
384
|
+
def ucd=(u)
|
385
|
+
@node['ucd'] = u.to_s
|
386
|
+
end
|
387
|
+
|
388
|
+
def arraysize
|
389
|
+
self.node['arraysize']
|
390
|
+
end
|
391
|
+
|
392
|
+
# Set the arraysize (if applicable).
|
393
|
+
# i.e. *, 8x2
|
394
|
+
def arraysize=(a)
|
395
|
+
@node['arraysize'] = a.to_s
|
396
|
+
end
|
397
|
+
|
398
|
+
# Retrieve the value of the parameter.
|
399
|
+
# If _cast_ is false (default), the value is returned as a simple string.
|
400
|
+
# However, if _cast_ is true, the datatype and arraysize are used to
|
401
|
+
# determine a suitable object (or list of objects) to return.
|
402
|
+
# See Castable#as_obj for more details.
|
403
|
+
def value(cast=false)
|
404
|
+
cast ? as_obj(self.value, self.datatype, self.arraysize) : self.node['value']
|
405
|
+
end
|
406
|
+
|
407
|
+
# Set the value of the parameter.
|
408
|
+
# An attempt is made to convert native ruby types using the datatype and
|
409
|
+
# arraysize parameters.
|
410
|
+
# param.value = Complex.new(1.1, 2.2) # etc.
|
411
|
+
def value=(v)
|
412
|
+
@node['value'] = v.is_a?(String) ? v : as_string(v, self.datatype, self.arraysize)
|
413
|
+
end
|
414
|
+
|
415
|
+
# Retrieve the description (Description).
|
416
|
+
def description
|
417
|
+
get_element(Description)
|
418
|
+
end
|
419
|
+
|
420
|
+
# Set the description (Description).
|
421
|
+
def description=(d)
|
422
|
+
set_element(Description, d)
|
423
|
+
end
|
424
|
+
|
425
|
+
# Retrieve the values (Values).
|
426
|
+
def values
|
427
|
+
get_element(Values)
|
428
|
+
end
|
429
|
+
|
430
|
+
# Set the values (Values).
|
431
|
+
def values=(v)
|
432
|
+
set_element(Values, v)
|
433
|
+
end
|
434
|
+
|
435
|
+
# Retrieve the links.
|
436
|
+
# Returns a HomogeneousNodeList object.
|
437
|
+
def links
|
438
|
+
HomogeneousNodeList.new(self.node, xpath_for(Link), Link)
|
439
|
+
end
|
440
|
+
|
441
|
+
# Set the links.
|
442
|
+
# Takes an array of Link objects.
|
443
|
+
def links=(lnks)
|
444
|
+
self.links.replace(lnks)
|
445
|
+
end
|
446
|
+
|
447
|
+
protected
|
448
|
+
|
449
|
+
def methods_to_test_for_equality
|
450
|
+
[
|
451
|
+
:id, :unit, :datatype, :precision, :width, :ref, :name, :ucd,
|
452
|
+
:value, :arraysize,
|
453
|
+
:description, :values, :links
|
454
|
+
]
|
455
|
+
end
|
456
|
+
end
|
457
|
+
|
458
|
+
# A name-value pair.
|
459
|
+
class Info < VORuby::VOTable::Base
|
460
|
+
ELEMENT_NAME = 'INFO'
|
461
|
+
|
462
|
+
# Create a new name-value pair.
|
463
|
+
# info = Info.new(:name => 'history', :value => 'my first observation')
|
464
|
+
def initialize(defn=nil)
|
465
|
+
super(defn)
|
466
|
+
end
|
467
|
+
|
468
|
+
def id
|
469
|
+
self.node['ID']
|
470
|
+
end
|
471
|
+
|
472
|
+
def id=(i)
|
473
|
+
@node['ID'] = i.to_s
|
474
|
+
end
|
475
|
+
|
476
|
+
def name
|
477
|
+
self.node['name']
|
478
|
+
end
|
479
|
+
|
480
|
+
def name=(n)
|
481
|
+
@node['name'] = n.to_s
|
482
|
+
end
|
483
|
+
|
484
|
+
def value
|
485
|
+
self.node['value']
|
486
|
+
end
|
487
|
+
|
488
|
+
def value=(v)
|
489
|
+
@node['value'] = v
|
490
|
+
end
|
491
|
+
|
492
|
+
protected
|
493
|
+
|
494
|
+
def methods_to_test_for_equality
|
495
|
+
[:id, :name, :value]
|
496
|
+
end
|
497
|
+
end
|
498
|
+
|
499
|
+
# A description and the data values of some logically independent data structure
|
500
|
+
# within the VOTable.
|
501
|
+
class Resource < VORuby::VOTable::Base
|
502
|
+
ELEMENT_NAME = 'RESOURCE'
|
503
|
+
|
504
|
+
def self.serialization_order
|
505
|
+
[
|
506
|
+
:description, :infos, :coordinate_systems, :params, :links, :tables, :resources,
|
507
|
+
:id, :name, :type
|
508
|
+
]
|
509
|
+
end
|
510
|
+
|
511
|
+
# Create a new resource.
|
512
|
+
# res = Resource.new(
|
513
|
+
# :name => 'myFavouriteGalaxies',
|
514
|
+
# :type => 'meta',
|
515
|
+
# :params => [Param.new()],
|
516
|
+
# :links => [Link.new()],
|
517
|
+
# :tables => [Table.new()]
|
518
|
+
# )
|
519
|
+
def initialize(defn=nil)
|
520
|
+
super(defn)
|
521
|
+
end
|
522
|
+
|
523
|
+
def name
|
524
|
+
self.node['name']
|
525
|
+
end
|
526
|
+
|
527
|
+
def name=(n)
|
528
|
+
@node['name'] = n.to_s
|
529
|
+
end
|
530
|
+
|
531
|
+
def id
|
532
|
+
self.node['ID']
|
533
|
+
end
|
534
|
+
|
535
|
+
def id=(i)
|
536
|
+
@node['ID'] = i.to_s
|
537
|
+
end
|
538
|
+
|
539
|
+
# Retrieve the type.
|
540
|
+
# A type of 'meta' means that the resource is descriptive only
|
541
|
+
# (does not contain any actual data in any of its sub-elements).
|
542
|
+
def type
|
543
|
+
self.node['type']
|
544
|
+
end
|
545
|
+
|
546
|
+
# Set the type.
|
547
|
+
def type=(t)
|
548
|
+
@node['type'] = t.to_s
|
549
|
+
end
|
550
|
+
|
551
|
+
# Retrieve the description (Description).
|
552
|
+
def description
|
553
|
+
get_element(Description)
|
554
|
+
end
|
555
|
+
|
556
|
+
# Set the description (Description).
|
557
|
+
# res.description = Description.new(:text => 'A fascinating resource')
|
558
|
+
def description=(d)
|
559
|
+
set_element(Description, d)
|
560
|
+
end
|
561
|
+
|
562
|
+
# Retrieve the name-value pairs (Info).
|
563
|
+
# Returns a HomogeneousNodeList.
|
564
|
+
def infos
|
565
|
+
HomogeneousNodeList.new(self.node, xpath_for(Info), Info)
|
566
|
+
end
|
567
|
+
|
568
|
+
# Set any name-value pairs.
|
569
|
+
# res.infos = [Info.new(), ...]
|
570
|
+
def infos=(is)
|
571
|
+
self.infos.replace(is)
|
572
|
+
end
|
573
|
+
|
574
|
+
# Retrieve the coordinate systems (Coosys).
|
575
|
+
# Returns a HomogeneousNodeList.
|
576
|
+
def coordinate_systems
|
577
|
+
HomogeneousNodeList.new(self.node, xpath_for(Coosys), Coosys)
|
578
|
+
end
|
579
|
+
|
580
|
+
# Set the coordinate systems (Coosys).
|
581
|
+
# res.coordinate_systems = [Coosys.new(), ...]
|
582
|
+
def coordinate_systems=(systems)
|
583
|
+
self.coordinate_systems.replace(systems)
|
584
|
+
end
|
585
|
+
|
586
|
+
# Retrieve the parameters (Param).
|
587
|
+
# Returns a HomogeneousNodeList.
|
588
|
+
def params
|
589
|
+
HomogeneousNodeList.new(self.node, xpath_for(Param), Param)
|
590
|
+
end
|
591
|
+
|
592
|
+
# Set the parameters (Param).
|
593
|
+
# res.params = [Param.new(), ...]
|
594
|
+
def params=(parameters)
|
595
|
+
self.params.clear
|
596
|
+
parameters.each do |p|
|
597
|
+
self.params << p
|
598
|
+
end
|
599
|
+
end
|
600
|
+
|
601
|
+
# Retrieve the links (Link).
|
602
|
+
# Returns a HomogeneousNodeList.
|
603
|
+
def links
|
604
|
+
HomogeneousNodeList.new(self.node, xpath_for(Link), Link)
|
605
|
+
end
|
606
|
+
|
607
|
+
# Set the links (Link).
|
608
|
+
# res.links = [Link.new(), ...]
|
609
|
+
def links=(lnks)
|
610
|
+
self.links.replace(lnks)
|
611
|
+
end
|
612
|
+
|
613
|
+
# Retrieve the tables (Table).
|
614
|
+
# Returns a HomogeneousNodeList.
|
615
|
+
def tables
|
616
|
+
HomogeneousNodeList.new(self.node, xpath_for(Table), Table)
|
617
|
+
end
|
618
|
+
|
619
|
+
# Set the tables (Table).
|
620
|
+
# res.tables = [Table.new(), ....]
|
621
|
+
def tables=(tbls)
|
622
|
+
self.tables.replace(tbls)
|
623
|
+
end
|
624
|
+
|
625
|
+
# Retrieve sub-resources (Resource).
|
626
|
+
# Returns a HomogeneousNodeList.
|
627
|
+
def resources
|
628
|
+
HomogeneousNodeList.new(self.node, xpath_for(Resource), Resource)
|
629
|
+
end
|
630
|
+
|
631
|
+
# Set sub-resources.
|
632
|
+
# res.resources = [Resource.new(), ...]
|
633
|
+
def resources=(res)
|
634
|
+
self.resources.replace(res)
|
635
|
+
end
|
636
|
+
|
637
|
+
# Convert a resource to HTML.
|
638
|
+
def to_html
|
639
|
+
builder = Builder::XmlMarkup.new(:indent => 2, :margin => 1)
|
640
|
+
|
641
|
+
resource_opts = {:class => 'resource'}
|
642
|
+
resource_opts[:id] = self.id if self.id
|
643
|
+
|
644
|
+
builder.div(resource_opts){ |resource|
|
645
|
+
resource.h3(self.name) if self.name
|
646
|
+
resource.div(self.description.text, :class => 'description') if self.description
|
647
|
+
|
648
|
+
self.tables.each do |tbl|
|
649
|
+
resource << tbl.to_html
|
650
|
+
end
|
651
|
+
|
652
|
+
self.resources.each do |res|
|
653
|
+
resource << res.to_html
|
654
|
+
end
|
655
|
+
}
|
656
|
+
end
|
657
|
+
|
658
|
+
protected
|
659
|
+
|
660
|
+
def methods_to_test_for_equality
|
661
|
+
[
|
662
|
+
:name, :id, :type,
|
663
|
+
:description, :infos, :coordinate_systems, :params,
|
664
|
+
:links, :tables, :resources
|
665
|
+
]
|
666
|
+
end
|
667
|
+
end
|
668
|
+
|
669
|
+
# A link or pointer to other documents or data servers on the Internet through a URI.
|
670
|
+
class Link < VORuby::VOTable::Base
|
671
|
+
ELEMENT_NAME = 'LINK'
|
672
|
+
|
673
|
+
# Create a new link.
|
674
|
+
# link = Link.new(
|
675
|
+
# :href => 'http://fits.gsfc.nasa.gov/nrao_data/samples/image/swp05569slg.fits',
|
676
|
+
# :content_type => 'image/fits'
|
677
|
+
# )
|
678
|
+
def initialize(defn=nil)
|
679
|
+
super(defn)
|
680
|
+
end
|
681
|
+
|
682
|
+
def id
|
683
|
+
self.node['ID']
|
684
|
+
end
|
685
|
+
|
686
|
+
def id=(i)
|
687
|
+
@node['ID'] = i.to_s
|
688
|
+
end
|
689
|
+
|
690
|
+
def content_role
|
691
|
+
self.node['content-role']
|
692
|
+
end
|
693
|
+
|
694
|
+
# Set the content role.
|
695
|
+
# May be one of: query, hints, doc or location.
|
696
|
+
def content_role=(c)
|
697
|
+
@node['content-role'] = c.to_s
|
698
|
+
end
|
699
|
+
|
700
|
+
def content_type
|
701
|
+
self.node['content-type']
|
702
|
+
end
|
703
|
+
|
704
|
+
# Set the content type (i.e. mimetype).
|
705
|
+
def content_type=(c)
|
706
|
+
@node['content-type'] = c.to_s
|
707
|
+
end
|
708
|
+
|
709
|
+
def title
|
710
|
+
self.node['title']
|
711
|
+
end
|
712
|
+
|
713
|
+
def title=(t)
|
714
|
+
@node['title'] = t.to_s
|
715
|
+
end
|
716
|
+
|
717
|
+
def value
|
718
|
+
self.node['value']
|
719
|
+
end
|
720
|
+
|
721
|
+
def value=(v)
|
722
|
+
@node['value'] = v.to_s
|
723
|
+
end
|
724
|
+
|
725
|
+
# Retrieve the URL.
|
726
|
+
# Returns a URI object.
|
727
|
+
def href
|
728
|
+
self.node['href'] ? URI.parse(self.node['href']) : nil
|
729
|
+
end
|
730
|
+
|
731
|
+
# Set the URL.
|
732
|
+
# link.href = 'http://www.noao.edu/' # or...
|
733
|
+
# link.href = URI.parse('http://www.noao.edu/')
|
734
|
+
def href=(h)
|
735
|
+
@node['href'] = h.to_s
|
736
|
+
end
|
737
|
+
|
738
|
+
def gref
|
739
|
+
self.node['gref']
|
740
|
+
end
|
741
|
+
|
742
|
+
def gref=(g)
|
743
|
+
@node['gref'] = g.to_s
|
744
|
+
end
|
745
|
+
|
746
|
+
# Retrieve the action.
|
747
|
+
# Returns a URI object.
|
748
|
+
def action
|
749
|
+
self.node['action'] ? URI.parse(self.node['action']) : nil
|
750
|
+
end
|
751
|
+
|
752
|
+
# Set the action.
|
753
|
+
# link.action = 'http://www.retrieve-me.com/' # or...
|
754
|
+
# link.action = URI.parse('http://www.retrieve-me.com/')
|
755
|
+
def action=(a)
|
756
|
+
@node['action'] = a.to_s
|
757
|
+
end
|
758
|
+
|
759
|
+
# Retrieve the link.
|
760
|
+
# Understands any URL groked by open-uri (including file://).
|
761
|
+
# Returns a File object.
|
762
|
+
def retrieve
|
763
|
+
shref = self.href
|
764
|
+
|
765
|
+
if shref
|
766
|
+
shref.scheme == 'file' ? File.open(shref.path) : open(shref.to_s)
|
767
|
+
else
|
768
|
+
nil
|
769
|
+
end
|
770
|
+
end
|
771
|
+
|
772
|
+
protected
|
773
|
+
|
774
|
+
def methods_to_test_for_equality
|
775
|
+
[
|
776
|
+
:id, :content_role, :content_type, :title, :value,
|
777
|
+
:href, :gref, :action
|
778
|
+
]
|
779
|
+
end
|
780
|
+
end
|
781
|
+
|
782
|
+
# The basic structure of a votable. Essentially, tablular data +
|
783
|
+
# a description of the columns of that data.
|
784
|
+
class Table < VORuby::VOTable::Base
|
785
|
+
ELEMENT_NAME= 'TABLE'
|
786
|
+
|
787
|
+
def self.serialization_order
|
788
|
+
[
|
789
|
+
:description, :fields, :links, :data,
|
790
|
+
:id, :name, :ref
|
791
|
+
]
|
792
|
+
end
|
793
|
+
|
794
|
+
# Create a new table.
|
795
|
+
# table = Table.new(
|
796
|
+
# :name => 'results',
|
797
|
+
# :fields => [Field.new()],
|
798
|
+
# :data => Data.new(:format => TableData.new())
|
799
|
+
# )
|
800
|
+
def initialize(defn=nil)
|
801
|
+
super(defn)
|
802
|
+
end
|
803
|
+
|
804
|
+
def id
|
805
|
+
self.node['ID']
|
806
|
+
end
|
807
|
+
|
808
|
+
def id=(i)
|
809
|
+
@node['ID'] = i.to_s
|
810
|
+
end
|
811
|
+
|
812
|
+
def name
|
813
|
+
self.node['name']
|
814
|
+
end
|
815
|
+
|
816
|
+
def name=(n)
|
817
|
+
@node['name'] = n.to_s
|
818
|
+
end
|
819
|
+
|
820
|
+
def ref
|
821
|
+
self.node['ref']
|
822
|
+
end
|
823
|
+
|
824
|
+
def ref=(r)
|
825
|
+
@node['ref'] = r.to_s
|
826
|
+
end
|
827
|
+
|
828
|
+
# Retrieve the description (Description).
|
829
|
+
def description
|
830
|
+
get_element(Description)
|
831
|
+
end
|
832
|
+
|
833
|
+
# Set the description (Description).
|
834
|
+
def description=(d)
|
835
|
+
set_element(Description, d)
|
836
|
+
end
|
837
|
+
|
838
|
+
# Retrieve the data (Data).
|
839
|
+
def data
|
840
|
+
get_element(Data)
|
841
|
+
end
|
842
|
+
|
843
|
+
# Set the data (Data).
|
844
|
+
def data=(d)
|
845
|
+
set_element(Data, d)
|
846
|
+
end
|
847
|
+
|
848
|
+
# Retrieve the fields (Field), a.k.a. column descriptions.
|
849
|
+
# Returns a HomogeneousNodeList.
|
850
|
+
def fields
|
851
|
+
HomogeneousNodeList.new(self.node, xpath_for(Field), Field)
|
852
|
+
end
|
853
|
+
|
854
|
+
# Set the fields.
|
855
|
+
# table.fields = [Field.new(), ...]
|
856
|
+
def fields=(flds)
|
857
|
+
self.fields.replace(flds)
|
858
|
+
end
|
859
|
+
|
860
|
+
# Retrieve the links (Link).
|
861
|
+
# Returns a HomogeneousNodeList.
|
862
|
+
def links
|
863
|
+
HomogeneousNodeList.new(self.node, xpath_for(Link), Link)
|
864
|
+
end
|
865
|
+
|
866
|
+
# Set the links (Link).
|
867
|
+
# table.links = [Link.new(), ...]
|
868
|
+
def links=(lnks)
|
869
|
+
self.links.replace(lnks)
|
870
|
+
end
|
871
|
+
|
872
|
+
# Convert the table into HTML.
|
873
|
+
# Not all aspects of the votable are translated.
|
874
|
+
# table = Table.new(
|
875
|
+
# :id => 'table1',
|
876
|
+
# :description => Description.new(:text => 'A test table'),
|
877
|
+
# :fields => [
|
878
|
+
# Field.new(:name => 'RA', :id => 'col1', :ucd => 'pos.eq.ra;meta.main',
|
879
|
+
# :ref => 'J2000', :datatype => 'float', :width => 6, :precision => '2', :unit => 'deg'),
|
880
|
+
# Field.new(:name => 'Dec', :id => 'col2', :ucd => 'pos.eq.dec;meta.main',
|
881
|
+
# :ref => 'J2000', :datatype => 'float', :width => 6, :precision => '2', :unit => 'deg'),
|
882
|
+
# Field.new(:name => 'Name', :id => 'col3', :ucd => 'meta.id;meta.main',
|
883
|
+
# :datatype => 'char', :arraysize => '8*')
|
884
|
+
# ],
|
885
|
+
# :data => Data.new(
|
886
|
+
# :format => TableData.new(
|
887
|
+
# :trs => [
|
888
|
+
# Tr.new(:tds => [Td.new(:text => '123'), Td.new(:text => '456'), Td.new(:text => 'my_obj1')]),
|
889
|
+
# Tr.new(:tds => [Td.new(:text => '789'), Td.new(:text => '112'), Td.new(:text => 'my_obj2')]),
|
890
|
+
# Tr.new(:tds => [Td.new(:text => '145'), Td.new(:text => '178'), Td.new(:text => 'my_obj3')])
|
891
|
+
# ]
|
892
|
+
# )
|
893
|
+
# )
|
894
|
+
# )
|
895
|
+
#
|
896
|
+
# puts table.to_html # =>
|
897
|
+
# <table id="table1">
|
898
|
+
# <caption>A test table</caption>
|
899
|
+
# <thead>
|
900
|
+
# <tr>
|
901
|
+
# <th>
|
902
|
+
# <div class="field" id="col1">
|
903
|
+
# <div class="name">RA</div>
|
904
|
+
# <div class="ucd">pos.eq.ra;meta.main</div>
|
905
|
+
# <div class="unit">deg</div>
|
906
|
+
# <span class="datatype">float</span>
|
907
|
+
# </div>
|
908
|
+
# </th>
|
909
|
+
# <th>
|
910
|
+
# <div class="field" id="col2">
|
911
|
+
# <div class="name">Dec</div>
|
912
|
+
# <div class="ucd">pos.eq.dec;meta.main</div>
|
913
|
+
# <div class="unit">deg</div>
|
914
|
+
# <span class="datatype">float</span>
|
915
|
+
# </div>
|
916
|
+
# </th>
|
917
|
+
# <th>
|
918
|
+
# <div class="field" id="col3">
|
919
|
+
# <div class="name">Name</div>
|
920
|
+
# <div class="ucd">meta.id;meta.main</div>
|
921
|
+
# <span class="datatype">char</span>
|
922
|
+
# <span class="arraysize">8*</span>
|
923
|
+
# </div>
|
924
|
+
# </th>
|
925
|
+
# </tr>
|
926
|
+
# </thead>
|
927
|
+
# <tbody>
|
928
|
+
# <tr>
|
929
|
+
# <td>123</td>
|
930
|
+
# <td>456</td>
|
931
|
+
# <td>my_obj1</td>
|
932
|
+
# </tr>
|
933
|
+
# <tr>
|
934
|
+
# <td>789</td>
|
935
|
+
# <td>112</td>
|
936
|
+
# <td>my_obj2</td>
|
937
|
+
# </tr>
|
938
|
+
# <tr>
|
939
|
+
# <td>145</td>
|
940
|
+
# <td>178</td>
|
941
|
+
# <td>my_obj3</td>
|
942
|
+
# </tr>
|
943
|
+
# </tbody>
|
944
|
+
# </table
|
945
|
+
def to_html
|
946
|
+
builder = Builder::XmlMarkup.new(:indent => 2, :margin => 2)
|
947
|
+
|
948
|
+
tbl_options = {}
|
949
|
+
tbl_options[:id] = self.id if self.id
|
950
|
+
|
951
|
+
builder.table(tbl_options) { |table|
|
952
|
+
table.caption(self.description.text) if self.description
|
953
|
+
|
954
|
+
table.thead { |thead|
|
955
|
+
if self.fields.size > 0
|
956
|
+
thead.tr { |tr|
|
957
|
+
self.fields.each do |field|
|
958
|
+
tr.th { |th|
|
959
|
+
th << field.to_html
|
960
|
+
}
|
961
|
+
end
|
962
|
+
}
|
963
|
+
end
|
964
|
+
}
|
965
|
+
|
966
|
+
if self.data and self.data.format
|
967
|
+
table.tbody { |tbody|
|
968
|
+
self.data.format.trs.each do |tr|
|
969
|
+
tbody << tr.to_html
|
970
|
+
end
|
971
|
+
}
|
972
|
+
end
|
973
|
+
}
|
974
|
+
end
|
975
|
+
|
976
|
+
protected
|
977
|
+
|
978
|
+
def methods_to_test_for_equality
|
979
|
+
[
|
980
|
+
:id, :name, :ref,
|
981
|
+
:description, :data, :fields,
|
982
|
+
:links
|
983
|
+
]
|
984
|
+
end
|
985
|
+
end
|
986
|
+
|
987
|
+
# The description of an actual table column.
|
988
|
+
class Field < VORuby::VOTable::Base
|
989
|
+
ELEMENT_NAME = 'FIELD'
|
990
|
+
|
991
|
+
def self.serialization_order
|
992
|
+
[
|
993
|
+
:description, :values, :links,
|
994
|
+
:id, :unit, :datatype, :precision, :width, :ref,
|
995
|
+
:name, :ucd, :arraysize, :type
|
996
|
+
]
|
997
|
+
end
|
998
|
+
|
999
|
+
# Create a new table column description.
|
1000
|
+
# field = Field.new(
|
1001
|
+
# :name => 'RA',
|
1002
|
+
# :id => 'col1',
|
1003
|
+
# :ucd => 'pos.eq.ra;meta.main',
|
1004
|
+
# :ref => 'J2000',
|
1005
|
+
# :datatype => 'float',
|
1006
|
+
# :width => 6,
|
1007
|
+
# :precision => '2',
|
1008
|
+
# :unit => 'deg'
|
1009
|
+
# )
|
1010
|
+
def initialize(defn=nil)
|
1011
|
+
super(defn)
|
1012
|
+
end
|
1013
|
+
|
1014
|
+
def id
|
1015
|
+
self.node['ID']
|
1016
|
+
end
|
1017
|
+
|
1018
|
+
def id=(i)
|
1019
|
+
@node['ID'] = i.to_s
|
1020
|
+
end
|
1021
|
+
|
1022
|
+
def unit
|
1023
|
+
self.node['unit']
|
1024
|
+
end
|
1025
|
+
|
1026
|
+
# Set the unit.
|
1027
|
+
# Units should be of the form outlined by Vizier[http://vizier.u-strasbg.fr/doc/catstd-3.2.htx].
|
1028
|
+
def unit=(u)
|
1029
|
+
@node['unit'] = u.to_s
|
1030
|
+
end
|
1031
|
+
|
1032
|
+
def datatype
|
1033
|
+
self.node['datatype']
|
1034
|
+
end
|
1035
|
+
|
1036
|
+
# Set the datatype.
|
1037
|
+
# Should be one of: boolean, bit, unsignedByte, short, int, long,
|
1038
|
+
# char, unicodeChar, float, double, floatComplex, doubleComplex.
|
1039
|
+
def datatype=(d)
|
1040
|
+
@node['datatype'] = d.to_s
|
1041
|
+
end
|
1042
|
+
|
1043
|
+
def precision
|
1044
|
+
self.node['precision']
|
1045
|
+
end
|
1046
|
+
|
1047
|
+
# Set the precision of the value.
|
1048
|
+
# Should match [EF]?[1-9][0-9]*
|
1049
|
+
# param.precision = '1'
|
1050
|
+
def precision=(p)
|
1051
|
+
@node['precision'] = p.to_s
|
1052
|
+
end
|
1053
|
+
|
1054
|
+
def width
|
1055
|
+
self.node['width'] ? self.node['width'].to_i : nil
|
1056
|
+
end
|
1057
|
+
|
1058
|
+
# Set the width.
|
1059
|
+
# Should be an integer.
|
1060
|
+
# param.width = 2
|
1061
|
+
def width=(w)
|
1062
|
+
@node['width'] = w.to_s
|
1063
|
+
end
|
1064
|
+
|
1065
|
+
def ref
|
1066
|
+
self.node['ref']
|
1067
|
+
end
|
1068
|
+
|
1069
|
+
def ref=(r)
|
1070
|
+
@node['ref'] = r.to_s
|
1071
|
+
end
|
1072
|
+
|
1073
|
+
def name
|
1074
|
+
self.node['name']
|
1075
|
+
end
|
1076
|
+
|
1077
|
+
def name=(n)
|
1078
|
+
@node['name'] = n.to_s
|
1079
|
+
end
|
1080
|
+
|
1081
|
+
def ucd
|
1082
|
+
self.node['ucd']
|
1083
|
+
end
|
1084
|
+
|
1085
|
+
# Set the unified content descriptor or UCD[http://vizier.u-strasbg.fr/doc/UCD.htx].
|
1086
|
+
def ucd=(u)
|
1087
|
+
@node['ucd'] = u.to_s
|
1088
|
+
end
|
1089
|
+
|
1090
|
+
def arraysize
|
1091
|
+
self.node['arraysize']
|
1092
|
+
end
|
1093
|
+
|
1094
|
+
# Set the arraysize (if applicable).
|
1095
|
+
# i.e. *, 8x2
|
1096
|
+
def arraysize=(a)
|
1097
|
+
@node['arraysize'] = a.to_s
|
1098
|
+
end
|
1099
|
+
|
1100
|
+
def type
|
1101
|
+
self.node['type']
|
1102
|
+
end
|
1103
|
+
|
1104
|
+
# Set the type. May be one of: hidden, no_query or trigger.
|
1105
|
+
def type=(t)
|
1106
|
+
@node['type'] = t.to_s
|
1107
|
+
end
|
1108
|
+
|
1109
|
+
# Retrieve the description (Description).
|
1110
|
+
def description
|
1111
|
+
get_element(Description)
|
1112
|
+
end
|
1113
|
+
|
1114
|
+
# Set the description (Description).
|
1115
|
+
def description=(d)
|
1116
|
+
set_element(Description, d)
|
1117
|
+
end
|
1118
|
+
|
1119
|
+
# Retrieve the values (Values).
|
1120
|
+
def values
|
1121
|
+
HomogeneousNodeList.new(self.node, xpath_for(Values), Values)
|
1122
|
+
end
|
1123
|
+
|
1124
|
+
# Set the values (Values).
|
1125
|
+
def values=(vals)
|
1126
|
+
self.values.replace(vals)
|
1127
|
+
end
|
1128
|
+
|
1129
|
+
# Retrieve the links.
|
1130
|
+
# Returns a HomogeneousNodeList object.
|
1131
|
+
def links
|
1132
|
+
HomogeneousNodeList.new(self.node, xpath_for(Link), Link)
|
1133
|
+
end
|
1134
|
+
|
1135
|
+
# Set the links.
|
1136
|
+
# Takes an array of Link objects.
|
1137
|
+
def links=(lnks)
|
1138
|
+
self.links.replace(lnks)
|
1139
|
+
end
|
1140
|
+
|
1141
|
+
# Convert a field to HTML.
|
1142
|
+
def to_html
|
1143
|
+
builder = Builder::XmlMarkup.new(:indent => 2, :margin => 6)
|
1144
|
+
|
1145
|
+
field_opts = {:class => 'field'}
|
1146
|
+
field_opts[:id] = self.id if self.id
|
1147
|
+
|
1148
|
+
builder.div(field_opts) { |field|
|
1149
|
+
field.div(self.name, :class => 'name')
|
1150
|
+
field.div(self.ucd, :class => 'ucd') if self.ucd
|
1151
|
+
field.div(self.unit, :class => 'unit') if self.unit
|
1152
|
+
field.span(self.datatype, :class => 'datatype') if self.datatype
|
1153
|
+
field.span(self.arraysize, :class => 'arraysize') if self.arraysize
|
1154
|
+
}
|
1155
|
+
end
|
1156
|
+
|
1157
|
+
protected
|
1158
|
+
|
1159
|
+
def methods_to_test_for_equality
|
1160
|
+
[
|
1161
|
+
:id, :unit, :datatype, :precision, :width, :ref,
|
1162
|
+
:name, :ucd, :arraysize, :type,
|
1163
|
+
:description, :values, :links
|
1164
|
+
]
|
1165
|
+
end
|
1166
|
+
end
|
1167
|
+
|
1168
|
+
# Holds subsidiary information about the domain of the data.
|
1169
|
+
class Values < VORuby::VOTable::Base
|
1170
|
+
ELEMENT_NAME = 'VALUES'
|
1171
|
+
|
1172
|
+
def self.serialization_order
|
1173
|
+
[
|
1174
|
+
:min, :max, :options,
|
1175
|
+
:id, :type, :null, :invalid
|
1176
|
+
]
|
1177
|
+
end
|
1178
|
+
|
1179
|
+
# Create some new subsidiary information about the domain.
|
1180
|
+
# values = Values.new(
|
1181
|
+
# :id => 'RAdomain',
|
1182
|
+
# :min => Min.new(:value => '0'),
|
1183
|
+
# :max => Max.new(:value => '360', :inclusive => false)
|
1184
|
+
# )
|
1185
|
+
def initialize(defn=nil)
|
1186
|
+
super(defn)
|
1187
|
+
self.type = 'legal' if !self.type
|
1188
|
+
end
|
1189
|
+
|
1190
|
+
def id
|
1191
|
+
self.node['ID']
|
1192
|
+
end
|
1193
|
+
|
1194
|
+
def id=(i)
|
1195
|
+
@node['ID'] = i.to_s
|
1196
|
+
end
|
1197
|
+
|
1198
|
+
def type
|
1199
|
+
self.node['type']
|
1200
|
+
end
|
1201
|
+
|
1202
|
+
# Set the scope of values present.
|
1203
|
+
# Possible values are: legal, actual.
|
1204
|
+
# Defaults to legal.
|
1205
|
+
def type=(t)
|
1206
|
+
@node['type'] = t.to_s
|
1207
|
+
end
|
1208
|
+
|
1209
|
+
def null
|
1210
|
+
self.node['null']
|
1211
|
+
end
|
1212
|
+
|
1213
|
+
# Set the value that is used to specify
|
1214
|
+
# non-existent data.
|
1215
|
+
def null=(n)
|
1216
|
+
@node['null'] = n.to_s
|
1217
|
+
end
|
1218
|
+
|
1219
|
+
def invalid
|
1220
|
+
self.node['invalid']
|
1221
|
+
end
|
1222
|
+
|
1223
|
+
# Returns a boolean depending on whether the
|
1224
|
+
# value is considered invalid.
|
1225
|
+
def invalid?
|
1226
|
+
self.node['invalid'] == 'yes'
|
1227
|
+
end
|
1228
|
+
|
1229
|
+
# Set the invalid flag.
|
1230
|
+
# Takes boolean value or the strings yes/no.
|
1231
|
+
def invalid=(i)
|
1232
|
+
if i.is_a?(TrueClass)
|
1233
|
+
@node['invalid'] = 'yes'
|
1234
|
+
elsif i.is_a?(FalseClass)
|
1235
|
+
@node['invalid'] = 'no'
|
1236
|
+
else
|
1237
|
+
@node['invalid'] = i.to_s
|
1238
|
+
end
|
1239
|
+
end
|
1240
|
+
|
1241
|
+
# Retrieve the maximum of the value (Max).
|
1242
|
+
def max
|
1243
|
+
get_element(Max)
|
1244
|
+
end
|
1245
|
+
|
1246
|
+
# Set the maximum of the value (Max).
|
1247
|
+
def max=(m)
|
1248
|
+
set_element(Max, m)
|
1249
|
+
end
|
1250
|
+
|
1251
|
+
def min
|
1252
|
+
get_element(Min)
|
1253
|
+
end
|
1254
|
+
|
1255
|
+
# Set the minimum of the value (Min).
|
1256
|
+
def min=(m)
|
1257
|
+
set_element(Min, m)
|
1258
|
+
end
|
1259
|
+
|
1260
|
+
# Retrieve the possible values (Option) the column can take on.
|
1261
|
+
# Returns a HomogeneousNodeList object.
|
1262
|
+
def options
|
1263
|
+
HomogeneousNodeList.new(self.node, xpath_for(Option), Option)
|
1264
|
+
end
|
1265
|
+
|
1266
|
+
# Set the possible values the column can take on.
|
1267
|
+
# values.options = [Option.new(), ...]
|
1268
|
+
def options=(opts)
|
1269
|
+
self.options.replace(opts)
|
1270
|
+
end
|
1271
|
+
|
1272
|
+
protected
|
1273
|
+
|
1274
|
+
def methods_to_test_for_equality
|
1275
|
+
[
|
1276
|
+
:id, :type, :null, :invalid,
|
1277
|
+
:max, :min, :options
|
1278
|
+
]
|
1279
|
+
end
|
1280
|
+
end
|
1281
|
+
|
1282
|
+
# A minimum value a column can take on.
|
1283
|
+
class Min < VORuby::VOTable::Base
|
1284
|
+
ELEMENT_NAME = 'MIN'
|
1285
|
+
|
1286
|
+
# Create a new minimum value for a column.
|
1287
|
+
# min = Min.new(:value => '0')
|
1288
|
+
def initialize(defn=nil)
|
1289
|
+
super(defn)
|
1290
|
+
self.inclusive = true if !self.inclusive
|
1291
|
+
end
|
1292
|
+
|
1293
|
+
def value
|
1294
|
+
self.node['value']
|
1295
|
+
end
|
1296
|
+
|
1297
|
+
def value=(v)
|
1298
|
+
@node['value'] = v.to_s
|
1299
|
+
end
|
1300
|
+
|
1301
|
+
def inclusive
|
1302
|
+
self.node['inclusive']
|
1303
|
+
end
|
1304
|
+
|
1305
|
+
# Check whether the minimum value is inclusive or not.
|
1306
|
+
# By default, the minimum is inclusive.
|
1307
|
+
def inclusive?
|
1308
|
+
self.node['inclusive'] == 'yes'
|
1309
|
+
end
|
1310
|
+
|
1311
|
+
# Set whether the minimum value is inclusive or not.
|
1312
|
+
# Takes a boolean value or a yes/no string.
|
1313
|
+
# min.inclusive = false # or...
|
1314
|
+
# min.inclusive = 'no'
|
1315
|
+
def inclusive=(i)
|
1316
|
+
if i.is_a?(TrueClass)
|
1317
|
+
@node['inclusive'] = 'yes'
|
1318
|
+
elsif i.is_a?(FalseClass)
|
1319
|
+
@node['inclusive'] = 'no'
|
1320
|
+
else
|
1321
|
+
@node['inclusive'] = i.to_s
|
1322
|
+
end
|
1323
|
+
end
|
1324
|
+
|
1325
|
+
protected
|
1326
|
+
|
1327
|
+
def methods_to_test_for_equality
|
1328
|
+
[:value, :inclusive]
|
1329
|
+
end
|
1330
|
+
end
|
1331
|
+
|
1332
|
+
# The maximum value a column may take on.
|
1333
|
+
class Max < VORuby::VOTable::Base
|
1334
|
+
ELEMENT_NAME = 'MAX'
|
1335
|
+
|
1336
|
+
# Create a new maximum value for a column.
|
1337
|
+
# max = Max.new(:value => '360', :inclusive => false)
|
1338
|
+
def initialize(defn=nil)
|
1339
|
+
super(defn)
|
1340
|
+
self.inclusive = true if !self.inclusive
|
1341
|
+
end
|
1342
|
+
|
1343
|
+
def value
|
1344
|
+
self.node['value']
|
1345
|
+
end
|
1346
|
+
|
1347
|
+
def value=(v)
|
1348
|
+
@node['value'] = v.to_s
|
1349
|
+
end
|
1350
|
+
|
1351
|
+
def inclusive
|
1352
|
+
self.node['inclusive']
|
1353
|
+
end
|
1354
|
+
|
1355
|
+
# Check whether the maximum value is inclusive or not.
|
1356
|
+
# By default, the maximum is inclusive.
|
1357
|
+
def inclusive?
|
1358
|
+
self.node['inclusive'] == 'yes'
|
1359
|
+
end
|
1360
|
+
|
1361
|
+
# Set whether the maximum value is inclusive or not.
|
1362
|
+
# Takes a boolean value or a yes/no string.
|
1363
|
+
# max.inclusive = false # or...
|
1364
|
+
# max.inclusive = 'no'
|
1365
|
+
def inclusive=(i)
|
1366
|
+
if i.is_a?(TrueClass)
|
1367
|
+
@node['inclusive'] = 'yes'
|
1368
|
+
elsif i.is_a?(FalseClass)
|
1369
|
+
@node['inclusive'] = 'no'
|
1370
|
+
else
|
1371
|
+
@node['inclusive'] = i.to_s
|
1372
|
+
end
|
1373
|
+
end
|
1374
|
+
|
1375
|
+
protected
|
1376
|
+
|
1377
|
+
def methods_to_test_for_equality
|
1378
|
+
[:value, :inclusive]
|
1379
|
+
end
|
1380
|
+
end
|
1381
|
+
|
1382
|
+
# An enumeration of possible values.
|
1383
|
+
# Essentially a hierarchy of key-value pairs.
|
1384
|
+
class Option < VORuby::VOTable::Base
|
1385
|
+
ELEMENT_NAME = 'OPTION'
|
1386
|
+
|
1387
|
+
# Create a new enumeration.
|
1388
|
+
# option = Option.new(
|
1389
|
+
# :name => 'author',
|
1390
|
+
# :value => 'David Gasson'
|
1391
|
+
# )
|
1392
|
+
def initialize(defn=nil)
|
1393
|
+
super(defn)
|
1394
|
+
end
|
1395
|
+
|
1396
|
+
def name
|
1397
|
+
self.node['name']
|
1398
|
+
end
|
1399
|
+
|
1400
|
+
def name=(n)
|
1401
|
+
@node['name'] = n.to_s
|
1402
|
+
end
|
1403
|
+
|
1404
|
+
def value
|
1405
|
+
self.node['value']
|
1406
|
+
end
|
1407
|
+
|
1408
|
+
def value=(v)
|
1409
|
+
@node['value'] = v.to_s
|
1410
|
+
end
|
1411
|
+
|
1412
|
+
protected
|
1413
|
+
|
1414
|
+
def methods_to_test_for_equality
|
1415
|
+
[:name, :value]
|
1416
|
+
end
|
1417
|
+
end
|
1418
|
+
|
1419
|
+
# The actual tabular data.
|
1420
|
+
class Data < VORuby::VOTable::Base
|
1421
|
+
ELEMENT_NAME = 'DATA'
|
1422
|
+
|
1423
|
+
# Create a new body of data.
|
1424
|
+
# data = Data.new(:format => TableData.new())
|
1425
|
+
def initialize(defn=nil)
|
1426
|
+
super(defn)
|
1427
|
+
end
|
1428
|
+
|
1429
|
+
# Retrieve the formatted data. May be TableData, Binary or Fits.
|
1430
|
+
def format
|
1431
|
+
format_node = self.node.find_first("#{xpath_for(TableData)}|#{xpath_for(Binary)}|#{xpath_for(Fits)}")
|
1432
|
+
return nil if !format_node
|
1433
|
+
|
1434
|
+
case format_node.name
|
1435
|
+
when 'TABLEDATA' then TableData.new(format_node)
|
1436
|
+
when 'BINARY' then Binary.new(format_node)
|
1437
|
+
when 'FITS' then Fits.new(format_node)
|
1438
|
+
else nil
|
1439
|
+
end
|
1440
|
+
end
|
1441
|
+
|
1442
|
+
# Set the formatted data. Must be one of the allowed
|
1443
|
+
# data formats--TableData, Binary or Fits.
|
1444
|
+
def format=(f)
|
1445
|
+
raise 'Data format must be one of TableData, Binary or Fits' if ![TableData, Binary, Fits].include?(f.class)
|
1446
|
+
|
1447
|
+
self.node.each_child do |c|
|
1448
|
+
c.remove!
|
1449
|
+
end
|
1450
|
+
set_element(f.class, f)
|
1451
|
+
end
|
1452
|
+
|
1453
|
+
protected
|
1454
|
+
|
1455
|
+
def methods_to_test_for_equality; [:format] end
|
1456
|
+
end
|
1457
|
+
|
1458
|
+
# The most typical way of representing tabular data.
|
1459
|
+
class TableData < VORuby::VOTable::Base
|
1460
|
+
ELEMENT_NAME = 'TABLEDATA'
|
1461
|
+
|
1462
|
+
# Create new table data.
|
1463
|
+
# tabledata = TableData.new(:trs => [Tr.new, Tr.new, Tr.new])
|
1464
|
+
def initialize(defn=nil)
|
1465
|
+
super(defn)
|
1466
|
+
end
|
1467
|
+
|
1468
|
+
# Retrieve the rows of data.
|
1469
|
+
# Returns a HomogeneousNodeList.
|
1470
|
+
def trs
|
1471
|
+
HomogeneousNodeList.new(self.node, xpath_for(Tr), Tr)
|
1472
|
+
end
|
1473
|
+
|
1474
|
+
# Set the rows of data.
|
1475
|
+
# tabledata.rows = [Tr.new(), ...]
|
1476
|
+
def trs=(rows)
|
1477
|
+
self.trs.replace(rows)
|
1478
|
+
end
|
1479
|
+
|
1480
|
+
protected
|
1481
|
+
|
1482
|
+
def methods_to_test_for_equality; [:trs] end
|
1483
|
+
end
|
1484
|
+
|
1485
|
+
# Tabular data represented as a binary format.
|
1486
|
+
class Binary < VORuby::VOTable::Base
|
1487
|
+
ELEMENT_NAME = 'BINARY'
|
1488
|
+
|
1489
|
+
# Create a new binary table.
|
1490
|
+
# binary = Binary.new(:stream => Stream.new())
|
1491
|
+
def initialize(defn=nil)
|
1492
|
+
super(defn)
|
1493
|
+
end
|
1494
|
+
|
1495
|
+
# Retrieve the stream (Stream) representing the data.
|
1496
|
+
def stream
|
1497
|
+
get_element(Stream)
|
1498
|
+
end
|
1499
|
+
|
1500
|
+
# Set the stream representing the data.
|
1501
|
+
# binary.stream = Stream.new()
|
1502
|
+
def stream=(s)
|
1503
|
+
set_element(Stream, s)
|
1504
|
+
end
|
1505
|
+
|
1506
|
+
protected
|
1507
|
+
|
1508
|
+
def methods_to_test_for_equality; [:stream] end
|
1509
|
+
end
|
1510
|
+
|
1511
|
+
class Stream < VORuby::VOTable::Base
|
1512
|
+
ELEMENT_NAME = 'STREAM'
|
1513
|
+
|
1514
|
+
# Represents a stream of bytes, either local or remote.
|
1515
|
+
def initialize(defn=nil)
|
1516
|
+
super(defn)
|
1517
|
+
self.type = 'locator' if !self.type
|
1518
|
+
self.actuate = 'onRequest' if !self.actuate
|
1519
|
+
self.encoding = 'none' if !self.encoding
|
1520
|
+
end
|
1521
|
+
|
1522
|
+
def type
|
1523
|
+
self.node['type']
|
1524
|
+
end
|
1525
|
+
|
1526
|
+
# Set the type of stream. May be one of: locator or other.
|
1527
|
+
# Default is locator.
|
1528
|
+
def type=(t)
|
1529
|
+
@node['type'] = t.to_s
|
1530
|
+
end
|
1531
|
+
|
1532
|
+
# Retrieve the URL of the stream.
|
1533
|
+
# Returns a URI object.
|
1534
|
+
def href
|
1535
|
+
self.node['href'] ? URI.parse(self.node['href']) : nil
|
1536
|
+
end
|
1537
|
+
|
1538
|
+
# Set the URL of the stream.
|
1539
|
+
# link.href = 'http://www.noao.edu/my.dat' # or...
|
1540
|
+
# link.href = URI.parse('http://www.noao.edu/my.dat')
|
1541
|
+
def href=(h)
|
1542
|
+
@node['href'] = h.to_s
|
1543
|
+
end
|
1544
|
+
|
1545
|
+
def actuate
|
1546
|
+
self.node['actuate']
|
1547
|
+
end
|
1548
|
+
|
1549
|
+
# Set when the stream should be retrieved.
|
1550
|
+
# Possible values are: onLoad, onRequest, other or none.
|
1551
|
+
# Default is onRequest. In this implementation the value of this
|
1552
|
+
# parameter doesn't effect when the stream is retrieved--
|
1553
|
+
# you must always use #retrieve.
|
1554
|
+
def actuate=(a)
|
1555
|
+
@node['actuate'] = a.to_s
|
1556
|
+
end
|
1557
|
+
|
1558
|
+
def encoding
|
1559
|
+
self.node['encoding']
|
1560
|
+
end
|
1561
|
+
|
1562
|
+
# Set the encoding of the stream (i.e. base64).
|
1563
|
+
# Default is none.
|
1564
|
+
def encoding=(e)
|
1565
|
+
@node['encoding'] = e.to_s
|
1566
|
+
end
|
1567
|
+
|
1568
|
+
def expires
|
1569
|
+
self.node['expires'] ? DateTime.parse(self.node['expires']) : nil
|
1570
|
+
end
|
1571
|
+
|
1572
|
+
# Retrieve when the data in the stream expires.
|
1573
|
+
# Returns a DateTime object.
|
1574
|
+
def expires=(e)
|
1575
|
+
@node['expires'] = e.to_s
|
1576
|
+
end
|
1577
|
+
|
1578
|
+
def rights
|
1579
|
+
self.node['rights']
|
1580
|
+
end
|
1581
|
+
|
1582
|
+
# Set any authentication information necessary to access
|
1583
|
+
# the remote resource (i.e. a password to an encrypted document).
|
1584
|
+
# The current implementation ignores this value when retrieving
|
1585
|
+
# the stream.
|
1586
|
+
def rights=(r)
|
1587
|
+
@node['rights'] = r.to_s
|
1588
|
+
end
|
1589
|
+
|
1590
|
+
# If the stream is text-based, it can be directly embedded
|
1591
|
+
# within the document, and can be retrieved with this method.
|
1592
|
+
def text
|
1593
|
+
self.node['content']
|
1594
|
+
end
|
1595
|
+
|
1596
|
+
# If the stream is text-based it can be directly embedded with
|
1597
|
+
# this method.
|
1598
|
+
# stream.text = 'AAAAAj/yVZiDGSSUwFZ6ypR4yGkADwAcQV0euAAIAAJBmMzNwZWZmkGle4tBR3jVQT9ocwAA'
|
1599
|
+
def text=(txt)
|
1600
|
+
@node['content'] = txt.to_s
|
1601
|
+
end
|
1602
|
+
|
1603
|
+
# Retrieve the document specified by #href.
|
1604
|
+
# Returns a File object, of if the document is
|
1605
|
+
# directly embedded in the stream a StringIO object.
|
1606
|
+
def retrieve
|
1607
|
+
shref = self.href
|
1608
|
+
|
1609
|
+
if shref
|
1610
|
+
shref.scheme == 'file' ? File.open(shref.path) : open(shref.to_s)
|
1611
|
+
else
|
1612
|
+
StringIO.new(self.text)
|
1613
|
+
end
|
1614
|
+
end
|
1615
|
+
|
1616
|
+
protected
|
1617
|
+
|
1618
|
+
def methods_to_test_for_equality
|
1619
|
+
[:type, :href, :actuate, :encoding, :expires, :rights, :text]
|
1620
|
+
end
|
1621
|
+
end
|
1622
|
+
|
1623
|
+
# Tabular data represented as a FITS[http://archive.stsci.edu/fits/fits_standard/] file.
|
1624
|
+
class Fits < VORuby::VOTable::Base
|
1625
|
+
ELEMENT_NAME = 'FITS'
|
1626
|
+
|
1627
|
+
# Create a new FITS data stream.
|
1628
|
+
# fits = Fits.new(
|
1629
|
+
# :extnum => 2,
|
1630
|
+
# :stream => Stream.new(:href => http://fits.gsfc.nasa.gov/nrao_data/samples/image/swp05569slg.fits')
|
1631
|
+
# )
|
1632
|
+
def initialize(defn=nil)
|
1633
|
+
super(defn)
|
1634
|
+
end
|
1635
|
+
|
1636
|
+
# Retrieve the FITS extension number.
|
1637
|
+
# Returns an integer.
|
1638
|
+
def extnum
|
1639
|
+
self.node['extnum'] ? self.node['extnum'].to_i : nil
|
1640
|
+
end
|
1641
|
+
|
1642
|
+
# Set the FITS extension number.
|
1643
|
+
def extnum=(e)
|
1644
|
+
@node['extnum'] = e.to_s
|
1645
|
+
end
|
1646
|
+
|
1647
|
+
# Retrieve the stream (Stream) associated with the FITS file.
|
1648
|
+
def stream
|
1649
|
+
get_element(Stream)
|
1650
|
+
end
|
1651
|
+
|
1652
|
+
# Set the stream (Stream) associated with the FITS file.
|
1653
|
+
# fits.stream = Stream.new(:href => 'http://whatever/my_fits.fits')
|
1654
|
+
def stream=(s)
|
1655
|
+
set_element(Stream, s)
|
1656
|
+
end
|
1657
|
+
|
1658
|
+
# Retrieves the FITS file locally and returns it.
|
1659
|
+
# If rfits[http://rubyforge.org/projects/rfits/] is present
|
1660
|
+
# a RFits::File object is returned (or a RFits::HDU subclass if #extnum is specified).
|
1661
|
+
# If rfits is _not_ present a File object is returned instead.
|
1662
|
+
def to_rfits
|
1663
|
+
io = self.stream.retrieve
|
1664
|
+
|
1665
|
+
io_obj = if io.is_a?(StringIO)
|
1666
|
+
tmp = Tempfile.new('fits')
|
1667
|
+
tmp.write(io.read)
|
1668
|
+
tmp
|
1669
|
+
else
|
1670
|
+
io
|
1671
|
+
end
|
1672
|
+
|
1673
|
+
# RFits isn't absolutely required, but it's nice to have.
|
1674
|
+
return io_obj if !VORuby.rfits?
|
1675
|
+
|
1676
|
+
rfits = RFits::File.new(io_obj.path)
|
1677
|
+
self.extnum ? rfits[self.extnum - 1] : rfits
|
1678
|
+
end
|
1679
|
+
|
1680
|
+
protected
|
1681
|
+
|
1682
|
+
def methods_to_test_for_equality
|
1683
|
+
[:extnum, :stream]
|
1684
|
+
end
|
1685
|
+
end
|
1686
|
+
|
1687
|
+
# A row of data in a TableData.
|
1688
|
+
class Tr < VORuby::VOTable::Base
|
1689
|
+
ELEMENT_NAME = 'TR'
|
1690
|
+
|
1691
|
+
# Create a new row of data.
|
1692
|
+
# tr = Tr.new(:tds => [Td.new()])
|
1693
|
+
def initialize(defn=nil)
|
1694
|
+
super(defn)
|
1695
|
+
end
|
1696
|
+
|
1697
|
+
# Retrieve the table data elements in the row.
|
1698
|
+
# Returns a HomogeneousNodeList.
|
1699
|
+
def tds
|
1700
|
+
HomogeneousNodeList.new(self.node, xpath_for(Td), Td)
|
1701
|
+
end
|
1702
|
+
|
1703
|
+
# Set the data elements of the row.
|
1704
|
+
# tr.tds = [Td.new(), ...]
|
1705
|
+
def tds=(columns)
|
1706
|
+
self.tds.replace(columns)
|
1707
|
+
end
|
1708
|
+
|
1709
|
+
# Convert a table row to HTML.
|
1710
|
+
# tr = Tr.new(:tds => [Td.new(:text => 'hello'), Td.new(:text => 'world')])
|
1711
|
+
# puts tr.to_html # =>
|
1712
|
+
# <tr>
|
1713
|
+
# <td>hello</td>
|
1714
|
+
# <td>world</td>
|
1715
|
+
# </tr>
|
1716
|
+
def to_html
|
1717
|
+
builder = Builder::XmlMarkup.new(:indent => 2, :margin => 4)
|
1718
|
+
|
1719
|
+
builder.tr { |tr|
|
1720
|
+
self.tds.each do |column|
|
1721
|
+
tr << column.to_html
|
1722
|
+
end
|
1723
|
+
}
|
1724
|
+
end
|
1725
|
+
|
1726
|
+
protected
|
1727
|
+
|
1728
|
+
def methods_to_test_for_equality; [:tds] end
|
1729
|
+
end
|
1730
|
+
|
1731
|
+
# A data element in a table row.
|
1732
|
+
class Td < VORuby::VOTable::Base
|
1733
|
+
include Castable
|
1734
|
+
|
1735
|
+
ELEMENT_NAME = 'TD'
|
1736
|
+
|
1737
|
+
# Create a new data element.
|
1738
|
+
# td = Td.new(:text => '123.2')
|
1739
|
+
def initialize(defn=nil)
|
1740
|
+
super(defn)
|
1741
|
+
end
|
1742
|
+
|
1743
|
+
def ref
|
1744
|
+
self.node['ref']
|
1745
|
+
end
|
1746
|
+
|
1747
|
+
def ref=(r)
|
1748
|
+
@node['ref'] = r.to_s
|
1749
|
+
end
|
1750
|
+
|
1751
|
+
# Retrieve the value of the data element as text.
|
1752
|
+
def text
|
1753
|
+
self.node.content
|
1754
|
+
end
|
1755
|
+
|
1756
|
+
# Set the value of the data element as text.
|
1757
|
+
def text=(txt)
|
1758
|
+
@node.content = txt.to_s
|
1759
|
+
end
|
1760
|
+
|
1761
|
+
# Retrieve the value of the data element as an appropriate
|
1762
|
+
# object (or list of objects), according to the datatype and arraysize of the
|
1763
|
+
# Field corresponding to this column. See Castable#as_obj
|
1764
|
+
# for more details.
|
1765
|
+
def value
|
1766
|
+
cfield = self.field
|
1767
|
+
as_obj(self.text, cfield.datatype, cfield.arraysize)
|
1768
|
+
end
|
1769
|
+
|
1770
|
+
# Set the value of the data element.
|
1771
|
+
# An attempt is made to convert native ruby types using the datatype and
|
1772
|
+
# arraysize parameters of the associated Field.
|
1773
|
+
def value=(v)
|
1774
|
+
cfield = self.field
|
1775
|
+
self.text = as_string(v, cfield.datatype, cfield.arraysize)
|
1776
|
+
end
|
1777
|
+
|
1778
|
+
# Retrieve the Field associated with this column.
|
1779
|
+
def field
|
1780
|
+
node_path = self.node.path
|
1781
|
+
|
1782
|
+
# use the xpath to determine the position
|
1783
|
+
pos = (node_path =~ /TD\[\d+\]$/) ?
|
1784
|
+
node_path.split('/').last.match(/TD\[(\d+)\]$/)[1] :
|
1785
|
+
'1'
|
1786
|
+
|
1787
|
+
field_node = self.node.find_first("../../../../*[local-name()='FIELD'][#{pos}]")
|
1788
|
+
field_node ? Field.new(field_node) : raise("Unable to associate a FIELD with this TD")
|
1789
|
+
end
|
1790
|
+
|
1791
|
+
# Convert a column to HTML.
|
1792
|
+
# td = Td.new(:text => 'hello')
|
1793
|
+
# puts td.to_html # => <td>hello</td>
|
1794
|
+
def to_html
|
1795
|
+
builder = Builder::XmlMarkup.new(:indent => 2, :margin => 5)
|
1796
|
+
|
1797
|
+
builder.td(self.text)
|
1798
|
+
end
|
1799
|
+
|
1800
|
+
protected
|
1801
|
+
|
1802
|
+
def methods_to_test_for_equality; [:text, :ref] end
|
1803
|
+
end
|
1804
|
+
|
1805
|
+
end
|
1806
|
+
end
|
1807
|
+
end
|