Class: JSON::LD::Resource

Inherits:
Object
  • Object
show all
Defined in:
lib/json/ld/resource.rb

Overview

Simple Ruby reflector class to provide native access to JSON-LD objects

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(node_definition, options = {}) ⇒ Resource

A new resource from the parsed graph

Parameters:

  • node_definition (Hash{String => Object})
  • options (Hash{Symbol => Object}) (defaults to: {})

Options Hash (options):

  • :context (String)

    Resource context, used for finding appropriate collection and JSON-LD context.

  • :clean (Boolean) — default: false
  • :compact (Boolean) — default: false

    Assume ‘node_definition` is in expanded form and compact using `context`.

  • :reconciled (Boolean) — default: !new

    node_definition is not based on Mongo IDs and must be reconciled against Mongo, or merged into another resource.

  • :new (Boolean) — default: true

    This is a new resource, not yet saved to Mongo

  • :stub (Boolean) — default: false

    This is a stand-in for another resource that has not yet been retrieved (or created) from Mongo



78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
# File 'lib/json/ld/resource.rb', line 78

def initialize(node_definition, options = {})
  @context_name = options[:context]
  @context = self.class.set_context(@context_name)
  @clean = options.fetch(:clean, false)
  @new = options.fetch(:new, true)
  @reconciled = options.fetch(:reconciled, !@new)
  @resolved = false
  @attributes = if options[:compact]
    JSON::LD::API.compact(node_definition, @context)
  else
    node_definition
  end
  @id = @attributes['@id']
  @anon = @id.nil? || @id.to_s[0,2] == '_:'
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(method, *args) ⇒ Object

Access individual fields, from subject definition



228
229
230
# File 'lib/json/ld/resource.rb', line 228

def method_missing(method, *args)
  property(method.to_s)
end

Instance Attribute Details

#attributesHash<String => Object] Object representation of resource (readonly)

Returns Hash<String => Object] Object representation of resource.

Returns:

  • (Hash<String => Object] Object representation of resource)

    Hash<String => Object] Object representation of resource



7
8
9
# File 'lib/json/ld/resource.rb', line 7

def attributes
  @attributes
end

#contextJSON::LD::Context (readonly)

Returns Context associated with this resource.

Returns:



15
16
17
# File 'lib/json/ld/resource.rb', line 15

def context
  @context
end

#idString (readonly)

Returns ID of this resource.

Returns:

  • (String)

    ID of this resource



11
12
13
# File 'lib/json/ld/resource.rb', line 11

def id
  @id
end

Class Method Details

.set_context(ctx) ⇒ JSON::LD::Context

Manage contexts used by resources.

Parameters:

  • ctx (String)

Returns:



55
56
57
# File 'lib/json/ld/resource.rb', line 55

def self.set_context(ctx)
  (@@contexts ||= {})[ctx] = JSON::LD::Context.new.parse(ctx)
end

Instance Method Details

#anonymous?Boolean

Anonymous resources have BNode ids or no schema:url

Returns:

  • (Boolean)


41
# File 'lib/json/ld/resource.rb', line 41

def anonymous?; @anon; end

#clean?Boolean

Is this resource clean (i.e., saved to mongo?)

Returns:

  • (Boolean)


20
# File 'lib/json/ld/resource.rb', line 20

def clean?; @clean; end

#deresolveHash

Reverse resolution of resource attributes. Just returns ‘attributes` if resource is unresolved. Otherwise, replaces `Resource` values with node references.

Result is expanded and re-compacted to get to normalized representation.

Returns:

  • (Hash)

    deresolved attribute hash



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
# File 'lib/json/ld/resource.rb', line 109

def deresolve
  node_definition = if resolved?
    deresolved = attributes.keys.inject({}) do |memo, prop|
      value = attributes[prop]
      memo[prop] = case value
      when Resource
        {'id' => value.id}
      when Array
        value.map do |v|
          v.is_a?(Resource) ? {'id' => v.id} : v
        end
      else
        value
      end
      memo
    end
    deresolved
  else
    attributes
  end

  compacted = nil
  JSON::LD::API.expand(node_definition, @context) do |expanded|
    compacted = JSON::LD::API.compact(expanded, @context)
  end
  compacted.delete_if {|k, v| k == '@context'}
end

#dirty?Boolean

Is this resource dirty (i.e., not yet saved to mongo?)

Returns:

  • (Boolean)


25
# File 'lib/json/ld/resource.rb', line 25

def dirty?; !clean?; end

#hashFixnum

Return a hash of this object, suitable for use by for ETag

Returns:

  • (Fixnum)


96
97
98
# File 'lib/json/ld/resource.rb', line 96

def hash
  self.deresolve.hash
end

#inspectObject



232
233
234
235
236
237
238
# File 'lib/json/ld/resource.rb', line 232

def inspect
  "<Resource" +
  attributes.map do |k, v|
    "\n  #{k}: #{v.inspect}"
  end.join(" ") +
  ">"
end

#merge(resource) ⇒ Resource

Merge resources FIXME: If unreconciled or unresolved resources are merged against reconciled/resolved resources, they will appear to not match, even if they are really the same thing.

Parameters:

Returns:



196
197
198
199
200
201
202
203
204
205
206
207
208
209
# File 'lib/json/ld/resource.rb', line 196

def merge(resource)
  if attributes.neq?(resource.attributes)
    resource.attributes.each do |p, v|
      next if p == 'id'
      if v.nil? or (v.is_a?(Array) and v.empty?)
        attributes.delete(p)
      else
        attributes[p] = v
      end
    end
    @resolved = @clean = false
  end
  self
end

#new?Boolean

Is this a new resource, which has not yet been synched or created within the DB?

Returns:

  • (Boolean)


49
# File 'lib/json/ld/resource.rb', line 49

def new?; !!@new; end

#property(prop_name) ⇒ Object

Access individual fields, from subject definition



225
# File 'lib/json/ld/resource.rb', line 225

def property(prop_name); @attributes.fetch(prop_name, nil); end

#reconciled?Boolean

Has this resource been reconciled against a mongo ID?

Returns:

  • (Boolean)


30
# File 'lib/json/ld/resource.rb', line 30

def reconciled?; @reconciled; end

#resolve(reference_map) ⇒ Resource

Update node references using the provided map. This replaces node references with Resources, either stub or instantiated.

Node references with ids not in the reference_map will cause stub resources to be added to the map.

Parameters:

Returns:



155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
# File 'lib/json/ld/resource.rb', line 155

def resolve(reference_map)
  return if resolved?
  def update_obj(obj, reference_map)
    case obj
    when Array
      obj.map {|o| update_obj(o, reference_map)}
    when Hash
      if obj.node_ref?
        reference_map[obj['id']] ||= Resource.new(obj,
          :context => @context_name,
          :clean => false,
          :stub => true
          )
      else
        obj.keys.each do |k|
          obj[k] = update_obj(obj[k], reference_map)
        end
        obj
      end
    else
      obj
    end
  end

  #$logger.debug "resolve(0): #{attributes.inspect}"
  @attributes.each do |k, v|
    next if %w(id type).include?(k)
    @attributes[k] = update_obj(@attributes[k], reference_map)
  end
  #$logger.debug "resolve(1): #{attributes.inspect}"
  @resolved = true
  self
end

#resolved?Boolean

Has this resource been resolved so that all references are to other Resources?

Returns:

  • (Boolean)


36
# File 'lib/json/ld/resource.rb', line 36

def resolved?; @resolved; end

#saveBoolean

Override this method to implement save using an appropriate storage mechanism.

Save the object to the Mongo collection use Upsert to create things that don’t exist. First makes sure that the resource is valid.

Returns:

  • (Boolean)

    true or false if resource not saved

Raises:

  • (NotImplemented)


220
221
222
# File 'lib/json/ld/resource.rb', line 220

def save
  raise NotImplemented
end

#stub?Boolean

Is this a stub resource, which has not yet been synched or created within the DB?

Returns:

  • (Boolean)


45
# File 'lib/json/ld/resource.rb', line 45

def stub?; !!@stub; end

#to_json(options = nil) ⇒ String

Serialize to JSON-LD, minus ‘@context` using a deresolved version of the attributes

Parameters:

  • options (Hash) (defaults to: nil)

Returns:

  • (String)

    serizlied JSON representation of resource



142
143
144
# File 'lib/json/ld/resource.rb', line 142

def to_json(options = nil)
  deresolve.to_json(options)
end

#update_obj(obj, reference_map) ⇒ Object



157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
# File 'lib/json/ld/resource.rb', line 157

def update_obj(obj, reference_map)
  case obj
  when Array
    obj.map {|o| update_obj(o, reference_map)}
  when Hash
    if obj.node_ref?
      reference_map[obj['id']] ||= Resource.new(obj,
        :context => @context_name,
        :clean => false,
        :stub => true
        )
    else
      obj.keys.each do |k|
        obj[k] = update_obj(obj[k], reference_map)
      end
      obj
    end
  else
    obj
  end
end