active-fedora 7.0.4 → 7.1.0

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.
Files changed (64) hide show
  1. checksums.yaml +4 -4
  2. data/.rspec +1 -0
  3. data/History.txt +51 -1
  4. data/active-fedora.gemspec +19 -19
  5. data/lib/active_fedora.rb +1 -6
  6. data/lib/active_fedora/associations/builder/has_and_belongs_to_many.rb +1 -1
  7. data/lib/active_fedora/associations/collection_association.rb +1 -1
  8. data/lib/active_fedora/associations/has_and_belongs_to_many_association.rb +1 -1
  9. data/lib/active_fedora/attributes.rb +8 -0
  10. data/lib/active_fedora/base.rb +1 -1
  11. data/lib/active_fedora/callbacks.rb +1 -1
  12. data/lib/active_fedora/core.rb +13 -5
  13. data/lib/active_fedora/datastream_attribute.rb +1 -1
  14. data/lib/active_fedora/datastream_hash.rb +12 -6
  15. data/lib/active_fedora/fedora_attributes.rb +1 -1
  16. data/lib/active_fedora/file_configurator.rb +3 -3
  17. data/lib/active_fedora/fixture_loader.rb +2 -2
  18. data/lib/active_fedora/model.rb +2 -2
  19. data/lib/active_fedora/om_datastream.rb +2 -2
  20. data/lib/active_fedora/persistence.rb +22 -18
  21. data/lib/active_fedora/railtie.rb +5 -1
  22. data/lib/active_fedora/rdf.rb +11 -9
  23. data/lib/active_fedora/rdf/indexing.rb +1 -1
  24. data/lib/active_fedora/rdf/object_resource.rb +1 -1
  25. data/lib/active_fedora/rdf/rdf_datastream.rb +3 -3
  26. data/lib/active_fedora/relation/finder_methods.rb +16 -10
  27. data/lib/active_fedora/solr_instance_loader.rb +1 -1
  28. data/lib/active_fedora/solr_service.rb +1 -3
  29. data/lib/active_fedora/version.rb +1 -1
  30. data/spec/integration/attributes_spec.rb +4 -4
  31. data/spec/integration/base_spec.rb +32 -13
  32. data/spec/integration/complex_rdf_datastream_spec.rb +4 -4
  33. data/spec/integration/delete_all_spec.rb +1 -1
  34. data/spec/integration/load_from_solr_spec.rb +1 -1
  35. data/spec/integration/rdf_nested_attributes_spec.rb +4 -4
  36. data/spec/integration/scoped_query_spec.rb +6 -6
  37. data/spec/spec_helper.rb +5 -3
  38. data/spec/unit/attributes_spec.rb +19 -1
  39. data/spec/unit/builder/has_and_belongs_to_many_spec.rb +9 -0
  40. data/spec/unit/datastreams_spec.rb +4 -0
  41. data/spec/unit/file_configurator_spec.rb +5 -5
  42. data/spec/unit/logger_spec.rb +20 -0
  43. data/spec/unit/om_datastream_spec.rb +1 -1
  44. data/spec/unit/persistence_spec.rb +50 -0
  45. data/spec/unit/query_spec.rb +15 -5
  46. data/spec/unit/rdf_resource_datastream_spec.rb +3 -3
  47. data/spec/unit/rdfxml_rdf_datastream_spec.rb +1 -1
  48. data/spec/unit/solr_config_options_spec.rb +1 -1
  49. data/spec/unit/solr_service_spec.rb +1 -1
  50. metadata +33 -168
  51. data/lib/active_fedora/rdf/configurable.rb +0 -59
  52. data/lib/active_fedora/rdf/list.rb +0 -155
  53. data/lib/active_fedora/rdf/nested_attributes.rb +0 -130
  54. data/lib/active_fedora/rdf/node_config.rb +0 -57
  55. data/lib/active_fedora/rdf/properties.rb +0 -94
  56. data/lib/active_fedora/rdf/repositories.rb +0 -36
  57. data/lib/active_fedora/rdf/resource.rb +0 -328
  58. data/lib/active_fedora/rdf/term.rb +0 -188
  59. data/spec/unit/rdf_configurable_spec.rb +0 -37
  60. data/spec/unit/rdf_list_nested_attributes_spec.rb +0 -99
  61. data/spec/unit/rdf_list_spec.rb +0 -180
  62. data/spec/unit/rdf_properties_spec.rb +0 -81
  63. data/spec/unit/rdf_repositories_spec.rb +0 -28
  64. data/spec/unit/rdf_resource_spec.rb +0 -345
@@ -1,59 +0,0 @@
1
- module ActiveFedora::Rdf
2
- ##
3
- # Module to include configurable class-wide properties common to
4
- # Resource and RDFDatastream. It does its work at the class level,
5
- # and is meant to be extended.
6
- #
7
- # Define properties at the class level with:
8
- #
9
- # configure base_uri: "http://oregondigital.org/resource/", repository: :parent
10
- # Available properties are base_uri, rdf_label, type, and repository
11
- module Configurable
12
- extend Deprecation
13
-
14
- def base_uri
15
- nil
16
- end
17
-
18
- def rdf_label
19
- nil
20
- end
21
-
22
- def type
23
- nil
24
- end
25
-
26
- def rdf_type(value)
27
- Deprecation.warn Configurable, "rdf_type is deprecated and will be removed in active-fedora 8.0.0. Use configure type: instead.", caller
28
- configure type: value
29
- end
30
-
31
- def repository
32
- :parent
33
- end
34
-
35
- # API method for configuring class properties an RDF Resource may need.
36
- # This is an alternative to overriding the methods extended with this module.
37
- def configure(options = {})
38
- {
39
- base_uri: options[:base_uri],
40
- rdf_label: options[:rdf_label],
41
- type: options[:type],
42
- repository: options[:repository]
43
- }.each do |name, value|
44
- if value
45
- value = self.send("transform_#{name}", value) if self.respond_to?("transform_#{name}")
46
- define_singleton_method(name) do
47
- value
48
- end
49
- end
50
- end
51
- end
52
-
53
- def transform_type(value)
54
- RDF::URI.new(value).tap do |value|
55
- Resource.type_registry[value] = self
56
- end
57
- end
58
- end
59
- end
@@ -1,155 +0,0 @@
1
- module ActiveFedora::Rdf
2
- ##
3
- # An implementation of RDF::List intregrated with ActiveFedora::Rdf.
4
- #
5
- # A thoughtful reflection period is encouraged before using the
6
- # rdf:List concept in your data. The community may pursue other
7
- # options for ordered sets.
8
- class List < RDF::List
9
- include ActiveFedora::Rdf::NestedAttributes
10
- extend Configurable
11
- extend Properties
12
-
13
- delegate :rdf_subject, :mark_for_destruction, :marked_for_destruction?, :set_value, :get_values, :parent, :dump, :attributes=, to: :resource
14
- alias_method :to_ary, :to_a
15
-
16
- class << self
17
- def from_uri(uri, vals)
18
- list = ListResource.from_uri(uri, vals)
19
- self.new(list.rdf_subject, list)
20
- end
21
- end
22
-
23
- def resource
24
- graph
25
- end
26
-
27
- def initialize(*args)
28
- super
29
- parent = graph.parent if graph.respond_to? :parent
30
- @graph = ListResource.new(subject) << graph unless graph.kind_of? Resource
31
- graph << parent if parent
32
- graph.list = self
33
- graph.singleton_class.properties = self.class.properties
34
- graph.singleton_class.properties.keys.each do |property|
35
- graph.singleton_class.send(:register_property, property)
36
- end
37
- graph.insert RDF::Statement.new(subject, RDF.type, RDF.List)
38
- graph.reload
39
- end
40
-
41
- def []=(idx, value)
42
- raise IndexError "index #{idx} too small for array: minimum 0" if idx < 0
43
-
44
- if idx >= length
45
- (idx - length).times do
46
- self << RDF::OWL.Nothing
47
- end
48
- return self << value
49
- end
50
- each_subject.with_index do |v, i|
51
- next unless i == idx
52
- resource.set_value(v, RDF.first, value)
53
- end
54
- end
55
-
56
- ##
57
- # Override to return AF::Rdf::Resources as values, where
58
- # appropriate.
59
- def each(&block)
60
- return super unless block_given?
61
-
62
- super do |value|
63
- block.call(node_from_value(value))
64
- end
65
- end
66
-
67
- ##
68
- # Do these like #each.
69
- def first
70
- node_from_value(super)
71
- end
72
-
73
- def shift
74
- node_from_value(super)
75
- end
76
-
77
- ##
78
- # Find an AF::Rdf::Resource from the value returned by RDF::List
79
- def node_from_value(value)
80
- if value.kind_of? RDF::Resource
81
- type_uri = resource.query([value, RDF.type, nil]).to_a.first.try(:object)
82
- klass = ActiveFedora::Rdf::Resource.type_registry[type_uri]
83
- klass ||= Resource
84
- return klass.from_uri(value,resource)
85
- end
86
- value
87
- end
88
-
89
- ##
90
- # This class is the graph/Resource that backs the List and
91
- # supplies integration with the rest of ActiveFedora::Rdf
92
- class ListResource < Resource
93
- attr_reader :list
94
-
95
- def list=(list)
96
- @list ||= list
97
- end
98
-
99
- def attributes=(values)
100
- raise ArgumentError, "values must be a Hash, you provided #{values.class}" unless values.kind_of? Hash
101
- values.with_indifferent_access.each do |key, value|
102
- if self.singleton_class.properties.keys.map{ |k| "#{k}_attributes"}.include?(key)
103
- klass = properties[key[0..-12]]['class_name']
104
- klass = ActiveFedora.class_from_string(klass, final_parent.class) if klass.is_a? String
105
- value.is_a?(Hash) ? attributes_hash_to_list(values[key], klass) : attributes_to_list(value, klass)
106
- values.delete key
107
- end
108
- end
109
- persist!
110
- super
111
- end
112
-
113
- private
114
- def attributes_to_list(value, klass)
115
- value.each do |entry|
116
- item = klass.new()
117
- item.attributes = entry
118
- list << item
119
- end
120
- end
121
-
122
- def attributes_hash_to_list(value, klass)
123
- value.each do |counter, attr|
124
- item = klass.new()
125
- item.attributes = attr if attr
126
- list[counter.to_i] = item
127
- end
128
- end
129
- end
130
-
131
- ##
132
- # Monkey patch to allow lists to have subject URIs.
133
- # Overrides RDF::List to prevent URI subjects
134
- # from being replaced with nodes.
135
- #
136
- # @NOTE Lists built this way will return false for #valid?
137
- def <<(value)
138
- value = case value
139
- when nil then RDF.nil
140
- when RDF::Value then value
141
- when Array then RDF::List.new(nil, graph, value)
142
- else value
143
- end
144
-
145
- if empty?
146
- resource.set_value(RDF.first, value)
147
- resource.insert([subject, RDF.rest, RDF.nil])
148
- resource << value if value.kind_of? Resource
149
- return self
150
- end
151
- super
152
- resource << value if value.kind_of? Resource
153
- end
154
- end
155
- end
@@ -1,130 +0,0 @@
1
- module ActiveFedora
2
- module Rdf
3
- module NestedAttributes
4
- extend ActiveSupport::Concern
5
-
6
- included do
7
- class_attribute :nested_attributes_options, :instance_writer => false
8
- self.nested_attributes_options = {}
9
- end
10
-
11
- private
12
-
13
- UNASSIGNABLE_KEYS = %w(_destroy )
14
-
15
- # @param [Symbol] association_name
16
- # @param [Hash, Array] attributes_collection
17
- # @example
18
- #
19
- # assign_nested_attributes_for_collection_association(:people, {
20
- # '1' => { id: '1', name: 'Peter' },
21
- # '2' => { name: 'John' },
22
- # '3' => { id: '2', _destroy: true }
23
- # })
24
- #
25
- # Will update the name of the Person with ID 1, build a new associated
26
- # person with the name 'John', and mark the associated Person with ID 2
27
- # for destruction.
28
- #
29
- # Also accepts an Array of attribute hashes:
30
- #
31
- # assign_nested_attributes_for_collection_association(:people, [
32
- # { id: '1', name: 'Peter' },
33
- # { name: 'John' },
34
- # { id: '2', _destroy: true }
35
- # ])
36
- def assign_nested_attributes_for_collection_association(association_name, attributes_collection)
37
- options = self.nested_attributes_options[association_name]
38
-
39
- # TODO
40
- #check_record_limit!(options[:limit], attributes_collection)
41
-
42
- if attributes_collection.is_a?(Hash)
43
- attributes_collection = attributes_collection.values
44
- end
45
-
46
- association = self.send(association_name)
47
-
48
- attributes_collection.each do |attributes|
49
- attributes = attributes.with_indifferent_access
50
-
51
- if attributes['id'] && existing_record = association.detect { |record| record.rdf_subject.to_s == attributes['id'].to_s }
52
- if !call_reject_if(association_name, attributes)
53
- assign_to_or_mark_for_destruction(existing_record, attributes, options[:allow_destroy])
54
- end
55
- else
56
- attributes = attributes.with_indifferent_access
57
- association.build(attributes.except(*UNASSIGNABLE_KEYS))
58
- end
59
- end
60
- end
61
-
62
- # Updates a record with the +attributes+ or marks it for destruction if
63
- # +allow_destroy+ is +true+ and has_destroy_flag? returns +true+.
64
- def assign_to_or_mark_for_destruction(record, attributes, allow_destroy)
65
- record.attributes = attributes.except(*UNASSIGNABLE_KEYS)
66
- record.mark_for_destruction if has_destroy_flag?(attributes) && allow_destroy
67
- end
68
-
69
- def call_reject_if(association_name, attributes)
70
- return false if has_destroy_flag?(attributes)
71
- case callback = self.nested_attributes_options[association_name][:reject_if]
72
- when Symbol
73
- method(callback).arity == 0 ? send(callback) : send(callback, attributes)
74
- when Proc
75
- callback.call(attributes)
76
- end
77
- end
78
-
79
- # Determines if a hash contains a truthy _destroy key.
80
- def has_destroy_flag?(hash)
81
- ["1", "true"].include?(hash['_destroy'].to_s)
82
- end
83
-
84
-
85
- module ClassMethods
86
- def accepts_nested_attributes_for *attr_names
87
- options = { :allow_destroy => false, :update_only => false }
88
- options.update(attr_names.extract_options!)
89
- options.assert_valid_keys(:allow_destroy, :reject_if, :limit, :update_only)
90
- options[:reject_if] = REJECT_ALL_BLANK_PROC if options[:reject_if] == :all_blank
91
-
92
- attr_names.each do |association_name|
93
- nested_attributes_options = self.nested_attributes_options.dup
94
- nested_attributes_options[association_name] = options
95
- self.nested_attributes_options = nested_attributes_options
96
-
97
- generate_association_writer(association_name)
98
- end
99
- end
100
-
101
- private
102
-
103
- # Generates a writer method for this association. Serves as a point for
104
- # accessing the objects in the association. For example, this method
105
- # could generate the following:
106
- #
107
- # def pirate_attributes=(attributes)
108
- # assign_nested_attributes_for_collection_association(:pirate, attributes)
109
- # end
110
- #
111
- # This redirects the attempts to write objects in an association through
112
- # the helper methods defined below. Makes it seem like the nested
113
- # associations are just regular associations.
114
- def generate_association_writer(association_name)
115
- class_eval <<-eoruby, __FILE__, __LINE__ + 1
116
- if method_defined?(:#{association_name}_attributes=)
117
- remove_method(:#{association_name}_attributes=)
118
- end
119
- def #{association_name}_attributes=(attributes)
120
- assign_nested_attributes_for_collection_association(:#{association_name}, attributes)
121
- ## in lieu of autosave_association_callbacks just save all of em.
122
- send(:#{association_name}).each {|obj| obj.marked_for_destruction? ? obj.destroy : nil}
123
- send(:#{association_name}).reset!
124
- end
125
- eoruby
126
- end
127
- end
128
- end
129
- end
130
- end
@@ -1,57 +0,0 @@
1
- module ActiveFedora
2
- module Rdf
3
- class NodeConfig
4
- attr_accessor :predicate, :term, :class_name, :type, :behaviors, :multivalue
5
-
6
- def initialize(term, predicate, args={})
7
- self.term = term
8
- self.predicate = predicate
9
- self.class_name = args.delete(:class_name)
10
- self.multivalue = args.delete(:multivalue) { true }
11
- raise ArgumentError, "Invalid arguments for Rdf Node configuration: #{args} on #{predicate}" unless args.empty?
12
- end
13
-
14
- def [](value)
15
- value = value.to_sym
16
- self.respond_to?(value) ? self.send(value) : nil
17
- end
18
-
19
- def class_name
20
- if @class_name.kind_of?(String)
21
- begin
22
- new_class = @class_name.constantize
23
- @class_name = new_class
24
- rescue NameError
25
- end
26
- end
27
- @class_name
28
- end
29
-
30
- def with_index (&block)
31
- # needed for solrizer integration
32
- iobj = IndexObject.new
33
- yield iobj
34
- self.type = iobj.data_type
35
- self.behaviors = iobj.behaviors
36
- end
37
-
38
- # this enables a cleaner API for solr integration
39
- class IndexObject
40
- attr_accessor :data_type, :behaviors
41
- def initialize
42
- @behaviors = []
43
- @data_type = :string
44
- end
45
- def as(*args)
46
- @behaviors = args
47
- end
48
- def type(sym)
49
- @data_type = sym
50
- end
51
- def defaults
52
- :noop
53
- end
54
- end
55
- end
56
- end
57
- end
@@ -1,94 +0,0 @@
1
- module ActiveFedora::Rdf
2
- ##
3
- # Implements property configuration common to Rdf::Resource,
4
- # RDFDatastream, and others. It does its work at the class level,
5
- # and is meant to be extended.
6
- #
7
- # Define properties at the class level with:
8
- #
9
- # property :title, predicate: RDF::DC.title, class_name: ResourceClass
10
- #
11
- # or with the 'old' style:
12
- #
13
- # map_predicates do |map|
14
- # map.title(in: RDF::DC)
15
- # end
16
- #
17
- # You can pass a block to either to set index behavior.
18
- module Properties
19
- extend Deprecation
20
- attr_accessor :config
21
-
22
- ##
23
- # Registers properties for Resource-like classes
24
- # @param [Symbol] name of the property (and its accessor methods)
25
- # @param [Hash] opts for this property, must include a :predicate
26
- # @yield [index] index sets solr behaviors for the property
27
- def property(name, opts={}, &block)
28
- self.config[name] = ActiveFedora::Rdf::NodeConfig.new(name, opts[:predicate], opts.except(:predicate)).tap do |config|
29
- config.with_index(&block) if block_given?
30
- end
31
- behaviors = config[name].behaviors.flatten if config[name].behaviors and not config[name].behaviors.empty?
32
- register_property(name)
33
- end
34
-
35
- def config
36
- @config ||= if superclass.respond_to? :config
37
- superclass.config.dup
38
- else
39
- {}.with_indifferent_access
40
- end
41
- end
42
-
43
- alias_method :properties, :config
44
- alias_method :properties=, :config=
45
-
46
- def config_for_term_or_uri(term)
47
- return config[term.to_sym] unless term.kind_of? RDF::Resource
48
- config.each { |k, v| return v if v.predicate == term.to_uri }
49
- end
50
-
51
- def fields
52
- properties.keys.map(&:to_sym)
53
- end
54
-
55
- private
56
-
57
- ##
58
- # Private method for creating accessors for a given property.
59
- # If used on an ActiveFedora::Datastream it will create accessors which use the datastream's resource.
60
- # @param [#to_s] name Name of the accessor to be created, get/set_value is called on the resource using this.
61
- def register_property(name)
62
- parent = Proc.new{self}
63
- parent = Proc.new{resource} if self < ActiveFedora::Datastream
64
- define_method "#{name}=" do |*args|
65
- instance_eval(&parent).set_value(name.to_sym, *args)
66
- end
67
- define_method name do
68
- instance_eval(&parent).get_values(name.to_sym)
69
- end
70
- end
71
-
72
- public
73
- # Mapper is for backwards compatibility with AF::RDFDatastream
74
- class Mapper
75
- attr_accessor :parent
76
- def initialize(parent)
77
- @parent = parent
78
- end
79
- def method_missing(name, *args, &block)
80
- properties = args.first || {}
81
- vocab = properties.delete(:in)
82
- to = properties.delete(:to) || name
83
- predicate = vocab.send(to)
84
- parent.property(name, properties.merge(predicate: predicate), &block)
85
- end
86
- end
87
- def map_predicates
88
- Deprecation.warn Properties, "map_predicates is deprecated and will be removed in active-fedora 8.0.0. Use property :name, predicate: predicate instead.", caller
89
- mapper = Mapper.new(self)
90
- yield(mapper)
91
- end
92
-
93
- end
94
- end