active-fedora 3.1.1 → 3.1.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -141,7 +141,15 @@ Use the relationships method to list the object's relationships:
141
141
 
142
142
  <pre>
143
143
  newthing.relationships
144
- => {:self=>{}}
144
+ => #<RDF::Graph:0x83a53088(<>)>
145
+
146
+ newthing.relationships.statements.map(&:inspect)
147
+ => ["#<RDF::Statement:0x8371a858(<info:fedora/changeme:30> <info:fedora/fedora-system:def/model#hasModel> <info:fedora/hydra-cModel:DisplaySet> .)>",
148
+ "#<RDF::Statement:0x8371a6f0(<info:fedora/changeme:30> <info:fedora/fedora-system:def/model#hasModel> <info:fedora/hydra-cModel:CommonMetadata> .)>",
149
+ "#<RDF::Statement:0x8371a3e4(<info:fedora/changeme:30> <info:fedora/fedora-system:def/relations-external#isMemberOf> <info:fedora/changeme:parentSet> .)>"]
150
+
151
+ newthing.relationships(:is_member_of)
152
+ => ["info:fedora/changeme:parentSet"]
145
153
  </pre>
146
154
 
147
155
  The SpecialThing class definition contains these lines:
@@ -174,8 +182,17 @@ Now we'll create another Fedora object (using the default ActiveFedora object mo
174
182
  newobj = ActiveFedora::Base.new
175
183
  newobj.add_relationship(:has_derivation, newthing)
176
184
  => true
185
+
177
186
  newobj.relationships
178
- => {:self=>{:has_derivation=>["info:fedora/changeme:30"]}}
187
+ => #<RDF::Graph:0x83a53088(<>)>
188
+
189
+ newobj.relationships.statements.map(&:inspect)
190
+ => ["#<RDF::Statement:0x8371a3e4(<info:fedora/changeme:30> <info:fedora/fedora-system:def/relations-external#hasDerivation> <info:fedora/changeme:30> .)>"]
191
+
192
+ newobj.relationships(:has_derivation)
193
+ => ["info:fedora/changeme:30"]
194
+
195
+
179
196
  newobj.save
180
197
  => ...
181
198
  newobj.pid
@@ -256,10 +273,6 @@ newthing.pid
256
273
  copy_as_base = ActiveFedora::Base.load_instance("changeme:30")
257
274
  copy_as_base.pid
258
275
  => "changeme:30"
259
- newthing.relationships
260
- => {:self=>{:has_model=>["info:fedora/afmodel:SpecialThing"]}}
261
- copy_as_base.relationships
262
- => {:self=>{:has_model=>["info:fedora/afmodel:SpecialThing"]}}
263
276
  newthing.datastreams.keys
264
277
  => ["DS1", "descMetadata", "Foo1", "minivan", "RELS-EXT", "rightsMetadata", "DC", "extraMetadataForFun"]
265
278
  copy_as_base.datastreams.keys
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- active-fedora (3.1.1)
4
+ active-fedora (3.1.2)
5
5
  activeresource (~> 3.0.0)
6
6
  activesupport (~> 3.0.0)
7
7
  equivalent-xml
@@ -1,3 +1,20 @@
1
+ 3.1.2
2
+ correctly handling non-default pid_namespace (Benjamin Armintor)
3
+ info uri support; rdf:type predicate compatibility with Fedora(Benjamin Armintor)
4
+ more flexibility for initializing Rubydora (Michael B. Klein)
5
+ NokogiriDatastream and RELS-EXT datastream set mimeType (Justin Coyne)
6
+
7
+
8
+ 3.1.1
9
+ adds support for better handling of literal values in the RELS-EXT datastream.
10
+ adds support for setting the controlGroup via a parameter to has_metadata.
11
+ ability to pass a predicate as a parameter to AF::Base#relationships to get a list of the matching targets. This reads a bit better than ids_for_outbound().
12
+ refactoring to support overriding certain sections (ContentModel) by consumers of active-fedora.
13
+
14
+ 3.1.0
15
+ Based on rubydora for fedora interface
16
+ RDF-xml for the relationships
17
+
1
18
  3.0.4
2
19
 
3
20
  HYDRA-663 -- Passing an empty string to a id setter should clear the belongs to association
@@ -106,4 +106,188 @@ After calling add_datastream, then everything will be ready to save to Fedora.
106
106
 
107
107
  <pre>
108
108
  st.datastreams["descMetadata"].save
109
- </pre>
109
+ </pre>
110
+
111
+ h2. (Rails3) Using ActiveModel methods and delegate to treat xml nodes like regular ActiveModel attributes
112
+
113
+ h3. Handling most xml fields with delegate method
114
+
115
+ Say you want to treat a mods title like a regular ActiveModel attribute so that you can use all of the Rails helpers and methods like form_for.
116
+
117
+ The Datastream definition:
118
+
119
+ <pre>
120
+ # app/models/mods_generic_content.rb
121
+ class ModsGenericContent < ObjectMods
122
+
123
+ set_terminology do |t|
124
+ t.root(:path=>"mods", :xmlns=>"http://www.loc.gov/mods/v3", :schema=>"http://www.loc.gov/standards/mods/v3/mods-3-2.xsd")
125
+
126
+ t.title_info(:path=>"titleInfo") {
127
+ t.main_title(:path=>"title", :label=>"title", :index_as=>[:facetable])
128
+ }
129
+
130
+ # Proxy Terms (delegate can only reference root terms, so you have to create a root term "title" that proxies to the correct spot in the Terminology)
131
+ t.title(:proxy=>[:title_info, :main_title])
132
+ end
133
+ end
134
+ </pre>
135
+
136
+ The Model:
137
+
138
+
139
+ <pre>
140
+ # app/models/generic_content.rb
141
+ class GenericContent < ActiveFedora::Base
142
+
143
+ include Hydra::ModelMethods
144
+ has_metadata :name => "descMetadata", :label=>"MODS metadata", :type => ModsGenericContent
145
+
146
+ delegate :title, :to=>:descMetadata
147
+ end
148
+ </pre>
149
+
150
+ Example form:
151
+
152
+
153
+ <pre>
154
+ # app/views/generic_contents.html.erb
155
+ <%= form_for @generic_content do |f| %>
156
+ <dl>
157
+ <dt class="title">
158
+ <%= f.label "Title:" %>
159
+ </dt>
160
+ <dd class="title">
161
+ <%= f.text_field :title %>
162
+ </dd>
163
+ </dl>
164
+ <%= f.submit "Save Changes" %>
165
+ <% end %>
166
+ </pre>
167
+
168
+ The Controller that processes updates:
169
+
170
+ <pre>
171
+ # app/controllers/generic_contents_controller.rb
172
+ class GenericContentsController < ApplicationController
173
+
174
+ # This renders the edit form
175
+ def edit
176
+ @generic_content = GenericContent.find(params[:id])
177
+ end
178
+
179
+ # This updates the object based on the info submitted by your form, which puts the Hash of new values into params["generic_content"]
180
+ def update
181
+ @generic_content = GenericContent.find(params[:id])
182
+ @generic_content.update_attributes(params[:generic_content])
183
+ if @generic_content.save
184
+ flash[:notice] = "Saved changes to #{@generic_content.title}"
185
+ else
186
+ flash[:error] = "Failed to save your changes!"
187
+ end
188
+ redirect_to edit_generic_content_path(@generic_content)
189
+ end
190
+ end
191
+ </pre>
192
+
193
+ h3. Handling complex xml structures in attributes= method
194
+
195
+ This approach complements the usage of the delegate method to handle most xml nodes in your datasreams.
196
+
197
+ With this approach, you can still create relatively normal Rails forms while updating complex xml structures (ie. MODS name entries) internally without creating a separate controller & model for those structures.
198
+
199
+ Example: You want to create/edit xml like this in a descMetadata datastream that uses the GenericContentXml datatstream definition.
200
+
201
+ <pre>
202
+ <subject>
203
+ <topic>Subject 1</topic>
204
+ <catgegory>topic</category>
205
+ </subject>
206
+ <subject>
207
+ <topic>Subject 2</topic>
208
+ <catgegory>geographic</category>
209
+ </subject>
210
+ </pre>
211
+
212
+ You have a form that submits parameters like this:
213
+
214
+ <pre>
215
+ {
216
+ "generic_content" => {
217
+ "subjects" =>[
218
+ {
219
+ "topic" => "Subject 1",
220
+ "category" => "topic"
221
+ },{
222
+ "topic" => "Subject 2",
223
+ "category" => "geographic"
224
+ }
225
+ ]
226
+ }}
227
+ </pre>
228
+
229
+ Here's the test:
230
+
231
+ <pre>
232
+ # spec/models/generic_content_spec.rb
233
+ describe "attributes=" do
234
+ before do
235
+ @node = GenericContent.new
236
+ @sample_post_params = {
237
+ "generic_content" => {
238
+ "subjects" =>[
239
+ {
240
+ "topic" => "Subject 1",
241
+ "category" => "topic"
242
+ },{
243
+ "topic" => "Subject 2",
244
+ "category" => "geographic"
245
+ }
246
+ ]
247
+ }}
248
+
249
+ end
250
+ it "with subjects" do
251
+ @node.attributes = @sample_post_params["generic_content"]
252
+ @node.descMetadata.subject.length.should == 2
253
+ @node.descMetadata.subject(0).topic.should == ["Subject 1"]
254
+ @node.descMetadata.subject(0).category.should == ["topic"]
255
+ @node.descMetadata.subject(1).topic.should == ["Subject 2"]
256
+ @node.descMetadata.subject(1).category.should == ["geographic"]
257
+ end
258
+ end
259
+ </pre>
260
+
261
+ In the OM terminology of the Datasream definition:
262
+
263
+ <pre>
264
+ # app/models/generic_content_xml.rb
265
+ ...
266
+ t.subject(:path=>"subject", :attributes=>{:authority=>"UoH"}) {
267
+ t.topic(:index_as=>[:facetable])
268
+ t.category
269
+ }
270
+ ...
271
+ </pre>
272
+
273
+ The Model:
274
+
275
+ <pre>
276
+ # app/models/generic_content.rb
277
+ class GenericContent < ActiveFedora::Base
278
+
279
+ include Hydra::ModelMethods
280
+ has_metadata :name => "descMetadata", :label=>"generic metadata", :type => GenericContentXml
281
+
282
+ def attributes=(properties)
283
+ if (properties["subjects"])
284
+ self.descMetadata.subject.nodeset.remove # wipe out existing values
285
+ properties["subjects"].each_with_index do |subject_hash, index|
286
+ self.descMetadata.subject(index).topic = subject_hash["topic"]
287
+ self.descMetadata.subject(index).category = subject_hash["category"]
288
+ end
289
+ properties.delete("subjects")
290
+ end
291
+ super
292
+ end
293
+ </pre>
@@ -8,11 +8,36 @@ module ActiveFedora
8
8
  # much in the way ActiveRecord does.
9
9
  module Model
10
10
  extend ActiveFedora::FedoraObject
11
-
11
+ DEFAULT_NS = 'afmodel'
12
12
 
13
13
  def self.included(klass) # :nodoc:
14
14
  klass.extend(ClassMethods)
15
15
  end
16
+
17
+ # Takes a Fedora URI for a cModel, and returns a
18
+ # corresponding Model if available
19
+ # This method should reverse ClassMethods#to_class_uri
20
+ def self.from_class_uri(uri)
21
+ if match_data = /info:fedora\/([a-zA-z0-9\-_]+):(.+)$/.match(uri)
22
+ pid_ns = match_data[1]
23
+ model_value = match_data[2]
24
+ model_value.gsub!('_', '::')
25
+ else
26
+ raise "model URI incorrectly formatted: #{uri}"
27
+ end
28
+ if model_value.include?("::")
29
+ result = eval(model_value)
30
+ else
31
+ result = Kernel.const_get(model_value)
32
+ end
33
+ unless result.nil?
34
+ model_ns = (result.respond_to? :pid_namespace) ? result.pid_namespace : DEFAULT_NS
35
+ if model_ns != pid_ns
36
+ logger.warn "Model class namespace (#{model_ns}) and uri namespace (#{pid_ns}) do not match!"
37
+ end
38
+ end
39
+ result
40
+ end
16
41
 
17
42
  def add_metadata
18
43
  end
@@ -52,7 +77,15 @@ module ActiveFedora
52
77
  def load_instance(pid)
53
78
  RubydoraConnection.instance.find_model(pid, self)
54
79
  end
55
-
80
+
81
+ # Returns a suitable uri object for :has_model
82
+ # Should reverse Model#from_class_uri
83
+ def to_class_uri
84
+ ns = (self.respond_to? :pid_namespace) ? self.pid_namespace : Model::DEFAULT_NS
85
+ pid = self.name.gsub(/::/,'_')
86
+ "info:fedora/#{ns}:#{pid}"
87
+ end
88
+
56
89
  # Takes :all or a pid as arguments
57
90
  # Returns an Array of objects of the Class that +find+ is being
58
91
  # called on
@@ -62,7 +95,7 @@ module ActiveFedora
62
95
  if args == :all
63
96
  return_multiple = true
64
97
  # escaped_class_name = self.name.gsub(/(:)/, '\\:')
65
- escaped_class_uri = "info:fedora/afmodel:#{self.name}".gsub(/(:)/, '\\:')
98
+ escaped_class_uri = SolrService.escape_uri_for_query(self.to_class_uri)
66
99
  # q = "#{ActiveFedora::SolrService.solr_name(:active_fedora_model, :symbol)}:#{escaped_class_name}"
67
100
  q = "#{ActiveFedora::SolrService.solr_name(:has_model, :symbol)}:#{escaped_class_uri}"
68
101
  elsif args.class == String
@@ -16,6 +16,12 @@ module ActiveFedora
16
16
  alias_method(:om_update_values, :update_values) unless method_defined?(:om_update_values)
17
17
 
18
18
  attr_accessor :internal_solr_doc
19
+
20
+ before_create :add_mime_type
21
+
22
+ def add_mime_type
23
+ self.mimeType= 'text/xml'
24
+ end
19
25
 
20
26
  # Create an instance of this class based on xml content
21
27
  # @param [String, File, Nokogiri::XML::Node] xml the xml content to build from
@@ -0,0 +1,69 @@
1
+ require 'uri'
2
+ require 'rdf/rdfxml'
3
+ require 'rdf'
4
+
5
+ module ActiveFedora
6
+ # This class ensures that the RELS-EXT datastream is always serialized
7
+ # with an rdf:Description container for the properties
8
+ # the default behavior for RDF:RDFXML::Writer is to change that element if
9
+ # an rdf:type assertion is present; this is incompatible with Fedora
10
+ class RDFXMLWriter < RDF::RDFXML::Writer
11
+ def subject(subject, parent_node)
12
+ node = nil
13
+
14
+ raise RDF::WriterError, "Illegal use of subject #{subject.inspect}, not supported in RDF/XML" unless subject.resource?
15
+
16
+ if !is_done?(subject)
17
+ subject_done(subject)
18
+ properties = @graph.properties(subject)
19
+ add_debug {"subject: #{subject.inspect}, props: #{properties.inspect}"}
20
+
21
+ @graph.query(:subject => subject).each do |st|
22
+ raise RDF::WriterError, "Illegal use of predicate #{st.predicate.inspect}, not supported in RDF/XML" unless st.predicate.uri?
23
+ end
24
+
25
+ prop_list = order_properties(properties)
26
+ add_debug {"=> property order: #{prop_list.to_sentence}"}
27
+
28
+ qname = "rdf:Description"
29
+ prefixes[:rdf] = RDF.to_uri
30
+
31
+ node = Nokogiri::XML::Element.new(qname, parent_node.document)
32
+
33
+ if subject.is_a?(RDF::Node)
34
+ # Only need nodeID if it's referenced elsewhere
35
+ if ref_count(subject) > (@depth == 0 ? 0 : 1)
36
+ node["rdf:nodeID"] = subject.id
37
+ else
38
+ node.add_child(Nokogiri::XML::Comment.new(node.document, "Serialization for #{subject}")) if RDF::RDFXML::debug?
39
+ end
40
+ else
41
+ node["rdf:about"] = relativize(subject)
42
+ end
43
+
44
+ prop_list.each do |prop|
45
+ prop_ref = RDF::URI.intern(prop)
46
+
47
+ properties[prop].each do |object|
48
+ raise RDF::WriterError, "Illegal use of object #{object.inspect}, not supported in RDF/XML" unless object.resource? || object.literal?
49
+
50
+ @depth += 1
51
+ predicate(prop_ref, object, node, properties[prop].length == 1)
52
+ @depth -= 1
53
+ end
54
+ end
55
+ elsif @force_RDF_about.include?(subject)
56
+ add_debug {"subject: #{subject.inspect}, force about"}
57
+ node = Nokogiri::XML::Element.new("rdf:Description", parent_node.document)
58
+ if subject.is_a?(RDF::Node)
59
+ node["rdf:nodeID"] = subject.id
60
+ else
61
+ node["rdf:about"] = relativize(subject)
62
+ end
63
+ end
64
+ @force_RDF_about.delete(subject)
65
+
66
+ parent_node.add_child(node) if node
67
+ end
68
+ end
69
+ end
@@ -3,13 +3,20 @@ require 'solrizer/field_name_mapper'
3
3
  require 'uri'
4
4
  require 'rdf/rdfxml'
5
5
  require 'rdf'
6
+ require 'active_fedora/rdf_xml_writer'
6
7
 
7
8
  module ActiveFedora
8
9
  class RelsExtDatastream < Datastream
9
10
 
10
11
  include Solrizer::FieldNameMapper
11
12
  attr_accessor :model
12
-
13
+
14
+ before_create :add_mime_type
15
+
16
+ def add_mime_type
17
+ self.mimeType= 'application/rdf+xml'
18
+ end
19
+
13
20
  def serialize!
14
21
  self.content = to_rels_ext() if model.relationships_are_dirty
15
22
  model.relationships_are_dirty = false
@@ -46,7 +53,7 @@ module ActiveFedora
46
53
  # @param [Hash] relationships (optional) @default self.relationships
47
54
  # Note: This method is implemented on SemanticNode instead of RelsExtDatastream because SemanticNode contains the relationships array
48
55
  def to_rels_ext()
49
- xml = RDF::RDFXML::Writer.buffer do |writer|
56
+ xml = ActiveFedora::RDFXMLWriter.buffer do |writer|
50
57
  model.relationships.each_statement do |statement|
51
58
  writer << statement
52
59
  end
@@ -9,6 +9,7 @@ module ActiveFedora
9
9
  attr_accessor :options
10
10
 
11
11
  def self.connect(params={})
12
+ params = params.dup
12
13
  if params.kind_of? String
13
14
  u = URI.parse params
14
15
  params = {}
@@ -17,14 +18,17 @@ module ActiveFedora
17
18
  params[:url] = "#{u.scheme}://#{u.host}:#{u.port}#{u.path}"
18
19
  end
19
20
  instance = self.instance
21
+ force = params.delete(:force)
20
22
  instance.options = params
21
- instance.connect
23
+ instance.connect force
22
24
  instance
23
25
  end
24
26
 
25
- def connect()
26
- return unless @connection.nil?
27
- @connection = Rubydora.connect :url => options[:url], :user => options[:user], :password => options[:password]
27
+ def connect(force=false)
28
+ return unless @connection.nil? or force
29
+ allowable_options = [:url, :user, :password, :timeout, :open_timeout, :ssl_client_cert, :ssl_client_key]
30
+ client_options = options.reject { |k,v| not allowable_options.include?(k) }
31
+ @connection = Rubydora.connect client_options
28
32
  end
29
33
 
30
34
  def nextid(attrs={})
@@ -32,21 +32,31 @@ module ActiveFedora
32
32
  # @param uri a string represending the subject
33
33
  # @param predicate a predicate symbol
34
34
  # @param target an object to store
35
- def build_statement(uri, predicate, target, literal=nil)
35
+ def build_statement(uri, predicate, target, literal=false)
36
36
  raise "Not allowed anymore" if uri == :self
37
37
  target = target.internal_uri if target.respond_to? :internal_uri
38
38
  subject = RDF::URI.new(uri) #TODO cache
39
- if literal.nil?
39
+ unless literal or target.is_a? RDF::Resource
40
40
  begin
41
- literal = URI.parse(target).scheme.nil?
41
+ target_uri = (target.is_a? URI) ? target : URI.parse(target)
42
+ if target_uri.scheme.nil?
43
+ raise ArgumentError, "Invalid target \"#{target}\". Must have namespace."
44
+ end
45
+ if target_uri.to_s =~ /\A[\w\-]+:[\w\-]+\Z/
46
+ raise ArgumentError, "Invalid target \"#{target}\". Target should be a complete URI, and not a pid."
47
+ end
42
48
  rescue URI::InvalidURIError
43
- literal = false
49
+ raise ArgumentError, "Invalid target \"#{target}\". Target must be specified as a literal, or be a valid URI."
44
50
  end
45
51
  end
46
- raise ArgumentError, "Invalid target \"#{target}\". Must have namespace." unless literal || /^info/.match(target)
47
- object = literal ? RDF::Literal.new(target) : RDF::URI.new(target)
48
-
49
- RDF::Statement.new(subject, find_graph_predicate(predicate), object)
52
+ if literal
53
+ object = RDF::Literal.new(target)
54
+ elsif target.is_a? RDF::Resource
55
+ object = target
56
+ else
57
+ object = RDF::URI.new(target)
58
+ end
59
+ RDF::Statement.new(subject, find_graph_predicate(predicate), object)
50
60
 
51
61
  end
52
62
 
@@ -44,18 +44,7 @@ module ActiveFedora
44
44
 
45
45
  def self.class_from_solr_document(hit)
46
46
  model_value = hit[solr_name("has_model", :symbol)].first
47
- if match_data = /info:fedora\/afmodel:(.+)$/.match(model_value)
48
- model_value = match_data[1]
49
- model_value.gsub!('_', '::')
50
- else
51
- raise "has_model assertion incorrectly formatted: #{model_value}"
52
- end
53
-
54
- if model_value.include?("::")
55
- eval(model_value)
56
- else
57
- Kernel.const_get(model_value)
58
- end
47
+ Model.from_class_uri(model_value)
59
48
  end
60
49
 
61
50
  # Construct a solr query for a list of pids
@@ -1,3 +1,3 @@
1
1
  module ActiveFedora
2
- VERSION = "3.1.1"
2
+ VERSION = "3.1.2"
3
3
  end
@@ -69,12 +69,6 @@ namespace :active_fedora do
69
69
  t.rcov_opts << ['--exclude', 'spec']
70
70
  end
71
71
 
72
- desc "Refresh test fixtres"
73
- task :refresh_fixtures do
74
- Rake::Task["active_fedora:clean_jetty"].invoke
75
- Rake::Task["active_fedora:load_fixtures"].invoke
76
- end
77
-
78
72
  task :clean_jetty do
79
73
  Dir.chdir("./jetty")
80
74
  system("git clean -f -d")
@@ -83,12 +77,6 @@ namespace :active_fedora do
83
77
  end
84
78
 
85
79
  task :load_fixtures => :environment do
86
- # require 'solrizer'
87
- # require 'solrizer-fedora'
88
- # require 'spec/samples/models/hydrangea_article'
89
- # ENV["FEDORA_HOME"] ||= File.expand_path(File.join(File.dirname(__FILE__),'..','..','jetty','fedora','default'))
90
- # retval = `$FEDORA_HOME/client/bin/fedora-ingest-demos.sh localhost 8983 fedoraAdmin fedoraAdmin http`
91
- # puts "loaded demo objects #{retval}"
92
80
  ActiveFedora.init unless Thread.current[:repo]
93
81
 
94
82
  ENV["pid"] = "hydrangea:fixture_mods_article1"
@@ -17,6 +17,9 @@ describe ActiveFedora::Model do
17
17
 
18
18
  class Basic < ActiveFedora::Base
19
19
  include ActiveFedora::Model
20
+ def self.pid_namespace
21
+ "foo"
22
+ end
20
23
  end
21
24
 
22
25
  end
@@ -34,9 +37,10 @@ describe ActiveFedora::Model do
34
37
 
35
38
  describe '#find' do
36
39
  it "should return an array of instances of the calling Class" do
37
- pending
38
40
  result = ModelIntegrationSpec::Basic.find(:all)
39
41
  result.should be_instance_of(Array)
42
+ # this test is meaningless if the array length is zero
43
+ result.length.should > 0
40
44
  result.each do |obj|
41
45
  obj.class.should == ModelIntegrationSpec::Basic
42
46
  end
@@ -21,12 +21,14 @@ describe ActiveFedora::NokogiriDatastream do
21
21
  end
22
22
  end
23
23
 
24
- @pid = "hydrangea:fixture_mods_article1"
25
- @test_solr_object = HydrangeaArticle2.load_instance_from_solr(@pid)
26
- @test_object = HydrangeaArticle2.load_instance(@pid)
27
24
  end
28
25
 
29
26
  describe '.term_values' do
27
+ before do
28
+ @pid = "hydrangea:fixture_mods_article1"
29
+ @test_solr_object = HydrangeaArticle2.load_instance_from_solr(@pid)
30
+ @test_object = HydrangeaArticle2.load_instance(@pid)
31
+ end
30
32
 
31
33
  it "should return the same values whether getting from solr or Fedora" do
32
34
  @test_solr_object.datastreams["descMetadata"].term_values(:name,:role,:text).should == ["Creator","Contributor","Funder","Host"]
@@ -6,6 +6,9 @@ describe ActiveFedora::SolrService do
6
6
  describe "#reify_solr_results" do
7
7
  before(:all) do
8
8
  class FooObject < ActiveFedora::Base
9
+ def self.pid_namespace
10
+ "foo"
11
+ end
9
12
  has_metadata :name => "properties", :type => ActiveFedora::MetadataDatastream do |m|
10
13
  m.field "holding_id", :string
11
14
  end
@@ -103,7 +103,8 @@ describe ActiveFedora::Model do
103
103
  mock_solr = mock("SolrConnection")
104
104
  mock_result = mock("MockResult")
105
105
  mock_result.expects(:hits).returns([{"id" => "changeme:30"}, {"id" => "changeme:22"}])
106
- mock_solr.expects(:query).with('has_model_s:info\\:fedora/afmodel\\:SpecModel\:\:Basic', :rows=>1001).returns(mock_result)
106
+ #mock_solr.expects(:query).with('has_model_s:info\\:fedora/afmodel\\:SpecModel\:\:Basic', :rows=>1001).returns(mock_result)
107
+ mock_solr.expects(:query).with('has_model_s:info\\:fedora/afmodel\\:SpecModel_Basic', :rows=>1001).returns(mock_result)
107
108
  ActiveFedora::SolrService.expects(:instance).returns(mock("SolrService", :conn => mock_solr))
108
109
  ActiveFedora::RubydoraConnection.instance.expects(:find_model).with("changeme:30", SpecModel::Basic).returns("Fake Object1")
109
110
  ActiveFedora::RubydoraConnection.instance.expects(:find_model).with("changeme:22", SpecModel::Basic).returns("Fake Object2")
@@ -25,7 +25,7 @@ describe ActiveFedora::NokogiriDatastream do
25
25
 
26
26
  after(:each) do
27
27
  end
28
-
28
+
29
29
  it "should include the Solrizer::XML::TerminologyBasedSolrizer for .to_solr support" do
30
30
  ActiveFedora::NokogiriDatastream.included_modules.should include(Solrizer::XML::TerminologyBasedSolrizer)
31
31
  end
@@ -171,10 +171,12 @@ describe ActiveFedora::NokogiriDatastream do
171
171
  end
172
172
  it "should persist the product of .to_xml in fedora" do
173
173
  @test_ds.expects(:new?).returns(true).twice
174
- @mock_repo.expects(:add_datastream).with(:pid => nil, :dsid => 'descMetadata', :checksumType => 'DISABLED', :versionable => true, :content => 'fake xml', :controlGroup => 'M', :dsState => 'A')
174
+ @mock_repo.expects(:datastream).with(:pid => nil, :dsid => 'descMetadata')
175
+ @mock_repo.expects(:add_datastream).with(:pid => nil, :dsid => 'descMetadata', :checksumType => 'DISABLED', :versionable => true, :content => 'fake xml', :controlGroup => 'M', :dsState => 'A', :mimeType=>'text/xml')
175
176
  @test_ds.expects(:to_xml).returns("fake xml")
176
177
  @test_ds.serialize!
177
178
  @test_ds.save
179
+ @test_ds.mimeType.should == 'text/xml'
178
180
  end
179
181
  end
180
182
 
@@ -0,0 +1,63 @@
1
+ require File.join( File.dirname(__FILE__), "../spec_helper" )
2
+ require File.join( File.dirname(__FILE__), "../../lib/active_fedora/rdf_xml_writer" )
3
+
4
+ describe ActiveFedora::RDFXMLWriter do
5
+ before(:all) do
6
+ @rdf_xml = <<-EOS
7
+ <rdf:RDF xmlns:rdf='http://www.w3.org/1999/02/22-rdf-syntax-ns#'>
8
+ <rdf:Description rdf:about='info:fedora/test:sample_pid'>
9
+ <isMemberOf rdf:resource='info:fedora/demo:10' xmlns='info:fedora/fedora-system:def/relations-external#'/>
10
+ <isPartOf rdf:resource='info:fedora/demo:11' xmlns='info:fedora/fedora-system:def/relations-external#'/>
11
+ <hasPart rdf:resource='info:fedora/demo:12' xmlns='info:fedora/fedora-system:def/relations-external#'/>
12
+ <hasModel rdf:resource='info:fedora/afmodel:OtherModel' xmlns='info:fedora/fedora-system:def/model#'/>
13
+ <hasModel rdf:resource='info:fedora/afmodel:SampleModel' xmlns='info:fedora/fedora-system:def/model#'/>
14
+ </rdf:Description>
15
+ </rdf:RDF>
16
+ EOS
17
+
18
+ @rdf_xml_with_type = <<-EOS
19
+ <rdf:RDF xmlns:rdf='http://www.w3.org/1999/02/22-rdf-syntax-ns#'>
20
+ <rdf:Description rdf:about='info:fedora/test:sample_pid'>
21
+ <isMemberOf rdf:resource='demo:10' xmlns='info:fedora/fedora-system:def/relations-external#'/>
22
+ <type rdf:resource='http://purl.org/dc/dcmitype/Collection' xmlns='http://www.w3.org/1999/02/22-rdf-syntax-ns#' />
23
+ </rdf:Description>
24
+ </rdf:RDF>
25
+ EOS
26
+
27
+ end
28
+ it "should serialize graphs using the rdf:Description element despite the presence of rdf:type statements" do
29
+ graph = RDF::Graph.new
30
+ subject = RDF::URI.new "info:fedora/test:sample_pid"
31
+ graph.insert RDF::Statement.new(subject, ActiveFedora::Base.new.find_graph_predicate(:is_member_of), RDF::URI.new('demo:10'))
32
+ graph.insert RDF::Statement.new(subject, RDF::URI('http://www.w3.org/1999/02/22-rdf-syntax-ns#type'), RDF::URI.new('http://purl.org/dc/dcmitype/Collection'))
33
+ content = RDF::RDFXML::Writer.buffer do |writer|
34
+ graph.each_statement do |statement|
35
+ writer << statement
36
+ end
37
+ end
38
+ EquivalentXml.equivalent?(content, @rdf_xml_with_type).should be_true
39
+ end
40
+
41
+ it 'should serialize graphs without rdf:type equivalently to RDF::RDFXML::Writer' do
42
+ graph = RDF::Graph.new
43
+ subject = RDF::URI.new "info:fedora/test:sample_pid"
44
+ graph.insert RDF::Statement.new(subject, ActiveFedora::Base.new.find_graph_predicate(:is_member_of), RDF::URI.new('info:fedora/demo:10'))
45
+ graph.insert RDF::Statement.new(subject, ActiveFedora::Base.new.find_graph_predicate(:is_part_of), RDF::URI.new('info:fedora/demo:11'))
46
+ graph.insert RDF::Statement.new(subject, ActiveFedora::Base.new.find_graph_predicate(:has_part), RDF::URI.new('info:fedora/demo:12'))
47
+ graph.insert RDF::Statement.new(subject, ActiveFedora::Base.new.find_graph_predicate(:has_model), RDF::URI.new("info:fedora/afmodel:OtherModel"))
48
+ graph.insert RDF::Statement.new(subject, ActiveFedora::Base.new.find_graph_predicate(:has_model), RDF::URI.new("info:fedora/afmodel:SampleModel"))
49
+
50
+ local_content = ActiveFedora::RDFXMLWriter.buffer do |writer|
51
+ graph.each_statement do |statement|
52
+ writer << statement
53
+ end
54
+ end
55
+ generic_content = RDF::RDFXML::Writer.buffer do |writer|
56
+ graph.each_statement do |statement|
57
+ writer << statement
58
+ end
59
+ end
60
+ EquivalentXml.equivalent?(local_content, @rdf_xml).should be_true
61
+ EquivalentXml.equivalent?(local_content, generic_content).should be_true
62
+ end
63
+ end
@@ -21,9 +21,17 @@ describe ActiveFedora::RelsExtDatastream do
21
21
  mock_inner.stubs(:pid).returns(@pid)
22
22
  @test_ds = ActiveFedora::RelsExtDatastream.new(mock_inner, "RELS-EXT")
23
23
  end
24
-
25
- it 'should respond to #save' do
26
- @test_ds.should respond_to(:save)
24
+
25
+ describe "#save" do
26
+ before do
27
+ @mock_repo.expects(:add_datastream).with(:pid => 'test:sample_pid', :dsid => 'RELS-EXT', :checksumType => 'DISABLED', :versionable => true, :content => 'fake xml', :controlGroup => 'M', :dsState => 'A', :mimeType=>'application/rdf+xml')
28
+ @mock_repo.expects(:datastream).with(:pid => 'test:sample_pid', :dsid => 'RELS-EXT')
29
+ @test_ds.content = 'fake xml'
30
+ end
31
+ it 'should set the mime type' do
32
+ @test_ds.save
33
+ @test_ds.mimeType.should == 'application/rdf+xml'
34
+ end
27
35
  end
28
36
 
29
37
 
@@ -16,6 +16,35 @@ describe ActiveFedora::RubydoraConnection do
16
16
  end
17
17
  end
18
18
 
19
+ describe 'connect' do
20
+ before do
21
+ @instance = ActiveFedora::RubydoraConnection.instance
22
+ @reconfig = { :force => true, :url => @instance.connection.client.url }.merge(@instance.connection.client.options)
23
+ end
24
+
25
+ after do
26
+ ActiveFedora::RubydoraConnection.connect @reconfig
27
+ end
28
+
29
+ it "shouldn't reconnect by default" do
30
+ client_id = @instance.connection.client.object_id
31
+ ActiveFedora::RubydoraConnection.connect :timeout => 3600
32
+ @instance.connection.client.object_id.should == client_id
33
+ end
34
+
35
+ it "should reconnect with force" do
36
+ client_id = @instance.connection.client.object_id
37
+ ActiveFedora::RubydoraConnection.connect :force => true
38
+ @instance.connection.client.object_id.should_not == client_id
39
+ end
40
+
41
+ it "should pass through valid options" do
42
+ ActiveFedora::RubydoraConnection.connect :timeout => 3600, :fake_option => :missing, :force => true
43
+ @instance.connection.client.options[:timeout].should == 3600
44
+ @instance.connection.client.options.has_key?(:fake_option).should be_false
45
+ end
46
+ end
47
+
19
48
  describe 'find_model' do
20
49
 
21
50
  end
@@ -26,6 +26,14 @@ describe ActiveFedora::SemanticNode do
26
26
  stm = @node.build_statement('info:fedora/spec:9', :is_part_of, 'info:fedora/spec:7')
27
27
  stm.object.to_s.should == "info:fedora/spec:7"
28
28
  end
29
+ it "should also be happy with non-info URIs" do
30
+ stm = @node.build_statement('info:fedora/spec:9', :is_annotation_of, 'http://www.w3.org/standards/techs/rdf')
31
+ stm.object.to_s.should == "http://www.w3.org/standards/techs/rdf"
32
+ end
33
+ it "should also be happy with targets that are URI::Generics" do
34
+ stm = @node.build_statement('info:fedora/spec:9', :is_annotation_of, URI.parse('http://www.w3.org/standards/techs/rdf'))
35
+ stm.object.to_s.should == "http://www.w3.org/standards/techs/rdf"
36
+ end
29
37
  end
30
38
 
31
39
  describe "with a bunch of objects" do
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: active-fedora
3
3
  version: !ruby/object:Gem::Version
4
- hash: 1
4
+ hash: 7
5
5
  prerelease:
6
6
  segments:
7
7
  - 3
8
8
  - 1
9
- - 1
10
- version: 3.1.1
9
+ - 2
10
+ version: 3.1.2
11
11
  platform: ruby
12
12
  authors:
13
13
  - Matt Zumwalt
@@ -16,7 +16,7 @@ autorequire:
16
16
  bindir: bin
17
17
  cert_chain: []
18
18
 
19
- date: 2011-11-08 00:00:00 -06:00
19
+ date: 2011-11-18 00:00:00 -06:00
20
20
  default_executable:
21
21
  dependencies:
22
22
  - !ruby/object:Gem::Dependency
@@ -589,6 +589,7 @@ files:
589
589
  - lib/active_fedora/property.rb
590
590
  - lib/active_fedora/qualified_dublin_core_datastream.rb
591
591
  - lib/active_fedora/railtie.rb
592
+ - lib/active_fedora/rdf_xml_writer.rb
592
593
  - lib/active_fedora/reflection.rb
593
594
  - lib/active_fedora/relationship.rb
594
595
  - lib/active_fedora/relationships_helper.rb
@@ -707,6 +708,7 @@ files:
707
708
  - spec/unit/nokogiri_datastream_spec.rb
708
709
  - spec/unit/property_spec.rb
709
710
  - spec/unit/qualified_dublin_core_datastream_spec.rb
711
+ - spec/unit/rdf_xml_writer.rb
710
712
  - spec/unit/relationship_spec.rb
711
713
  - spec/unit/relationships_helper_spec.rb
712
714
  - spec/unit/rels_ext_datastream_spec.rb
@@ -843,6 +845,7 @@ test_files:
843
845
  - spec/unit/nokogiri_datastream_spec.rb
844
846
  - spec/unit/property_spec.rb
845
847
  - spec/unit/qualified_dublin_core_datastream_spec.rb
848
+ - spec/unit/rdf_xml_writer.rb
846
849
  - spec/unit/relationship_spec.rb
847
850
  - spec/unit/relationships_helper_spec.rb
848
851
  - spec/unit/rels_ext_datastream_spec.rb