activedocument 0.2.2 → 0.3

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.
@@ -65,35 +65,47 @@ module ActiveDocument
65
65
  # -------------------
66
66
  class Base < Finder
67
67
  include ClassLevelInheritableAttributes
68
- inheritable_attributes_list :namespaces, :default_namespace, :root
69
- @namespaces = Hash.new
70
- @default_namespace = String.new
71
- attr_reader :document, :uri
68
+ inheritable_attributes_list :my_namespaces, :my_default_namespace, :root
69
+ @my_namespaces = Hash.new
70
+ @my_default_namespace = String.new
71
+ attr_reader :document, :uri, :my_namespaces, :my_default_namespace, :root
72
72
 
73
73
 
74
74
  # create a new instance with an optional xml string to use for constructing the model
75
- def initialize(xml_string = nil, uri = nil)
76
- unless xml_string.nil?
77
- @document = Nokogiri::XML(xml_string) do |config|
78
- config.noblanks
79
- end
75
+ def initialize(xml_string = "", uri = "nil")
76
+ @document = Nokogiri::XML(xml_string) do |config|
77
+ config.noblanks
78
+ end
79
+ if !xml_string.empty? then
80
+ @root = @document.root.name
80
81
  end
81
- @root = self.class.to_s
82
82
  @uri = uri
83
83
  end
84
84
 
85
+ def to_s
86
+ @document.to_xml(:save_with => Nokogiri::XML::Node::SaveOptions::NO_DECLARATION)
87
+ end
88
+
89
+ # saves this document to the repository. If _uri_ is provided then that will be the value used for the uri.
90
+ # If no uri was passed in then the existing value or the uri is used, unless uri is nil in which case an exception
91
+ # will be thrown
92
+ def save(uri = nil)
93
+ doc_uri = (uri || @uri)
94
+ if doc_uri then
95
+ @@ml_http.send_xquery(@@xquery_builder.save(self, doc_uri))
96
+ else
97
+ raise ArgumentError, "uri must not be nil", caller
98
+ end
99
+
100
+ end
101
+
85
102
  # Returns the root element for this object
86
103
  def root
87
104
  @root
88
105
  end
89
106
 
90
- # Sets the root element for this object
91
- def root=(value)
92
- @root = value
93
- end
94
-
95
107
  # enables the dynamic finders
96
- def method_missing(method_id, *arguments, &block)
108
+ def method_missing(method_id, * arguments, & block)
97
109
  @@log.debug("ActiveDocument::Base at line #{__LINE__}: method called is #{method_id} with arguments #{arguments}")
98
110
  method = method_id.to_s
99
111
  if method =~ /^(\w*)$/ # methods with no '.' in them and not ending in '='
@@ -101,77 +113,47 @@ module ActiveDocument
101
113
  super
102
114
  end
103
115
  access_element $1
116
+ elsif method =~ /^(\w*)=$/ && arguments.length == 1 # methods with no '.' in them and ending in '='
117
+ set_element($1, arguments)
104
118
  end
105
119
  end
106
120
 
107
- def access_element(element)
108
- xpath = ""
109
- xpath = "//" unless self.instance_of? PartialResult
110
- namespace = self.class.namespace_for_element(element)
111
- element = "ns:#{element}" unless namespace.nil? || namespace.empty?
112
- xpath << element
113
- if namespace.nil?
114
- nodes = @document.xpath(xpath)
115
- else
116
- nodes = @document.xpath(xpath, {'ns' => namespace})
117
- end
118
- evaluate_nodeset(nodes)
119
-
120
- end
121
121
 
122
+ class << self
123
+ attr_reader :namespaces, :default_namespace, :root
122
124
 
123
- def evaluate_nodeset(result_nodeset)
124
- if result_nodeset.length == 1 # found one match
125
- if result_nodeset[0].children.length == 1 and result_nodeset[0].children[0].type == Nokogiri::XML::Node::TEXT_NODE
126
- result_nodeset[0].text
127
- elsif result_nodeset[0].children.length >1 # we are now dealing with complex nodes
128
- PartialResult.new(result_nodeset)
129
- end
130
- elsif result_nodeset.length >1 # multiple matches
131
- if result_nodeset.all? {|node| node.children.length == 1} and result_nodeset.all? {|node| node.children[0].type == Nokogiri::XML::Node::TEXT_NODE}
132
- # we have multiple simple text nodes
133
- result_nodeset.collect {|node| node.text}
125
+ def namespace_for_element(element)
126
+ namespace = nil
127
+ if !@my_namespaces.nil? && @my_namespaces[element]
128
+ namespace = @my_namespaces[element]
134
129
  else
135
- # we have multiple complex elements
136
- PartialResult.new(result_nodeset)
130
+ namespace = @my_default_namespace unless @my_default_namespace.nil?
137
131
  end
138
- end
139
- end
140
-
141
- class PartialResult < self
142
- def initialize(nodeset)
143
- @document = nodeset
144
- @root = nodeset[0].name
145
- end
146
-
147
- def to_s
148
- @document.to_s
132
+ namespace
149
133
  end
150
134
 
151
-
152
- end
153
-
154
- class << self
155
- attr_reader :namespaces, :default_namespace, :root
156
-
157
135
  def namespaces(namespace_hash)
158
- @namespaces = namespace_hash
136
+ @my_namespaces = namespace_hash
159
137
  end
160
138
 
161
139
  def add_namespace(element, uri)
162
- @namespaces[element.to_s] == uri
140
+ @my_namespaces[element.to_s] == uri
163
141
  end
164
142
 
165
143
  def remove_namespace(element)
166
- @namespaces.delete element
144
+ @my_namespaces.delete element
167
145
  end
168
146
 
169
147
  def default_namespace(namespace)
170
- @default_namespace = namespace # todo should this just be an entry in namespaces?
148
+ @my_default_namespace = namespace # todo should this just be an entry in namespaces?
149
+ end
150
+
151
+ def delete(uri)
152
+ @@ml_http.send_xquery(@@xquery_builder.delete(uri))
171
153
  end
172
154
 
173
155
  # enables the dynamic finders
174
- def method_missing(method_id, *arguments, &block)
156
+ def method_missing(method_id, * arguments, & block)
175
157
  @@log.debug("ActiveDocument::Base at line #{__LINE__}: method called is #{method_id} with arguments #{arguments}")
176
158
  method = method_id.to_s
177
159
  # identify element search methods
@@ -198,28 +180,126 @@ module ActiveDocument
198
180
 
199
181
  end
200
182
 
201
- # Returns an ActiveXML object representing the requested information
183
+ # Returns an ActiveXML object representing the requested information. If no document exists at that uri then an
184
+ # empty domain object is created and returned
202
185
  def load(uri)
203
186
  self.new(@@ml_http.send_xquery(@@xquery_builder.load(uri)), uri)
204
187
  end
205
188
 
206
189
  # Finds all documents of this type that contain the word anywhere in their structure
207
- def find_by_word(word, root=@root, namespace=@default_namespace)
190
+ def find_by_word(word, root=@root, namespace=@my_default_namespace)
208
191
  SearchResults.new(@@ml_http.send_xquery(@@xquery_builder.find_by_word(word, root, namespace)))
209
192
  end
210
193
 
211
- def namespace_for_element(element)
212
- namespace = nil
213
- if @namespaces[element]
214
- namespace = @namespaces[element]
194
+
195
+ end # end inner class
196
+
197
+
198
+ class PartialResult < self
199
+ # todo should this contain a reference to its parent?
200
+ def initialize(nodeset, parent)
201
+ @document = nodeset
202
+ @root = nodeset[0].name
203
+ @my_namespaces = parent.class.my_namespaces
204
+ @my_default_namespace = parent.class.my_default_namespace
205
+ end
206
+
207
+ # returns the number of Nodes in the underlying _NodeSet_
208
+ def length
209
+ @document.length
210
+ end
211
+
212
+ # provides access to the child nodes
213
+ def children
214
+ @document.children
215
+ end
216
+
217
+ # provides access to an indexed node
218
+ def [](index)
219
+ @document[index]
220
+ end
221
+
222
+ end
223
+
224
+ private
225
+ def namespace_for_element(element)
226
+ namespace = nil
227
+ ns = @my_namespaces || self.class.my_namespaces
228
+ default_ns = @my_default_namespace || self.class.my_default_namespace
229
+ if !ns.nil? && ns[element]
230
+ namespace = ns[element]
231
+ else
232
+ namespace = default_ns unless default_ns.nil?
233
+ end
234
+ namespace
235
+ end
236
+
237
+ def xpath_for_element(element)
238
+ xpath = String.new
239
+ xpath = "//" unless self.instance_of? PartialResult
240
+ namespace = namespace_for_element(element)
241
+ element = "ns:#{element}" unless namespace.nil? || namespace.empty?
242
+ xpath << element
243
+ return xpath, namespace
244
+ end
245
+
246
+ def evaluate_nodeset(result_nodeset)
247
+ if result_nodeset.length == 1 # found one match
248
+ if result_nodeset[0].children.length == 1 and result_nodeset[0].children[0].type == Nokogiri::XML::Node::TEXT_NODE
249
+ result_nodeset[0].text
250
+ #elsif result_nodeset[0].children.length >1 # we are now dealing with complex nodes
215
251
  else
216
- namespace = @default_namespace unless @default_namespace.nil?
252
+ PartialResult.new(result_nodeset, self)
253
+ end
254
+ elsif result_nodeset.length >1 # multiple matches
255
+ if result_nodeset.all? { |node| node.children.length == 1 } and result_nodeset.all? { |node| node.children[0].type == Nokogiri::XML::Node::TEXT_NODE }
256
+ # we have multiple simple text nodes
257
+ result_nodeset.collect { |node| node.text }
258
+ else
259
+ # we have multiple complex elements
260
+ PartialResult.new(result_nodeset, self)
217
261
  end
218
- namespace
219
262
  end
220
- end # end inner class
263
+ end
264
+
265
+ def set_element(element, value)
266
+ # element.chop!
267
+ xpath, namespace = xpath_for_element(element)
268
+ if namespace.nil?
269
+ node = @document.xpath(xpath)
270
+ else
271
+ node = @document.xpath(xpath, {'ns' => namespace})
272
+ end
273
+ if node[0].child.type == Nokogiri::XML::Node::TEXT_NODE
274
+ node[0].child.content = value
275
+ else
276
+ raise ArgumentError, "You can't modify a complex node", caller
277
+ end
278
+ end
279
+
280
+ def access_element(element)
281
+ xpath, namespace = xpath_for_element(element)
282
+ if namespace.nil?
283
+ nodes = @document.xpath(xpath)
284
+ else
285
+ nodes = @document.xpath(xpath, {'ns' => namespace})
286
+ end
287
+ evaluate_nodeset(nodes)
288
+
289
+ end
290
+
291
+
292
+ end
293
+
294
+ # end class
295
+
296
+ class ActiveDocumentException < Exception
297
+
298
+ end
299
+
300
+ class PersistenceException < ActiveDocumentException
221
301
 
222
- end # end class
302
+ end
223
303
 
224
304
 
225
305
  end # end module
@@ -20,6 +20,21 @@ module ActiveDocument
20
20
  "fn:doc('#{uri}')"
21
21
  end
22
22
 
23
+ def delete(uri)
24
+ "xdmp:document-delete('#{uri}')"
25
+ end
26
+
27
+ def save(document, uri)
28
+ xquery = <<-GENERATED
29
+ xdmp:document-insert(
30
+ "#{uri}",
31
+ #{document.to_s},
32
+ xdmp:default-permissions(),
33
+ xdmp:default-collections())
34
+ GENERATED
35
+
36
+ end
37
+
23
38
  # This method does a full text search
24
39
  def find_by_word(word, root, namespace)
25
40
  xquery = <<GENERATED
@@ -58,6 +58,10 @@ module ActiveDocument
58
58
  root.to_s.delete(":/") # remove the : and / to get the root element name
59
59
  end
60
60
 
61
+ def [](index)
62
+ SearchMatch.new(@node.xpath("./search:snippet/search:match")[index])
63
+ end
64
+
61
65
  def realize(klass)
62
66
  klass.load(uri)
63
67
  end
@@ -70,6 +70,10 @@ module ActiveDocument
70
70
  @results_document.xpath("/search:response/search:result").each {|node| yield SearchResult.new(node)}
71
71
  end
72
72
 
73
+ def [](index)
74
+ @results_document[index]
75
+ end
76
+
73
77
  end
74
78
 
75
79
  end
metadata CHANGED
@@ -4,9 +4,8 @@ version: !ruby/object:Gem::Version
4
4
  prerelease: false
5
5
  segments:
6
6
  - 0
7
- - 2
8
- - 2
9
- version: 0.2.2
7
+ - 3
8
+ version: "0.3"
10
9
  platform: ruby
11
10
  authors:
12
11
  - Clark D. Richey, Jr.
@@ -14,7 +13,7 @@ autorequire:
14
13
  bindir: bin
15
14
  cert_chain: []
16
15
 
17
- date: 2010-04-08 00:00:00 -04:00
16
+ date: 2010-06-01 00:00:00 -04:00
18
17
  default_executable:
19
18
  dependencies:
20
19
  - !ruby/object:Gem::Dependency