rdf-mapper 0.0.1
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.
- data/README.rdoc +188 -0
- data/UNLICENSE +25 -0
- data/VERSION +1 -0
- data/lib/lib/adapters/base.rb +83 -0
- data/lib/lib/adapters/rails.rb +307 -0
- data/lib/lib/adapters/rest.rb +45 -0
- data/lib/lib/adapters/sparql.rb +105 -0
- data/lib/lib/associations/base.rb +95 -0
- data/lib/lib/associations/belongs_to.rb +64 -0
- data/lib/lib/associations/has_and_belongs.rb +17 -0
- data/lib/lib/associations/has_many.rb +147 -0
- data/lib/lib/associations/has_one.rb +17 -0
- data/lib/lib/model/association.rb +59 -0
- data/lib/lib/model/attribute.rb +186 -0
- data/lib/lib/model/base.rb +623 -0
- data/lib/lib/model/output.rb +70 -0
- data/lib/lib/model/property.rb +78 -0
- data/lib/lib/scope/collection.rb +165 -0
- data/lib/lib/scope/condition.rb +132 -0
- data/lib/lib/scope/loader.rb +111 -0
- data/lib/lib/scope/model.rb +129 -0
- data/lib/lib/scope/query.rb +281 -0
- data/lib/lib/util/http.rb +66 -0
- data/lib/lib/util/logger.rb +68 -0
- data/lib/rdf-mapper.rb +15 -0
- metadata +141 -0
@@ -0,0 +1,105 @@
|
|
1
|
+
module RDFMapper
|
2
|
+
module Adapters
|
3
|
+
##
|
4
|
+
# [-]
|
5
|
+
##
|
6
|
+
class SPARQL < Base
|
7
|
+
|
8
|
+
##
|
9
|
+
# [-]
|
10
|
+
##
|
11
|
+
def initialize(cls, options = {})
|
12
|
+
@rdf, @options = cls, options
|
13
|
+
end
|
14
|
+
|
15
|
+
##
|
16
|
+
# [-]
|
17
|
+
##
|
18
|
+
def load(query)
|
19
|
+
Query.new(query, @options).find
|
20
|
+
end
|
21
|
+
|
22
|
+
class Query
|
23
|
+
|
24
|
+
include RDFMapper::Logger
|
25
|
+
|
26
|
+
##
|
27
|
+
# [-]
|
28
|
+
##
|
29
|
+
def initialize(query, options = {})
|
30
|
+
@query, @options = query, options
|
31
|
+
@rdf = @query.cls
|
32
|
+
end
|
33
|
+
|
34
|
+
##
|
35
|
+
# [-]
|
36
|
+
##
|
37
|
+
def find
|
38
|
+
describe
|
39
|
+
end
|
40
|
+
|
41
|
+
|
42
|
+
private
|
43
|
+
|
44
|
+
##
|
45
|
+
# [-]
|
46
|
+
##
|
47
|
+
def describe
|
48
|
+
data = sparql_writer(:describe) do |writer|
|
49
|
+
triples = @query.to_triples
|
50
|
+
writer.write_triples(triples)
|
51
|
+
# Target always comes first in first triple
|
52
|
+
primary = triples.first.first
|
53
|
+
writer.targets << primary
|
54
|
+
end
|
55
|
+
repository = {}
|
56
|
+
download(data).each_triple do |triple|
|
57
|
+
s, p, o = triple
|
58
|
+
repository[s.to_s] ||= {}
|
59
|
+
repository[s.to_s][p.to_s] ||= []
|
60
|
+
repository[s.to_s][p.to_s] << o
|
61
|
+
end
|
62
|
+
objects(repository)
|
63
|
+
end
|
64
|
+
|
65
|
+
##
|
66
|
+
# [-]
|
67
|
+
##
|
68
|
+
def objects(repository)
|
69
|
+
repository.select do |uri, atts|
|
70
|
+
atts.key?(RDF.type.to_s)
|
71
|
+
end.select do |uri, atts|
|
72
|
+
@rdf.type == atts[RDF.type.to_s].first
|
73
|
+
end.map do |uri, atts|
|
74
|
+
atts.delete(RDF.type.to_s)
|
75
|
+
atts[:id] = uri
|
76
|
+
atts
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
##
|
81
|
+
# [-]
|
82
|
+
##
|
83
|
+
def sparql_writer(type, &block)
|
84
|
+
RDF::Writer.for(:sparql).buffer({ :type => type }, &block)
|
85
|
+
end
|
86
|
+
|
87
|
+
##
|
88
|
+
# [-]
|
89
|
+
##
|
90
|
+
def download(request)
|
91
|
+
data = RDFMapper::HTTP.post(@options[:server], request)
|
92
|
+
|
93
|
+
if data =~ /\<sparql/
|
94
|
+
RDF::Reader.for(:sparql_results)
|
95
|
+
elsif data =~ /\<rdf:RDF/
|
96
|
+
RDF::Reader.for(:xml)
|
97
|
+
else
|
98
|
+
raise RuntimeError, 'Unknown content type'
|
99
|
+
end.new(data)
|
100
|
+
end
|
101
|
+
|
102
|
+
end # Query
|
103
|
+
end # SPARQL
|
104
|
+
end # Adapters
|
105
|
+
end # RDFMapper
|
@@ -0,0 +1,95 @@
|
|
1
|
+
module RDFMapper
|
2
|
+
module Associations
|
3
|
+
|
4
|
+
autoload :BelongsTo, 'lib/associations/belongs_to'
|
5
|
+
autoload :HasMany, 'lib/associations/has_many'
|
6
|
+
autoload :HasOne, 'lib/associations/has_one'
|
7
|
+
autoload :HasAndBelongs, 'lib/associations/has_and_belongs'
|
8
|
+
|
9
|
+
##
|
10
|
+
# Base class for all association types. Contains default constructor.
|
11
|
+
##
|
12
|
+
class Base
|
13
|
+
|
14
|
+
include RDFMapper::Logger
|
15
|
+
|
16
|
+
def initialize(instance, options = {})
|
17
|
+
@instance = instance
|
18
|
+
@association = options[:cls]
|
19
|
+
@options = options
|
20
|
+
end
|
21
|
+
|
22
|
+
##
|
23
|
+
# [-]
|
24
|
+
##
|
25
|
+
def replace(value)
|
26
|
+
raise NotImplementedError, 'Expected association to override `replace`'
|
27
|
+
end
|
28
|
+
|
29
|
+
##
|
30
|
+
# [-]
|
31
|
+
##
|
32
|
+
def object(force = false)
|
33
|
+
value.nil? and value.empty? if force
|
34
|
+
self
|
35
|
+
end
|
36
|
+
|
37
|
+
##
|
38
|
+
# [-]
|
39
|
+
##
|
40
|
+
def to_statements(options = {})
|
41
|
+
options[:skip] ||= []
|
42
|
+
if value.kind_of? Array
|
43
|
+
items = value
|
44
|
+
else
|
45
|
+
items = [value]
|
46
|
+
end
|
47
|
+
items.reject do |item|
|
48
|
+
options[:skip].include?(items)
|
49
|
+
end.map do |item|
|
50
|
+
node = if options[:full]
|
51
|
+
item.to_statements(:skip => @instance)
|
52
|
+
else
|
53
|
+
item.to_statements(:short => true)
|
54
|
+
end
|
55
|
+
node + [{
|
56
|
+
:subject => @instance.id,
|
57
|
+
:predicate => @options[:type],
|
58
|
+
:object => item.id
|
59
|
+
}]
|
60
|
+
end.flatten
|
61
|
+
end
|
62
|
+
|
63
|
+
##
|
64
|
+
# Developer-friendly representation of the instance
|
65
|
+
#
|
66
|
+
# @return [String]
|
67
|
+
##
|
68
|
+
def inspect #nodoc
|
69
|
+
value.inspect
|
70
|
+
end
|
71
|
+
|
72
|
+
|
73
|
+
private
|
74
|
+
|
75
|
+
##
|
76
|
+
# [-]
|
77
|
+
##
|
78
|
+
def value
|
79
|
+
raise NotImplementedError, 'Expected association to override `value`'
|
80
|
+
end
|
81
|
+
|
82
|
+
##
|
83
|
+
# [-]
|
84
|
+
##
|
85
|
+
def method_missing(symbol, *args, &block)
|
86
|
+
if value.respond_to? symbol
|
87
|
+
value.send(symbol, *args, &block)
|
88
|
+
else
|
89
|
+
raise RuntimeError, 'Undefined method `%s`' % symbol
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
end # Base
|
94
|
+
end # Associations
|
95
|
+
end # RDFMapper
|
@@ -0,0 +1,64 @@
|
|
1
|
+
module RDFMapper
|
2
|
+
module Associations
|
3
|
+
##
|
4
|
+
# [-]
|
5
|
+
##
|
6
|
+
class BelongsTo < Base
|
7
|
+
|
8
|
+
##
|
9
|
+
# [-]
|
10
|
+
##
|
11
|
+
def id
|
12
|
+
value.id
|
13
|
+
end
|
14
|
+
|
15
|
+
##
|
16
|
+
# [-]
|
17
|
+
##
|
18
|
+
def nil?
|
19
|
+
value.nil?
|
20
|
+
end
|
21
|
+
|
22
|
+
##
|
23
|
+
# [-]
|
24
|
+
##
|
25
|
+
def kind_of?(type)
|
26
|
+
value.kind_of?(type)
|
27
|
+
end
|
28
|
+
|
29
|
+
##
|
30
|
+
# Replaces current association with a new object
|
31
|
+
##
|
32
|
+
def replace(value)
|
33
|
+
if value.kind_of? String
|
34
|
+
@key = RDF::URI.new(value)
|
35
|
+
end
|
36
|
+
if value.kind_of? RDF::URI
|
37
|
+
@key = value
|
38
|
+
end
|
39
|
+
if value.kind_of? RDFMapper::Model
|
40
|
+
@value = value
|
41
|
+
else
|
42
|
+
nil
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
|
47
|
+
private
|
48
|
+
|
49
|
+
##
|
50
|
+
# [-]
|
51
|
+
##
|
52
|
+
def value
|
53
|
+
unless @value.nil?
|
54
|
+
return @value
|
55
|
+
end
|
56
|
+
if @key.nil?
|
57
|
+
return nil
|
58
|
+
end
|
59
|
+
replace(@association.find(@key))
|
60
|
+
end
|
61
|
+
|
62
|
+
end # BelongsTo
|
63
|
+
end # Associations
|
64
|
+
end # RDFMapper
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module RDFMapper
|
2
|
+
module Associations
|
3
|
+
##
|
4
|
+
# [-]
|
5
|
+
##
|
6
|
+
class HasAndBelongs
|
7
|
+
|
8
|
+
##
|
9
|
+
# [-]
|
10
|
+
##
|
11
|
+
def initialize(instance, options = {})
|
12
|
+
raise NotImplementedError, 'has_and_belongs_to is not yet implemented'
|
13
|
+
end
|
14
|
+
|
15
|
+
end # HasAndBelongs
|
16
|
+
end # Associations
|
17
|
+
end # RDFMapper
|
@@ -0,0 +1,147 @@
|
|
1
|
+
module RDFMapper
|
2
|
+
module Associations
|
3
|
+
##
|
4
|
+
# [-]
|
5
|
+
##
|
6
|
+
class HasMany < Base
|
7
|
+
|
8
|
+
##
|
9
|
+
# Replaces the collections content by deleting and adding
|
10
|
+
# objects as appropriate.
|
11
|
+
##
|
12
|
+
def replace(objects)
|
13
|
+
new_objects = filter(objects.to_a)
|
14
|
+
return @value if new_objects.empty?
|
15
|
+
|
16
|
+
new_objects.each do |child|
|
17
|
+
self << child
|
18
|
+
end
|
19
|
+
|
20
|
+
@value ||= []
|
21
|
+
@value.each do |child|
|
22
|
+
delete(child) unless new_objects.include?(child)
|
23
|
+
end
|
24
|
+
|
25
|
+
@value
|
26
|
+
end
|
27
|
+
|
28
|
+
##
|
29
|
+
# Adds one or more objects to the collection by setting their
|
30
|
+
# foreign keys to the collection's primary key.
|
31
|
+
##
|
32
|
+
def <<(*objects)
|
33
|
+
objects.to_a.select do |child|
|
34
|
+
child.kind_of? RDFMapper::Model
|
35
|
+
end.each do |child|
|
36
|
+
unless include?(child)
|
37
|
+
child[reverse] = @instance
|
38
|
+
@value << child
|
39
|
+
end
|
40
|
+
end
|
41
|
+
self
|
42
|
+
end
|
43
|
+
|
44
|
+
alias_method :push, :<<
|
45
|
+
|
46
|
+
##
|
47
|
+
# Removes one or more objects from the collection by removing
|
48
|
+
# the association between objects
|
49
|
+
##
|
50
|
+
def delete(*objects)
|
51
|
+
objects.each do |child|
|
52
|
+
if include?(child)
|
53
|
+
child[reverse] = nil
|
54
|
+
@value.delete(child)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
self
|
58
|
+
end
|
59
|
+
|
60
|
+
##
|
61
|
+
# Removes every object from the collection.
|
62
|
+
##
|
63
|
+
def clear
|
64
|
+
delete(@value)
|
65
|
+
end
|
66
|
+
|
67
|
+
##
|
68
|
+
# Finds an associated object according to the same rules as
|
69
|
+
# RDFMapper::Model.find.
|
70
|
+
##
|
71
|
+
def find
|
72
|
+
raise NotImplementedError, '`find` not yet implemented' # TODO
|
73
|
+
end
|
74
|
+
|
75
|
+
##
|
76
|
+
# Returns one or more new objects of the collection type that
|
77
|
+
# have been instantiated with attributes and linked to this object
|
78
|
+
# through a foreign key, but have not yet been saved.
|
79
|
+
##
|
80
|
+
def build
|
81
|
+
raise NotImplementedError, '`build` not yet implemented' # TODO
|
82
|
+
end
|
83
|
+
|
84
|
+
##
|
85
|
+
# Returns a new object of the collection type that has been
|
86
|
+
# instantiated with attributes, linked to this object through
|
87
|
+
# a foreign key, and that has already been saved.
|
88
|
+
##
|
89
|
+
def create
|
90
|
+
raise NotImplementedError, '`create` not yet implemented' # TODO
|
91
|
+
end
|
92
|
+
|
93
|
+
##
|
94
|
+
# Returns true if a given object is present in the collection
|
95
|
+
##
|
96
|
+
def include?(object)
|
97
|
+
@value ||= []
|
98
|
+
@value.include?(object)
|
99
|
+
end
|
100
|
+
|
101
|
+
##
|
102
|
+
# [-]
|
103
|
+
##
|
104
|
+
def to_a
|
105
|
+
value
|
106
|
+
end
|
107
|
+
|
108
|
+
|
109
|
+
private
|
110
|
+
|
111
|
+
def filter(objects)
|
112
|
+
objects.select do |child|
|
113
|
+
child.kind_of? RDFMapper::Model
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
##
|
118
|
+
# [-]
|
119
|
+
##
|
120
|
+
def value
|
121
|
+
unless @value.nil?
|
122
|
+
return @value
|
123
|
+
end
|
124
|
+
if @instance.id.nil?
|
125
|
+
return []
|
126
|
+
end
|
127
|
+
replace @association.find(:all, {
|
128
|
+
:conditions => { reverse => @instance },
|
129
|
+
:skip => [reverse]
|
130
|
+
})
|
131
|
+
end
|
132
|
+
|
133
|
+
##
|
134
|
+
# [-]
|
135
|
+
##
|
136
|
+
def reverse
|
137
|
+
@reverse ||= @association.has?(nil, @instance)
|
138
|
+
if @reverse.nil?
|
139
|
+
raise RuntimeError, 'Expected %s to belong to %s' % [@association, @instance.class]
|
140
|
+
else
|
141
|
+
@reverse.name
|
142
|
+
end
|
143
|
+
end
|
144
|
+
|
145
|
+
end # HasMany
|
146
|
+
end # Associations
|
147
|
+
end # RDFMapper
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module RDFMapper
|
2
|
+
module Associations
|
3
|
+
##
|
4
|
+
# [-]
|
5
|
+
##
|
6
|
+
class HasOne
|
7
|
+
|
8
|
+
##
|
9
|
+
# [-]
|
10
|
+
##
|
11
|
+
def initialize(instance, options = {})
|
12
|
+
raise NotImplementedError, 'has_one is not yet implemented'
|
13
|
+
end
|
14
|
+
|
15
|
+
end # HasOne
|
16
|
+
end # Associations
|
17
|
+
end # RDFMapper
|
@@ -0,0 +1,59 @@
|
|
1
|
+
module RDFMapper
|
2
|
+
class Model
|
3
|
+
class << self
|
4
|
+
|
5
|
+
##
|
6
|
+
# Specifies a one-to-many association. The following methods for retrieval
|
7
|
+
# and query of collections of associated objects will be added:
|
8
|
+
#
|
9
|
+
# * collection(force_load = false) -- Returns an array of all the associated
|
10
|
+
# objects. An empty array is returned if none are found.
|
11
|
+
#
|
12
|
+
# * collection<<(object, ...) -- Adds one or more objects to the collection by
|
13
|
+
# setting their foreign keys to the collection‘s primary key.
|
14
|
+
#
|
15
|
+
# * collection.delete(object, ...) -- Removes one or more objects from the
|
16
|
+
# collection by removing the association between objects.
|
17
|
+
#
|
18
|
+
# * collection=objects -- Replaces the collections content by deleting and
|
19
|
+
# adding objects as appropriate.
|
20
|
+
#
|
21
|
+
# * collection.clear -- Removes every object from the collection.
|
22
|
+
#
|
23
|
+
# * collection.empty? -- Returns true if there are no associated objects.
|
24
|
+
#
|
25
|
+
# * collection.size -- Returns the number of associated objects.
|
26
|
+
#
|
27
|
+
# @param [Symbol] name name of the association
|
28
|
+
#
|
29
|
+
# @param [Symbol] options[:class_name] class name of the association. Use it
|
30
|
+
# only if that name can't be inferred from the association name
|
31
|
+
#
|
32
|
+
# @return [Object] instance of RDFMapper::Attribute
|
33
|
+
##
|
34
|
+
def has_many(name, options = {})
|
35
|
+
attribute(name, options.merge(:association => :has_many))
|
36
|
+
end
|
37
|
+
|
38
|
+
##
|
39
|
+
# Specifies a one-to-one association with another class. The following
|
40
|
+
# methods for retrieval and query of the associated object will be added:
|
41
|
+
#
|
42
|
+
# * association(force_reload = false) -- Returns the associated object.
|
43
|
+
# nil is returned if none is found.
|
44
|
+
#
|
45
|
+
# * association=(associate) -- Assigns the associate object.
|
46
|
+
#
|
47
|
+
# @param [Symbol] name name of the association
|
48
|
+
#
|
49
|
+
# @param [Symbol] options[:class_name] class name of the association. Use it
|
50
|
+
# only if that name can't be inferred from the association name
|
51
|
+
##
|
52
|
+
def belongs_to(name, options = {})
|
53
|
+
attribute(name, options.merge(:association => :belongs_to))
|
54
|
+
end
|
55
|
+
|
56
|
+
end
|
57
|
+
end # Model
|
58
|
+
end # RDFMapper
|
59
|
+
|
@@ -0,0 +1,186 @@
|
|
1
|
+
module RDFMapper
|
2
|
+
class Model
|
3
|
+
##
|
4
|
+
# Contains configuration and convenience methods for model attributes.
|
5
|
+
# Instances of this class are assigned to classes (not instances!) of
|
6
|
+
# RDFMapper::Model.
|
7
|
+
##
|
8
|
+
class Attribute
|
9
|
+
|
10
|
+
include RDFMapper::Logger
|
11
|
+
|
12
|
+
attr_reader :name
|
13
|
+
|
14
|
+
##
|
15
|
+
# Constructor is called for each attribute of a model at the time
|
16
|
+
# the model is defined.
|
17
|
+
#
|
18
|
+
# @param [Object] cls class of the model
|
19
|
+
# @param [String] name name of the attribute
|
20
|
+
# @param [Hash] options options to pass on to the property / association constructor
|
21
|
+
#
|
22
|
+
# @return [self]
|
23
|
+
##
|
24
|
+
def initialize(cls, name, options)
|
25
|
+
@cls = cls
|
26
|
+
@name = name
|
27
|
+
@options = options.dup
|
28
|
+
end
|
29
|
+
|
30
|
+
##
|
31
|
+
# Checks if this attribute is a `belongs_to` association.
|
32
|
+
#
|
33
|
+
# @return [Boolean]
|
34
|
+
##
|
35
|
+
def belongs_to?
|
36
|
+
not property? and not multiple?
|
37
|
+
end
|
38
|
+
|
39
|
+
##
|
40
|
+
# Checks if this attribute is a property (i.e. not an association).
|
41
|
+
#
|
42
|
+
# @return [Boolean]
|
43
|
+
##
|
44
|
+
def property?
|
45
|
+
@options[:association].nil?
|
46
|
+
end
|
47
|
+
|
48
|
+
##
|
49
|
+
# Returns attribute's RDF predicate.
|
50
|
+
#
|
51
|
+
# @return [RDF::URI]
|
52
|
+
# @return [nil] if not specified and model has no namespace
|
53
|
+
##
|
54
|
+
def type
|
55
|
+
# Type is 'cached': lookups based on namespace can be quite slow
|
56
|
+
@type ||= unless @options[:predicate].nil?
|
57
|
+
RDF::URI.new(@options[:predicate].to_s)
|
58
|
+
else
|
59
|
+
# Keep this weird comparison. RDF::Vocabulary doesn't recognize `nil?` or `==`
|
60
|
+
(nil == @cls.namespace) ? nil : @cls.namespace[@name]
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
##
|
65
|
+
# Returns class of the associated model. Uses either the `:class_name`
|
66
|
+
# option or relies on association name. It follows ActiveRecord naming
|
67
|
+
# conventions(e.g. has_many should be plural, belongs_to - singular).
|
68
|
+
#
|
69
|
+
# @return [Object] a subclass of RDFMapper::Model
|
70
|
+
# @return [nil] if association is not found or this is a property attribute
|
71
|
+
##
|
72
|
+
def model
|
73
|
+
# A bit of 'caching': lookups based on namespace can be quite slow
|
74
|
+
unless @model.nil?
|
75
|
+
return @model
|
76
|
+
end
|
77
|
+
|
78
|
+
# Should return nil if this is not an association
|
79
|
+
if property?
|
80
|
+
return nil
|
81
|
+
end
|
82
|
+
|
83
|
+
if @model = model_from_options || model_from_namespace
|
84
|
+
@model
|
85
|
+
else
|
86
|
+
raise RuntimeError, 'Could not find association model for %s (%s :%s)' % [@cls, @options[:association], @name]
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
##
|
91
|
+
# Returns the class or an instance of a class associated with this
|
92
|
+
# attribute.
|
93
|
+
|
94
|
+
# When model instance is not specified, it will return Associations::HasMany,
|
95
|
+
# Associations::BelongsTo, Property, etc. Alternatively, when RDFMapper::Model
|
96
|
+
# is specified, it will return an instance of these classes.
|
97
|
+
#
|
98
|
+
# @param [Object] instance instance of RDFMapper::Model
|
99
|
+
# @return [Object] class of this attribute
|
100
|
+
# @return [Object] instance of this attribute
|
101
|
+
##
|
102
|
+
def value(instance = nil)
|
103
|
+
if nil == instance
|
104
|
+
return attribute_type
|
105
|
+
end
|
106
|
+
attribute_type.new(instance, @options.merge({
|
107
|
+
:cls => model,
|
108
|
+
:type => type,
|
109
|
+
:name => name
|
110
|
+
}))
|
111
|
+
end
|
112
|
+
|
113
|
+
##
|
114
|
+
# Checks if this attribute has the same predicate and / or value.
|
115
|
+
# Value is accepted both as an instance and a class.
|
116
|
+
##
|
117
|
+
def matches?(predicate, value = nil)
|
118
|
+
if type.nil? # Always false if attribute predicate is not defined
|
119
|
+
return false
|
120
|
+
end
|
121
|
+
if value == nil # Checking predicates
|
122
|
+
return type.to_s == predicate.to_s
|
123
|
+
end
|
124
|
+
unless value.respond_to? :new # Converting instance to a class
|
125
|
+
value = value.class
|
126
|
+
end
|
127
|
+
if model.nil? # Value is not nil, but model is undefined
|
128
|
+
return false
|
129
|
+
end
|
130
|
+
if value.type != model.type # Value type and model type should match
|
131
|
+
return false
|
132
|
+
end
|
133
|
+
if predicate.nil? # Value and model types match
|
134
|
+
true
|
135
|
+
else
|
136
|
+
predicate == type
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
|
141
|
+
private
|
142
|
+
|
143
|
+
##
|
144
|
+
# Returns attribute's class (e.g. Associations::HasMany, Property) based
|
145
|
+
# on the supplied `options[:association]`
|
146
|
+
##
|
147
|
+
def attribute_type #nodoc
|
148
|
+
case @options[:association]
|
149
|
+
when :has_many then Associations::HasMany
|
150
|
+
when :belongs_to then Associations::BelongsTo
|
151
|
+
when :has_one then Association::HasOne
|
152
|
+
when :has_and_belongs then Association::HasAndBelongs
|
153
|
+
else Property
|
154
|
+
end
|
155
|
+
end
|
156
|
+
|
157
|
+
##
|
158
|
+
# Derives the name of associated model from `options[:class_name]` and
|
159
|
+
# returns its class.
|
160
|
+
##
|
161
|
+
def model_from_options #nodoc
|
162
|
+
@options[:class_name].nil? ? nil : @options[:class_name].constantize
|
163
|
+
end
|
164
|
+
|
165
|
+
##
|
166
|
+
# Derives the name of associated model from association name and
|
167
|
+
# returns its class
|
168
|
+
##
|
169
|
+
def model_from_namespace #nodoc
|
170
|
+
name = multiple? ? @name.to_s.classify : @name.to_s.pluralize.classify
|
171
|
+
# Keep this weird comparison. RDF::Vocabulary doesn't recognize `nil?` or `==`
|
172
|
+
(nil == @cls.namespace) ? nil : @cls[@cls.namespace[name]]
|
173
|
+
end
|
174
|
+
|
175
|
+
##
|
176
|
+
# Checks if this attribute is an association with multiple objects
|
177
|
+
# (i.e. `has_many` or `has_and_belongs_to`). Used for deriving association
|
178
|
+
# name (plural / singular)
|
179
|
+
##
|
180
|
+
def multiple? #nodoc
|
181
|
+
@options[:association] == :has_many || @options[:association] == :has_and_belongs
|
182
|
+
end
|
183
|
+
|
184
|
+
end # Attribute
|
185
|
+
end # Model
|
186
|
+
end # RDFMapper
|