active-fedora 3.1.1 → 3.1.2

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.
@@ -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