active-fedora 3.3.2 → 4.0.0.rc1
Sign up to get free protection for your applications and to get access to all the features.
- data/Gemfile.lock +21 -22
- data/History.txt +9 -0
- data/README.textile +1 -1
- data/TODO +1 -0
- data/active-fedora.gemspec +3 -3
- data/config/fedora.yml +9 -3
- data/lib/active_fedora.rb +43 -33
- data/lib/active_fedora/base.rb +80 -31
- data/lib/active_fedora/config.rb +38 -0
- data/lib/active_fedora/content_model.rb +0 -6
- data/lib/active_fedora/datastream.rb +22 -0
- data/lib/active_fedora/delegating.rb +24 -25
- data/lib/active_fedora/digital_object.rb +2 -1
- data/lib/active_fedora/file_management.rb +1 -0
- data/lib/active_fedora/fixture_exporter.rb +1 -1
- data/lib/active_fedora/fixture_loader.rb +3 -3
- data/lib/active_fedora/metadata_datastream.rb +6 -0
- data/lib/active_fedora/model.rb +24 -5
- data/lib/active_fedora/nokogiri_datastream.rb +1 -0
- data/lib/active_fedora/ntriples_rdf_datastream.rb +0 -1
- data/lib/active_fedora/persistence.rb +2 -1
- data/lib/active_fedora/predicates.rb +27 -27
- data/lib/active_fedora/rdf_datastream.rb +104 -30
- data/lib/active_fedora/rels_ext_datastream.rb +14 -10
- data/lib/active_fedora/rubydora_connection.rb +4 -27
- data/lib/active_fedora/service_definitions.rb +2 -3
- data/lib/active_fedora/solr_digital_object.rb +22 -8
- data/lib/active_fedora/solr_service.rb +1 -1
- data/lib/active_fedora/unsaved_digital_object.rb +1 -4
- data/lib/active_fedora/version.rb +1 -1
- data/lib/tasks/active_fedora.rake +6 -6
- data/lib/tasks/active_fedora_dev.rake +0 -1
- data/spec/fixtures/mixed_rdf_descMetadata.nt +6 -0
- data/spec/fixtures/rails_root/config/fedora.yml +3 -1
- data/spec/fixtures/sharded_fedora.yml +11 -0
- data/spec/integration/base_file_management_spec.rb +6 -3
- data/spec/integration/base_find_by_fields_spec.rb +15 -16
- data/spec/integration/base_spec.rb +11 -178
- data/spec/integration/datastream_collections_spec.rb +1 -1
- data/spec/integration/full_featured_model_spec.rb +1 -2
- data/spec/integration/model_spec.rb +8 -9
- data/spec/integration/mods_article_integration_spec.rb +1 -1
- data/spec/integration/nokogiri_datastream_spec.rb +1 -1
- data/spec/integration/ntriples_datastream_spec.rb +80 -0
- data/spec/integration/rels_ext_datastream_spec.rb +0 -1
- data/spec/integration/semantic_node_spec.rb +18 -26
- data/spec/integration/solr_service_spec.rb +51 -1
- data/{lib/active_fedora → spec}/samples/hydra-mods_article_datastream.rb +0 -0
- data/{lib/active_fedora → spec}/samples/hydra-rights_metadata_datastream.rb +0 -0
- data/{lib/active_fedora → spec}/samples/marpa-dc_datastream.rb +0 -0
- data/spec/samples/models/hydrangea_article.rb +2 -2
- data/spec/samples/samples.rb +2 -0
- data/{lib/active_fedora → spec}/samples/special_thing.rb +3 -3
- data/spec/spec_helper.rb +1 -0
- data/spec/unit/active_fedora_spec.rb +17 -50
- data/spec/unit/base_extra_spec.rb +4 -0
- data/spec/unit/base_file_management_spec.rb +5 -2
- data/spec/unit/base_spec.rb +692 -628
- data/spec/unit/config_spec.rb +19 -0
- data/spec/unit/content_model_spec.rb +1 -24
- data/spec/unit/datastream_collections_spec.rb +11 -14
- data/spec/unit/datastreams_spec.rb +49 -54
- data/spec/unit/model_spec.rb +24 -53
- data/spec/unit/nokogiri_datastream_spec.rb +6 -1
- data/spec/unit/ntriples_datastream_spec.rb +73 -0
- data/spec/unit/qualified_dublin_core_datastream_spec.rb +1 -1
- data/spec/unit/relationships_spec.rb +6 -3
- data/spec/unit/rels_ext_datastream_spec.rb +19 -0
- data/spec/unit/rubydora_connection_spec.rb +2 -56
- data/spec/unit/solr_service_spec.rb +3 -1
- data/spec/unit/unsaved_digital_object_spec.rb +2 -2
- metadata +46 -33
- data/lib/active_fedora/dcrdf_datastream.rb +0 -11
- data/lib/active_fedora/relationship.rb +0 -47
- data/lib/active_fedora/samples.rb +0 -3
- data/spec/integration/dc_rdf_datastream_spec.rb +0 -24
- data/spec/unit/dc_rdf_datastream_spec.rb +0 -50
- data/spec/unit/relationship_spec.rb +0 -92
@@ -0,0 +1,38 @@
|
|
1
|
+
module ActiveFedora
|
2
|
+
class Config
|
3
|
+
attr_reader :path, :credentials
|
4
|
+
def initialize(config_path, env)
|
5
|
+
@path = config_path
|
6
|
+
val = YAML.load(File.open(config_path))[env]
|
7
|
+
if val.is_a? Array
|
8
|
+
init_shards(val)
|
9
|
+
else
|
10
|
+
init_single(val)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
def sharded?
|
15
|
+
credentials.is_a? Array
|
16
|
+
end
|
17
|
+
|
18
|
+
private
|
19
|
+
|
20
|
+
def init_shards(vals)
|
21
|
+
@credentials = vals.map(&:symbolize_keys)
|
22
|
+
end
|
23
|
+
|
24
|
+
def init_single(vals)
|
25
|
+
@credentials = vals.symbolize_keys
|
26
|
+
if @credentials[:url] && !@credentials[:user]
|
27
|
+
ActiveSupport::Deprecation.warn("Using \":url\" in the fedora.yml file without :user and :password is no longer supported")
|
28
|
+
u = URI.parse @credentials[:url]
|
29
|
+
@credentials[:user] = u.user
|
30
|
+
@credentials[:password] = u.password
|
31
|
+
@credentials[:url] = "#{u.scheme}://#{u.host}:#{u.port}#{u.path}"
|
32
|
+
end
|
33
|
+
unless @credentials.has_key?(:user) && @credentials.has_key?(:password) && @credentials.has_key?(:url)
|
34
|
+
raise ActiveFedora::ConfigurationError, "You must provide user, password and url in the #{env} section of #{@path}"
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -11,12 +11,6 @@ module ActiveFedora
|
|
11
11
|
super
|
12
12
|
end
|
13
13
|
|
14
|
-
# @deprecated Please use {.to_class_uri} instead
|
15
|
-
def self.pid_from_ruby_class(klass,attrs={})
|
16
|
-
ActiveSupport::Deprecation.warn("pid_from_ruby_class is deprecated. Use klass.to_class_uri instead")
|
17
|
-
klass.to_class_uri(attrs)
|
18
|
-
end
|
19
|
-
|
20
14
|
###Override this, if you prefer your class names serialized some other way
|
21
15
|
def self.sanitized_class_name(klass)
|
22
16
|
klass.name.gsub(/(::)/, '_')
|
@@ -93,6 +93,28 @@ module ActiveFedora
|
|
93
93
|
return true
|
94
94
|
end
|
95
95
|
|
96
|
+
def solrize_profile(solr_doc = Hash.new) # :nodoc:
|
97
|
+
profile.each_pair do |property,value|
|
98
|
+
if property =~ /Date/
|
99
|
+
value = Time.parse(value) unless value.is_a?(Time)
|
100
|
+
value = value.xmlschema
|
101
|
+
end
|
102
|
+
solr_doc[ActiveFedora::SolrService.solr_name("#{dsid}_dsProfile_#{property}", property =~ /Date/ ? :date : :symbol)] = value
|
103
|
+
end
|
104
|
+
solr_doc
|
105
|
+
end
|
106
|
+
|
107
|
+
def from_solr(solr_doc)
|
108
|
+
profile_from_solr(solr_doc)
|
109
|
+
end
|
110
|
+
|
111
|
+
def profile_from_solr(solr_doc)
|
112
|
+
profile_attrs = solr_doc.keys.select { |k| k =~ /^#{dsid}_dsProfile_/ }
|
113
|
+
profile_attrs.each do |key|
|
114
|
+
attr_name = key.split(/_/)[2..-2].join('_')
|
115
|
+
profile[attr_name] = solr_doc[key].to_s
|
116
|
+
end
|
117
|
+
end
|
96
118
|
end
|
97
119
|
|
98
120
|
class DatastreamConcurrencyException < Exception # :nodoc:
|
@@ -1,7 +1,7 @@
|
|
1
1
|
module ActiveFedora
|
2
2
|
module Delegating
|
3
3
|
extend ActiveSupport::Concern
|
4
|
-
|
4
|
+
|
5
5
|
module ClassMethods
|
6
6
|
# Provides a delegate class method to expose methods in metadata streams
|
7
7
|
# as member of the base object. Pass the target datastream via the
|
@@ -26,33 +26,32 @@ module ActiveFedora
|
|
26
26
|
create_delegate_accessor(field, args)
|
27
27
|
create_delegate_setter(field, args)
|
28
28
|
end
|
29
|
-
|
29
|
+
|
30
30
|
private
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
end
|
31
|
+
def create_delegate_accessor(field, args)
|
32
|
+
define_method field do
|
33
|
+
ds = self.send(args[:to])
|
34
|
+
val = if ds.kind_of?(ActiveFedora::MetadataDatastream) || ds.kind_of?(ActiveFedora::RDFDatastream)
|
35
|
+
ds.send(:get_values, field)
|
36
|
+
else
|
37
|
+
terminology = args[:at] || [field]
|
38
|
+
ds.send(:term_values, *terminology)
|
39
|
+
end
|
40
|
+
args[:unique] ? val.first : val
|
43
41
|
end
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
42
|
+
end
|
43
|
+
|
44
|
+
def create_delegate_setter(field, args)
|
45
|
+
define_method "#{field}=".to_sym do |v|
|
46
|
+
ds = self.send(args[:to])
|
47
|
+
if ds.kind_of?(ActiveFedora::MetadataDatastream) || ds.kind_of?(ActiveFedora::RDFDatastream)
|
48
|
+
ds.send(:set_value, field, v)
|
49
|
+
else
|
50
|
+
terminology = args[:at] || [field]
|
51
|
+
ds.send(:update_indexed_attributes, {terminology => v})
|
52
|
+
end
|
55
53
|
end
|
54
|
+
end
|
56
55
|
end
|
57
56
|
end
|
58
57
|
end
|
@@ -4,7 +4,8 @@ module ActiveFedora
|
|
4
4
|
attr_accessor :original_class
|
5
5
|
|
6
6
|
def self.find(original_class, pid)
|
7
|
-
|
7
|
+
conn = original_class.connection_for_pid(pid)
|
8
|
+
obj = super(pid, conn)
|
8
9
|
obj.original_class = original_class
|
9
10
|
obj
|
10
11
|
end
|
@@ -3,6 +3,7 @@ module ActiveFedora
|
|
3
3
|
extend ActiveSupport::Concern
|
4
4
|
|
5
5
|
included do
|
6
|
+
include ActiveFedora::Relationships
|
6
7
|
has_relationship "collection_members", :has_collection_member
|
7
8
|
has_relationship "part_of", :is_part_of
|
8
9
|
has_bidirectional_relationship "parts", :has_part, :is_part_of
|
@@ -24,7 +24,7 @@ module ActiveFedora
|
|
24
24
|
end
|
25
25
|
end
|
26
26
|
|
27
|
-
|
27
|
+
ActiveFedora::Base.connection_for_pid(pid).export(:pid=>pid, :format=>format, :context=>extra_params[:context].to_s)
|
28
28
|
end
|
29
29
|
|
30
30
|
|
@@ -26,7 +26,7 @@ module ActiveFedora
|
|
26
26
|
end
|
27
27
|
|
28
28
|
def import_and_index(pid)
|
29
|
-
body = self.class.import_to_fedora(filename_for_pid(pid))
|
29
|
+
body = self.class.import_to_fedora(filename_for_pid(pid), pid)
|
30
30
|
self.class.index(pid)
|
31
31
|
body
|
32
32
|
end
|
@@ -36,9 +36,9 @@ module ActiveFedora
|
|
36
36
|
solrizer.solrize(pid)
|
37
37
|
end
|
38
38
|
|
39
|
-
def self.import_to_fedora(filename)
|
39
|
+
def self.import_to_fedora(filename, pid)
|
40
40
|
file = File.new(filename, "r")
|
41
|
-
result = ActiveFedora::
|
41
|
+
result = ActiveFedora::Base.connection_for_pid(pid).ingest(:file=>file.read)
|
42
42
|
raise "Failed to ingest the fixture." unless result
|
43
43
|
result.body
|
44
44
|
end
|
@@ -40,7 +40,12 @@ module ActiveFedora
|
|
40
40
|
#
|
41
41
|
# ====Warning
|
42
42
|
# Solr must be synchronized with data in Fedora.
|
43
|
+
# @content is initialized to the empty document template to satisfy #ensure_xml_loaded
|
44
|
+
# (called from #update_attributes and #update_indexed_attributes)
|
43
45
|
def from_solr(solr_doc)
|
46
|
+
@content = self.to_xml
|
47
|
+
self.xml_loaded = true
|
48
|
+
profile_from_solr(solr_doc)
|
44
49
|
fields.each do |field_key, field_info|
|
45
50
|
field_symbol = ActiveFedora::SolrService.solr_name(field_key, field_info[:type])
|
46
51
|
value = (solr_doc[field_symbol].nil? ? solr_doc[field_symbol.to_s]: solr_doc[field_symbol])
|
@@ -241,6 +246,7 @@ module ActiveFedora
|
|
241
246
|
#you will end up replicating the values in the underlying datastream, resulting in mysterious dubling, quadrupling, etc.
|
242
247
|
#whenever you edit the field's values.
|
243
248
|
def field(name, tupe, opts={})
|
249
|
+
#TODO add term to terminology
|
244
250
|
@fields[name.to_s.to_sym]={:type=>tupe, :values=>[]}.merge(opts)
|
245
251
|
eval <<-EOS
|
246
252
|
def #{name}_values=(arg)
|
data/lib/active_fedora/model.rb
CHANGED
@@ -21,6 +21,7 @@ module ActiveFedora
|
|
21
21
|
# Takes a Fedora URI for a cModel, and returns a
|
22
22
|
# corresponding Model if available
|
23
23
|
# This method should reverse ClassMethods#to_class_uri
|
24
|
+
# @return [Class, False] the class of the model or false, if it does not exist
|
24
25
|
def self.from_class_uri(uri)
|
25
26
|
model_value, pid_ns = classname_from_uri(uri)
|
26
27
|
raise "model URI incorrectly formatted: #{uri}" unless model_value
|
@@ -79,8 +80,21 @@ module ActiveFedora
|
|
79
80
|
# @example this will return an instance of Book, even if the object hydra:dataset1 asserts that it is a Dataset
|
80
81
|
# Book.load_instance("hydra:dataset1")
|
81
82
|
def load_instance(pid)
|
82
|
-
|
83
|
+
self.allocate.init_with(DigitalObject.find(self, pid))
|
83
84
|
end
|
85
|
+
|
86
|
+
# Retrieve the Fedora object with te given pid, explore the returned object, determine its model
|
87
|
+
# using #{known_models_for} and cast to that class.
|
88
|
+
# @param [String] pid of the object to load
|
89
|
+
#
|
90
|
+
# @example because the object hydra:dataset1 asserts it is a Dataset (hasModel info:fedora/afmodel:Dataset), return a Dataset object (not a Book).
|
91
|
+
# Book.find_document("hydra:dataset1")
|
92
|
+
def find_document(pid)
|
93
|
+
af_base = load_instance(pid)
|
94
|
+
the_model = ActiveFedora::ContentModel.known_models_for( af_base ).first
|
95
|
+
af_base.adapt_to(the_model)
|
96
|
+
end
|
97
|
+
|
84
98
|
|
85
99
|
# Returns a suitable uri object for :has_model
|
86
100
|
# Should reverse Model#from_class_uri
|
@@ -103,20 +117,25 @@ module ActiveFedora
|
|
103
117
|
# called on
|
104
118
|
def find(args, opts={})
|
105
119
|
opts = {:rows=>25}.merge(opts)
|
106
|
-
return_multiple = false
|
107
120
|
if args == :all
|
108
|
-
return_multiple = true
|
109
121
|
escaped_class_uri = SolrService.escape_uri_for_query(self.to_class_uri)
|
110
122
|
q = "#{ActiveFedora::SolrService.solr_name(:has_model, :symbol)}:#{escaped_class_uri}"
|
111
123
|
hits = SolrService.instance.conn.query(q, :rows=>opts[:rows]).hits
|
112
124
|
return hits.map do |hit|
|
113
|
-
|
125
|
+
pid = hit[SOLR_DOCUMENT_ID]
|
126
|
+
load_instance(pid)
|
114
127
|
end
|
115
128
|
elsif args.class == String
|
116
|
-
return
|
129
|
+
return load_instance(args)
|
117
130
|
end
|
118
131
|
end
|
119
132
|
|
133
|
+
def find_model(pid)
|
134
|
+
ActiveSupport::Deprection.warn("find_model is deprecated. Use load_instance instead")
|
135
|
+
load_instance(pid)
|
136
|
+
end
|
137
|
+
|
138
|
+
|
120
139
|
# Get a count of the number of objects from solr
|
121
140
|
# Takes :conditions as an argument
|
122
141
|
def count(args = {})
|
@@ -100,6 +100,7 @@ module ActiveFedora
|
|
100
100
|
#
|
101
101
|
# See ActiveFedora::Base.load_instance_from_solr and +get_values_from_solr+ for more information.
|
102
102
|
def from_solr(solr_doc)
|
103
|
+
profile_from_solr(solr_doc)
|
103
104
|
#just initialize internal_solr_doc since any value retrieval will be done via lazy loading on this doc on-demand
|
104
105
|
@internal_solr_doc = solr_doc
|
105
106
|
end
|
@@ -91,8 +91,9 @@ module ActiveFedora
|
|
91
91
|
persist
|
92
92
|
end
|
93
93
|
|
94
|
+
# replace the unsaved digital object with a saved digital object
|
94
95
|
def assign_pid
|
95
|
-
@inner_object = @inner_object.save
|
96
|
+
@inner_object = @inner_object.save
|
96
97
|
end
|
97
98
|
|
98
99
|
# Pushes the object and all of its new or dirty datastreams into Fedora
|
@@ -1,41 +1,41 @@
|
|
1
1
|
module ActiveFedora
|
2
|
-
|
3
2
|
module Predicates
|
4
3
|
def self.find_graph_predicate(predicate)
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
end
|
15
|
-
else
|
16
|
-
xmlns="info:fedora/fedora-system:def/relations-external#"
|
17
|
-
begin
|
18
|
-
rel_predicate = predicate_lookup(predicate,xmlns)
|
19
|
-
rescue UnregisteredPredicateError
|
20
|
-
xmlns = nil
|
21
|
-
rel_predicate = nil
|
22
|
-
end
|
4
|
+
#TODO, these could be cached
|
5
|
+
case predicate
|
6
|
+
when :has_model, "hasModel", :hasModel
|
7
|
+
xmlns="info:fedora/fedora-system:def/model#"
|
8
|
+
begin
|
9
|
+
rel_predicate = predicate_lookup(predicate,xmlns)
|
10
|
+
rescue UnregisteredPredicateError
|
11
|
+
xmlns = nil
|
12
|
+
rel_predicate = nil
|
23
13
|
end
|
24
|
-
|
25
|
-
|
26
|
-
|
14
|
+
else
|
15
|
+
xmlns="info:fedora/fedora-system:def/relations-external#"
|
16
|
+
begin
|
17
|
+
rel_predicate = predicate_lookup(predicate,xmlns)
|
18
|
+
rescue UnregisteredPredicateError
|
19
|
+
xmlns = nil
|
20
|
+
rel_predicate = nil
|
27
21
|
end
|
28
|
-
|
22
|
+
end
|
23
|
+
|
24
|
+
unless xmlns && rel_predicate
|
25
|
+
rel_predicate, xmlns = find_predicate(predicate)
|
26
|
+
end
|
27
|
+
|
28
|
+
vocabularies[xmlns][rel_predicate]
|
29
29
|
end
|
30
30
|
|
31
31
|
def self.vocabularies
|
32
|
-
|
33
|
-
|
34
|
-
|
32
|
+
@vocabularies ||= {}
|
33
|
+
predicate_mappings.keys.each do |ns|
|
34
|
+
@vocabularies[ns] = RDF::Vocabulary.new(ns) unless @vocabularies.has_key? ns
|
35
|
+
end
|
35
36
|
@vocabularies
|
36
37
|
end
|
37
38
|
|
38
|
-
|
39
39
|
# If predicate is a symbol, looks up the predicate in the predicate_mappings
|
40
40
|
# If predicate is not a Symbol, returns the predicate untouched
|
41
41
|
# @raise UnregisteredPredicateError if the predicate is a symbol but is not found in the predicate_mappings
|
@@ -2,6 +2,72 @@ require 'rdf'
|
|
2
2
|
|
3
3
|
module ActiveFedora
|
4
4
|
class RDFDatastream < Datastream
|
5
|
+
module ModelMethods
|
6
|
+
extend ActiveSupport::Concern
|
7
|
+
module ClassMethods
|
8
|
+
def config
|
9
|
+
ActiveFedora::Predicates.predicate_config
|
10
|
+
end
|
11
|
+
def map_predicates(&block)
|
12
|
+
yield self
|
13
|
+
end
|
14
|
+
def method_missing(name, *args)
|
15
|
+
args = args.first if args.respond_to? :first
|
16
|
+
raise "mapping must specify RDF vocabulary as :in argument" unless args.has_key? :in
|
17
|
+
vocab = args[:in]
|
18
|
+
predicate = args.fetch(:to, name)
|
19
|
+
raise "Vocabulary '#{vocab.inspect}' does not define property '#{predicate.inspect}'" unless vocab.respond_to? predicate
|
20
|
+
vocab = vocab.to_s
|
21
|
+
if config
|
22
|
+
if config[:predicate_mapping].has_key? vocab
|
23
|
+
config[:predicate_mapping][vocab][name] = predicate
|
24
|
+
else
|
25
|
+
config[:predicate_mapping][vocab] = { name => predicate }
|
26
|
+
end
|
27
|
+
else
|
28
|
+
config = {
|
29
|
+
:default_namespace => vocab,
|
30
|
+
:predicate_mapping => {
|
31
|
+
vocab => { name => predicate }
|
32
|
+
}
|
33
|
+
}
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
class TermProxy
|
40
|
+
# @param [Symbol, RDF::URI] predicate the predicate to insert into the graph
|
41
|
+
# @param [ActiveFedora::RelationshipGraph] graph the graph
|
42
|
+
include Enumerable
|
43
|
+
def initialize(graph, predicate, values=[])
|
44
|
+
@graph = graph
|
45
|
+
@predicate = predicate
|
46
|
+
@values = values
|
47
|
+
end
|
48
|
+
def each(&block)
|
49
|
+
@values.each { |value| block.call(value)}
|
50
|
+
end
|
51
|
+
def <<(*values)
|
52
|
+
@values.concat(values)
|
53
|
+
values.each { |value| @graph.add(@predicate, value, true) }
|
54
|
+
@graph.dirty = true
|
55
|
+
@values
|
56
|
+
end
|
57
|
+
def ==(other)
|
58
|
+
other.inspect == @values.inspect
|
59
|
+
end
|
60
|
+
def delete(*values)
|
61
|
+
values.each do |value|
|
62
|
+
res = @values.delete(value)
|
63
|
+
@graph.delete(@predicate, value) unless res.nil?
|
64
|
+
@graph.dirty = true
|
65
|
+
end
|
66
|
+
@values
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
include ModelMethods
|
5
71
|
attr_accessor :loaded
|
6
72
|
|
7
73
|
def ensure_loaded
|
@@ -19,66 +85,79 @@ module ActiveFedora
|
|
19
85
|
end
|
20
86
|
end
|
21
87
|
|
88
|
+
# @param [Symbol, RDF::URI] predicate the predicate to insert into the graph
|
89
|
+
def find_predicate(predicate)
|
90
|
+
predicate = predicate.to_sym unless predicate.kind_of? RDF::URI
|
91
|
+
result = ActiveFedora::Predicates.find_predicate(predicate)
|
92
|
+
return RDF::URI(result.reverse.to_s)
|
93
|
+
end
|
94
|
+
|
22
95
|
def graph
|
23
96
|
@graph ||= RelationshipGraph.new
|
24
97
|
end
|
25
98
|
|
99
|
+
# @param [Symbol, RDF::URI] predicate the predicate to insert into the graph
|
26
100
|
def get_values(predicate)
|
27
101
|
ensure_loaded
|
28
|
-
predicate =
|
102
|
+
predicate = find_predicate(predicate) unless predicate.kind_of? RDF::URI
|
29
103
|
results = graph[predicate]
|
30
|
-
|
104
|
+
return if results.nil?
|
105
|
+
values = []
|
31
106
|
results.each do |object|
|
32
|
-
|
107
|
+
values << (object.kind_of?(RDF::Literal) ? object.value : object.to_str)
|
33
108
|
end
|
34
|
-
|
109
|
+
TermProxy.new(graph, predicate, values)
|
110
|
+
end
|
111
|
+
|
112
|
+
def to_solr
|
113
|
+
# TODO
|
35
114
|
end
|
36
|
-
|
115
|
+
|
37
116
|
# if there are any existing statements with this predicate, replace them
|
117
|
+
# @param [Symbol, RDF::URI] predicate the predicate to insert into the graph
|
38
118
|
def set_value(predicate, args)
|
39
119
|
ensure_loaded
|
40
|
-
predicate =
|
120
|
+
predicate = find_predicate(predicate) unless predicate.kind_of? RDF::URI
|
41
121
|
graph.delete(predicate)
|
42
|
-
|
122
|
+
args.each do |arg|
|
123
|
+
graph.add(predicate, arg, true)
|
124
|
+
end
|
125
|
+
graph.dirty = true
|
126
|
+
return TermProxy.new(graph, predicate, args)
|
43
127
|
end
|
44
128
|
|
45
129
|
# append a value
|
130
|
+
# @param [Symbol, RDF::URI] predicate the predicate to insert into the graph
|
46
131
|
def append(predicate, args)
|
47
132
|
ensure_loaded
|
133
|
+
predicate = find_predicate(predicate) unless predicate.kind_of? RDF::URI
|
48
134
|
graph.add(predicate, args, true)
|
135
|
+
graph.dirty = true
|
136
|
+
return TermProxy.new(graph, predicate, args)
|
49
137
|
end
|
50
138
|
|
51
|
-
|
139
|
+
def serialization_format
|
140
|
+
raise "you must override the `serialization_format' method in a subclass"
|
141
|
+
end
|
52
142
|
|
53
143
|
def method_missing(name, *args)
|
54
|
-
if
|
55
|
-
get_values(pred)
|
56
|
-
elsif (md = /^([^=]+)=$/.match(name.to_s)) && pred = resolve_predicate(md[1])
|
144
|
+
if (md = /^([^=]+)=$/.match(name.to_s)) && pred = find_predicate(md[1])
|
57
145
|
set_value(pred, *args)
|
146
|
+
elsif pred = find_predicate(name)
|
147
|
+
get_values(name)
|
58
148
|
else
|
59
149
|
super
|
60
150
|
end
|
61
151
|
end
|
62
|
-
|
63
|
-
def serialization_format
|
64
|
-
raise "you must override the `serialization_format' method in a subclass"
|
65
|
-
end
|
66
|
-
|
67
152
|
|
68
|
-
# given a symbol or string, map it to a RDF::URI
|
69
|
-
# if the provided parameter is not allowed in the vocabulary, return nil
|
70
|
-
def resolve_predicate(predicate)
|
71
|
-
raise "you must override the `resolve_predicate' method in a subclass"
|
72
|
-
end
|
73
|
-
|
74
153
|
# Populate a RDFDatastream object based on the "datastream" content
|
75
154
|
# Assumes that the datastream contains RDF XML from a Fedora RELS-EXT datastream
|
76
|
-
# @param [
|
77
|
-
# @param [String] the "rdf" node
|
155
|
+
# @param [String] data the "rdf" node
|
78
156
|
def deserialize(data)
|
79
157
|
unless data.nil?
|
80
158
|
RDF::Reader.for(serialization_format).new(data) do |reader|
|
81
159
|
reader.each_statement do |statement|
|
160
|
+
next unless statement.subject == "info:fedora/#{pid}"
|
82
161
|
literal = statement.object.kind_of?(RDF::Literal)
|
83
162
|
object = literal ? statement.object.value : statement.object.to_str
|
84
163
|
graph.add(statement.predicate, object, literal)
|
@@ -89,10 +168,8 @@ module ActiveFedora
|
|
89
168
|
end
|
90
169
|
|
91
170
|
# Creates a RDF datastream for insertion into a Fedora Object
|
92
|
-
# @param [String] pid
|
93
|
-
# @param [Hash] relationships (optional) @default self.relationships
|
94
171
|
# Note: This method is implemented on SemanticNode instead of RelsExtDatastream because SemanticNode contains the relationships array
|
95
|
-
def serialize
|
172
|
+
def serialize
|
96
173
|
out = RDF::Writer.for(serialization_format).buffer do |writer|
|
97
174
|
graph.to_graph("info:fedora/#{pid}").each_statement do |statement|
|
98
175
|
writer << statement
|
@@ -100,9 +177,6 @@ module ActiveFedora
|
|
100
177
|
end
|
101
178
|
out
|
102
179
|
end
|
103
|
-
|
104
|
-
|
105
180
|
end
|
106
|
-
|
107
181
|
end
|
108
182
|
|