activedocument 0.2.2 → 0.3

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