Class: Rets::Metadata::Root
- Inherits:
-
Object
- Object
- Rets::Metadata::Root
- Defined in:
- lib/rets/metadata/root.rb
Overview
It’s useful when dealing with the Rets standard to represent their relatively flat namespace of interweived components as a Tree. With a collection of resources at the top, and their various, classes, tables, lookups, and lookup types underneath.
It looks something like …
Resource
|
Class
|
`-- Table
|
`-- Lookups
|
`-- LookupType
For our purposes it was helpful to denormalize some of the more deeply nested branches. In particular by relating Lookups to LookupTypes, and Tables to lookups with can simplify this diagram.
Resource
|
Class
|
`-- Table
|
`-- Lookups
By associating Tables and lookups when we parse this structure. It allows us to seemlessly map Lookup values to their Long or Short value forms.
Instance Attribute Summary collapse
- #metadata_types ⇒ Object
-
#sources ⇒ Object
Sources are the raw xml documents fetched for each metadata type they are stored as a hash with the type names as their keys and the raw xml as the values.
- #tree ⇒ Object
Instance Method Summary collapse
- #build_container(fragment) ⇒ Object
-
#build_containers(doc) ⇒ Object
Returns an array of container classes that represents the metadata stored in the document provided.
- #build_tree ⇒ Object
-
#current?(current_timestamp, current_version) ⇒ Boolean
Wether there exists a more up to date version of the metadata to fetch is dependant on either a timestamp indicating when the most recent version was published, or a version number.
- #date ⇒ Object
- #fetch_source_by_type(type) ⇒ Object
- #fetch_sources ⇒ Object
- #for(metadata_key) ⇒ Object
-
#initialize(client) ⇒ Root
constructor
A new instance of Root.
- #marshal_dump ⇒ Object
- #marshal_load(sources) ⇒ Object
- #metadata_type(source) ⇒ Object
- #print_tree ⇒ Object
- #version ⇒ Object
Constructor Details
#initialize(client) ⇒ Root
60 61 62 63 64 65 |
# File 'lib/rets/metadata/root.rb', line 60 def initialize(client) @tree = nil = {} # TODO think up a better name ... containers? @sources = {} @client = client end |
Instance Attribute Details
#metadata_types ⇒ Object
137 138 139 140 141 142 143 |
# File 'lib/rets/metadata/root.rb', line 137 def sources.each do |name, source| [name.downcase.to_sym] ||= (source) end end |
#sources ⇒ Object
Sources are the raw xml documents fetched for each metadata type they are stored as a hash with the type names as their keys and the raw xml as the values
58 59 60 |
# File 'lib/rets/metadata/root.rb', line 58 def sources @sources end |
#tree ⇒ Object
122 123 124 |
# File 'lib/rets/metadata/root.rb', line 122 def tree @tree ||= build_tree end |
Instance Method Details
#build_container(fragment) ⇒ Object
158 159 160 161 162 163 164 165 166 167 |
# File 'lib/rets/metadata/root.rb', line 158 def build_container(fragment) tag = fragment.name # METADATA-RESOURCE type = tag.sub(/^METADATA-/, "") # RESOURCE class_name = type.capitalize.gsub(/_(\w)/) { $1.upcase } container_name = "#{class_name}Container" container_class = Containers.constants.include?(container_name.to_sym) ? Containers.const_get(container_name) : Containers::Container container_class.new(fragment) end |
#build_containers(doc) ⇒ Object
Returns an array of container classes that represents the metadata stored in the document provided.
151 152 153 154 155 156 |
# File 'lib/rets/metadata/root.rb', line 151 def build_containers(doc) # find all tags that match /RETS/METADATA-* fragments = doc.xpath("/RETS/*[starts-with(name(), 'METADATA-')]") fragments.map { |fragment| build_container(fragment) } end |
#build_tree ⇒ Object
107 108 109 110 111 112 113 114 115 116 117 118 119 120 |
# File 'lib/rets/metadata/root.rb', line 107 def build_tree tree = Hash.new { |h, k| h.key?(k.downcase) ? h[k.downcase] : nil } resource_containers = resource_containers.each do |resource_container| resource_container.rows.each do |resource_fragment| resource = Resource.build(resource_fragment, ) tree[resource.id.downcase] = resource end end tree end |
#current?(current_timestamp, current_version) ⇒ Boolean
Wether there exists a more up to date version of the metadata to fetch is dependant on either a timestamp indicating when the most recent version was published, or a version number. These values may or may not exist on any given rets server.
99 100 101 102 103 104 105 |
# File 'lib/rets/metadata/root.rb', line 99 def current?(, current_version) if !current_version.to_s.empty? && !version.to_s.empty? current_version == version else ? == date : true end end |
#date ⇒ Object
91 92 93 |
# File 'lib/rets/metadata/root.rb', line 91 def date [:system].first.date end |
#fetch_source_by_type(type) ⇒ Object
75 76 77 |
# File 'lib/rets/metadata/root.rb', line 75 def fetch_source_by_type(type) self.sources[type] ||= @client.(type) end |
#fetch_sources ⇒ Object
71 72 73 |
# File 'lib/rets/metadata/root.rb', line 71 def fetch_sources @fetch_sources ||= Hash[*METADATA_TYPES.map {|type| [type, @client.(type)] }.flatten] end |
#for(metadata_key) ⇒ Object
132 133 134 135 |
# File 'lib/rets/metadata/root.rb', line 132 def for() raise "Unknown metatadata key '#{metadata_key}'" unless key = METADATA_MAP[] [key] ||= (fetch_source_by_type(key)) end |
#marshal_dump ⇒ Object
79 80 81 |
# File 'lib/rets/metadata/root.rb', line 79 def marshal_dump sources end |
#marshal_load(sources) ⇒ Object
83 84 85 |
# File 'lib/rets/metadata/root.rb', line 83 def marshal_load(sources) self.sources = sources end |
#metadata_type(source) ⇒ Object
145 146 147 |
# File 'lib/rets/metadata/root.rb', line 145 def (source) build_containers(Nokogiri.parse(source)) end |
#print_tree ⇒ Object
126 127 128 129 130 |
# File 'lib/rets/metadata/root.rb', line 126 def print_tree tree.each do |name, value| value.print_tree end end |
#version ⇒ Object
87 88 89 |
# File 'lib/rets/metadata/root.rb', line 87 def version [:system].first.version end |