-
Notifications
You must be signed in to change notification settings - Fork 98
/
writable.rb
159 lines (149 loc) · 5.07 KB
/
writable.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
module RDF
##
# Classes that include this module must implement the methods
# `#insert_statement`.
#
# @see RDF::Graph
# @see RDF::Repository
module Writable
extend RDF::Util::Aliasing::LateBound
include RDF::Util::Coercions
##
# Returns `true` if `self` is writable.
#
# @return [Boolean] `true` or `false`
# @see RDF::Readable#readable?
def writable?
!frozen?
end
##
# Inserts RDF data into `self`.
#
# @param [RDF::Enumerable, RDF::Statement, #to_rdf] data
# @return [self]
def <<(data)
case data
when RDF::Reader
insert_reader(data)
when RDF::Graph
insert_graph(data)
when RDF::Enumerable
insert_statements(data)
when RDF::Statement
insert_statement(data)
else case
when data.respond_to?(:to_rdf) && !data.equal?(rdf = data.to_rdf)
self << rdf
else
insert_statement(Statement.from(data))
end
end
return self
end
##
# Inserts RDF statements into `self`.
#
# @note using splat argument syntax with excessive arguments provided
# significantly affects performance. Use Enumerator form for large
# numbers of statements.
#
# @overload insert(*statements)
# @param [Array<RDF::Statement>] statements
# @return [self]
# @raise [ArgumentError] on an attempt to insert an embedded statement when it is not supported
#
# @overload insert(statements)
# @param [Enumerable<RDF::Statement>] statements
# @return [self]
# @raise [ArgumentError] on an attempt to insert an embedded statement when it is not supported
def insert(*statements)
coerce_statements(statements) { |value| insert_statements value }
return self
end
alias_method :insert!, :insert
protected
##
# Inserts statements from the given RDF reader into the underlying
# storage or output stream.
#
# Defaults to passing the reader to the {RDF::Writable#insert_statements} method.
#
# Subclasses of {RDF::Repository} may wish to override this method in
# case their underlying storage can efficiently import RDF data directly
# in particular serialization formats, thus avoiding the intermediate
# parsing overhead.
#
# @param [RDF::Reader] reader
# @return [void]
# @since 0.2.3
def insert_reader(reader)
insert_statements(reader)
end
##
# Inserts the given RDF graph into the underlying storage or output
# stream.
#
# Defaults to passing the graph to the {RDF::Writable#insert_statements} method.
#
# Subclasses of {RDF::Repository} may wish to override this method in
# case their underlying storage architecture is graph-centric rather
# than statement-oriented.
#
# Subclasses of {RDF::Writer} may wish to override this method if the
# output format they implement supports named graphs, in which case
# implementing this method may help in producing prettier and more
# concise output.
#
# @param [RDF::Graph] graph
# @return [void]
def insert_graph(graph)
insert_statements(graph)
end
##
# Inserts the given RDF statements into the underlying storage or output
# stream.
#
# Defaults to invoking {RDF::Writable#insert_statement} for each given statement.
#
# Subclasses of {RDF::Repository} may wish to override this method if
# they are capable of more efficiently inserting multiple statements at
# once.
#
# Subclasses of {RDF::Writer} don't generally need to implement this
# method.
#
# @param [RDF::Enumerable] statements
# @return [void]
# @raise [ArgumentError] on an attempt to insert an embedded statement when it is not supported
# @since 0.1.6
def insert_statements(statements)
each = statements.respond_to?(:each_statement) ? :each_statement : :each
statements.__send__(each) do |statement|
if statement.embedded? && respond_to?(:supports?) && !supports?(:quoted_triples)
raise ArgumentError, "Writable does not support quoted triples"
end
if statement.object && statement.object.literal? && statement.object.direction? && respond_to?(:supports?) && !supports?(:base_direction)
raise ArgumentError, "Writable does not support directional languaged-tagged strings"
end
insert_statement(statement)
end
end
##
# Inserts an RDF statement into the underlying storage or output stream.
#
# Subclasses of {RDF::Repository} must implement this method, except if
# they are immutable.
#
# Subclasses of {RDF::Writer} must implement this method.
#
# @param [RDF::Statement] statement
# @return [void]
# @raise [ArgumentError] on an attempt to insert an embedded statement when it is not supported
# @abstract
def insert_statement(statement)
raise NotImplementedError.new("#{self.class}#insert_statement")
end
protected :insert_statements
protected :insert_statement
end # Writable
end # RDF