@@ -2,60 +2,59 @@ module JSON::LD
22 # Simple Ruby reflector class to provide native
33 # access to JSON-LD objects
44 class Resource
5- # @!attribute [r] attributes
5+ include RDF ::Enumerable
6+
67 # @return [Hash<String => Object] Object representation of resource
78 attr_reader :attributes
89
9- # @!attribute [r] id
1010 # @return [String] ID of this resource
1111 attr_reader :id
1212
13- # @!attribute [r] context
1413 # @return [JSON::LD::Context] Context associated with this resource
1514 attr_reader :context
1615
16+ ##
1717 # Is this resource clean (i.e., saved to mongo?)
1818 #
1919 # @return [Boolean]
2020 def clean? ; @clean ; end
2121
22+ ##
2223 # Is this resource dirty (i.e., not yet saved to mongo?)
2324 #
2425 # @return [Boolean]
2526 def dirty? ; !clean? ; end
26-
27+
28+ ##
2729 # Has this resource been reconciled against a mongo ID?
2830 #
2931 # @return [Boolean]
3032 def reconciled? ; @reconciled ; end
3133
34+ ##
3235 # Has this resource been resolved so that
3336 # all references are to other Resources?
3437 #
3538 # @return [Boolean]
3639 def resolved? ; @resolved ; end
3740
41+ ##
3842 # Anonymous resources have BNode ids or no schema:url
3943 #
4044 # @return [Boolean]
4145 def anonymous? ; @anon ; end
4246
47+ ##
4348 # Is this a stub resource, which has not yet been
4449 # synched or created within the DB?
4550 def stub? ; !!@stub ; end
4651
52+ ##
4753 # Is this a new resource, which has not yet been
4854 # synched or created within the DB?
4955 def new? ; !!@new ; end
5056
51- # Manage contexts used by resources.
52- #
53- # @param [String] ctx
54- # @return [JSON::LD::Context]
55- def self . set_context ( ctx )
56- ( @@contexts ||= { } ) [ ctx ] = JSON ::LD ::Context . new . parse ( ctx )
57- end
58-
57+ ##
5958 # A new resource from the parsed graph
6059 # @param [Hash{String => Object}] node_definition
6160 # @param [Hash{Symbol => Object}] options
@@ -76,8 +75,7 @@ def self.set_context(ctx)
7675 # This is a stand-in for another resource that has
7776 # not yet been retrieved (or created) from Mongo
7877 def initialize ( node_definition , options = { } )
79- @context_name = options [ :context ]
80- @context = self . class . set_context ( @context_name )
78+ @context = options [ :context ]
8179 @clean = options . fetch ( :clean , false )
8280 @new = options . fetch ( :new , true )
8381 @reconciled = options . fetch ( :reconciled , !@new )
@@ -91,12 +89,14 @@ def initialize(node_definition, options = {})
9189 @anon = @id . nil? || @id . to_s [ 0 , 2 ] == '_:'
9290 end
9391
92+ ##
9493 # Return a hash of this object, suitable for use by for ETag
9594 # @return [Fixnum]
9695 def hash
9796 self . deresolve . hash
9897 end
9998
99+ ##
100100 # Reverse resolution of resource attributes.
101101 # Just returns `attributes` if
102102 # resource is unresolved. Otherwise, replaces `Resource`
@@ -134,6 +134,7 @@ def deresolve
134134 compacted . delete_if { |k , v | k == '@context' }
135135 end
136136
137+ ##
137138 # Serialize to JSON-LD, minus `@context` using
138139 # a deresolved version of the attributes
139140 #
@@ -143,6 +144,13 @@ def to_json(options = nil)
143144 deresolve . to_json ( options )
144145 end
145146
147+ ##
148+ # Enumerate over statements associated with this resource
149+ def each ( &block )
150+ JSON ::LD ::API . toRdf ( attributes , expandContext : context , &block )
151+ end
152+
153+ ##
146154 # Update node references using the provided map.
147155 # This replaces node references with Resources,
148156 # either stub or instantiated.
@@ -186,29 +194,7 @@ def update_obj(obj, reference_map)
186194 self
187195 end
188196
189- # Merge resources
190- # FIXME: If unreconciled or unresolved resources are merged
191- # against reconciled/resolved resources, they will appear
192- # to not match, even if they are really the same thing.
193- #
194- # @param [Resource] resource
195- # @return [Resource] self
196- def merge ( resource )
197- if attributes . neq? ( resource . attributes )
198- resource . attributes . each do |p , v |
199- next if p == 'id'
200- if v . nil? or ( v . is_a? ( Array ) and v . empty? )
201- attributes . delete ( p )
202- else
203- attributes [ p ] = v
204- end
205- end
206- @resolved = @clean = false
207- end
208- self
209- end
210-
211- #
197+ ##
212198 # Override this method to implement save using
213199 # an appropriate storage mechanism.
214200 #
@@ -218,12 +204,14 @@ def merge(resource)
218204 #
219205 # @return [Boolean] true or false if resource not saved
220206 def save
221- raise NotImplemented
207+ raise NotImplementedError
222208 end
223209
210+ ##
224211 # Access individual fields, from subject definition
225212 def property ( prop_name ) ; @attributes . fetch ( prop_name , nil ) ; end
226213
214+ ##
227215 # Access individual fields, from subject definition
228216 def method_missing ( method , *args )
229217 property ( method . to_s )
0 commit comments