Class: ActiveDocument::Base
- Includes:
- ClassLevelInheritableAttributes
- Defined in:
- lib/ActiveDocument/active_document.rb
Overview
Developers should extend this class to create their own domain classes
= Usage
Dynamic Finders
ActiveDocument::Base provides extensive methods for finding matching documents based on a variety of criteria.
Find By Element
Accessed via find_by_ELEMENT method where Element = the name of your element. Executes a search for all documents with an element ELEMENT that contains the value passed in to the method call. The signature of this dynamic finder is: find_by_ELEMENT(value, root [optional], element_namespace [optional], root_namespace [optional])
Parameters details are as follows: Value: the text to be found within the given element. This is a mandatory parameter Namespace: The namespace in which the element being searched occurs. This is an optional element. If provided, it will be used in the search and will override any default values. If no namespace if provided then the code will attempt to dynamically determine the namespace. First, if the element name is contained in the namespaces hash then that namespace is used. If the element name is not found then the default_namespace is used. If there is no default namespace, then no namespace is used.
== Dynamic Accessors
In addition to the ability to access the underlying XML document (as a Nokogiri XML Document) you have the ability to access the XML as attributes of your domain object via dynamic attribute accessors (eg. domain_object.element_name). Attribute accessors always return instances of ActiveDocument::ActiveDocument::PartialResult. This class works just like a regular ActiveDocument::ActiveDocument::Base object in that you access its members like regular properties.
NOTE: Ruby does NOT support hyphens in method names. Because of this if you have an element called, for example, version-number, you CAN’T do x.version-number to access the version-number element. To work around this problem substitute the word HYPHEN (all caps) for any - in your elements names. In the previous exmaple using x.versionHYPHENnumber will correctly resolve to the version-number element.
More complex dynamic accessors are also supported. Instead of just looking for an element anywhere in the document, you can be more specific. For example, domain_object.chapter.paragraph will find all paragraph elements that are children of chapter elements.
Direct Known Subclasses
Defined Under Namespace
Classes: PartialResult
Class Attribute Summary collapse
-
.default_namespace(prefix) ⇒ the default element namespace prefix
readonly
defines the default namespace prefix to be used for all otherwise unspecified elements.
-
.namespaces(namespace_hash) ⇒ the resultant hash
readonly
Sets the hash of elements to namespace prefixes.
-
.root(root) ⇒ Object
readonly
sets the root element of the document.
Instance Attribute Summary collapse
-
#document ⇒ Object
readonly
Returns the value of attribute document.
-
#my_attribute_namespaces ⇒ Object
readonly
Returns the value of attribute my_attribute_namespaces.
-
#my_default_attribute_namespaces ⇒ Object
readonly
Returns the value of attribute my_default_attribute_namespaces.
-
#my_default_namespace ⇒ Object
readonly
Returns the value of attribute my_default_namespace.
-
#my_namespaces ⇒ Object
readonly
Returns the value of attribute my_namespaces.
-
#root ⇒ Object
readonly
Returns the root element for this object.
-
#uri ⇒ Object
readonly
Returns the value of attribute uri.
Class Method Summary collapse
-
.add_attribute_namespace(attribute, prefix) ⇒ the resultant updated hash of attributes to namespace prefixes
Adds an attribute / namespace prefix pair to the existing hash.
-
.add_namespace(element, prefix) ⇒ the resultant updated hash of elements to namespace prefixes
Adds an element / namespace prefix pair to the existing hash.
-
.attribute_namespaces(namespace_hash) ⇒ the resultant hash
Sets the hash of attributes to namespace prefixes.
-
.default_attribute_namespace(prefix) ⇒ the default attribute namespace prefix
defines the default namespace prefix to be used for all otherwise unspecified attributes.
- .delete(uri) ⇒ Object
-
.find_by_word(word, root = @root, namespace = @my_default_namespace) ⇒ Object
Finds all documents of this type that contain the word anywhere in their structure.
-
.load(uri) ⇒ Object
Returns an ActiveXML object representing the requested information.
-
.method_missing(method_id, *arguments, &block) ⇒ Object
enables the dynamic finders.
- .my_root ⇒ Object
- .namespace_for_attribute(attribute) ⇒ Object
- .namespace_for_element(element) ⇒ Object
-
.remove_attribute_namespace(attribute) ⇒ the resultant updated hash of attributes to namespace prefixes
Removes an attribute / namespace prefix pair from the existing hash.
-
.remove_namespace(element) ⇒ the resultant updated hash of elements to namespace prefixes
Removes an element / namespace prefix pair from the existing hash.
Instance Method Summary collapse
- #[](key) ⇒ Object
- #[]=(key, value) ⇒ Object
-
#initialize(xml_string = "", uri = "nil") ⇒ Base
constructor
create a new instance with an optional xml string to use for constructing the model.
-
#method_missing(method_id, *arguments, &block) ⇒ Object
enables the dynamic property accessors.
-
#save(uri = nil) ⇒ Object
saves this document to the repository.
- #to_s ⇒ Object
Methods included from ClassLevelInheritableAttributes
Methods inherited from Finder
co_occurrence, config, execute_attribute_finder, execute_finder, search
Constructor Details
#initialize(xml_string = "", uri = "nil") ⇒ Base
create a new instance with an optional xml string to use for constructing the model
75 76 77 78 79 80 81 82 83 84 85 |
# File 'lib/ActiveDocument/active_document.rb', line 75 def initialize(xml_string = "", uri = "nil") @document = Nokogiri::XML(xml_string) do |config| config.noblanks end if !xml_string.empty? and self.class.my_root.nil? then @root = @document.root.name else @root = self.class.my_root end @uri = uri end |
Dynamic Method Handling
This class handles dynamic methods through the method_missing method
#method_missing(method_id, *arguments, &block) ⇒ Object
enables the dynamic property accessors
128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 |
# File 'lib/ActiveDocument/active_document.rb', line 128 def method_missing(method_id, * arguments, & block) @@log.debug("ActiveDocument::Base at line #{__LINE__}: method called is #{method_id} with arguments #{arguments}") method = method_id.to_s method = method.sub("HYPHEN", "-") if method =~ /^(\w*-?\w*)$/ # methods with no '.' in them and not ending in '=' if arguments.length > 0 super end access_element $1 elsif method =~ /^(\w*)=$/ && arguments.length == 1 # methods with no '.' in them and ending in '=' set_element($1, arguments[0]) else super end end |
Class Attribute Details
.default_namespace(prefix) ⇒ the default element namespace prefix (readonly)
defines the default namespace prefix to be used for all otherwise unspecified elements. The prefix should have already been registered with the framework via the ActiveDocument::DataBaseConfiguration class. Otherwise, errors will likely occur at runtime
230 231 232 |
# File 'lib/ActiveDocument/active_document.rb', line 230 def default_namespace @default_namespace end |
.namespaces(namespace_hash) ⇒ the resultant hash (readonly)
Sets the hash of elements to namespace prefixes. All prefixes should have already been registered with the framework via the ActiveDocument::DataBaseConfiguration class. Otherwise, errors will likely occur at runtime prefixes as strings]
174 175 176 |
# File 'lib/ActiveDocument/active_document.rb', line 174 def namespaces @namespaces end |
.root(root) ⇒ Object (readonly)
sets the root element of the document. If not set it will default to the classname
246 247 248 |
# File 'lib/ActiveDocument/active_document.rb', line 246 def root @root end |
Instance Attribute Details
#document ⇒ Object (readonly)
Returns the value of attribute document.
71 72 73 |
# File 'lib/ActiveDocument/active_document.rb', line 71 def document @document end |
#my_attribute_namespaces ⇒ Object (readonly)
Returns the value of attribute my_attribute_namespaces.
71 72 73 |
# File 'lib/ActiveDocument/active_document.rb', line 71 def my_attribute_namespaces @my_attribute_namespaces end |
#my_default_attribute_namespaces ⇒ Object (readonly)
Returns the value of attribute my_default_attribute_namespaces.
71 72 73 |
# File 'lib/ActiveDocument/active_document.rb', line 71 def my_default_attribute_namespaces @my_default_attribute_namespaces end |
#my_default_namespace ⇒ Object (readonly)
Returns the value of attribute my_default_namespace.
71 72 73 |
# File 'lib/ActiveDocument/active_document.rb', line 71 def my_default_namespace @my_default_namespace end |
#my_namespaces ⇒ Object (readonly)
Returns the value of attribute my_namespaces.
71 72 73 |
# File 'lib/ActiveDocument/active_document.rb', line 71 def my_namespaces @my_namespaces end |
#root ⇒ Object (readonly)
Returns the root element for this object
110 111 112 |
# File 'lib/ActiveDocument/active_document.rb', line 110 def root @root end |
#uri ⇒ Object (readonly)
Returns the value of attribute uri.
71 72 73 |
# File 'lib/ActiveDocument/active_document.rb', line 71 def uri @uri end |
Class Method Details
.add_attribute_namespace(attribute, prefix) ⇒ the resultant updated hash of attributes to namespace prefixes
Adds an attribute / namespace prefix pair to the existing hash. All prefixes should have already been registered with the framework via the ActiveDocument::DataBaseConfiguration class. Otherwise, errors will likely occur at runtime
204 205 206 207 |
# File 'lib/ActiveDocument/active_document.rb', line 204 def add_attribute_namespace(attribute, prefix) @my_attribute_namespaces[attribute.to_s] = prefix @my_attribute_namespaces end |
.add_namespace(element, prefix) ⇒ the resultant updated hash of elements to namespace prefixes
Adds an element / namespace prefix pair to the existing hash. All prefixes should have already been registered with the framework via the ActiveDocument::DataBaseConfiguration class. Otherwise, errors will likely occur at runtime
194 195 196 197 |
# File 'lib/ActiveDocument/active_document.rb', line 194 def add_namespace(element, prefix) @my_namespaces[element.to_s] = prefix @my_namespaces end |
.attribute_namespaces(namespace_hash) ⇒ the resultant hash
Sets the hash of attributes to namespace prefixes. All prefixes should have already been registered with the framework via the ActiveDocument::DataBaseConfiguration class. Otherwise, errors will likely occur at runtime prefixes as strings]
184 185 186 187 |
# File 'lib/ActiveDocument/active_document.rb', line 184 def attribute_namespaces(namespace_hash) @my_attribute_namespaces = namespace_hash @my_attribute_namespaces end |
.default_attribute_namespace(prefix) ⇒ the default attribute namespace prefix
defines the default namespace prefix to be used for all otherwise unspecified attributes. The prefix should have already been registered with the framework via the ActiveDocument::DataBaseConfiguration class. Otherwise, errors will likely occur at runtime
240 241 242 243 |
# File 'lib/ActiveDocument/active_document.rb', line 240 def default_attribute_namespace(prefix) @my_default_attribute_namespace = prefix @my_default_attribute_namespace end |
.delete(uri) ⇒ Object
255 256 257 258 259 260 261 262 263 264 |
# File 'lib/ActiveDocument/active_document.rb', line 255 def delete(uri) doc_uri = (uri || @uri) if doc_uri then response_array = ActiveDocument::CoronaInterface.delete(doc_uri) uri_array = response_array[:uri] @@ml_http.send_corona_request(uri_array[0], uri_array[1]) else raise ArgumentError, "uri must not be nil", caller end end |
.find_by_word(word, root = @root, namespace = @my_default_namespace) ⇒ Object
Finds all documents of this type that contain the word anywhere in their structure
348 349 350 351 352 353 |
# File 'lib/ActiveDocument/active_document.rb', line 348 def find_by_word(word, root=@root, namespace=@my_default_namespace) response_array = ActiveDocument::CoronaInterface.find_by_word(word, root, namespace) uri_array = response_array[:uri] @@log.info("ActiveDocument.execute_find_by_word at line #{__LINE__}: #{response_array}") SearchResults.new(@@ml_http.send_corona_request(uri_array[0], uri_array[1], nil, response_array[:post_parameters])) end |
.load(uri) ⇒ Object
Returns an ActiveXML object representing the requested information. If no document exists at that uri then a LoadException is thrown
333 334 335 336 337 338 339 340 341 342 343 344 345 |
# File 'lib/ActiveDocument/active_document.rb', line 333 def load(uri) response_array = ActiveDocument::CoronaInterface.load(uri) uri_array = response_array[:uri] begin document = @@ml_http.send_corona_request(uri_array[0], uri_array[1]) rescue Net::HTTPServerException => exception raise LoadException, "File #{uri} not found", caller end if document.empty? raise LoadException, "File #{uri} not found", caller end self.new(document, uri) end |
.method_missing(method_id, *arguments, &block) ⇒ Object
enables the dynamic finders
267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 |
# File 'lib/ActiveDocument/active_document.rb', line 267 def method_missing(method_id, * arguments, & block) @@log.debug("ActiveDocument::Base at line #{__LINE__}: method called is #{method_id} with arguments #{arguments}") method = method_id.to_s # identify attribute search methods if method =~ /find_by_attribute_(.*)$/ and arguments.length >= 2 attribute = $1.to_sym element = arguments[0] value = arguments[1] if arguments[2] root = arguments[2] else root = @root || self.class.name end if arguments[3] element_namespace = arguments[3] else element_namespace = namespace_for_element(element) end if arguments[4] attribute_namespace = arguments[4] else attribute_namespace = namespace_for_attribute(attribute) end if arguments[5] root_namespace = arguments[5] else root_namespace = namespace_for_element(root) end if arguments[6] = arguments[6] else = nil end execute_attribute_finder(element, attribute, value, root, element_namespace, attribute_namespace, root_namespace, ) elsif method =~ /find_by_(.*)$/ and arguments.length > 0 # identify element search methods value = arguments[0] element = $1 # todo: this used to be converted to a symbol. Make sure that keeping it as a string doesn't break something if arguments[1] root = arguments[1] else root = @root end if arguments[2] element_namespace = arguments[2] else element_namespace = namespace_for_element(element) end if arguments[3] root_namespace = arguments[3] else root_namespace = namespace_for_element(root) unless root.nil? end if arguments[4] = arguments[4] else = nil end execute_finder(element, value, root, element_namespace, root_namespace, ) else super end end |
.my_root ⇒ Object
250 251 252 |
# File 'lib/ActiveDocument/active_document.rb', line 250 def my_root @root end |
.namespace_for_attribute(attribute) ⇒ Object
158 159 160 161 162 163 164 165 166 |
# File 'lib/ActiveDocument/active_document.rb', line 158 def namespace_for_attribute(attribute) namespace = nil if !@my_attribute_namespaces.nil? && @my_attribute_namespaces[attribute.to_sym] namespace = @my_attribute_namespaces[attribute.to_sym] else namespace = @my_default_attribute_namespace unless @my_default_attribute_namespace.nil? end namespace end |
.namespace_for_element(element) ⇒ Object
148 149 150 151 152 153 154 155 156 |
# File 'lib/ActiveDocument/active_document.rb', line 148 def namespace_for_element(element) namespace = nil if !@my_namespaces.nil? && @my_namespaces[element.to_sym] namespace = @my_namespaces[element.to_sym] else namespace = @my_default_namespace unless @my_default_namespace.nil? end namespace end |
.remove_attribute_namespace(attribute) ⇒ the resultant updated hash of attributes to namespace prefixes
Removes an attribute / namespace prefix pair from the existing hash. #todo what about the corona config?
220 221 222 223 |
# File 'lib/ActiveDocument/active_document.rb', line 220 def remove_attribute_namespace(attribute) @my_attribute_namespaces.delete attribute.to_s @my_attribute_namespaces end |
.remove_namespace(element) ⇒ the resultant updated hash of elements to namespace prefixes
Removes an element / namespace prefix pair from the existing hash. #todo what about the corona config?
212 213 214 215 |
# File 'lib/ActiveDocument/active_document.rb', line 212 def remove_namespace(element) @my_namespaces.delete element.to_s @my_namespaces end |
Instance Method Details
#[](key) ⇒ Object
114 115 116 117 118 119 120 121 |
# File 'lib/ActiveDocument/active_document.rb', line 114 def [](key) namespace = namespace_for_element(key) if namespace.nil? || namespace.empty? @document.root.xpath("@#{key}").to_s else @document.root.xpath("@ns:#{key}", {'ns' => namespace}).to_s end end |
#[]=(key, value) ⇒ Object
123 124 125 |
# File 'lib/ActiveDocument/active_document.rb', line 123 def []=(key, value) set_attribute(key, value) end |
#save(uri = nil) ⇒ Object
saves this document to the repository. If uri is provided then that will be the value used for the uri. If no uri was passed in then the existing value or the uri is used, unless uri is nil in which case an exception will be thrown
98 99 100 101 102 103 104 105 106 107 |
# File 'lib/ActiveDocument/active_document.rb', line 98 def save(uri = nil) doc_uri = (uri || @uri) if doc_uri then response_array = ActiveDocument::CoronaInterface.save(doc_uri) uri_array = response_array[:uri] @@ml_http.send_corona_request(uri_array[0], uri_array[1], self.document.to_s) else raise ArgumentError, "uri must not be nil", caller end end |
#to_s ⇒ Object
87 88 89 90 91 92 93 |
# File 'lib/ActiveDocument/active_document.rb', line 87 def to_s if @document @document.to_xml(:save_with => Nokogiri::XML::Node::SaveOptions::NO_DECLARATION) else super.to_s end end |